memset(fr_sbuff_current(&sbuff), ',', conf->list_da_num);
fr_sbuff_advance(&sbuff, conf->list_da_num);
- *fr_sbuff_current(&sbuff) = '\0';
+ fr_sbuff_terminate(&sbuff);
}
fprintf(stdout , "%s\n", buffer);
goto error;
}
- switch (*fr_sbuff_current(in)) {
+ fr_sbuff_switch(in, '\0') {
/*
* More ranges...
*/
while (fr_sbuff_extend(&in)) {
fr_sbuff_adv_until(&in, SIZE_MAX, &dir_sep, '\0');
- switch (*fr_sbuff_current(&in)) {
+ fr_sbuff_switch(&in, '\0') {
case '/':
fr_sbuff_set(&dir_end, &in);
fr_sbuff_advance(&in, 1);
fr_slen_t ret = 0;
fr_slen_t parsed = 0;
- switch(*fr_sbuff_current(sbuff)) {
+ fr_sbuff_switch(sbuff, '\0') {
case '&':
node->logic_op = LDAP_FILTER_LOGIC_AND;
node->orig = talloc_typed_strdup(node, "&");
* Otherwise the $INCLUDE name is an absolute path, use
* it as -is.
*/
- c = *fr_sbuff_current(&name);
+ c = fr_sbuff_char(&name, '\0');
if (c != '/') {
p = strrchr(file, '/');
#define fr_sbuff_skip_whitespace(_x) \
do { \
- while (isspace((int) *fr_sbuff_current(_x))) fr_sbuff_advance(_x, 1); \
+ while (isspace((int) fr_sbuff_char(_x, '\0'))) fr_sbuff_advance(_x, 1); \
} while (0)
static ssize_t tokenize_expression(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in,
*
* e.g. '%{myfirstxlat'
*/
- if (!fr_sbuff_remaining(in)) {
+ if (!fr_sbuff_extend(in)) {
fr_strerror_const("Missing closing brace");
fr_sbuff_marker_release(&s_m);
return -1;
}
- hint = *fr_sbuff_current(in);
+ hint = fr_sbuff_char(in, '\0');
XLAT_DEBUG("EXPANSION HINT TOKEN '%c'", hint);
if (len == 0) {
/*
* Find the first non-base32 char
*/
- while (fr_sbuff_extend(&our_in) && fr_is_base32_nstd(*fr_sbuff_current(&our_in), alphabet)) {
+ while (fr_sbuff_extend(&our_in) && fr_is_base32_nstd(fr_sbuff_char(&our_in, '\0'), alphabet)) {
fr_sbuff_advance(&our_in, 1);
}
}
if (!fr_sbuff_next_if_char(&our_in, '=')) {
fr_strerror_printf("Found non-padding char '%c' at end of base32 string",
- *fr_sbuff_current(&our_in));
+ fr_sbuff_char(&our_in, '\0'));
if (err) *err = FR_SBUFF_PARSE_ERROR_FORMAT;
if (no_trailing && fr_sbuff_extend(&our_in)) {
fr_strerror_printf("Found trailing garbage '%c' at end of base32 string",
- *fr_sbuff_current(&our_in));
+ fr_sbuff_char(&our_in, '\0'));
if (err) *err = FR_SBUFF_PARSE_ERROR_TRAILING;
/*
* Find the first non-base64 char
*/
- while (fr_sbuff_extend(&our_in) && fr_is_base64_nstd(*fr_sbuff_current(&our_in), alphabet)) {
+ while (fr_sbuff_extend(&our_in) && fr_is_base64_nstd(fr_sbuff_char(&our_in, '\0'), alphabet)) {
fr_sbuff_advance(&our_in, 1);
}
}
if (!fr_sbuff_next_if_char(&our_in, '=')) {
fr_strerror_printf("Found non-padding char '%c' at end of base64 string",
- *fr_sbuff_current(&our_in));
+ fr_sbuff_char(&our_in, '\0'));
goto bad_format;
}
}
if (no_trailing && fr_sbuff_extend(&our_in)) {
fr_strerror_printf("Found trailing garbage '%c' at end of base64 string",
- *fr_sbuff_current(&our_in));
+ fr_sbuff_char(&our_in, '\0'));
if (err) *err = FR_SBUFF_PARSE_ERROR_TRAILING;
int len = (p - name) + 1;
fr_dict_enum_value_t *enumv;
- *p = *fr_sbuff_current(&our_in);
+ *p = fr_sbuff_char(&our_in, '\0');
if (!fr_dict_enum_allowed_chars[*p]) {
break;
}
};
if (fr_sbuff_is_in_charset(&our_in, bool_prefix)) {
- switch (tolower(*fr_sbuff_current(&our_in))) {
+ switch (tolower(fr_sbuff_char(&our_in, '\0'))) {
default:
break;
char *p; //!< Mutable position pointer.
};
+ char const *err; //!< Where the last error occurred.
+
uint8_t is_const:1; //!< Can't be modified.
uint8_t adv_parent:1; //!< If true, advance the parent.
((size_t)(fr_sbuff_start(_sbuff_or_marker) > fr_sbuff_current(_sbuff_or_marker) ? \
0 : (fr_sbuff_current(_sbuff_or_marker) - fr_sbuff_start(_sbuff_or_marker))))
+
+/** Sets an error marker in the parent
+ *
+ * If an error already exists at this level it will be used instead of the provided error.
+ *
+ * @param[in] sbuff who's parent we'll set the error marker in.
+ * @param[in] err marker to set.
+ * @return <0 the negative offset of the error.
+ */
+static inline fr_slen_t _fr_sbuff_error(fr_sbuff_t *sbuff, char const *err)
+{
+ fr_sbuff_t *parent = sbuff->parent;
+
+ if (sbuff->err) err = sbuff->err;
+ if (parent) parent->err = err;
+
+ return -((err - fr_sbuff_start(sbuff)) + 1);
+}
+
/** Return the current position as an error marker
+ *
+ * @param[in] _sbuff_or_marker Error marker will be set from the current position of this sbuff.
*
* +1 is added to the position to disambiguate with 0 meaning "parsed no data".
*
* An error at offset 0 will be returned as -1.
*/
#define fr_sbuff_error(_sbuff_or_marker) \
- (-(fr_sbuff_used(_sbuff_or_marker) + 1))
+ _fr_sbuff_error(fr_sbuff_ptr(_sbuff_or_marker), fr_sbuff_current(_sbuff_or_marker));
/** Like fr_sbuff_used, but adjusts for the value returned for the amount shifted
*
static inline void _fr_sbuff_set_recurse(fr_sbuff_t *sbuff, char const *p)
{
sbuff->p_i = p;
+ sbuff->err = NULL; /* Modifying the position of the sbuff clears the error */
+
if (sbuff->adv_parent && sbuff->parent) _fr_sbuff_set_recurse(sbuff->parent, p);
}
if (unlikely(p > sbuff->end)) return -(p - sbuff->end);
if (unlikely(p < sbuff->start)) return 0;
+ sbuff->err = NULL; /* Modifying the position of any markers clears the error, unsure if this is correct? */
m->p_i = p;
return p - current;
if (fr_sbuff_out(NULL, &size, &our_in) < 0) return fr_sbuff_error(&our_in);
if (!fr_sbuff_extend(&our_in)) goto done;
- c = tolower(*fr_sbuff_current(&our_in));
+ c = tolower(fr_sbuff_char(&our_in, '\0'));
/*
* Special cases first...
fr_value_box_t *uri_vb = NULL;
fr_uri_part_t const *uri_part;
fr_sbuff_t sbuff;
- char const *p;
uri_part = uri_parts;
do {
fr_sbuff_adv_until(&sbuff, SIZE_MAX, uri_part->terminals, '\0');
- p = fr_sbuff_current(&sbuff);
/*
* We've not found a terminal in the current box
*/
- if (uri_part->part_adv[(uint8_t)*p] == 0) continue;
+ if (uri_part->part_adv[fr_sbuff_char(&sbuff, '\0')] == 0) continue;
/*
* This terminator has trailing characters to skip
/*
* Move to the next part
*/
- uri_part += uri_part->part_adv[(uint8_t)*p];
+ uri_part += uri_part->part_adv[fr_sbuff_char(&sbuff, '\0')];
if (!uri_part->terminals) break;
} while (fr_sbuff_advance(&sbuff, 1) > 0);
}