OSSP CVS Repository

ossp - Difference in ossp-pkg/var/var.c versions 1.37 and 1.38
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/var/var.c 1.37 -> 1.38

--- var.c        2001/12/03 10:51:27     1.37
+++ var.c        2001/12/04 13:36:37     1.38
@@ -72,12 +72,13 @@
         "undefined variable",                                                   /* VAR_ERR_UNDEFINED_VARIABLE = -12 */
         "input is neither text nor variable",                                   /* VAR_ERR_INPUT_ISNT_TEXT_NOR_VARIABLE = -13 */
         "unknown command in variable",                                          /* VAR_ERR_UNKNOWN_COMMAND_CHAR = -14 */
+        "unknown error",                                                        /* -15 is not used */
         "malformated search and replace operation",                             /* VAR_ERR_MALFORMATTED_REPLACE = -16 */
         "unknown flag specified in search and replace operation",               /* VAR_ERR_UNKNOWN_REPLACE_FLAG = -17 */
         "invalid regular expression in search and replace operation",           /* VAR_ERR_INVALID_REGEX_IN_REPLACE = -18 */
         "missing parameter in command",                                         /* VAR_ERR_MISSING_PARAMETER_IN_COMMAND = -19 */
         "empty search string in search and replace operation",                  /* VAR_ERR_EMPTY_SEARCH_STRING = -20 */
-        "start offset missing in cut operation"                                 /* VAR_ERR_MISSING_START_OFFSET = -21 */
+        "start offset missing in cut operation",                                /* VAR_ERR_MISSING_START_OFFSET = -21 */
         "offsets in cut operation delimited by unknown character",              /* VAR_ERR_INVALID_OFFSET_DELIMITER = -22 */
         "range in cut operation is out of bounds",                              /* VAR_ERR_RANGE_OUT_OF_BOUNDS = -23 */
         "offset in cut operation is out of bounds",                             /* VAR_ERR_OFFSET_OUT_OF_BOUNDS = -24 */
@@ -92,8 +93,11 @@
         "unknown quoted pair in search and replace operation",                  /* VAR_ERR_UNKNOWN_QUOTED_PAIR_IN_REPLACE = -33 */
         "submatch referred to in replace string does not exist in search string", /* VAR_ERR_SUBMATCH_OUT_OF_RANGE = -34 */
         "invalid argument",                                                     /* VAR_ERR_INVALID_ARGUMENT = -35 */
-        "incomplete quoted pair"                                                /* VAR_ERR_INCOMPLETE_QUOTED_PAIR = -36 */
-        "lookup function does not support variable arrays"                      /* VAR_ERR_ARRAY_LOOKUPS_ARE_UNSUPPORTED = -37 */
+        "incomplete quoted pair",                                               /* VAR_ERR_INCOMPLETE_QUOTED_PAIR = -36 */
+        "lookup function does not support variable arrays",                     /* VAR_ERR_ARRAY_LOOKUPS_ARE_UNSUPPORTED = -37 */
+        "index specification of array variable contains an invalid character",  /* VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC = -38 */
+        "index specification of array variable is incomplete",                  /* VAR_ERR_INCOMPLETE_INDEX_SPEC = -39 */
+        "bracket expression in array variable's index is not closed"            /* VAR_ERR_UNCLOSED_BRACKET_IN_INDEX = -40 */
     };
 
     rc = 0 - rc;
@@ -427,6 +431,8 @@
                     const char_class_t, var_cb_t, void *, int, tokenbuf_t *);
 static int command(const char *, const char *, const var_config_t *,
                    const char_class_t, var_cb_t, void *, int, tokenbuf_t *);
+static int num_exp(const char *begin, const char *end, int current_index,
+                   int* result, const var_config_t *config);
 
 static int text(const char *begin, const char *end, char varinit,
                 char escape)
@@ -488,18 +494,153 @@
     return p - begin;
 }
 
+static int num_exp_read_int(const char** begin, const char* end)
+    {
+    int num = 0;
+    do
+        {
+        num *= 10;
+        num += **begin - '0';
+        ++(*begin);
+        }
+    while (isdigit(**begin) && *begin != end);
+    return num;
+    }
+
+static int num_exp_read_operand(const char *begin, const char *end, int current_index,
+                                int* result, const var_config_t *config)
+    {
+    const char* p = begin;
+    int rc;
+
+    if (begin == end)
+        return VAR_ERR_INCOMPLETE_INDEX_SPEC;
+
+    printf("Parsing for operand: '%s'\n", p);
+
+    if (*p == '(')
+        {
+        rc = num_exp(++p, end, current_index, result, config);
+        if (rc < 0)
+            return rc;
+        p += rc;
+        if (p == end)
+            return VAR_ERR_INCOMPLETE_INDEX_SPEC;
+        if (*p != ')')
+            return VAR_ERR_UNCLOSED_BRACKET_IN_INDEX;
+        ++p;
+        }
+    else if (*p == config->current_index)
+        {
+        ++p;
+        *result = current_index;
+        }
+    else if (isdigit(*p))
+        {
+        *result = num_exp_read_int(&p, end);
+        }
+    else if (*p == '+')
+        {
+        if (end - p > 1 && isdigit(p[1]))
+            {
+            ++p;
+            *result = num_exp_read_int(&p, end);
+            }
+        else
+            return VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC;
+        }
+    else if (*p == '-')
+        {
+        if (end - p > 1 && isdigit(p[1]))
+            {
+            ++p;
+            *result = num_exp_read_int(&p, end);
+            *result = 0 - *result;
+            }
+        else
+            return VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC;
+        }
+    else
+        return VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC;
+
+    return p - begin;
+    }
+
+static int num_exp(const char *begin, const char *end, int current_index,
+                   int* result, const var_config_t *config)
+    {
+    const char* p = begin;
+    char operator;
+    int right;
+    int rc;
+
+    if (begin == end)
+        return VAR_ERR_INCOMPLETE_INDEX_SPEC;
+
+    rc = num_exp_read_operand(p, end, current_index, result, config);
+    if (rc < 0)
+        return rc;
+    p += rc;
+    printf("left operand is %d\n", *result);
+
+    while (p != end)
+        {
+        printf("Parsing for operator: '%s'\n", p);
+        if (*p == '+' || *p == '-')
+            {
+            operator = *p++;
+            printf("Operator is '%c'\n", operator);
+            rc = num_exp(p, end, current_index, &right, config);
+            if (rc < 0)
+                return rc;
+            p += rc;
+            printf("Calculating %d %c %d --> ", *result, operator, right);
+            if (operator == '+')
+                *result = *result + right;
+            else
+                *result = *result - right;
+            printf("%d\n", *result);
+            }
+        else if (*p == '*' || *p == '/' || *p == '%')
+            {
+            operator = *p++;
+            printf("Operator is '%c'\n", operator);
+
+
+            rc = num_exp_read_operand(p, end, current_index, &right, config);
+            if (rc < 0)
+                return rc;
+            p += rc;
+            printf("Calculating %d %c %d --> ", *result, operator, right);
+            if (operator == '*')
+                *result = *result * right;
+            else if (operator == '/')
+                *result = *result / right;
+            else if (operator == '%')
+                *result = *result % right;
+            printf("%d\n", *result);
+            }
+        else
+            break;
+
+        printf("Parsing for right: '%s'\n", p);
+        }
+
+    return p - begin;
+    }
 
 static int expression(const char *begin, const char *end,
                       const var_config_t *config,
                       const char_class_t nameclass, var_cb_t lookup,
                       void *lookup_context, int force_expand,
                       tokenbuf_t *result)
-{
+    {
     const char *p = begin;
     const char *data;
     size_t len, buffer_size;
     int failed = 0;
     int rc;
+    int index = 0;
     tokenbuf_t name;
     tokenbuf_t tmp;
 
@@ -520,63 +661,107 @@
     /* Get the name of the variable to expand. The name may consist of
        an arbitrary number of VARNAMEs and VARIABLEs. */
 
-    do {
+    do
+        {
         rc = varname(p, end, nameclass);
         if (rc < 0)
             goto error_return;
-        if (rc > 0) {
-            if (!tokenbuf_append(&name, p, rc)) {
+        if (rc > 0)
+            {
+            if (!tokenbuf_append(&name, p, rc))
+                {
                 rc = VAR_ERR_OUT_OF_MEMORY;
                 goto error_return;
-            }
+                }
             p += rc;
-        }
+            }
 
         rc = variable(p, end, config, nameclass, lookup, lookup_context,
                       force_expand, &tmp);
         if (rc < 0)
             goto error_return;
-        if (rc > 0) {
-            if (!tokenbuf_append(&name, tmp.begin, tmp.end - tmp.begin)) {
+        if (rc > 0)
+            {
+            if (!tokenbuf_append(&name, tmp.begin, tmp.end - tmp.begin))
+                {
                 rc = VAR_ERR_OUT_OF_MEMORY;
                 goto error_return;
-            }
+                }
             p += rc;
+            }
         }
-    }
     while (rc > 0);
 
     /* We must have the complete variable name now, so make sure we
        do. */
 
-    if (name.begin == name.end) {
+    if (name.begin == name.end)
+        {
         rc = VAR_ERR_INCOMPLETE_VARIABLE_SPEC;
         goto error_return;
-    }
+        }
+
+    /* If the next token is START-INDEX, read the index specification. */
+
+    if (*p == config->startindex)
+        {
+        printf("Found START-INDEX: %s\n", p);
+        ++p;
+
+        rc = num_exp(p, end, 0, &index, config);
+        if (rc < 0)
+            goto error_return;
+        if (rc == 0)
+            {
+            rc = VAR_ERR_INCOMPLETE_INDEX_SPEC;
+            goto error_return;
+            }
+        p += rc;
+
+        printf("Expecting END-INDEX: %s\n", p);
+
+        if (p == end)
+            {
+            rc = VAR_ERR_INCOMPLETE_INDEX_SPEC;
+            goto error_return;
+            }
+        if (*p != config->endindex)
+            {
+            rc = VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC;
+            goto error_return;
+            }
+        ++p;
+
+        printf("Found index %d.\n", index);
+
+        }
 
-    /* Now we have the name of the variable stored in "name". We
-       expect an ENDDELIM here. */
+    /* 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->enddelim && *p != ':')) {
+    if (p == end || (*p != config->enddelim && *p != ':'))
+        {
         rc = VAR_ERR_INCOMPLETE_VARIABLE_SPEC;
         goto error_return;
-    }
+        }
     ++p;
 
     /* Use the lookup callback to get the variable's contents. */
 
-    rc = (*lookup) (lookup_context, name.begin, name.end - name.begin, 0,
+    rc = (*lookup) (lookup_context, name.begin, name.end - name.begin, index,
                     &data, &len, &buffer_size);
     if (rc < 0)
         goto error_return;
-    if (rc == 0) {
+    if (rc == 0)
+        {
         /* The variable is undefined. What we'll do now depends on the
            force_expand flag. */
 
-        if (force_expand) {
+        if (force_expand)
+            {
             rc = VAR_ERR_UNDEFINED_VARIABLE;
             goto error_return;
-        }
+            }
         /* Initialize result to point back to the original text in
            the buffer. */
 
@@ -584,21 +769,25 @@
         result->end = p;
         result->buffer_size = 0;
         failed = 1;
-    } else {
+        }
+    else
+        {
         /* The preliminary result is the contents of the variable.
            This may be modified by the commands that may follow. */
 
         result->begin = data;
         result->end = data + len;
         result->buffer_size = buffer_size;
-    }
+        }
 
-    if (p[-1] == ':') {
+    if (p[-1] == ':')
+        {
         /* Parse and execute commands. */
 
         tokenbuf_free(&tmp);
         --p;
-        while (p != end && *p == ':') {
+        while (p != end && *p == ':')
+            {
             ++p;
             if (!failed)
                 rc = command(p, end, config, nameclass, lookup,
@@ -611,16 +800,17 @@
             p += rc;
             if (failed)
                 result->end += rc;
-        }
+            }
 
-        if (p == end || *p != config->enddelim) {
+        if (p == end || *p != config->enddelim)
+            {
             rc = VAR_ERR_INCOMPLETE_VARIABLE_SPEC;
             goto error_return;
-        }
+            }
         ++p;
         if (failed)
             ++result->end;
-    }
+        }
 
     /* Exit gracefully. */
 
@@ -635,7 +825,7 @@
     tokenbuf_free(&tmp);
     tokenbuf_free(result);
     return rc;
-}
+    }
 
 static int variable(const char *begin, const char *end,
                     const var_config_t *config, const char_class_t nameclass,
@@ -1312,9 +1502,9 @@
 
     case '#':                   /* Substitute length of the string. */
         if (data->begin) {
-            char buf[((sizeof(int)*8)/3)+10]; /* sufficient size: <#bits> x log_10(2) + safety */
-            sprintf(buf, "%d", (int)(data->end - data->begin));
-            tokenbuf_free(data);
+            char buf[((sizeof(int)*8)/3)+10]; /* sufficient size: <#bits> x log_10(2) + safety */
+            sprintf(buf, "%d", (int)(data->end - data->begin));
+            tokenbuf_free(data);
             if (!tokenbuf_assign(data, buf, strlen(buf))) {
                 rc = VAR_ERR_OUT_OF_MEMORY;
                 goto error_return;

CVSTrac 2.0.1