virNWFilterRuleDefDetailsFormat(virBuffer *buf,
const char *type,
const virXMLAttr2Struct *att,
- virNWFilterRuleDef *def)
+ virNWFilterRuleDef *def,
+ bool negative,
+ bool *hasAttrs)
{
- size_t i = 0, j;
- bool typeShown = false;
- bool neverShown = true;
- bool asHex;
- enum match {
- MATCH_NONE = 0,
- MATCH_YES,
- MATCH_NO
- } matchShown = MATCH_NONE;
- nwItemDesc *item;
+ g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
+ bool present = false;
+ size_t i;
+ size_t j;
- while (att[i].name) {
- virNWFilterEntryItemFlags flags;
+ if (negative)
+ virBufferAddLit(&attrBuf, " match='no'");
+
+ for (i = 0; att[i].name; i++) {
+ nwItemDesc *item;
VIR_WARNINGS_NO_CAST_ALIGN
item = (nwItemDesc *)((char *)def + att[i].dataIdx);
VIR_WARNINGS_RESET
- flags = item->flags;
- if ((flags & NWFILTER_ENTRY_ITEM_FLAG_EXISTS)) {
- if (!typeShown) {
- virBufferAsprintf(buf, "<%s", type);
- typeShown = true;
- neverShown = false;
- }
+ if (!(item->flags & NWFILTER_ENTRY_ITEM_FLAG_EXISTS))
+ continue;
- if ((flags & NWFILTER_ENTRY_ITEM_FLAG_IS_NEG)) {
- if (matchShown == MATCH_NONE) {
- virBufferAddLit(buf, " match='no'");
- matchShown = MATCH_NO;
- } else if (matchShown == MATCH_YES) {
- virBufferAddLit(buf, "/>\n");
- typeShown = false;
- matchShown = MATCH_NONE;
- continue;
- }
- } else {
- if (matchShown == MATCH_NO) {
- virBufferAddLit(buf, "/>\n");
- typeShown = false;
- matchShown = MATCH_NONE;
- continue;
- }
- matchShown = MATCH_YES;
+ if (negative != !!(item->flags & NWFILTER_ENTRY_ITEM_FLAG_IS_NEG))
+ continue;
+
+ present = true;
+ *hasAttrs = true;
+
+ virBufferAsprintf(&attrBuf, " %s='", att[i].name);
+
+ if (att[i].formatter && !(item->flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) {
+ if (!att[i].formatter(&attrBuf, def, item)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("formatter for %1$s %2$s reported error"),
+ type, att[i].name);
+ return;
}
+ } else if ((item->flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) {
+ virBufferAddChar(&attrBuf, '$');
+ virNWFilterVarAccessPrint(item->varAccess, &attrBuf);
+ } else {
- virBufferAsprintf(buf, " %s='",
- att[i].name);
- if (att[i].formatter && !(flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) {
- if (!att[i].formatter(buf, def, item)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("formatter for %1$s %2$s reported error"),
- type,
- att[i].name);
- return;
- }
- } else if ((flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) {
- virBufferAddChar(buf, '$');
- virNWFilterVarAccessPrint(item->varAccess, buf);
- } else {
- asHex = false;
-
- switch (item->datatype) {
-
- case DATATYPE_UINT8_HEX:
- asHex = true;
- G_GNUC_FALLTHROUGH;
- case DATATYPE_IPMASK:
- case DATATYPE_IPV6MASK:
- /* display all masks in CIDR format */
- case DATATYPE_UINT8:
- virBufferAsprintf(buf, asHex ? "0x%x" : "%d",
- item->u.u8);
- break;
-
- case DATATYPE_UINT16_HEX:
- asHex = true;
- G_GNUC_FALLTHROUGH;
- case DATATYPE_UINT16:
- virBufferAsprintf(buf, asHex ? "0x%x" : "%d",
- item->u.u16);
- break;
-
- case DATATYPE_UINT32_HEX:
- asHex = true;
- G_GNUC_FALLTHROUGH;
- case DATATYPE_UINT32:
- virBufferAsprintf(buf, asHex ? "0x%x" : "%u",
- item->u.u32);
- break;
-
- case DATATYPE_IPADDR:
- case DATATYPE_IPV6ADDR:
- virNWIPAddressFormat(buf,
- &item->u.ipaddr);
- break;
-
- case DATATYPE_MACMASK:
- case DATATYPE_MACADDR:
- for (j = 0; j < 6; j++)
- virBufferAsprintf(buf, "%02x%s",
- item->u.macaddr.addr[j],
- (j < 5) ? ":" : "");
- break;
-
- case DATATYPE_STRINGCOPY:
- virBufferEscapeString(buf, "%s", item->u.string);
- break;
-
- case DATATYPE_BOOLEAN:
- if (item->u.boolean)
- virBufferAddLit(buf, "true");
- else
- virBufferAddLit(buf, "false");
- break;
-
- case DATATYPE_IPSETNAME:
- case DATATYPE_IPSETFLAGS:
- case DATATYPE_STRING:
- case DATATYPE_LAST:
- default:
- virBufferAsprintf(buf,
- "UNSUPPORTED DATATYPE 0x%02x\n",
- att[i].datatype);
- }
+ switch (item->datatype) {
+
+ case DATATYPE_UINT8_HEX:
+ virBufferAsprintf(&attrBuf, "0x%x", item->u.u8);
+ break;
+
+ case DATATYPE_IPMASK:
+ case DATATYPE_IPV6MASK:
+ /* display all masks in CIDR format */
+ case DATATYPE_UINT8:
+ virBufferAsprintf(&attrBuf, "%d", item->u.u8);
+ break;
+
+ case DATATYPE_UINT16_HEX:
+ virBufferAsprintf(&attrBuf, "0x%x", item->u.u16);
+ break;
+
+ case DATATYPE_UINT16:
+ virBufferAsprintf(&attrBuf, "%d", item->u.u16);
+ break;
+
+ case DATATYPE_UINT32_HEX:
+ virBufferAsprintf(&attrBuf, "0x%x", item->u.u32);
+ break;
+
+ case DATATYPE_UINT32:
+ virBufferAsprintf(&attrBuf, "%u", item->u.u32);
+ break;
+
+ case DATATYPE_IPADDR:
+ case DATATYPE_IPV6ADDR:
+ virNWIPAddressFormat(&attrBuf, &item->u.ipaddr);
+ break;
+
+ case DATATYPE_MACMASK:
+ case DATATYPE_MACADDR:
+ for (j = 0; j < 6; j++)
+ virBufferAsprintf(&attrBuf, "%02x%s",
+ item->u.macaddr.addr[j],
+ (j < 5) ? ":" : "");
+ break;
+
+ case DATATYPE_STRINGCOPY:
+ virBufferEscapeString(&attrBuf, "%s", item->u.string);
+ break;
+
+ case DATATYPE_BOOLEAN:
+ if (item->u.boolean)
+ virBufferAddLit(&attrBuf, "true");
+ else
+ virBufferAddLit(&attrBuf, "false");
+ break;
+
+ case DATATYPE_IPSETNAME:
+ case DATATYPE_IPSETFLAGS:
+ case DATATYPE_STRING:
+ case DATATYPE_LAST:
+ default:
+ virBufferAsprintf(&attrBuf,
+ "UNSUPPORTED DATATYPE 0x%02x\n",
+ att[i].datatype);
}
- virBufferAddLit(buf, "'");
}
- i++;
+
+ virBufferAddLit(&attrBuf, "'");
}
- if (typeShown)
- virBufferAddLit(buf, "/>\n");
- if (neverShown)
- virBufferAsprintf(buf,
- "<%s/>\n", type);
+ if (!present)
+ return;
- return;
+ virXMLFormatElement(buf, type, &attrBuf, NULL);
}
virBufferAddLit(&attrBuf, " statematch='false'");
for (i = 0; virAttr[i].id; i++) {
+ bool hasAttrs = false;
+
if (virAttr[i].prtclType != def->prtclType)
continue;
- virNWFilterRuleDefDetailsFormat(&childBuf, virAttr[i].id, virAttr[i].att, def);
+ virNWFilterRuleDefDetailsFormat(&childBuf, virAttr[i].id, virAttr[i].att, def, false, &hasAttrs);
+ virNWFilterRuleDefDetailsFormat(&childBuf, virAttr[i].id, virAttr[i].att, def, true, &hasAttrs);
+
+ if (!hasAttrs)
+ virBufferAsprintf(&childBuf, "<%s/>\n", virAttr[i].id);
+
break;
}