case TMPL_TYPE_ATTR:
break;
- case TMPL_TYPE_ATTR_UNDEFINED:
+ case TMPL_TYPE_ATTR_UNPARSED:
cf_log_err(map->ci, "Unknown attribute %s", tmpl_unknown_name(map->lhs));
return -1;
case TMPL_TYPE_UNPARSED:
break;
- case TMPL_TYPE_ATTR_UNDEFINED:
+ case TMPL_TYPE_ATTR_UNPARSED:
cf_log_err(map->ci, "Unknown attribute %s", tmpl_unknown_name(map->rhs));
return -1;
if (!cp->printed) cf_log_debug(cs, "%.*s%s = %s", PAIR_SPACE(cs), parse_spaces, cf_pair_attr(cp), cp->value);
/*
- * This is so we produce TMPL_TYPE_ATTR_UNDEFINED template that
+ * This is so we produce TMPL_TYPE_ATTR_UNPARSED template that
* the bootstrap functions can use to create an attribute.
*
* For other types of template such as xlats, we don't bother.
/*
* All attributes should have been defined by this point.
*/
- case TMPL_TYPE_ATTR_UNDEFINED:
+ case TMPL_TYPE_ATTR_UNPARSED:
cf_log_err(cp, "Unknown attribute '%s'", tmpl_unknown_name(vpt));
talloc_free(vpt); /* Free last (vpt needed for log) */
return -1;
break;
case TMPL_TYPE_UNKNOWN:
+ case TMPL_TYPE_REGEX_UNPARSED:
case TMPL_TYPE_REGEX:
- case TMPL_TYPE_REGEX_STRUCT:
case TMPL_TYPE_NULL:
fr_assert(0);
/* Don't add default */
/*
* Can't have a bare ... (/foo/) ...
*/
+ case TMPL_TYPE_REGEX_UNPARSED:
case TMPL_TYPE_REGEX:
- case TMPL_TYPE_REGEX_STRUCT:
fr_assert(0 == 1);
/* FALL-THROUGH */
EVAL_DEBUG("CMP WITH REGEX");
switch (map->rhs->type) {
- case TMPL_TYPE_REGEX_STRUCT: /* pre-compiled to a regex */
+ case TMPL_TYPE_REGEX: /* pre-compiled to a regex */
preg = tmpl_preg(map->rhs);
break;
/*
* RHS is a compiled regex, we don't need to do anything with it.
*/
- case TMPL_TYPE_REGEX_STRUCT:
+ case TMPL_TYPE_REGEX:
CAST(lhs);
rcode = cond_cmp_values(request, c, lhs, NULL);
break;
case TMPL_TYPE_NULL:
case TMPL_TYPE_LIST:
case TMPL_TYPE_UNKNOWN:
- case TMPL_TYPE_ATTR_UNDEFINED:
- case TMPL_TYPE_REGEX: /* Should now be a TMPL_TYPE_REGEX_STRUCT or TMPL_TYPE_XLAT */
+ case TMPL_TYPE_ATTR_UNPARSED:
+ case TMPL_TYPE_REGEX_UNPARSED: /* Should now be a TMPL_TYPE_REGEX or TMPL_TYPE_XLAT */
fr_assert(0);
rcode = -1;
break;
* Unsupported types (should have been parse errors)
*/
case TMPL_TYPE_NULL:
- case TMPL_TYPE_ATTR_UNDEFINED:
+ case TMPL_TYPE_ATTR_UNPARSED:
case TMPL_TYPE_UNKNOWN:
- case TMPL_TYPE_REGEX: /* should now be a TMPL_TYPE_REGEX_STRUCT or TMPL_TYPE_XLAT */
- case TMPL_TYPE_REGEX_STRUCT: /* not allowed as LHS */
+ case TMPL_TYPE_REGEX_UNPARSED: /* should now be a TMPL_TYPE_REGEX or TMPL_TYPE_XLAT */
+ case TMPL_TYPE_REGEX: /* not allowed as LHS */
fr_assert(0);
rcode = -1;
break;
switch (c->data.vpt->type) {
case TMPL_TYPE_XLAT_UNPARSED:
case TMPL_TYPE_ATTR:
- case TMPL_TYPE_ATTR_UNDEFINED:
+ case TMPL_TYPE_ATTR_UNPARSED:
case TMPL_TYPE_LIST:
case TMPL_TYPE_EXEC:
break;
/** Map #tmpl_type_t values to descriptive strings
*/
fr_table_num_sorted_t const tmpl_type_table[] = {
- { "attr", TMPL_TYPE_ATTR },
+ { "null", TMPL_TYPE_NULL },
{ "data", TMPL_TYPE_DATA },
- { "exec", TMPL_TYPE_EXEC },
+
+ { "attr", TMPL_TYPE_ATTR },
{ "list", TMPL_TYPE_LIST },
- { "literal", TMPL_TYPE_UNPARSED },
- { "null", TMPL_TYPE_NULL },
- { "parsed regex", TMPL_TYPE_REGEX_STRUCT },
- { "parsed xlat", TMPL_TYPE_XLAT },
+
+ { "exec", TMPL_TYPE_EXEC },
+ { "xlat", TMPL_TYPE_XLAT },
+
{ "regex", TMPL_TYPE_REGEX },
- { "unknown attr", TMPL_TYPE_ATTR_UNDEFINED },
- { "xlat", TMPL_TYPE_XLAT_UNPARSED }
+
+ { "literal", TMPL_TYPE_UNPARSED },
+ { "attr-undefined", TMPL_TYPE_ATTR_UNPARSED },
+ { "xlat-unparsed", TMPL_TYPE_XLAT_UNPARSED },
+ { "regex-unparsed", TMPL_TYPE_REGEX_UNPARSED }
};
size_t tmpl_type_table_len = NUM_ELEMENTS(tmpl_type_table);
fr_assert(type <= TMPL_TYPE_NULL);
#ifndef HAVE_REGEX
- if ((type == TMPL_TYPE_REGEX) || (type == TMPL_TYPE_REGEX_STRUCT)) {
+ if ((type == TMPL_TYPE_REGEX_UNPARSED) || (type == TMPL_TYPE_REGEX)) {
return NULL;
}
#endif
* to search for a #VALUE_PAIR in a #REQUEST.
* - allow_undefined If true, we don't generate a parse error on
* unknown attributes. If an unknown attribute is
- * found a #TMPL_TYPE_ATTR_UNDEFINED
+ * found a #TMPL_TYPE_ATTR_UNPARSED
* #vp_tmpl_t will be produced.
* - allow_foreign If true, allow attribute names to be qualified
* with a protocol outside of the passed dict_def.
/*
* Copy the name to a field for later resolution
*/
- vpt->type = TMPL_TYPE_ATTR_UNDEFINED;
+ vpt->type = TMPL_TYPE_ATTR_UNPARSED;
for (q = p; (q < (name + name_len)) && ((*q == '.') || fr_dict_attr_allowed_chars[(uint8_t) *q]); q++);
if (q == p) {
fr_strerror_printf("Invalid attribute name");
* @param[in] type of quoting around value. May be one of:
* - #T_BARE_WORD - If string begins with ``&``
* produces #TMPL_TYPE_ATTR,
- * #TMPL_TYPE_ATTR_UNDEFINED, #TMPL_TYPE_LIST or error.
+ * #TMPL_TYPE_ATTR_UNPARSED, #TMPL_TYPE_LIST or error.
* If string does not begin with ``&`` produces
* #TMPL_TYPE_UNPARSED, #TMPL_TYPE_ATTR or #TMPL_TYPE_LIST.
* - #T_SINGLE_QUOTED_STRING - Produces #TMPL_TYPE_UNPARSED
* - #T_DOUBLE_QUOTED_STRING - Produces #TMPL_TYPE_XLAT_UNPARSED or
* #TMPL_TYPE_UNPARSED (if string doesn't contain ``%``).
* - #T_BACK_QUOTED_STRING - Produces #TMPL_TYPE_EXEC
- * - #T_OP_REG_EQ - Produces #TMPL_TYPE_REGEX
+ * - #T_OP_REG_EQ - Produces #TMPL_TYPE_REGEX_UNPARSED
* @param[in] rules Parsing rules for attribute references.
* @param[in] do_unescape whether or not we should do unescaping.
* Should be false if the caller already did it.
break;
case T_OP_REG_EQ: /* hack */
- vpt = tmpl_alloc(ctx, TMPL_TYPE_REGEX, in, inlen, T_BARE_WORD);
+ vpt = tmpl_alloc(ctx, TMPL_TYPE_REGEX_UNPARSED, in, inlen, T_BARE_WORD);
slen = vpt->len;
break;
case TMPL_TYPE_UNKNOWN:
case TMPL_TYPE_NULL:
case TMPL_TYPE_LIST:
+ case TMPL_TYPE_REGEX_UNPARSED:
+ case TMPL_TYPE_ATTR_UNPARSED:
case TMPL_TYPE_REGEX:
- case TMPL_TYPE_ATTR_UNDEFINED:
- case TMPL_TYPE_REGEX_STRUCT:
fr_assert(0);
return -1;
}
case TMPL_TYPE_UNKNOWN:
case TMPL_TYPE_NULL:
case TMPL_TYPE_LIST:
+ case TMPL_TYPE_REGEX_UNPARSED:
+ case TMPL_TYPE_ATTR_UNPARSED:
case TMPL_TYPE_REGEX:
- case TMPL_TYPE_ATTR_UNDEFINED:
- case TMPL_TYPE_REGEX_STRUCT:
fr_assert(0);
goto error;
}
RETURN_IF_TRUNCATED(need, len, out_p, out, end);
goto inst_and_tag;
- case TMPL_TYPE_ATTR_UNDEFINED:
+ case TMPL_TYPE_ATTR_UNPARSED:
p = tmpl_unknown_name(vpt);
goto print_name;
switch (vpt->type) {
case TMPL_TYPE_LIST:
- case TMPL_TYPE_ATTR_UNDEFINED:
+ case TMPL_TYPE_ATTR_UNPARSED:
case TMPL_TYPE_ATTR:
*out_p++ = '&';
return tmpl_snprint_attr_str(need, out_p, end - out_p, vpt) + 1;
/*
* Regexes have their own set of escaping rules
*/
+ case TMPL_TYPE_REGEX_UNPARSED:
case TMPL_TYPE_REGEX:
- case TMPL_TYPE_REGEX_STRUCT:
if ((end - out_p) <= 3) { /* / + <c> + / + \0 */
no_space:
if (out_p > end) out_p = end; /* Safety */
/* tmpl_xlat(vpt) can be initialized */
break;
- case TMPL_TYPE_ATTR_UNDEFINED:
+ case TMPL_TYPE_ATTR_UNPARSED:
fr_assert(tmpl_da(vpt) == NULL);
break;
break;
- case TMPL_TYPE_REGEX:
+ case TMPL_TYPE_REGEX_UNPARSED:
#ifdef HAVE_REGEX
if (tmpl_preg(vpt) != NULL) {
- fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_REGEX "
+ fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_REGEX_UNPARSED "
"preg field was not NULL", file, line);
}
#else
- fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_REGEX - No regex support",
+ fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_REGEX_UNPARSED - No regex support",
file, line);
#endif
break;
- case TMPL_TYPE_REGEX_STRUCT:
+ case TMPL_TYPE_REGEX:
#ifdef HAVE_REGEX
if (tmpl_preg(vpt) == NULL) {
- fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_REGEX_STRUCT "
+ fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_REGEX "
"comp field was NULL", file, line);
}
#else
- fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_REGEX_STRUCT - No regex support",
+ fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_REGEX - No regex support",
file, line);
#endif
break;
*/
typedef enum tmpl_type_e {
TMPL_TYPE_UNKNOWN = 0, //!< Uninitialised.
- TMPL_TYPE_UNPARSED, //!< Unparsed literal string.
- TMPL_TYPE_XLAT_UNPARSED, //!< XLAT expansion.
- TMPL_TYPE_ATTR, //!< Dictionary attribute.
- TMPL_TYPE_ATTR_UNDEFINED, //!< Attribute not found in the global dictionary.
- TMPL_TYPE_LIST, //!< Attribute list.
- TMPL_TYPE_REGEX, //!< Regular expression.
+
+ TMPL_TYPE_NULL, //!< Has no value. Usually a placeholder in a binary
+ ///< expression that's really a unary expression.
+ TMPL_TYPE_DATA, //!< Value in native boxed format.
+
+ TMPL_TYPE_LIST, //!< Reference to an attribute list.
+ TMPL_TYPE_ATTR, //!< Reference to one or more attributes.
+
TMPL_TYPE_EXEC, //!< Callout to an external script or program.
- TMPL_TYPE_DATA, //!< Value in native format.
- TMPL_TYPE_XLAT, //!< Pre-parsed XLAT expansion.
- TMPL_TYPE_REGEX_STRUCT, //!< Pre-parsed regular expression.
- TMPL_TYPE_NULL //!< Has no value.
+ TMPL_TYPE_XLAT, //!< Pre-parsed xlat expansion.
+
+ TMPL_TYPE_REGEX, //!< Compiled (and possibly JIT'd) regular expression.
+
+ /** @name Unparsed types
+ *
+ * These are tmpls which could not immediately be transformed into
+ * their "parsed" or "compiled" form due to missing references,
+ * or because the tmpl is "dynamic".
+ *
+ * @{
+ */
+ TMPL_TYPE_UNPARSED, //!< Unparsed literal string. May be an intermediary phase
+ ///< where the tmpl is created as a temporary structure
+ ///< during parsing.
+
+ TMPL_TYPE_ATTR_UNPARSED, //!< An attribute reference that we couldn't resolve.
+ ///< May be resolvable later once more attributes are
+ ///< defined.
+
+ TMPL_TYPE_XLAT_UNPARSED, //!< Unparsed xlat expansion. May have a dynamic element.
+
+ TMPL_TYPE_REGEX_UNPARSED, //!< Unparsed regular expression. May have a dynamic element.
+ /** @} */
} tmpl_type_t;
/** Helpers to verify the type of #vp_tmpl_t
#define tmpl_is_unparsed(vpt) (vpt->type == TMPL_TYPE_UNPARSED)
#define tmpl_is_xlat(vpt) (vpt->type == TMPL_TYPE_XLAT_UNPARSED)
#define tmpl_is_attr(vpt) (vpt->type == TMPL_TYPE_ATTR)
-#define tmpl_is_attr_undefined(vpt) (vpt->type == TMPL_TYPE_ATTR_UNDEFINED)
+#define tmpl_is_attr_undefined(vpt) (vpt->type == TMPL_TYPE_ATTR_UNPARSED)
#define tmpl_is_list(vpt) (vpt->type == TMPL_TYPE_LIST)
-#define tmpl_is_regex(vpt) (vpt->type == TMPL_TYPE_REGEX)
+#define tmpl_is_regex(vpt) (vpt->type == TMPL_TYPE_REGEX_UNPARSED)
#define tmpl_is_exec(vpt) (vpt->type == TMPL_TYPE_EXEC)
#define tmpl_is_data(vpt) (vpt->type == TMPL_TYPE_DATA)
#define tmpl_is_xlat_struct(vpt) (vpt->type == TMPL_TYPE_XLAT)
-#define tmpl_is_regex_struct(vpt) (vpt->type == TMPL_TYPE_REGEX_STRUCT)
+#define tmpl_is_regex_struct(vpt) (vpt->type == TMPL_TYPE_REGEX)
#define tmpl_is_null(vpt) (vpt->type == TMPL_TYPE_NULL)
extern fr_table_num_sorted_t const tmpl_type_table[];
*
* @section conditional_maps Use in conditional vp_map_t
* When used as part of a condition it may be any of the RHS side types, as well as:
- * - #TMPL_TYPE_REGEX_STRUCT (pre-parsed regex)
+ * - #TMPL_TYPE_REGEX (pre-parsed regex)
*
* @see vp_map_t
*/
} data;
};
-/** @name Field accessors for #TMPL_TYPE_ATTR, #TMPL_TYPE_ATTR_UNDEFINED, #TMPL_TYPE_LIST
+/** @name Field accessors for #TMPL_TYPE_ATTR, #TMPL_TYPE_ATTR_UNPARSED, #TMPL_TYPE_LIST
*
* @{
*/
#define tmpl_value_type_set(_tmpl, _type) (_tmpl)->data.literal.type = (_type)
/** @} */
-/** @name Field accessors for #TMPL_TYPE_REGEX_STRUCT and #TMPL_TYPE_REGEX
+/** @name Field accessors for #TMPL_TYPE_REGEX and #TMPL_TYPE_REGEX_UNPARSED
*
* @{
*/
#ifdef HAVE_REGEX
-# define tmpl_preg(_tmpl) (_tmpl)->data.preg //!< #TMPL_TYPE_REGEX_STRUCT only.
+# define tmpl_preg(_tmpl) (_tmpl)->data.preg //!< #TMPL_TYPE_REGEX only.
# define tmpl_regex_flags(_tmpl) (_tmpl)->data.regex_flags
#endif
/** @} */
return false;
}
- vpt->type = TMPL_TYPE_REGEX_STRUCT;
+ vpt->type = TMPL_TYPE_REGEX;
tmpl_preg(vpt) = preg;
return true;
case TMPL_TYPE_UNPARSED:
case TMPL_TYPE_ATTR:
case TMPL_TYPE_XLAT_UNPARSED:
- case TMPL_TYPE_ATTR_UNDEFINED:
+ case TMPL_TYPE_ATTR_UNPARSED:
case TMPL_TYPE_EXEC:
break;
request, tmpl_xlat(map->lhs), false);
return UNLANG_ACTION_PUSHED_CHILD;
+ case TMPL_TYPE_REGEX_UNPARSED:
case TMPL_TYPE_REGEX:
- case TMPL_TYPE_REGEX_STRUCT:
case TMPL_TYPE_XLAT_UNPARSED:
fr_assert(0);
error:
request, tmpl_xlat(map->rhs), false);
return UNLANG_ACTION_PUSHED_CHILD;
+ case TMPL_TYPE_REGEX_UNPARSED:
case TMPL_TYPE_REGEX:
- case TMPL_TYPE_REGEX_STRUCT:
case TMPL_TYPE_XLAT_UNPARSED:
fr_assert(0);
goto error;
request, tmpl_xlat(inst->src), false);
return UNLANG_ACTION_PUSHED_CHILD;
+ case TMPL_TYPE_REGEX_UNPARSED:
case TMPL_TYPE_REGEX:
- case TMPL_TYPE_REGEX_STRUCT:
case TMPL_TYPE_XLAT_UNPARSED:
fr_assert(0);
goto error;
case TMPL_TYPE_EXEC:
case TMPL_TYPE_DATA:
case TMPL_TYPE_LIST:
- case TMPL_TYPE_REGEX:
+ case TMPL_TYPE_REGEX_UNPARSED:
case TMPL_TYPE_UNPARSED:
case TMPL_TYPE_XLAT_UNPARSED:
break;
case TMPL_TYPE_ATTR:
break;
- case TMPL_TYPE_ATTR_UNDEFINED:
+ case TMPL_TYPE_ATTR_UNPARSED:
cf_log_err(map->ci, "Unknown attribute %s", tmpl_unknown_name(map->lhs));
return -1;
}
break;
- case TMPL_TYPE_ATTR_UNDEFINED:
+ case TMPL_TYPE_ATTR_UNPARSED:
cf_log_err(map->ci, "Unknown attribute %s", tmpl_unknown_name(map->rhs));
return -1;