OSSP CVS Repository

ossp - Difference in ossp-pkg/l2/l2_ut_param.c versions 1.5 and 1.6
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/l2/l2_ut_param.c 1.5 -> 1.6

--- l2_ut_param.c        2001/09/08 22:06:09     1.5
+++ l2_ut_param.c        2001/11/07 13:05:20     1.6
@@ -30,82 +30,157 @@
 #include "l2.h"
 #include "l2_p.h"
 
+#include <stdlib.h>
 #include <string.h>
+#include <limits.h>
+#include <math.h>
+#include <ctype.h>
 
-l2_result_t l2_util_setparams(l2_param_t pa[], const char *fmt, va_list ap)
+l2_result_t l2_util_setparams(l2_env_t *env, l2_param_t pa[], const char *fmt, va_list ap)
 {
-    const char *cpB, *cpE;
-    const char *cpC, *cpG;
+    char *cpB, *cpE;
+    char *spec;
     int ok;
     int i; 
+    int n;
 
-    if (pa == NULL || fmt == NULL || ap == NULL)
+    /* argument sanity check */
+    if (env == NULL || pa == NULL || fmt == NULL || ap == NULL)
         return L2_ERR_ARG;
-    cpE = fmt;
+
+    /* on-the-fly create or just take over parameter specification string */
+    spec = l2_util_vasprintf(fmt, ap);
+
+    /* enter the parsing loop */
+    cpE = spec;
     while (*cpE != '\0') {
         /* determine begin of parameter name */
         cpB = cpE;
-        while (*cpB == ',')
-            cpB++;
+        if ((n = strspn(cpB, " \t\r\n")) > 0)
+            cpB += n;
 
         /* determine end of parameter name */
         cpE = cpB;
-        while (*cpE != ',' && *cpE != '\0')
+        if (!isalpha((int)*cpE)) {
+            l2_env_errorinfo(env, L2_ERR_ARG, 
+                             "expected alpha-numerical parameter "
+                             "start character, got '%c'", *cpE);
+            return L2_ERR_ARG;
+        }
+        cpE++;
+        while (isalnum((int)*cpE))
             cpE++;
+        if (*cpE != '=') {
+            l2_env_errorinfo(env, L2_ERR_ARG, 
+                             "expected assignment operator ('='), "
+                             "got '%c'", *cpE);
+            return L2_ERR_ARG;
+        }
+        *cpE++ = '\0';
 
         /* try to match with configured parameters */
         ok = FALSE;
         for (i = 0; pa[i].name != NULL; i++) {
-            cpC = pa[i].name;
-            cpG = cpB;
-            while (*cpC != '\0' && cpG < cpE) {
-                if (*cpC != *cpG)
+            if (strcmp(pa[i].name, cpB) == 0) {
+                ok = TRUE;
+                break;
+            }
+        }
+        if (!ok) {
+            l2_env_errorinfo(env, L2_ERR_ARG, "unknown parameter name '%s'", cpB);
+            return L2_ERR_ARG;
+        }
+
+        /* determine parameter value */
+        cpB = cpE;
+        if ((n = strspn(cpB, " \t\r\n")) > 0)
+            cpB += n;
+        if (*cpB == '"') {
+            cpB++;
+            while (1) {
+                cpE = cpB;
+                if ((cpE = strchr(cpE+1, '"')) == NULL) {
+                    l2_env_errorinfo(env, L2_ERR_ARG, "closing quote ('\"') not found");
+                    return L2_ERR_ARG;
+                }
+                if (*(cpE-1) != '\\')
                     break;
-                cpC++;
-                cpG++;
             }
-            if (*cpC == '\0' && cpG == cpE) {
-                /* parameter matched, so store value */
-                switch (pa[i].type) {
-                    case L2_TYPE_CHAR:
-                        *(char *)(pa[i].store) = va_get(ap, char); 
-                        break;
-                    case L2_TYPE_SHORT:
-                        *(short *)(pa[i].store) = va_get(ap, short); 
-                        break;
-                    case L2_TYPE_INT:
-                        *(int *)(pa[i].store) = va_get(ap, int); 
-                        break;
-                    case L2_TYPE_LONG:
-                        *(long *)(pa[i].store) = va_get(ap, long); 
-                        break;
-                    case L2_TYPE_FLOAT:
-                        *(float *)(pa[i].store) = va_get(ap, float); 
-                        break;
-                    case L2_TYPE_DOUBLE:
-                        *(double *)(pa[i].store) = va_get(ap, double); 
-                        break;
-                    case L2_TYPE_STRING:
-                        if (*(char **)(pa[i].store) != NULL) 
-                            free(*(char **)(pa[i].store));
-                        *(char **)(pa[i].store) = va_get(ap, charptr);
-                        if (*(char **)(pa[i].store) != NULL)
-                            *(char **)(pa[i].store) = strdup(*(char **)(pa[i].store));
-                        break;
-                    case L2_TYPE_CHARPTR:
-                        *(char **)(pa[i].store) = va_get(ap, charptr); 
-                        break;
-                    case L2_TYPE_VOIDPTR:
-                        *(void **)(pa[i].store) = va_get(ap, voidptr); 
-                        break;
+        }
+        else {
+            cpE = cpB;
+            while (1) {
+                if ((n = strcspn(cpE, " \t\r\n,")) > 0) {
+                    cpE += n;
+                    if (*(cpE-1) == '\\') {
+                        cpE++;
+                        continue;
+                    }
                 }
-                ok = TRUE;
                 break;
             }
         }
-        if (!ok)
-            return L2_ERR_USE;
+        *cpE++ = '\0';
+
+        /* store parameter value */
+        switch (pa[i].type) {
+            case L2_TYPE_INT: {
+                /* integer parameter */
+                long val = strtol(cpB, &cpE, 10);
+                if ((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE) {
+                    l2_env_errorinfo(env, L2_ERR_ARG, 
+                                     "numerical parameter value out of range "
+                                     "('%s')", cpB);
+                    return L2_ERR_ARG;
+                }
+                if (*cpE != '\0') {
+                    l2_env_errorinfo(env, L2_ERR_ARG, 
+                                     "expected valid numerical parameter value, "
+                                     "got '%c' character", *cpE);
+                    return L2_ERR_ARG;
+                }
+                *(int *)(pa[i].store) = (int)val;
+                break;
+            }
+            case L2_TYPE_FLT: {
+                /* floating point parameter */
+                double val = strtod(cpB, &cpE);
+                if (val == HUGE_VAL && errno == ERANGE) {
+                    l2_env_errorinfo(env, L2_ERR_ARG, 
+                                     "floating point parameter value too huge "
+                                     "('%s')", cpB);
+                    return L2_ERR_ARG;
+                }
+                if (val == 0 && cpE == cpB) {
+                    l2_env_errorinfo(env, L2_ERR_ARG, 
+                                     "floating point parameter value conversion failed "
+                                     "('%s')", cpB);
+                }
+                if (*cpE != '\0') {
+                    l2_env_errorinfo(env, L2_ERR_ARG, 
+                                     "expected valid floating point parameter value, "
+                                     "got '%c' character", *cpE);
+                    return L2_ERR_ARG;
+                }
+                *(float *)(pa[i].store) = (float)val;
+                break;
+            }
+            case L2_TYPE_STR: {
+                /* string parameter */
+                if (*(char **)(pa[i].store) != NULL) 
+                    free(*(char **)(pa[i].store));
+                *(char **)(pa[i].store) = strdup(cpB);
+                break;
+            }
+        }
+
+        /* skip delimiter */
+        if ((n = strspn(cpE, " \t\r\n,")) > 0)
+            cpE += n;
     }
+
+    free(spec);
+
     return L2_OK;
 }
 

CVSTrac 2.0.1