} while(0)
#define TAG_VALID(x) ((x) > 0 && (x) < 0x20)
-#define TAG_VALID_ZERO(x) ((x) < 0x20)
+#define TAG_VALID_ZERO(x) ((x) >= 0 && (x) < 0x20)
#define TAG_ANY INT8_MIN
+#define TAG_VALUE (INT8_MIN + 1)
#define TAG_NONE 0
/** Check if tags are equal
*
da = dict_attrbyvalue(attr.da->attr, attr.da->vendor);
if (da && (attr.da != da)) attr.da = da;
-
/*
* The string MIGHT have a tag.
*/
return -(p - name);
}
+ /*
+ * Get the tag from the value.
+ */
+ if (*p == 'V') {
+ attr.tag = TAG_VALUE;
+ p++;
+ goto do_num;
+ }
+
num = strtol(p + 1, &q, 10);
if ((num > 0x1f) || (num < 0)) {
fr_strerror_printf("Invalid tag value '%li' (should be between 0-31)", num);
}
data.strvalue = p;
+ /*
+ * Copy over any additional fields needed...
+ */
+ if ((vpt->type == TMPL_TYPE_ATTR) && vp->da->flags.has_tag) {
+ vp->tag = vpt->tmpl_tag;
+ }
+
/*
* New escapes: strings are in binary form.
*/
return -1;
}
- /*
- * Copy over any additional fields needed...
- */
- if ((vpt->type == TMPL_TYPE_ATTR) && vp->da->flags.has_tag) {
- vp->tag = vpt->tmpl_tag;
- }
-
*out = vp;
return 0;
}
q = out + len;
outlen -= len;
- if (vpt->tmpl_tag != TAG_ANY) {
+ if (vpt->tmpl_tag == TAG_ANY) {
+ /* do nothing */
+
+ } else if (vpt->tmpl_tag == TAG_VALUE) {
+ *q++ = ':';
+ *q++ = 'V';
+ outlen -= 2;
+
+ } else {
snprintf(q, outlen, ":%d", vpt->tmpl_tag);
len = strlen(q);
q += len;
* May not may not be found, but it *is* a known name.
*/
case TMPL_TYPE_ATTR:
+ if (vpt->tmpl_tag == TAG_ANY) {
+ if (err) *err = -1;
+ return NULL;
+ }
+
switch (vpt->tmpl_num) {
case NUM_ANY:
vp = fr_cursor_next_by_da(cursor, vpt->tmpl_da, vpt->tmpl_tag);
DEBUG("%.*sref %d", lvl + 1, xlat_tabs, node->attr.tmpl_request);
DEBUG("%.*slist %d", lvl + 1, xlat_tabs, node->attr.tmpl_list);
- if (node->attr.tmpl_tag != TAG_ANY) {
+ if (node->attr.tmpl_tag == TAG_VALUE) {
+ DEBUG("%.*stag V", lvl + 1, xlat_tabs);
+ } else if (node->attr.tmpl_tag != TAG_ANY) {
DEBUG("%.*stag %d", lvl + 1, xlat_tabs, node->attr.tmpl_tag);
}
if (node->attr.tmpl_num != NUM_ANY) {