--- var.c 2002/02/28 12:40:01 1.69
+++ var.c 2002/02/28 20:28:14 1.70
@@ -58,6 +58,16 @@
#define VAR_RC(rv) (rv)
#endif /* WITH_EX */
+#ifndef NUL
+#define NUL '\0'
+#endif
+
+/*
+**
+** ==== INTERNAL DATA STRUCTURES ====
+**
+*/
+
typedef char char_class_t[256]; /* 256 == 2 ^ sizeof(unsigned char)*8 */
/* the external context structure */
@@ -71,7 +81,7 @@
/* the internal expansion context structure */
typedef struct {
int force_expand;
-} var_expand_t;
+} var_parse_t;
/* the default syntax configuration */
static const var_syntax_t var_syntax_default = {
@@ -85,7 +95,11 @@
"a-zA-Z0-9_" /* name_chars */
};
-/* Routines for manipulation of token buffers. */
+/*
+**
+** ==== TOKEN BUFFER FUNCTIONS ====
+**
+*/
#define TOKENBUF_INITIAL_BUFSIZE 64
@@ -122,7 +136,7 @@
buf->begin = p;
buf->end = p + len;
buf->buffer_size = len + 1;
- *((char *)(buf->end)) = '\0';
+ *((char *)(buf->end)) = NUL;
return 1;
}
@@ -176,7 +190,7 @@
/* Append the data at the end of the current buffer. */
memcpy((char *)output->end, data, len);
output->end += len;
- *((char *)output->end) = '\0';
+ *((char *)output->end) = NUL;
return 1;
}
@@ -202,7 +216,11 @@
return num;
}
-/* Routines for the expansion of quoted-pair expressions. */
+/*
+**
+** ==== ESCAPE SEQUENCE FUNCTIONS ====
+**
+*/
static void expand_range(char a, char b, char_class_t class)
{
@@ -224,8 +242,8 @@
/* Walk through the class description and set the appropriate
entries in the array. */
- while (*desc != '\0') {
- if (desc[1] == '-' && desc[2] != '\0') {
+ while (*desc != NUL) {
+ if (desc[1] == '-' && desc[2] != NUL) {
if (desc[0] > desc[2])
return VAR_ERR_INCORRECT_CLASS_SPEC;
expand_range(desc[0], desc[2], class);
@@ -341,95 +359,115 @@
return expand_simple_hex(src, dst, end);
}
-/* The recursive-descent parser for variable expressions. */
-
-static int variable(const char *begin, const char *end,
- const var_syntax_t *config, const char_class_t nameclass,
- var_cb_value_t lookup, void *lookup_context,
- int force_expand, tokenbuf_t *result, int index_mark,
- int* rel_lookup_flag);
-static int command(const char *begin, const char *end,
- const var_syntax_t *config, const char_class_t nameclass,
- var_cb_value_t lookup, void *lookup_context, int force_expand,
- tokenbuf_t *data, int index_mark, int* rel_lookup_flag);
-static int num_exp(const char *begin, const char *end, int index_mark,
- int* result, int* failed, int* rel_lookup_flag,
- const var_syntax_t *config,
- const char_class_t nameclass,
- var_cb_value_t lookup, void* lookup_context);
-
-static int text(const char *begin, const char *end, char delim_init,
- char index_open, char index_close, char escape)
+/*
+**
+** ==== RECURSIVE-DESCEND VARIABLE EXPANSION PARSER ====
+**
+*/
+
+/* forward declarations */
+static int parse_variable(var_t *var, var_parse_t *ctx, const char *begin, const char *end, int force_expand, tokenbuf_t *result, int index_this, int* rel_lookup_flag);
+static int parse_command (var_t *var, var_parse_t *ctx, const char *begin, const char *end, int force_expand, tokenbuf_t *data, int index_this, int* rel_lookup_flag);
+static int parse_num_exp (var_t *var, var_parse_t *ctx, const char *begin, const char *end, int index_this, int* result, int* failed, int* rel_lookup_flag);
+
+/* parse plain text */
+static int
+parse_text(
+ var_t *var, var_parse_t *ctx,
+ const char *begin, const char *end)
{
const char *p;
- for (p = begin; p != end; ++p) {
- if (*p == escape) {
- if (++p == end)
+ /* parse until delim_init (variable construct)
+ or index_open (loop construct) is found */
+ for (p = begin; p != end; p++) {
+ if (*p == var->syntax.escape) {
+ p++; /* skip next character */
+ if (p == end)
return VAR_ERR_INCOMPLETE_QUOTED_PAIR;
}
- else if (*p == delim_init)
+ else if (*p == var->syntax.delim_init)
break;
- else if (index_open && (*p == index_open || *p == index_close))
+ else if ( var->syntax.index_open != NUL
+ && ( *p == var->syntax.index_open
+ || *p == var->syntax.index_close))
break;
}
- return p - begin;
+ return (p - begin);
}
-static int varname(const char *begin, const char *end,
- const char_class_t nameclass)
+/* parse variable name */
+static int
+parse_varname(
+ var_t *var, var_parse_t *ctx,
+ const char *begin, const char *end)
{
const char *p;
- for (p = begin; p != end && nameclass[(int) *p]; p++)
+ /* parse as long as name class characters are found */
+ for (p = begin; p != end && var->syntax_nameclass[(int)(*p)]; p++)
;
- return p - begin;
+ return (p - begin);
}
-static int number(const char *begin, const char *end)
+/* parse number */
+static int
+parse_number(
+ var_t *var, var_parse_t *ctx,
+ const char *begin, const char *end)
{
const char *p;
- for (p = begin; p != end && isdigit((int)*p); p++)
+ /* parse as long as digits are found */
+ for (p = begin; p != end && isdigit((int)(*p)); p++)
;
- return p - begin;
+ return (p - begin);
}
-static int substext(const char *begin, const char *end,
- const var_syntax_t *config)
+/* parse substitution text */
+static int
+parse_substext(
+ var_t *var, var_parse_t *ctx,
+ const char *begin, const char *end)
{
const char *p;
- for (p = begin; p != end && *p != config->delim_init && *p != '/'; p++) {
- if (*p == config->escape) {
+ /* parse until delim_init or '/' */
+ for (p = begin; p != end && *p != var->syntax.delim_init && *p != '/'; p++) {
+ if (*p == var->syntax.escape) {
if (p + 1 == end)
return VAR_ERR_INCOMPLETE_QUOTED_PAIR;
p++;
}
}
- return p - begin;
+ return (p - begin);
}
-static int exptext(const char *begin, const char *end,
- const var_syntax_t *config)
+/* parse expression? XXX text */
+static int
+parse_exptext(
+ var_t *var, var_parse_t *ctx,
+ const char *begin, const char *end)
{
const char *p;
- for (p = begin;
- p != end
- && *p != config->delim_init
- && *p != config->delim_close
- && *p != ':'; p++) {
- if (*p == config->escape) {
+ /* parse until delim_init or delim_close or ':' */
+ for (p = begin; p != end
+ && *p != var->syntax.delim_init
+ && *p != var->syntax.delim_close
+ && *p != ':'; p++) {
+ if (*p == var->syntax.escape) {
if (p + 1 == end)
return VAR_ERR_INCOMPLETE_QUOTED_PAIR;
p++;
}
}
- return p - begin;
+ return (p - begin);
}
-static int num_exp_read_int(const char **begin, const char *end)
+/* convert a string into a decimal number */
+static int
+convert_num_exp_read_int(const char **begin, const char *end)
{
int num = 0;
@@ -441,24 +479,26 @@
return num;
}
-static int num_exp_read_operand(const char *begin, const char *end, int index_mark,
- int *result, int *failed, int *rel_lookup_flag,
- const var_syntax_t *config,
- const char_class_t nameclass,
- var_cb_value_t lookup, void *lookup_context)
+/* parse number expression operand */
+static int
+parse_num_exp_operand(
+ var_t *var, var_parse_t *ctx,
+ const char *begin, const char *end,
+ int index_this, int *result, int *failed, int *rel_lookup_flag)
{
- const char* p = begin;
+ const char *p;
tokenbuf_t tmp;
int rc;
+ p = begin;
tokenbuf_init(&tmp);
if (begin == end)
return VAR_ERR_INCOMPLETE_INDEX_SPEC;
if (*p == '(') {
- rc = num_exp(++p, end, index_mark, result, failed,
- rel_lookup_flag, config, nameclass, lookup, lookup_context);
+ rc = parse_num_exp(var, ctx, ++p, end, index_this, result, failed,
+ rel_lookup_flag);
if (rc < 0)
return rc;
p += rc;
@@ -468,13 +508,13 @@
return VAR_ERR_UNCLOSED_BRACKET_IN_INDEX;
++p;
}
- else if (*p == config->delim_init) {
- rc = variable(p, end, config, nameclass, lookup,
- lookup_context, 1, &tmp, index_mark, rel_lookup_flag);
+ else if (*p == var->syntax.delim_init) {
+ rc = parse_variable(var, ctx, p, end,
+ 1, &tmp, index_this, rel_lookup_flag);
if (rc == VAR_ERR_UNDEFINED_VARIABLE) {
*failed = 1;
- rc = variable(p, end, config, nameclass, lookup,
- lookup_context, 0, &tmp, index_mark, rel_lookup_flag);
+ rc = parse_variable(var, ctx, p, end,
+ 0, &tmp, index_this, rel_lookup_flag);
if (rc < 0)
return rc;
p += rc;
@@ -484,25 +524,25 @@
if (rc < 0)
return rc;
p += rc;
- rc = num_exp(tmp.begin, tmp.end, index_mark, result,
- failed, rel_lookup_flag, config, nameclass, lookup, lookup_context);
+ rc = parse_num_exp(var, ctx, tmp.begin, tmp.end, index_this, result,
+ failed, rel_lookup_flag );
tokenbuf_free(&tmp);
if (rc < 0)
return rc;
}
}
- else if (config->index_mark && *p == config->index_mark) {
+ else if (var->syntax.index_mark && *p == var->syntax.index_mark) {
p++;
- *result = index_mark;
+ *result = index_this;
(*rel_lookup_flag)++;
}
else if (isdigit(*p)) {
- *result = num_exp_read_int(&p, end);
+ *result = convert_num_exp_read_int(&p, end);
}
else if (*p == '+') {
if (end - p > 1 && isdigit(p[1])) {
p++;
- *result = num_exp_read_int(&p, end);
+ *result = convert_num_exp_read_int(&p, end);
}
else
return VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC;
@@ -510,7 +550,7 @@
else if (*p == '-') {
if (end - p > 1 && isdigit(p[1])) {
p++;
- *result = num_exp_read_int(&p, end);
+ *result = convert_num_exp_read_int(&p, end);
*result = 0 - *result;
}
else
@@ -519,14 +559,15 @@
else
return VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC;
- return p - begin;
+ return (p - begin);
}
-static int num_exp(const char *begin, const char *end, int index_mark,
- int *result, int *failed, int *rel_lookup_flag,
- const var_syntax_t *config,
- const char_class_t nameclass,
- var_cb_value_t lookup, void *lookup_context)
+static int
+parse_num_exp(
+ var_t *var, var_parse_t *ctx,
+ const char *begin, const char *end,
+ int index_this,
+ int *result, int *failed, int *rel_lookup_flag)
{
const char *p = begin;
char operator;
@@ -536,9 +577,8 @@
if (begin == end)
return VAR_ERR_INCOMPLETE_INDEX_SPEC;
- rc = num_exp_read_operand(p, end, index_mark, result,
- failed, rel_lookup_flag, config, nameclass,
- lookup, lookup_context);
+ rc = parse_num_exp_operand(var, ctx, p, end, index_this, result,
+ failed, rel_lookup_flag);
if (rc < 0)
return rc;
p += rc;
@@ -546,8 +586,8 @@
while (p != end) {
if (*p == '+' || *p == '-') {
operator = *p++;
- rc = num_exp(p, end, index_mark, &right, failed,
- rel_lookup_flag, config, nameclass, lookup, lookup_context);
+ rc = parse_num_exp(var, ctx, p, end, index_this, &right, failed,
+ rel_lookup_flag);
if (rc < 0)
return rc;
p += rc;
@@ -558,8 +598,8 @@
}
else if (*p == '*' || *p == '/' || *p == '%') {
operator = *p++;
- rc = num_exp_read_operand(p, end, index_mark, &right, failed,
- rel_lookup_flag, config, nameclass, lookup, lookup_context);
+ rc = parse_num_exp_operand(var, ctx, p, end, index_this, &right, failed,
+ rel_lookup_flag);
if (rc < 0)
return rc;
p += rc;
@@ -593,12 +633,13 @@
return p - begin;
}
-static int expression(const char *begin, const char *end,
- const var_syntax_t *config,
- const char_class_t nameclass, var_cb_value_t lookup,
- void *lookup_context, int force_expand,
- tokenbuf_t *result, int index_mark, int *rel_lookup_flag)
- {
+static int
+parse_expression(
+ var_t *var, var_parse_t *ctx,
+ const char *begin, const char *end,
+ int force_expand,
+ tokenbuf_t *result, int index_this, int *rel_lookup_flag)
+{
const char *p = begin;
const char *data;
size_t len, buffer_size;
@@ -616,7 +657,7 @@
/* Expect STARTDELIM. */
- if (p == end || *p != config->delim_open)
+ if (p == end || *p != var->syntax.delim_open)
return 0;
if (++p == end)
@@ -626,7 +667,7 @@
an arbitrary number of VARNAMEs and VARIABLEs. */
do {
- rc = varname(p, end, nameclass);
+ rc = parse_varname(var, ctx, p, end);
if (rc < 0)
goto error_return;
if (rc > 0) {
@@ -637,8 +678,8 @@
p += rc;
}
- rc = variable(p, end, config, nameclass, lookup, lookup_context,
- force_expand, &tmp, index_mark, rel_lookup_flag);
+ rc = parse_variable(var, ctx, p, end,
+ force_expand, &tmp, index_this, rel_lookup_flag);
if (rc < 0)
goto error_return;
if (rc > 0) {
@@ -673,9 +714,9 @@
/* If the next token is START-INDEX, read the index specification. */
- if (config->index_open && *p == config->index_open) {
- rc = num_exp(++p, end, index_mark, &idx, &failed,
- rel_lookup_flag, config, nameclass, lookup, lookup_context);
+ if (var->syntax.index_open && *p == var->syntax.index_open) {
+ rc = parse_num_exp(var, ctx, ++p, end, index_this, &idx, &failed,
+ rel_lookup_flag);
if (rc < 0)
goto error_return;
if (rc == 0) {
@@ -688,7 +729,7 @@
rc = VAR_ERR_INCOMPLETE_INDEX_SPEC;
goto error_return;
}
- if (*p != config->index_close) {
+ if (*p != var->syntax.index_close) {
rc = VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC;
goto error_return;
}
@@ -698,7 +739,7 @@
/* Now we have the name of the variable stored in "name". The next
token here must either be an END-DELIM or a ':'. */
- if (p == end || (*p != config->delim_close && *p != ':')) {
+ if (p == end || (*p != var->syntax.delim_close && *p != ':')) {
rc = VAR_ERR_INCOMPLETE_VARIABLE_SPEC;
goto error_return;
}
@@ -712,7 +753,7 @@
result->buffer_size = 0;
}
else {
- rc = (*lookup) (NULL, lookup_context, name.begin, name.end - name.begin, idx,
+ rc = (*var->cb_value_fct) (var, var->cb_value_ctx, name.begin, name.end - name.begin, idx,
&data, &len, &buffer_size);
if (rc == VAR_ERR_UNDEFINED_VARIABLE) {
/* The variable is undefined. What we'll do now depends on the
@@ -748,13 +789,13 @@
while (p != end && *p == ':') {
p++;
if (!failed)
- rc = command(p, end, config, nameclass, lookup,
- lookup_context, force_expand, result,
- index_mark, rel_lookup_flag);
+ rc = parse_command(var, ctx, p, end,
+ force_expand, result,
+ index_this, rel_lookup_flag);
else
- rc = command(p, end, config, nameclass, lookup,
- lookup_context, force_expand, &tmp,
- index_mark, rel_lookup_flag);
+ rc = parse_command(var, ctx, p, end,
+ force_expand, &tmp,
+ index_this, rel_lookup_flag);
if (rc < 0)
goto error_return;
p += rc;
@@ -762,7 +803,7 @@
result->end += rc;
}
- if (p == end || *p != config->delim_close) {
+ if (p == end || *p != var->syntax.delim_close) {
rc = VAR_ERR_INCOMPLETE_VARIABLE_SPEC;
goto error_return;
}
@@ -786,11 +827,13 @@
return rc;
}
-static int variable(const char *begin, const char *end,
- const var_syntax_t *config, const char_class_t nameclass,
- var_cb_value_t lookup, void *lookup_context,
- int force_expand, tokenbuf_t *result, int index_mark,
- int *rel_lookup_flag)
+static int
+parse_variable(
+ var_t *var,
+ var_parse_t *ctx,
+ const char *begin, const char *end,
+ int force_expand, tokenbuf_t *result, int index_this,
+ int *rel_lookup_flag)
{
const char *p = begin;
const char *data;
@@ -804,7 +847,7 @@
/* Expect VARINIT. */
- if (p == end || *p != config->delim_init)
+ if (p == end || *p != var->syntax.delim_init)
return 0;
if (++p == end)
@@ -813,11 +856,11 @@
/* Try to read the variable name. If that fails, we're parsing a
complex expression. */
- rc = varname(p, end, nameclass);
+ rc = parse_varname(var, ctx, p, end);
if (rc < 0)
return rc;
if (rc > 0) {
- rc2 = (*lookup)(NULL, lookup_context, p, rc, 0, &data, &len, &buffer_size);
+ rc2 = (*var->cb_value_fct)(var, var->cb_value_ctx, p, rc, 0, &data, &len, &buffer_size);
if (rc2 == VAR_ERR_UNDEFINED_VARIABLE && !force_expand) {
result->begin = begin;
result->end = begin + 1 + rc;
@@ -834,19 +877,20 @@
/* OK, we're dealing with a complex expression here. */
- rc = expression(p, end, config, nameclass, lookup, lookup_context,
- force_expand, result, index_mark, rel_lookup_flag);
+ rc = parse_expression(var, ctx, p, end,
+ force_expand, result, index_this, rel_lookup_flag);
if (rc > 0)
rc++;
return rc;
}
-static int exptext_or_variable(const char *begin, const char *end,
- const var_syntax_t *config,
- const char_class_t nameclass, var_cb_value_t lookup,
- void *lookup_context, int force_expand,
- tokenbuf_t *result, int index_mark,
- int *rel_lookup_flag)
+static int
+parse_exptext_or_variable(
+ var_t *var, var_parse_t *ctx,
+ const char *begin, const char *end,
+ int force_expand,
+ tokenbuf_t *result, int index_this,
+ int *rel_lookup_flag)
{
const char *p = begin;
tokenbuf_t tmp;
@@ -859,7 +903,7 @@
return 0;
do {
- rc = exptext(p, end, config);
+ rc = parse_exptext(var, ctx, p, end);
if (rc < 0)
goto error_return;
if (rc > 0) {
@@ -870,8 +914,8 @@
p += rc;
}
- rc = variable(p, end, config, nameclass, lookup, lookup_context,
- force_expand, &tmp, index_mark, rel_lookup_flag);
+ rc = parse_variable(var, ctx, p, end,
+ force_expand, &tmp, index_this, rel_lookup_flag);
if (rc < 0)
goto error_return;
if (rc > 0) {
@@ -893,12 +937,13 @@
return rc;
}
-static int substext_or_variable(const char *begin, const char *end,
- const var_syntax_t *config,
- const char_class_t nameclass, var_cb_value_t lookup,
- void *lookup_context, int force_expand,
- tokenbuf_t *result, int index_mark,
- int *rel_lookup_flag)
+static int
+parse_substext_or_variable(
+ var_t *var, var_parse_t *ctx,
+ const char *begin, const char *end,
+ int force_expand,
+ tokenbuf_t *result, int index_this,
+ int *rel_lookup_flag)
{
const char *p = begin;
tokenbuf_t tmp;
@@ -911,7 +956,7 @@
return 0;
do {
- rc = substext(p, end, config);
+ rc = parse_substext(var, ctx, p, end);
if (rc < 0)
goto error_return;
if (rc > 0) {
@@ -922,8 +967,8 @@
p += rc;
}
- rc = variable(p, end, config, nameclass, lookup, lookup_context,
- force_expand, &tmp, index_mark, rel_lookup_flag);
+ rc = parse_variable(var, ctx, p, end,
+ force_expand, &tmp, index_this, rel_lookup_flag);
if (rc < 0)
goto error_return;
if (rc > 0) {
@@ -945,7 +990,7 @@
return rc;
}
-static int expand_class_description(tokenbuf_t *src, tokenbuf_t *dst)
+static int parse_class_description(tokenbuf_t *src, tokenbuf_t *dst)
{
unsigned char c, d;
const char *p = src->begin;
@@ -979,9 +1024,9 @@
tokenbuf_init(&srcclass);
tokenbuf_init(&dstclass);
- if ((rc = expand_class_description(search, &srcclass)) != VAR_OK)
+ if ((rc = parse_class_description(search, &srcclass)) != VAR_OK)
goto error_return;
- if ((rc = expand_class_description(replace, &dstclass)) != VAR_OK)
+ if ((rc = parse_class_description(replace, &dstclass)) != VAR_OK)
goto error_return;
if (srcclass.begin == srcclass.end) {
@@ -1067,7 +1112,7 @@
return VAR_OK;
}
-static int expand_regex_replace(const char *data, tokenbuf_t *orig,
+static int parse_regex_replace(const char *data, tokenbuf_t *orig,
regmatch_t *pmatch, tokenbuf_t *expanded)
{
const char *p = orig->begin;
@@ -1219,7 +1264,7 @@
tokenbuf_append(&tmp, p, mydata.end - p);
break;
} else {
- rc = expand_regex_replace(p, replace, pmatch, &myreplace);
+ rc = parse_regex_replace(p, replace, pmatch, &myreplace);
if (rc != VAR_OK) {
regfree(&preg);
tokenbuf_free(&tmp);
@@ -1379,10 +1424,12 @@
return VAR_OK;
}
-static int command(const char *begin, const char *end,
- const var_syntax_t *config, const char_class_t nameclass,
- var_cb_value_t lookup, void *lookup_context, int force_expand,
- tokenbuf_t *data, int index_mark, int *rel_lookup_flag)
+static int
+parse_command(
+ var_t *var, var_parse_t *ctx,
+ const char *begin, const char *end,
+ int force_expand,
+ tokenbuf_t *data, int index_this, int *rel_lookup_flag)
{
const char *p = begin;
tokenbuf_t tmptokbuf;
@@ -1438,7 +1485,7 @@
case 'o': /* Cut out substrings. */
++p;
- rc = number(p, end);
+ rc = parse_number(var, ctx, p, end);
if (rc == 0) {
rc = VAR_ERR_MISSING_START_OFFSET;
goto error_return;
@@ -1459,7 +1506,7 @@
goto error_return;
}
- rc = number(p, end);
+ rc = parse_number(var, ctx, p, end);
number2.begin = p;
number2.end = p + rc;
number2.buffer_size = 0;
@@ -1486,9 +1533,9 @@
case '-': /* Substitute parameter if data is empty. */
p++;
- rc = exptext_or_variable(p, end, config, nameclass, lookup,
- lookup_context, force_expand, &tmptokbuf,
- index_mark, rel_lookup_flag);
+ rc = parse_exptext_or_variable(var, ctx, p, end,
+ force_expand, &tmptokbuf,
+ index_this, rel_lookup_flag);
if (rc < 0)
goto error_return;
if (rc == 0) {
@@ -1504,8 +1551,8 @@
case '*': /* Return "" if data is not empty, parameter otherwise. */
p++;
- rc = exptext_or_variable(p, end, config, nameclass, lookup,
- lookup_context, force_expand, &tmptokbuf, index_mark, rel_lookup_flag);
+ rc = parse_exptext_or_variable(var, ctx, p, end,
+ force_expand, &tmptokbuf, index_this, rel_lookup_flag);
if (rc < 0)
goto error_return;
if (rc == 0) {
@@ -1527,8 +1574,8 @@
case '+': /* Substitute parameter if data is not empty. */
p++;
- rc = exptext_or_variable(p, end, config, nameclass, lookup,
- lookup_context, force_expand, &tmptokbuf, index_mark, rel_lookup_flag);
+ rc = parse_exptext_or_variable(var, ctx, p, end,
+ force_expand, &tmptokbuf, index_this, rel_lookup_flag);
if (rc < 0)
goto error_return;
if (rc == 0) {
@@ -1549,8 +1596,8 @@
return VAR_ERR_MALFORMATTED_REPLACE;
p++;
- rc = substext_or_variable(p, end, config, nameclass, lookup,
- lookup_context, force_expand, &search, index_mark, rel_lookup_flag);
+ rc = parse_substext_or_variable(var, ctx, p, end,
+ force_expand, &search, index_this, rel_lookup_flag);
if (rc < 0)
goto error_return;
p += rc;
@@ -1561,8 +1608,8 @@
}
p++;
- rc = substext_or_variable(p, end, config, nameclass, lookup,
- lookup_context, force_expand, &replace, index_mark, rel_lookup_flag);
+ rc = parse_substext_or_variable(var, ctx, p, end,
+ force_expand, &replace, index_this, rel_lookup_flag);
if (rc < 0)
goto error_return;
p += rc;
@@ -1573,7 +1620,7 @@
}
p++;
- rc = exptext(p, end, config);
+ rc = parse_exptext(var, ctx, p, end);
if (rc < 0)
goto error_return;
flags.begin = p;
@@ -1595,8 +1642,8 @@
return VAR_ERR_MALFORMATTED_TRANSPOSE;
p++;
- rc = substext_or_variable(p, end, config, nameclass, lookup,
- lookup_context, force_expand, &search, index_mark, rel_lookup_flag);
+ rc = parse_substext_or_variable(var, ctx, p, end,
+ force_expand, &search, index_this, rel_lookup_flag);
if (rc < 0)
goto error_return;
p += rc;
@@ -1607,8 +1654,8 @@
}
p++;
- rc = substext_or_variable(p, end, config, nameclass, lookup,
- lookup_context, force_expand, &replace, index_mark, rel_lookup_flag);
+ rc = parse_substext_or_variable(var, ctx, p, end,
+ force_expand, &replace, index_this, rel_lookup_flag);
if (rc < 0)
goto error_return;
p += rc;
@@ -1634,7 +1681,7 @@
return VAR_ERR_MALFORMATTED_PADDING;
p++;
- rc = number(p, end);
+ rc = parse_number(var, ctx, p, end);
if (rc == 0) {
rc = VAR_ERR_MISSING_PADDING_WIDTH;
goto error_return;
@@ -1650,8 +1697,8 @@
}
p++;
- rc = substext_or_variable(p, end, config, nameclass, lookup,
- lookup_context, force_expand, &replace, index_mark, rel_lookup_flag);
+ rc = parse_substext_or_variable(var, ctx, p, end,
+ force_expand, &replace, index_this, rel_lookup_flag);
if (rc < 0)
goto error_return;
p += rc;
@@ -1700,57 +1747,30 @@
return rc;
}
-struct wrapper_context {
- var_cb_value_t lookup;
- void *context;
- int *rel_lookup_flag;
-};
-
-static int lookup_wrapper(var_t *var, void *context,
- const char *name, size_t name_len, int idx,
- const char **data, size_t *data_len,
- size_t *buffer_size)
+/* expand the loop limits */
+static var_rc_t
+parse_looplimits(
+ var_t *var,
+ var_parse_t *ctx,
+ const char *begin, const char *end,
+ int* start, int* step, int* stop, int* open_end)
{
- static char buf[1];
- struct wrapper_context *wcon = context;
- int rc;
-
- rc = (*wcon->lookup)(NULL, wcon->context, name, name_len,
- idx, data, data_len, buffer_size);
- if (rc == VAR_ERR_UNDEFINED_VARIABLE) {
- (*wcon->rel_lookup_flag)--;
- *data = buf;
- *data_len = 0;
- *buffer_size = 0;
- return VAR_OK;
- }
- return rc;
-}
-
-static var_rc_t loop_limits(const char *begin, const char *end,
- const var_syntax_t *config,
- const char_class_t nameclass,
- var_cb_value_t lookup, void* lookup_context,
- int* start, int* step, int* stop, int* open_end)
- {
- const char* p = begin;
+ const char *p;
int rc;
int failed;
int dummy;
+ p = begin;
if (begin == end)
return 0;
-
- if (*p != config->delim_open)
+ if (*p != var->syntax.delim_open)
return 0;
else
- ++p;
+ p++;
/* Read start value for the loop. */
-
failed = 0;
- rc = num_exp(p, end, 0, start, &failed, &dummy,
- config, nameclass, lookup, lookup_context);
+ rc = parse_num_exp(var, ctx, p, end, 0, start, &failed, &dummy);
if (rc == VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC)
*start = 0; /* use default */
else if (rc < 0)
@@ -1763,13 +1783,11 @@
if (*p != ',')
return VAR_ERR_INVALID_CHAR_IN_LOOP_LIMITS;
else
- ++p;
+ p++;
/* Read step value for the loop. */
-
failed = 0;
- rc = num_exp(p, end, 0, step, &failed, &dummy,
- config, nameclass, lookup, lookup_context);
+ rc = parse_num_exp(var, ctx, p, end, 0, step, &failed, &dummy);
if (rc == VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC)
*step = 1; /* use default */
else if (rc < 0)
@@ -1778,14 +1796,11 @@
p += rc;
if (failed)
return VAR_ERR_UNDEFINED_VARIABLE;
-
- if (*p != ',')
- {
- if (*p != config->delim_close)
+ if (*p != ',') {
+ if (*p != var->syntax.delim_close)
return VAR_ERR_INVALID_CHAR_IN_LOOP_LIMITS;
- else
- {
- ++p;
+ else {
+ p++;
*stop = *step;
*step = 1;
if (rc > 0)
@@ -1793,43 +1808,77 @@
else
*open_end = 1;
return p - begin;
- }
}
+ }
else
- ++p;
+ p++;
/* Read stop value for the loop. */
-
failed = 0;
- rc = num_exp(p, end, 0, stop, &failed, &dummy,
- config, nameclass, lookup, lookup_context);
- if (rc == VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC)
- {
- *stop = 0; /* use default */
+ rc = parse_num_exp(var, ctx, p, end, 0, stop, &failed, &dummy);
+ if (rc == VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC) {
+ *stop = 0; /* use default */
*open_end = 1;
- }
+ }
else if (rc < 0)
return rc;
- else
- {
+ else {
*open_end = 0;
p += rc;
- }
+ }
if (failed)
return VAR_ERR_UNDEFINED_VARIABLE;
-
- if (*p != config->delim_close)
+ if (*p != var->syntax.delim_close)
return VAR_ERR_INVALID_CHAR_IN_LOOP_LIMITS;
return ++p - begin;
+}
+
+/* callback wrapper context */
+typedef struct {
+ var_cb_value_t cb_value_fct;
+ void *cb_value_ctx;
+ int *rel_lookup_flag;
+} var_wrapper_t;
+
+/* callback wrapper function */
+static int
+lookup_wrapper(
+ var_t *var, void *ctx,
+ const char *var_ptr, size_t var_len, int var_idx,
+ const char **val_ptr, size_t *val_len, size_t *val_size)
+{
+ char buf[1];
+ var_wrapper_t *wcon = (var_wrapper_t *)ctx;
+ int rc;
+
+ /* pass through to original callback */
+ rc = (*wcon->cb_value_fct)(var, wcon->cb_value_ctx,
+ var_ptr, var_len, var_idx,
+ val_ptr, val_len, val_size);
+
+ /* convert undefined variable into empty variable */
+ if (rc == VAR_ERR_UNDEFINED_VARIABLE) {
+ (*wcon->rel_lookup_flag)--;
+ buf[0] = NUL;
+ *val_ptr = buf;
+ *val_len = 0;
+ *val_size = 0;
+ return VAR_OK;
}
-static var_rc_t input(const char *begin, const char *end,
- const var_syntax_t *config,
- const char_class_t nameclass, var_cb_value_t lookup,
- void *lookup_context, int force_expand,
- tokenbuf_t *output, int index_mark,
- size_t recursion_level, int *rel_lookup_flag)
+ return rc;
+}
+
+/* expand input in general */
+static var_rc_t
+parse_input(
+ var_t *var,
+ var_parse_t *ctx,
+ const char *begin, const char *end,
+ int force_expand,
+ tokenbuf_t *output, int index_this,
+ size_t recursion_level, int *rel_lookup_flag)
{
const char *p = begin;
int rc, rc2;
@@ -1837,7 +1886,7 @@
int start, step, stop, open_end;
int i;
int output_backup;
- struct wrapper_context wcon;
+ var_wrapper_t wcon;
int my_rel_lookup_flag;
int original_rel_lookup_state;
int loop_limit_length;
@@ -1850,12 +1899,9 @@
}
do {
- if (begin != end && config->index_open && *begin == config->index_open) {
+ if (begin != end && var->syntax.index_open && *begin == var->syntax.index_open) {
original_rel_lookup_state = *rel_lookup_flag;
loop_limit_length = -1;
- wcon.lookup = lookup;
- wcon.context = lookup_context;
- wcon.rel_lookup_flag = rel_lookup_flag;
begin++;
start = 0;
step = 1;
@@ -1870,34 +1916,41 @@
i += step) {
*rel_lookup_flag = original_rel_lookup_state;
output_backup = output->end - output->begin;
- rc = input(begin, end, config, nameclass, &lookup_wrapper,
- &wcon, 1, output, i, recursion_level+1, rel_lookup_flag);
+
+ /* activate callback wrapper */
+ wcon.cb_value_fct = var->cb_value_fct;
+ wcon.cb_value_ctx = var->cb_value_ctx;
+ wcon.rel_lookup_flag = rel_lookup_flag;
+ var->cb_value_fct = lookup_wrapper;
+ var->cb_value_ctx = &wcon;
+
+ rc = parse_input(var, ctx, begin, end,
+ 1, output, i, recursion_level+1, rel_lookup_flag);
+
+ /* deactivate callback wrapper */
+ var->cb_value_fct = wcon.cb_value_fct;
+ var->cb_value_ctx = wcon.cb_value_ctx;
+
if (rc < 0)
goto error_return;
- if (begin[rc] != config->index_close) {
+ if (begin[rc] != var->syntax.index_close) {
rc = VAR_ERR_UNTERMINATED_LOOP_CONSTRUCT;
goto error_return;
}
- if (loop_limit_length < 0)
- {
- rc2 = loop_limits(begin + rc + 1, end, config, nameclass,
- lookup, lookup_context, &start, &step,
- &stop, &open_end);
+ if (loop_limit_length < 0) {
+ rc2 = parse_looplimits(var, ctx, begin + rc + 1, end,
+ &start, &step,
+ &stop, &open_end);
if (rc2 < 0)
- {
goto error_return;
- }
else if (rc2 == 0)
- {
loop_limit_length = 0;
- }
- else if (rc2 > 0)
- {
+ else if (rc2 > 0) {
loop_limit_length = rc2;
output->end = output->begin + output_backup;
goto re_loop;
- }
}
+ }
}
if (open_end)
output->end = output->begin + output_backup;
@@ -1909,8 +1962,7 @@
continue;
}
- rc = text(begin, end, config->delim_init, config->index_open,
- config->index_close, config->escape);
+ rc = parse_text(var, ctx, begin, end);
if (rc > 0) {
if (!tokenbuf_append(output, begin, rc)) {
rc = VAR_ERR_OUT_OF_MEMORY;
@@ -1921,9 +1973,9 @@
} else if (rc < 0)
goto error_return;
- rc = variable(begin, end, config, nameclass, lookup,
- lookup_context, force_expand, &result,
- index_mark, rel_lookup_flag);
+ rc = parse_variable(var, ctx, begin, end,
+ force_expand, &result,
+ index_this, rel_lookup_flag);
if (rc > 0) {
if (!tokenbuf_append(output, result.begin, result.end - result.begin)) {
rc = VAR_ERR_OUT_OF_MEMORY;
@@ -1952,7 +2004,11 @@
return rc;
}
-/* ------------------------------------------------------------------ */
+/*
+**
+** ==== APPLICATION PROGRAMMING INTERFACE (API) ====
+**
+*/
var_rc_t
var_create(
@@ -2088,7 +2144,7 @@
} else
*dst++ = *src++;
}
- *dst = '\0';
+ *dst = NUL;
return VAR_OK;
}
@@ -2099,7 +2155,7 @@
char **dst_ptr, size_t *dst_len,
int force_expand)
{
- var_expand_t ctx;
+ var_parse_t ctx;
tokenbuf_t output;
var_rc_t rc;
@@ -2116,10 +2172,9 @@
/* call the parsing */
tokenbuf_init(&output);
- rc = input(src_ptr, src_ptr + src_len,
- &var->syntax, var->syntax_nameclass,
- var->cb_value_fct, var->cb_value_ctx,
- ctx.force_expand, &output, 0, 0, NULL);
+ rc = parse_input(var, &ctx,
+ src_ptr, src_ptr + src_len,
+ ctx.force_expand, &output, 0, 0, NULL);
/* post-process output */
if (rc >= 0) {
|