OSSP CVS Repository

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

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;
 }
-

CVSTrac 2.0.1