OSSP CVS Repository

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

Check-in Number: 1438
Date: 2001-Dec-17 00:40:16 (local)
2001-Dec-16 23:40:16 (UTC)
User:rse
Branch:
Comment: Implemented loops with explicit start, stop, and step values.
Tickets:
Inspections:
Files:
ossp-pkg/var/var.c      1.52 -> 1.53     163 inserted, 26 deleted
ossp-pkg/var/var.h      1.18 -> 1.19     1 inserted, 0 deleted
ossp-pkg/var/var.pod      1.14 -> 1.15     3 inserted, 1 deleted
ossp-pkg/var/var_test.c      1.27 -> 1.28     10 inserted, 4 deleted

ossp-pkg/var/var.c 1.52 -> 1.53

--- var.c        2001/12/14 14:40:28     1.52
+++ var.c        2001/12/16 23:40:16     1.53
@@ -99,7 +99,8 @@
         "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 */
-        "unterterminated loop construct"                                        /* VAR_ERR_UNTERMINATED_LOOP_CONSTRUCT = -42 */
+        "unterminated loop construct",                                          /* VAR_ERR_UNTERMINATED_LOOP_CONSTRUCT = -42 */
+        "invalid character in loop limits"                                      /* VAR_ERR_INVALID_CHAR_IN_LOOP_LIMITS = -43 */
     };
 
     rc = 0 - rc;
@@ -502,8 +503,8 @@
     const char *p;
 
     for (p = begin;
-            p != end 
-         && *p != config->varinit 
+            p != end
+         && *p != config->varinit
          && *p != config->enddelim
          && *p != ':'; p++) {
         if (*p == config->escape) {
@@ -543,7 +544,7 @@
         return VAR_ERR_INCOMPLETE_INDEX_SPEC;
 
     if (*p == '(') {
-        rc = num_exp(++p, end, current_index, result, failed, 
+        rc = num_exp(++p, end, current_index, result, failed,
                      rel_lookup_flag, config, nameclass, lookup, lookup_context);
         if (rc < 0)
             return rc;
@@ -555,11 +556,11 @@
         ++p;
     }
     else if (*p == config->varinit) {
-        rc = variable(p, end, config, nameclass, lookup, 
+        rc = variable(p, end, config, nameclass, lookup,
                       lookup_context, 1, &tmp, current_index, rel_lookup_flag);
         if (rc == VAR_ERR_UNDEFINED_VARIABLE) {
             *failed = 1;
-            rc = variable(p, end, config, nameclass, lookup, 
+            rc = variable(p, end, config, nameclass, lookup,
                           lookup_context, 0, &tmp, current_index, rel_lookup_flag);
             if (rc < 0)
                 return rc;
@@ -570,7 +571,7 @@
             if (rc < 0)
                 return rc;
             p += rc;
-            rc = num_exp(tmp.begin, tmp.end, current_index, result, 
+            rc = num_exp(tmp.begin, tmp.end, current_index, result,
                          failed, rel_lookup_flag, config, nameclass, lookup, lookup_context);
             tokenbuf_free(&tmp);
             if (rc < 0)
@@ -622,8 +623,8 @@
     if (begin == end)
         return VAR_ERR_INCOMPLETE_INDEX_SPEC;
 
-    rc = num_exp_read_operand(p, end, current_index, result, 
-                              failed, rel_lookup_flag, config, nameclass, 
+    rc = num_exp_read_operand(p, end, current_index, result,
+                              failed, rel_lookup_flag, config, nameclass,
                               lookup, lookup_context);
     if (rc < 0)
         return rc;
@@ -632,7 +633,7 @@
     while (p != end) {
         if (*p == '+' || *p == '-') {
             operator = *p++;
-            rc = num_exp(p, end, current_index, &right, failed, 
+            rc = num_exp(p, end, current_index, &right, failed,
                          rel_lookup_flag, config, nameclass, lookup, lookup_context);
             if (rc < 0)
                 return rc;
@@ -644,7 +645,7 @@
         }
         else if (*p == '*' || *p == '/' || *p == '%') {
             operator = *p++;
-            rc = num_exp_read_operand(p, end, current_index, &right, failed, 
+            rc = num_exp_read_operand(p, end, current_index, &right, failed,
                                       rel_lookup_flag, config, nameclass, lookup, lookup_context);
             if (rc < 0)
                 return rc;
@@ -747,7 +748,7 @@
     /* If the next token is START-INDEX, read the index specification. */
 
     if (config->startindex && *p == config->startindex) {
-        rc = num_exp(++p, end, current_index, &idx, &failed, 
+        rc = num_exp(++p, end, current_index, &idx, &failed,
                      rel_lookup_flag, config, nameclass, lookup, lookup_context);
         if (rc < 0)
             goto error_return;
@@ -822,11 +823,11 @@
             p++;
             if (!failed)
                 rc = command(p, end, config, nameclass, lookup,
-                             lookup_context, force_expand, result, 
+                             lookup_context, force_expand, result,
                              current_index, rel_lookup_flag);
             else
                 rc = command(p, end, config, nameclass, lookup,
-                             lookup_context, force_expand, &tmp, 
+                             lookup_context, force_expand, &tmp,
                              current_index, rel_lookup_flag);
             if (rc < 0)
                 goto error_return;
@@ -1231,7 +1232,7 @@
             else
                 rc = strncmp(p, search->begin,
                              search->end - search->begin);
-            if (rc != 0) {      
+            if (rc != 0) {
                 /* no match, copy character */
                 if (!tokenbuf_append(&tmp, p, 1)) {
                     tokenbuf_free(&tmp);
@@ -1352,7 +1353,7 @@
                     return VAR_ERR_OUT_OF_MEMORY;
                 i--;
             }
-            i = (width - (data->end - data->begin)) 
+            i = (width - (data->end - data->begin))
                 % (fill->end - fill->begin);
             if (!tokenbuf_append(data, fill->begin, i))
                 return VAR_ERR_OUT_OF_MEMORY;
@@ -1369,7 +1370,7 @@
                 }
                 i--;
             }
-            i = (width - (data->end - data->begin)) 
+            i = (width - (data->end - data->begin))
                 % (fill->end - fill->begin);
             if (!tokenbuf_append(&result, fill->begin, i)) {
                 tokenbuf_free(&result);
@@ -1396,7 +1397,7 @@
                 }
                 i--;
             }
-            i = ((width - (data->end - data->begin)) / 2) 
+            i = ((width - (data->end - data->begin)) / 2)
                 % (fill->end - fill->begin);
             if (!tokenbuf_append(&result, fill->begin, i)) {
                 tokenbuf_free(&result);
@@ -1774,7 +1775,7 @@
     struct wrapper_context *wcon = context;
     int rc;
 
-    rc = (*wcon->lookup)(wcon->context, name, name_len, 
+    rc = (*wcon->lookup)(wcon->context, name, name_len,
                          idx, data, data_len, buffer_size);
     if (rc == 0) {
         (*wcon->rel_lookup_flag)--;
@@ -1787,6 +1788,105 @@
         return rc;
 }
 
+static var_rc_t loop_limits(const char *begin, const char *end,
+                            const var_config_t *config,
+                            const char_class_t nameclass,
+                            var_cb_t lookup, void* lookup_context,
+                            int* start, int* step, int* stop, int* open_end)
+    {
+    const char* p = begin;
+    int rc;
+    int failed;
+    int dummy;
+
+    printf("loop_limits() called: '%s'.\n", begin);
+
+    if (begin == end)
+        return 0;
+
+    if (*p != config->startdelim)
+        return 0;
+    else
+        ++p;
+
+    /* Read start value for the loop. */
+
+    failed = 0;
+    rc = num_exp(p, end, 0, start, &failed, &dummy,
+                 config, nameclass, lookup, lookup_context);
+    if (rc == VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC)
+        *start = 0;          /* use default */
+    else if (rc < 0)
+        return rc;
+    else
+        p += rc;
+    if (failed)
+        return VAR_ERR_UNDEFINED_VARIABLE;
+
+    if (*p != ',')
+        return VAR_ERR_INVALID_CHAR_IN_LOOP_LIMITS;
+    else
+        ++p;
+
+    /* Read step value for the loop. */
+
+    failed = 0;
+    rc = num_exp(p, end, 0, step, &failed, &dummy,
+                 config, nameclass, lookup, lookup_context);
+    if (rc == VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC)
+        *step = 1;          /* use default */
+    else if (rc < 0)
+        return rc;
+    else
+        p += rc;
+    if (failed)
+        return VAR_ERR_UNDEFINED_VARIABLE;
+
+    if (*p != ',')
+        {
+        if (*p != config->enddelim)
+            return VAR_ERR_INVALID_CHAR_IN_LOOP_LIMITS;
+        else
+            {
+            ++p;
+            *stop = *step;
+            *step = 1;
+            if (rc > 0)
+                *open_end = 0;
+            else
+                *open_end = 1;
+            return p - begin;
+            }
+        }
+    else
+        ++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 */
+        *open_end = 1;
+        }
+    else if (rc < 0)
+        return rc;
+    else
+        {
+        *open_end = 0;
+        p += rc;
+        }
+    if (failed)
+        return VAR_ERR_UNDEFINED_VARIABLE;
+
+    if (*p != config->enddelim)
+        return VAR_ERR_INVALID_CHAR_IN_LOOP_LIMITS;
+
+    return ++p - begin;
+    }
+
 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,
@@ -1795,13 +1895,15 @@
                       size_t recursion_level, int *rel_lookup_flag)
 {
     const char *p = begin;
-    int rc;
+    int rc, rc2;
     tokenbuf_t result;
+    int start, step, stop, open_end;
     int i;
     int output_backup;
     struct wrapper_context wcon;
     int my_rel_lookup_flag;
     int original_rel_lookup_state;
+    int loop_limit_length;
 
     tokenbuf_init(&result);
 
@@ -1813,14 +1915,23 @@
     do {
         if (begin != end && config->startindex && *begin == config->startindex) {
             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++;
-            for (i = 0; i == 0 || *rel_lookup_flag > original_rel_lookup_state; i++) {
+            start = 0;
+            step  = 1;
+            stop  = 0;
+            open_end = 1;
+      re_loop:
+            for (i = start;
+                 (open_end  && (loop_limit_length < 0 || *rel_lookup_flag > original_rel_lookup_state)) ||
+                     (!open_end && i <= stop);
+                 i += step) {
                 *rel_lookup_flag = original_rel_lookup_state;
                 output_backup = output->end - output->begin;
-                rc = input(begin, end, config, nameclass, &lookup_wrapper, 
+                rc = input(begin, end, config, nameclass, &lookup_wrapper,
                            &wcon, 1, output, i, recursion_level+1, rel_lookup_flag);
                 if (rc < 0)
                     goto error_return;
@@ -1828,14 +1939,41 @@
                     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 (rc2 < 0)
+                        {
+                        printf("loop_limits() failed: %d ('%s').\n", rc2, var_strerror(rc2));
+                        goto error_return;
+                        }
+                    else if (rc2 == 0)
+                        {
+                        loop_limit_length = 0;
+                        }
+                    else if (rc2 > 0)
+                        {
+                        printf("Found loop limits: start = %d, step = %d, stop = %d, open_end = %s\n",
+                               start, step, stop, (open_end) ? "true" : "false");
+                        loop_limit_length = rc2;
+                        output->end = output->begin + output_backup;
+                        goto re_loop;
+                        }
+                    }
             }
-            output->end = output->begin + output_backup;
+            if (open_end)
+                output->end = output->begin + output_backup;
+            else
+                *rel_lookup_flag = original_rel_lookup_state;
             begin += rc;
             begin++;
+            begin += loop_limit_length;
             continue;
         }
 
-        rc = text(begin, end, config->varinit, config->startindex, 
+        rc = text(begin, end, config->varinit, config->startindex,
                   config->endindex, config->escape);
         if (rc > 0) {
             if (!tokenbuf_append(output, begin, rc)) {
@@ -1848,7 +1986,7 @@
             goto error_return;
 
         rc = variable(begin, end, config, nameclass, lookup,
-                      lookup_context, force_expand, &result, 
+                      lookup_context, force_expand, &result,
                       current_index, rel_lookup_flag);
         if (rc > 0) {
             if (!tokenbuf_append(output, result.begin, result.end - result.begin)) {
@@ -1942,4 +2080,3 @@
 
     return rc;
 }
-


ossp-pkg/var/var.h 1.18 -> 1.19

--- var.h        2001/12/14 13:47:01     1.18
+++ var.h        2001/12/16 23:40:16     1.19
@@ -36,6 +36,7 @@
 
 typedef enum {
     VAR_ERR_CALLBACK = -64,
+    VAR_ERR_INVALID_CHAR_IN_LOOP_LIMITS = -43,
     VAR_ERR_UNTERMINATED_LOOP_CONSTRUCT = -42,
     VAR_ERR_DIVISION_BY_ZERO_IN_INDEX = -41,
     VAR_ERR_UNCLOSED_BRACKET_IN_INDEX = -40,


ossp-pkg/var/var.pod 1.14 -> 1.15

--- var.pod      2001/12/12 17:18:55     1.14
+++ var.pod      2001/12/16 23:40:16     1.15
@@ -616,7 +616,9 @@
 
 =head1 EBNF GRAMMAR OF SUPPORTED EXPRESSIONS
 
- input      : ( TEXT | variable | START-INDEX input END-INDEX )*
+ input      : ( TEXT | variable | START-INDEX input END-INDEX ( loop-limits )? )*
+
+ loop-limits: START-DELIM (numexp)? ',' (numexp)? ( ',' (numexp)? )? END-DELIM
 
  variable   : '$' (name|expression)
 


ossp-pkg/var/var_test.c 1.27 -> 1.28

--- var_test.c   2001/12/14 13:49:40     1.27
+++ var_test.c   2001/12/16 23:40:16     1.28
@@ -65,7 +65,7 @@
                 printf("Found variable at index %d.\n", i);
                 counter = 1;
                 length = strlen(vars[i].data);
-                while (   vars[i + counter].data 
+                while (   vars[i + counter].data
                        && strncmp(varname, vars[i + counter].name, name_len) == 0)
                     counter++;
                 if (counter == 1)
@@ -134,7 +134,7 @@
         { "${HOME:s/[esO]/_/gi}",         "/h_m_/r_gr___i_n-t__t_"                         },
         { "${OSTYPE:s/^[re]/_/g}",        "_egression-os"                                  },
         { "${EMPTY:s/^[re]/_/g}",         ""                                               },
-        { "${HOME:s/.*/heinz/}",          "heinz"                                          },
+        { "${HOME:s/.*\\x{}/heinz/}",     "heinz"                                          },
         { "${HOME:s/e/bla/t}",            "/hombla/regression-tests"                       },
         { "${HOME:s/E/bla/t}",            "/home/regression-tests"                         },
         { "${HOME:s/E/bla/ti}",           "/hombla/regression-tests"                       },
@@ -173,6 +173,8 @@
         { "${ARRAY[5/(${UNDEFINED})]}",   "${ARRAY[5/(${UNDEFINED})]}"                     },
         { "[${ARRAY[#]}-]",               "entry0-entry1-entry2-entry3-"                   },
         { "[${ARRAY[#+1]}-]",             "entry1-entry2-entry3-"                          },
+        { "-[${ARRAY[#]}:]{1,$NUMBER}-",  "-entry1:entry2:-"                               },
+        { "-[${ARRAY[#]}:]{1,3,5}-",      "-entry1::-"                                     },
         {
         "[${ARRAY}:${ARRAY[#]}-]",
         "entry0:entry0-entry0:entry1-entry0:entry2-entry0:entry3-"
@@ -188,7 +190,11 @@
         {
         "[${HEINZ[#]}: [${ARRAY[#]}${ARRAY[#+1]:+, }]${HEINZ[#+1]:+; }]",
         "heinz0: entry0, entry1, entry2, entry3; heinz1: entry0, entry1, entry2, entry3"
-        }
+        },
+        {
+        "[${ARRAY[#]}:[${ARRAY[#]},]{1,2,} ]{0,2,}",
+        "entry0:entry1,entry3, entry2:entry1,entry3, "
+        },
     };
     char *tmp;
     size_t tmp_len;
@@ -220,7 +226,7 @@
 #ifdef DEBUG
         printf("Test case #%02d: Expanded output is '%s'.\n", i, tmp);
 #endif
-        if (   tmp_len != strlen(tests[i].expected) 
+        if (   tmp_len != strlen(tests[i].expected)
             || tmp == NULL
             || memcmp(tests[i].expected, tmp, tmp_len) != 0) {
             printf("Test case #%d: Expected result '%s' but got '%s'.\n",

CVSTrac 2.0.1