XLAT_ALTERNATE //!< xlat conditional syntax :-
} xlat_state_t;
-#define XLAT_ATTR_NUMBER 65536 //!< The number of times this attribute appears in a list.
-#define XLAT_ATTR_CONCAT 65537 //!< All instance of this attribute should be concatenated into a string.
-
struct xlat_exp {
char const *fmt; //!< The format string.
size_t len; //!< Length of the format string.
DICT_ATTR const *da; //!< the name of the dictionary attribute
- int num; //!< attribute number
- int tag; //!< attribute tag
+ int8_t num; //!< attribute number
+ int8_t tag; //!< attribute tag
pair_lists_t list; //!< list of which attribute
request_refs_t ref; //!< outer / this / ...
* Check for array reference
*/
if (q) {
- unsigned long num;
+ int8_t num;
char *end;
p = q;
if (*p== '#') {
- node->num = XLAT_ATTR_NUMBER;
+ node->num = NUM_COUNT;
p++;
} else if (*p == '*') {
- node->num = XLAT_ATTR_CONCAT;
+ node->num = NUM_JOIN;
p++;
} else if (isdigit((int) *p)) {
num = strtoul(p, &end, 10);
- if ((num == ULONG_MAX) || (num >= XLAT_ATTR_NUMBER)) {
+ if (num > 127) {
talloc_free(node);
- *error = "Invalid number";
+ *error = "Invalid array reference";
return - (p - fmt);
}
p = end;
*error = "Unexpected text after array reference";
return - (p - fmt);
}
+ } else {
+ node->num = NUM_ANY;
}
rad_assert(!p || (p == brace));
rad_assert(node->da != NULL);
DEBUG("%.*sattribute --> %s", lvl, xlat_tabs, node->da->name);
rad_assert(node->child == NULL);
- if ((node->tag != 0) || (node->num != 0)) {
+ if ((node->tag != TAG_UNUSED) || (node->num != NUM_ANY)) {
DEBUG("%.*s{", lvl, xlat_tabs);
DEBUG("%.*sref %d", lvl + 1, xlat_tabs, node->ref);
DEBUG("%.*slist %d", lvl + 1, xlat_tabs, node->list);
if (node->tag) DEBUG("%.*stag %d", lvl + 1, xlat_tabs, node->tag);
- if (node->num) {
- if (node->num == XLAT_ATTR_NUMBER) {
+ if (node->num != NUM_ANY) {
+ if (node->num == NUM_COUNT) {
DEBUG("%.*s[#]", lvl + 1, xlat_tabs);
- } else if (node->num == XLAT_ATTR_CONCAT) {
+ } else if (node->num == NUM_JOIN) {
DEBUG("%.*s[*]", lvl + 1, xlat_tabs);
} else {
DEBUG("%.*s[%d]", lvl + 1, xlat_tabs, node->num);
p += strlen(p);
}
- if (node->num != 0) {
+ if (node->num != NUM_ANY) {
*(p++) = '[';
switch (node->num) {
- case XLAT_ATTR_NUMBER:
+ case NUM_COUNT:
*(p++) = '#';
break;
- case XLAT_ATTR_CONCAT:
+ case NUM_JOIN:
*(p++) = '*';
break;
static char *xlat_getvp(TALLOC_CTX *ctx, REQUEST *request, pair_lists_t list, DICT_ATTR const *da, int8_t tag,
- int num, bool return_null)
+ int8_t num, bool return_null)
{
VALUE_PAIR *vp, *vps = NULL, *myvp = NULL;
RADIUS_PACKET *packet = NULL;
/*
* Fake various operations for virtual attributes.
*/
- if (num && myvp) {
+ if ((num != NUM_ANY) && myvp) {
char *p;
+ switch (num) {
/*
* [*] means only one.
*/
- if (num == XLAT_ATTR_CONCAT) num = 0;
+ case NUM_JOIN:
+ num = 0;
+ break;
/*
* [n] means NULL, as there's only one.
*/
- if ((num > 0) && (num < XLAT_ATTR_NUMBER)) goto finish;
-
- p = vp_aprint_value(ctx, vp);
- rad_assert(p != NULL);
+ case NUM_COUNT:
+ p = vp_aprint_value(ctx, vp);
+ rad_assert(p != NULL);
- /*
- * Get the length of it.
- */
- if (num == XLAT_ATTR_NUMBER) {
+ /*
+ * Get the length of it.
+ */
ret = talloc_typed_asprintf(ctx, "%d", (int) strlen(p));
talloc_free(p);
goto finish;
- }
- ret = p;
- goto finish;
+ ret = p;
+ goto finish;
+
+ default:
+ goto finish;
+
+ }
}
/*
* We want the N'th VP.
*/
- if (num) {
+ if (num != NUM_ANY) {
int count = 0;
vp_cursor_t cursor;
/*
* Return a count of the VPs.
*/
- case XLAT_ATTR_NUMBER:
+ case NUM_COUNT:
fr_cursor_init(&cursor, &vp);
while (fr_cursor_next_by_da(&cursor, da, tag) != NULL) {
count++;
/*
* Ugly, but working.
*/
- case XLAT_ATTR_CONCAT:
+ case NUM_JOIN:
{
char *p, *q;
}
/*
- * Try to convert an xlat to a tmpl
+ * Try to convert an xlat to a tmpl for efficiency
*/
value_pair_tmpl_t *radius_xlat2tmpl(TALLOC_CTX *ctx, xlat_exp_t *xlat)
{
if (xlat->next || (xlat->type != XLAT_ATTRIBUTE)) return NULL;
/*
- * Can't convert Nth reference, or tags to templates.
- * They have no such fields.
+ * @todo it should be possible to emulate the concat and count operations in the
+ * map code.
*/
- if ((xlat->num != 0) || (xlat->tag != TAG_ANY)) return NULL;
+ if ((xlat->num == NUM_COUNT) || (xlat->num == NUM_JOIN)) return NULL;
vpt = talloc(ctx, value_pair_tmpl_t);
if (!vpt) return NULL;
vpt->vpt_request = xlat->ref;
vpt->vpt_list = xlat->list;
vpt->vpt_da = xlat->da;
+ vpt->vpt_num = xlat->num;
+ vpt->vpt_tag = xlat->tag;
return vpt;
}