OSSP CVS Repository

ossp - Check-in [1419]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 1419
Date: 2001-Dec-12 17:51:20 (local)
2001-Dec-12 16:51:20 (UTC)
User:simons
Branch:
Comment: Implemented the looping construct. However, there are still some semantical issues that need to be clarified before the code is stable.
Tickets:
Inspections:
Files:
ossp-pkg/var/var.c      1.42 -> 1.43     124 inserted, 44 deleted
ossp-pkg/var/var.h      1.16 -> 1.17     1 inserted, 0 deleted
ossp-pkg/var/var.pod      1.12 -> 1.13     2 inserted, 2 deleted
ossp-pkg/var/var_test.c      1.22 -> 1.23     2 inserted, 1 deleted

ossp-pkg/var/var.c 1.42 -> 1.43

--- var.c        2001/12/08 16:27:57     1.42
+++ var.c        2001/12/12 16:51:20     1.43
@@ -98,7 +98,8 @@
         "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 */
-        "division by zero error in index specification"                         /* VAR_ERR_DIVISION_BY_ZERO_IN_INDEX = -41 */
+        "division by zero error in index specification",                        /* VAR_ERR_DIVISION_BY_ZERO_IN_INDEX = -41 */
+        "unterterminated loop construct"                                        /* VAR_ERR_UNTERMINATED_LOOP_CONSTRUCT = -42 */
     };
 
     rc = 0 - rc;
@@ -429,28 +430,36 @@
 /* The recursive-descent parser for variable expressions. */
 
 static int variable(const char *, const char *, const var_config_t *,
-                    const char_class_t, var_cb_t, void *, int, tokenbuf_t *);
+                    const char_class_t, var_cb_t, void *, int, tokenbuf_t *, int);
 static int command(const char *, const char *, const var_config_t *,
-                   const char_class_t, var_cb_t, void *, int, tokenbuf_t *);
+                   const char_class_t, var_cb_t, void *, int, tokenbuf_t *, int);
 static int num_exp(const char *begin, const char *end, int current_index,
                    int* result, int* failed, const var_config_t *config,
                    const char_class_t nameclass,
                    var_cb_t lookup, void* lookup_context);
 
 static int text(const char *begin, const char *end, char varinit,
-                char escape)
-{
+                char startindex, char endindex, char escape)
+    {
     const char *p;
-    for (p = begin; p != end && *p != varinit; ++p) {
-        if (*p == escape) {
-            if (p + 1 == end)
+    for (p = begin; p != end; ++p)
+        {
+        if (*p == escape)
+            {
+            if (++p == end)
                 return VAR_ERR_INCOMPLETE_QUOTED_PAIR;
-            else
-                ++p;
+            }
+        else if (*p == varinit)
+            {
+            break;
+            }
+        else if (startindex && (*p == startindex || *p == endindex))
+            {
+            break;
+            }
         }
-    }
     return p - begin;
-}
+    }
 
 static int varname(const char *begin, const char *end,
                    const char_class_t nameclass)
@@ -540,11 +549,11 @@
         }
     else if (*p == config->varinit)
         {
-        rc = variable(p, end, config, nameclass, lookup, lookup_context, 1, &tmp);
+        rc = variable(p, end, config, nameclass, lookup, lookup_context, 1, &tmp, current_index);
         if (rc == VAR_ERR_UNDEFINED_VARIABLE)
             {
             *failed = 1;
-            rc = variable(p, end, config, nameclass, lookup, lookup_context, 0, &tmp);
+            rc = variable(p, end, config, nameclass, lookup, lookup_context, 0, &tmp, current_index);
             if (rc < 0)
                 return rc;
             p += rc;
@@ -689,14 +698,14 @@
                       const var_config_t *config,
                       const char_class_t nameclass, var_cb_t lookup,
                       void *lookup_context, int force_expand,
-                      tokenbuf_t *result)
+                      tokenbuf_t *result, int current_index)
     {
     const char *p = begin;
     const char *data;
     size_t len, buffer_size;
     int failed = 0;
     int rc;
-    int index = 0;
+    int index = current_index;
     tokenbuf_t name;
     tokenbuf_t tmp;
 
@@ -733,7 +742,7 @@
             }
 
         rc = variable(p, end, config, nameclass, lookup, lookup_context,
-                      force_expand, &tmp);
+                      force_expand, &tmp, current_index);
         if (rc < 0)
             goto error_return;
         if (rc > 0)
@@ -762,7 +771,7 @@
     if (config->startindex && *p == config->startindex)
         {
         printf("Found START-INDEX: %s\n", p);
-        rc = num_exp(++p, end, 0, &index, &failed, config, nameclass, lookup, lookup_context);
+        rc = num_exp(++p, end, current_index, &index, &failed, config, nameclass, lookup, lookup_context);
         if (rc < 0)
             goto error_return;
         if (rc == 0)
@@ -853,10 +862,10 @@
             ++p;
             if (!failed)
                 rc = command(p, end, config, nameclass, lookup,
-                             lookup_context, force_expand, result);
+                             lookup_context, force_expand, result, current_index);
             else
                 rc = command(p, end, config, nameclass, lookup,
-                             lookup_context, force_expand, &tmp);
+                             lookup_context, force_expand, &tmp, current_index);
             if (rc < 0)
                 goto error_return;
             p += rc;
@@ -892,7 +901,7 @@
 static int variable(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)
+                    int force_expand, tokenbuf_t *result, int current_index)
 {
     const char *p = begin;
     const char *data;
@@ -939,7 +948,7 @@
     /* OK, we're dealing with a complex expression here. */
 
     rc = expression(p, end, config, nameclass, lookup, lookup_context,
-                    force_expand, result);
+                    force_expand, result, current_index);
     if (rc > 0)
         ++rc;
     return rc;
@@ -949,7 +958,7 @@
                                const var_config_t *config,
                                const char_class_t nameclass, var_cb_t lookup,
                                void *lookup_context, int force_expand,
-                               tokenbuf_t *result)
+                               tokenbuf_t *result, int current_index)
 {
     const char *p = begin;
     tokenbuf_t tmp;
@@ -974,7 +983,7 @@
         }
 
         rc = variable(p, end, config, nameclass, lookup, lookup_context,
-                      force_expand, &tmp);
+                      force_expand, &tmp, current_index);
         if (rc < 0)
             goto error_return;
         if (rc > 0) {
@@ -1001,7 +1010,7 @@
                                 const var_config_t *config,
                                 const char_class_t nameclass, var_cb_t lookup,
                                 void *lookup_context, int force_expand,
-                                tokenbuf_t *result)
+                                tokenbuf_t *result, int current_index)
 {
     const char *p = begin;
     tokenbuf_t tmp;
@@ -1026,7 +1035,7 @@
         }
 
         rc = variable(p, end, config, nameclass, lookup, lookup_context,
-                      force_expand, &tmp);
+                      force_expand, &tmp, current_index);
         if (rc < 0)
             goto error_return;
         if (rc > 0) {
@@ -1472,7 +1481,7 @@
 static int command(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 *data)
+                   tokenbuf_t *data, int current_index)
 {
     const char *p = begin;
     tokenbuf_t tmptokbuf;
@@ -1578,7 +1587,7 @@
     case '-':                   /* Substitute parameter if data is empty. */
         ++p;
         rc = exptext_or_variable(p, end, config, nameclass, lookup,
-                                 lookup_context, force_expand, &tmptokbuf);
+                                 lookup_context, force_expand, &tmptokbuf, current_index);
         if (rc < 0)
             goto error_return;
         if (rc == 0) {
@@ -1595,7 +1604,7 @@
     case '*':                   /* Return "" if data is not empty, parameter otherwise. */
         ++p;
         rc = exptext_or_variable(p, end, config, nameclass, lookup,
-                                 lookup_context, force_expand, &tmptokbuf);
+                                 lookup_context, force_expand, &tmptokbuf, current_index);
         if (rc < 0)
             goto error_return;
         if (rc == 0) {
@@ -1618,7 +1627,7 @@
     case '+':                   /* Substitute parameter if data is not empty. */
         ++p;
         rc = exptext_or_variable(p, end, config, nameclass, lookup,
-                                 lookup_context, force_expand, &tmptokbuf);
+                                 lookup_context, force_expand, &tmptokbuf, current_index);
         if (rc < 0)
             goto error_return;
         if (rc == 0) {
@@ -1640,7 +1649,7 @@
         ++p;
 
         rc = substext_or_variable(p, end, config, nameclass, lookup,
-                                  lookup_context, force_expand, &search);
+                                  lookup_context, force_expand, &search, current_index);
         if (rc < 0)
             goto error_return;
         p += rc;
@@ -1652,7 +1661,7 @@
         ++p;
 
         rc = substext_or_variable(p, end, config, nameclass, lookup,
-                                  lookup_context, force_expand, &replace);
+                                  lookup_context, force_expand, &replace, current_index);
         if (rc < 0)
             goto error_return;
         p += rc;
@@ -1686,7 +1695,7 @@
         ++p;
 
         rc = substext_or_variable(p, end, config, nameclass, lookup,
-                                  lookup_context, force_expand, &search);
+                                  lookup_context, force_expand, &search, current_index);
         if (rc < 0)
             goto error_return;
         p += rc;
@@ -1698,7 +1707,7 @@
         ++p;
 
         rc = substext_or_variable(p, end, config, nameclass, lookup,
-                                  lookup_context, force_expand, &replace);
+                                  lookup_context, force_expand, &replace, current_index);
         if (rc < 0)
             goto error_return;
         p += rc;
@@ -1741,7 +1750,7 @@
         ++p;
 
         rc = substext_or_variable(p, end, config, nameclass, lookup,
-                                  lookup_context, force_expand, &replace);
+                                  lookup_context, force_expand, &replace, current_index);
         if (rc < 0)
             goto error_return;
         p += rc;
@@ -1790,31 +1799,101 @@
     return rc;
 }
 
+struct wrapper_context
+    {
+    var_cb_t lookup;
+    void*    context;
+    int*     found_variables;
+    };
+
+static int lookup_wrapper(void *context,
+                          const char *varname, size_t name_len, int index,
+                          const char **data, size_t *data_len,
+                          size_t *buffer_size)
+    {
+    static char buf[1];
+    struct wrapper_context* wcon = context;
+    int rc;
+
+    printf("Looking up '");
+    fwrite(varname, name_len, 1, stdout);
+    printf("[%d]' ... rc = ", index);
+
+    rc = (*wcon->lookup)(wcon->context, varname, name_len, index, data, data_len, buffer_size);
+    printf("%d\n", rc);
+    if (rc == 0)
+        {
+        *data = buf;
+        *data_len = 0;
+        *buffer_size = 0;
+        return 1;
+        }
+    else
+        {
+        *(wcon->found_variables) += 1;
+        return rc;
+        }
+    }
+
 static var_rc_t input(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 *output)
+                      tokenbuf_t *output, int current_index, size_t recursion_level)
 {
     const char* p = begin;
     int rc;
     tokenbuf_t result;
-
+    int found_variables;
+    int i;
+    int output_backup;
+    struct wrapper_context wcon;
     tokenbuf_init(&result);
 
     do {
-        rc = text(begin, end, config->varinit, config->escape);
+        printf("input(): Parsing string '%s'.\n", begin);
+
+        if (begin != end && *begin == config->startindex)
+            {
+            printf("Found loop construct.\n");
+            wcon.lookup = lookup;
+            wcon.context = lookup_context;
+            wcon.found_variables = &found_variables;
+            ++begin;
+            for (i = 0; i == 0 || found_variables; ++i)
+                {
+                output_backup = output->end - output->begin;
+                found_variables = 0;
+                printf("Recursing with default index %d.\n", i);
+                rc = input(begin, end, config, nameclass, &lookup_wrapper, &wcon, 1, output, i, recursion_level+1);
+                printf("input() recursion returned %d.\n", rc);
+                if (rc < 0)
+                    goto error_return;
+                if (begin[rc] != config->endindex)
+                    {
+                    rc = VAR_ERR_UNTERMINATED_LOOP_CONSTRUCT;
+                    goto error_return;
+                    }
+                }
+            output->end = output->begin + output_backup;
+            begin += rc;
+            ++begin;
+            continue;
+            }
+
+        rc = text(begin, end, config->varinit, config->startindex, config->endindex, config->escape);
         if (rc > 0) {
             if (!tokenbuf_append(output, begin, rc)) {
                 rc = VAR_ERR_OUT_OF_MEMORY;
                 goto error_return;
             }
             begin += rc;
+            continue;
         } else if (rc < 0)
             goto error_return;
 
         rc = variable(begin, end, config, nameclass, lookup,
-                      lookup_context, force_expand, &result);
+                      lookup_context, force_expand, &result, current_index);
         if (rc > 0) {
             if (!tokenbuf_append
                 (output, result.begin, result.end - result.begin)) {
@@ -1822,18 +1901,19 @@
                 goto error_return;
             }
             begin += rc;
+            continue;
         }
         if (rc < 0)
             goto error_return;
     }
-    while (rc > 0);
+    while (begin != end && rc > 0);
 
-    if (begin != end) {
+    if (recursion_level == 0 && begin != end) {
         rc = VAR_ERR_INPUT_ISNT_TEXT_NOR_VARIABLE;
         goto error_return;
     }
 
-    return VAR_OK;
+    return begin - p;
 
   error_return:
     tokenbuf_free(output);
@@ -1882,8 +1962,8 @@
     /* Call the parser. */
     tokenbuf_init(&output);
     rc = input(input_buf, input_buf + input_len, config, nameclass,
-               lookup, lookup_context, force_expand, &output);
+               lookup, lookup_context, force_expand, &output, 0, 0);
     *result = (char *)output.begin;
     *result_len = output.end - output.begin;
-    return rc;
+    return (rc >= 0) ? VAR_OK : rc;
 }


ossp-pkg/var/var.h 1.16 -> 1.17

--- var.h        2001/12/08 16:27:57     1.16
+++ var.h        2001/12/12 16:51:20     1.17
@@ -36,6 +36,7 @@
 
 typedef enum {
     VAR_ERR_CALLBACK = -64,
+    VAR_ERR_UNTERMINATED_LOOP_CONSTRUCT = -42,
     VAR_ERR_DIVISION_BY_ZERO_IN_INDEX = -41,
     VAR_ERR_UNCLOSED_BRACKET_IN_INDEX = -40,
     VAR_ERR_INCOMPLETE_INDEX_SPEC = -39,


ossp-pkg/var/var.pod 1.12 -> 1.13

--- var.pod      2001/12/12 14:34:18     1.12
+++ var.pod      2001/12/12 16:51:20     1.13
@@ -614,7 +614,7 @@
 
 =head1 EBNF GRAMMAR OF SUPPORTED EXPRESSIONS
 
- input      : (TEXT|variable)*
+ input      : ( TEXT | variable | START-INDEX input END-INDEX )*
 
  variable   : '$' (name|expression)
 
@@ -659,7 +659,7 @@
 
  EXPTEXT    : '[^$}:]+'
 
- TEXT       : '[^$]+'
+ TEXT       : '[^$[\]]+'
 
 Please note that the descriptions of START-DELIM, END-DELIM, VARNAME,
 SUBSTEXT, and EXPTEXT shown here assume that var_expand() has been


ossp-pkg/var/var_test.c 1.22 -> 1.23

--- var_test.c   2001/12/08 16:28:41     1.22
+++ var_test.c   2001/12/12 16:51:20     1.23
@@ -142,7 +142,8 @@
         { "${ARRAY[$NUMEXP]}",            "entry1"                                         },
         { "${ARRAY[$NUMEXP-1]}",          "entry0"                                         },
         { "${ARRAY[${UNDEFINED}-1]}",     "${ARRAY[${UNDEFINED}-1]}"                       },
-        { "${ARRAY[5/(${UNDEFINED})]}",   "${ARRAY[5/(${UNDEFINED})]}"                     }
+        { "${ARRAY[5/(${UNDEFINED})]}",   "${ARRAY[5/(${UNDEFINED})]}"                     },
+        { ":[${ARRAY}-]:",                ":entry0-entry1-entry2-entry3-:"                 }
     };
     char *tmp;
     size_t tmp_len;

CVSTrac 2.0.1