*
* @param[in,out] name string start.
* @return
- * - Attribute matching name.
- * - NULL if no matching attribute could be found.
+ * - <= 0 on error (offset as negative integer)
+ * - > 0 on success (number of bytes parsed).
*/
-fr_dict_t *fr_dict_by_protocol_substr(char const **name)
+ssize_t fr_dict_by_protocol_substr(fr_dict_t **out, char const *name)
{
fr_dict_attr_t root;
fr_dict_t find = { .root = &root };
* Advance p until we get something that's not part of
* the dictionary attribute name.
*/
- for (p = *name; fr_dict_attr_allowed_chars[(int)*p] && (*p != '.'); p++);
+ for (p = name; fr_dict_attr_allowed_chars[(int)*p] && (*p != '.'); p++);
- len = p - *name;
+ len = p - name;
if (len > FR_DICT_ATTR_MAX_NAME_LEN) {
fr_strerror_printf("Attribute name too long");
- return NULL;
+ return -(FR_DICT_ATTR_MAX_NAME_LEN);
}
root.name = talloc_bstrndup(NULL, *name, len);
if (!root.name) {
fr_strerror_printf("Out of memory");
- return NULL;
+ return 0;
}
dict = fr_hash_table_finddata(protocol_by_name, &find);
talloc_const_free(root.name);
if (!dict) {
- fr_strerror_printf("Unknown protocol '%.*s'", (int) len, *name);
- return NULL;
+ fr_strerror_printf("Unknown protocol '%.*s'", (int) len, name);
+ return 0;
}
- *name = p;
+ *out = dict;
- return dict;
+ return p - name;
}
/** Lookup a protocol by its name
* If the attribute does not exist, don't advance the pointer and return
* NULL.
*
+ * @param[out] out Where to store the resolve attribute.
* @param[in] dict of protocol context we're operating in.
* If NULL the internal dictionary will be used.
- * @param[in,out] name string start.
+ * @param[in] name string start.
* @return
- * - Attribute matching name.
- * - NULL if no matching attribute could be found.
+ * - <= 0 on failure.
+ * - The number of bytes of name consumed on success.
*/
-fr_dict_attr_t const *fr_dict_attr_by_name_substr(fr_dict_t const *dict, char const **name)
+ssize_t fr_dict_attr_by_name_substr(fr_dict_attr_t const **out, fr_dict_t const *dict, char const *name)
{
fr_dict_attr_t find;
fr_dict_attr_t const *da;
* Advance p until we get something that's not part of
* the dictionary attribute name.
*/
- for (p = *name; fr_dict_attr_allowed_chars[(int)*p]; p++);
+ for (p = name; fr_dict_attr_allowed_chars[(int)*p]; p++);
- len = p - *name;
+ len = p - name;
if (len > FR_DICT_ATTR_MAX_NAME_LEN) {
fr_strerror_printf("Attribute name too long");
- return NULL;
+ return -(FR_DICT_ATTR_MAX_NAME_LEN);
}
- find.name = talloc_bstrndup(NULL, *name, len);
+ find.name = talloc_bstrndup(NULL, name, len);
if (!find.name) {
fr_strerror_printf("Out of memory");
- return NULL;
+ return 0;
}
da = fr_hash_table_finddata(dict->attributes_by_name, &find);
talloc_const_free(find.name);
if (!da) {
- fr_strerror_printf("Unknown attribute '%.*s'", (int) len, *name);
- return NULL;
+ fr_strerror_printf("Unknown attribute '%.*s'", (int) len, name);
+ return 0;
}
- *name = p;
- return da;
+ *out = da;
+
+ return p - name;
}
/** Locate a #fr_dict_attr_t by its name
char const *p = ref, *q, *end = p + strlen(ref);
fr_dict_t *proto_dict;
fr_dict_attr_t const *da;
+ ssize_t slen;
/*
* If the reference does not begin with .
if (*p == '.') {
p++;
- da = fr_dict_attr_by_name_substr(proto_dict, &p);
- if (!da) {
+ slen = fr_dict_attr_by_name_substr(&da, proto_dict, p);
+ if (slen <= 0) {
fr_strerror_printf("Referenced attribute \"%s\" not found", p);
return NULL;
}
+
+ p += slen;
}
da = fr_dict_root(proto_dict);
* Look up by name, *including* any Attr-1.2.3.4 which was created when
* parsing the configuration files.
*/
- vpt->tmpl_da = fr_dict_attr_by_name_substr(NULL, &p);
- if (!vpt->tmpl_da) {
+ slen = fr_dict_attr_by_name_substr(&vpt->tmpl_da, NULL, p);
+ if (slen <= 0) {
char const *q;
fr_strerror(); /* Clear out any existing errors */
goto do_num;
}
+ /*
+ * Parsing was successful, so advance the pointer
+ */
+ p += slen;
+
/*
* If it's an attribute, look for a tag.
*
* isn't tagged. This lets us print more useful error
* messages.
*/
- else if (*p == ':') {
+ if (*p == ':') {
char *q;
if (!vpt->tmpl_da->flags.has_tag) { /* Lists don't have a da */
p = q;
}
- /*
- * The attribute is tagged, but the admin didn't
- * specify one. This means it's likely a
- * "search" thingy.. i.e. "find me ANY attribute,
- * no matter what the tag".
- */
+ /*
+ * The attribute is tagged, but the admin didn't
+ * specify one. This means it's likely a
+ * "search" thingy.. i.e. "find me ANY attribute,
+ * no matter what the tag".
+ */
} else if (vpt->tmpl_da->flags.has_tag) {
vpt->tmpl_tag = TAG_ANY;
}