OSSP CVS Repository

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

ossp-pkg/var/var.c 1.75 -> 1.76

--- var.c        2002/03/04 11:37:34     1.75
+++ var.c        2002/03/04 11:53:27     1.76
@@ -72,19 +72,21 @@
 
 /* the external context structure */
 struct var_st {
-    var_syntax_t   syntax;
-    char_class_t   syntax_nameclass;
-    var_cb_value_t cb_value_fct;
-    void          *cb_value_ctx;
+    var_syntax_t         syntax;
+    char_class_t         syntax_nameclass;
+    var_cb_value_t       cb_value_fct;
+    void                *cb_value_ctx;
+    var_cb_operation_t   cb_operation_fct;
+    void                *cb_operation_ctx;
 };
 
 /* the internal expansion context structure */
 struct var_parse_st {
     struct var_parse_st *lower;
-    int force_expand;
-    int rel_lookup_flag;
-    int rel_lookup_cnt;
-    int index_this;
+    int                  force_expand;
+    int                  rel_lookup_flag;
+    int                  rel_lookup_cnt;
+    int                  index_this;
 };
 typedef struct var_parse_st var_parse_t;
 
@@ -443,6 +445,7 @@
 /* forward declarations */
 static int parse_variable(var_t *var, var_parse_t *ctx, const char *begin, const char *end, tokenbuf_t *result);
 static int parse_numexp (var_t *var, var_parse_t *ctx, const char *begin, const char *end, int *result, int *failed);
+static int parse_name   (var_t *var, var_parse_t *ctx, const char *begin, const char *end);
 
 /* parse substitution text */
 static int 
@@ -485,6 +488,71 @@
     return (p - begin);
 }
 
+/* parse opertion argument text */
+static int 
+parse_opargtext(
+    var_t *var, var_parse_t *ctx,
+    const char *begin, const char *end)
+{
+    const char *p;
+
+    /* 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);
+}
+
+static int 
+parse_opargtext_or_variable(
+    var_t *var, var_parse_t *ctx,
+    const char *begin, const char *end,
+    tokenbuf_t *result)
+{
+    const char *p;
+    tokenbuf_t tmp;
+    int rc;
+
+    tokenbuf_init(result);
+    tokenbuf_init(&tmp);
+    p = begin;
+    if (p == end)
+        return 0;
+    do {
+        rc = parse_opargtext(var, ctx, p, end);
+        if (rc < 0)
+            goto error_return;
+        if (rc > 0) {
+            if (!tokenbuf_append(result, p, rc)) {
+                rc = VAR_ERR_OUT_OF_MEMORY;
+                goto error_return;
+            }
+            p += rc;
+        }
+        rc = parse_variable(var, ctx, p, end, &tmp);
+        if (rc < 0)
+            goto error_return;
+        if (rc > 0) {
+            p += rc;
+            if (!tokenbuf_merge(result, &tmp)) {
+                rc = VAR_ERR_OUT_OF_MEMORY;
+                goto error_return;
+            }
+        }
+    } while (rc > 0);
+    tokenbuf_free(&tmp);
+    return (p - begin);
+
+    error_return:
+    tokenbuf_free(&tmp);
+    tokenbuf_free(result);
+    return rc;
+}
+
 /* parse expression or variable */
 static int 
 parse_exptext_or_variable(
@@ -1314,6 +1382,62 @@
             }
             break;
         }
+        case '%': {
+            /* operation callback function */
+            const char *op_ptr;
+            size_t op_len;
+            const char *arg_ptr;
+            size_t arg_len;
+            const char *val_ptr;
+            size_t val_len;
+            const char *out_ptr;
+            size_t out_len; 
+            size_t out_size;
+            tokenbuf_t args;
+
+            p++;
+            rc = parse_name(var, ctx, p, end);
+            if (rc < 0)
+                goto error_return;
+            op_ptr = p;
+            op_len = rc;
+            p += rc;
+            if (*p == '(') {
+                p++;
+                tokenbuf_init(&args);
+                rc = parse_opargtext_or_variable(var, ctx, p, end, &args);
+                if (rc < 0)
+                    goto error_return;
+                p += rc;
+                arg_ptr = args.begin;
+                arg_len = args.end - args.begin;
+                if (*p != ')') {
+                    rc = VAR_ERR_MALFORMED_OPERATION_ARGUMENTS;
+                    goto error_return;
+                }
+                p++;
+            }
+            else {
+                arg_ptr = NULL;
+                arg_len = 0;
+            }
+            val_ptr = data->begin;
+            val_len = data->end - data->begin;
+
+            if (data->begin != NULL && var->cb_operation_fct != NULL) {
+                /* call operation callback function */
+                rc = (*var->cb_operation_fct)(var, var->cb_operation_ctx,
+                                              op_ptr, op_len,
+                                              arg_ptr, arg_len,
+                                              val_ptr, val_len,
+                                              &out_ptr, &out_len, &out_size);
+                if (rc < 0)
+                    goto error_return;
+                tokenbuf_free(data);
+                tokenbuf_set(data, out_ptr, out_ptr+out_len, out_size);
+            }
+            break;
+        }
         default:
             return VAR_ERR_UNKNOWN_COMMAND_CHAR;
     }
@@ -2141,6 +2265,15 @@
             var->cb_value_ctx = ctx;
             break;
         }
+        case VAR_CONFIG_CB_OPERATION: {
+            var_cb_operation_t fct;
+            void *ctx;
+            fct = (var_cb_operation_t)va_arg(ap, void *);
+            ctx = (void *)va_arg(ap, void *);
+            var->cb_operation_fct = fct;
+            var->cb_operation_ctx = ctx;
+            break;
+        }
         default:
             return VAR_RC(VAR_ERR_INVALID_ARGUMENT);
     }
@@ -2266,6 +2399,8 @@
 /* var_rc_t to string mapping table */
 static const char *var_errors[] = {
     "everything ok",                                           /* VAR_OK = 0 */
+    "undefined operation",                                     /* VAR_ERR_UNDEFINED_OPERATION */
+    "malformed operation argument list",                       /* VAR_ERR_MALFORMED_OPERATION_ARGUMENTS */
     "incomplete named character",                              /* VAR_ERR_INCOMPLETE_NAMED_CHARACTER */
     "incomplete hexadecimal value",                            /* VAR_ERR_INCOMPLETE_HEX */
     "invalid hexadecimal value",                               /* VAR_ERR_INVALID_HEX */

CVSTrac 2.0.1