about summary refs log tree commit diff
path: root/lib/util/shhopt.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/util/shhopt.c')
-rw-r--r--lib/util/shhopt.c135
1 files changed, 74 insertions, 61 deletions
diff --git a/lib/util/shhopt.c b/lib/util/shhopt.c
index 718186fa..ccf2d1eb 100644
--- a/lib/util/shhopt.c
+++ b/lib/util/shhopt.c
@@ -31,6 +31,7 @@
 
 #include "mallocvar.h"
 #include "nstring.h"
+#include "token.h"
 #include "shhopt.h"
 
 /*-----------------------------------------------------------------------+
@@ -76,7 +77,7 @@ optFatalFunc(const char *format, ...)
  |
  |  RETURNS       Number of options in the given array.
  |
- |  DESCRIPTION   Count elements in an optStruct-array. The strcture must
+ |  DESCRIPTION   Count elements in an optStruct-array. The structure must
  |                be ended using an element of type OPT_END.
  */
 static int
@@ -237,6 +238,7 @@ optNeedsArgument(const optEntry opt)
 	|| opt.type == OPT_ULONG
     || opt.type == OPT_FLOAT
     || opt.type == OPT_NAMELIST
+    || opt.type == OPT_STRINGLIST
         ;
 }
 
@@ -281,46 +283,12 @@ getToken(const char *  const tokenStart,
    we return an empty string and *nextP == tokenStart, i.e. *nextP
    doesn't necessarily advance.
 -----------------------------------------------------------------------------*/
-    char * token;
-    const char * cursor;
-    unsigned int charCount;
-
-    /* Run through the token, counting characters */
-
-    charCount = 0;
-    cursor = tokenStart;
-
-    while (*cursor != delimiter && *cursor != '\0') {
-        if (*cursor == '\\') {
-            ++cursor;
-            if (*cursor == '\0')
-                optFatal("string ends with an escape character (\\)");
-        }
-        ++cursor;
-        ++charCount;
-    }
+    const char * error;
     
-    token = malloc(charCount + 1);
-    if (token == NULL)
-        optFatal("Could not allocate %u bytes of memory to parse a string",
-                 charCount + 1);
-
-    /* Go back and do it again, this time copying the characters */
-    charCount = 0;
-    cursor = tokenStart;
-
-    while (*cursor != delimiter && *cursor != '\0') {
-        if (*cursor == '\\')
-            ++cursor;
-
-        assert(*cursor != '\0');
+    pm_gettoken(tokenStart, delimiter, tokenP, nextP, &error);
 
-        token[charCount++] = *cursor++;
-    }
-    token[charCount] = '\0';
-
-    *tokenP = token;
-    *nextP = cursor;
+    if (error)
+        optFatal("error parsing a token: %s", error);
 }
 
 
@@ -375,6 +343,41 @@ parseNameList(const char *           const listText,
 
 
 
+static void
+parseStringList(const char *   const listText,
+                const char *** const listP) {
+
+    unsigned int const maxStringCount = 100;
+
+    const char * cursor;
+    unsigned int stringCount;
+    const char ** list;
+
+    MALLOCARRAY_NOFAIL(list, maxStringCount+1);
+
+    cursor = &listText[0];  /* initial value */
+
+    stringCount = 0;  /* initial value */
+
+    while (stringCount < maxStringCount && *cursor != '\0') {
+        const char * next;
+
+        getToken(cursor, ',', &list[stringCount++], &next);
+
+        cursor = next;
+
+        if (*cursor != '\0') {
+            assert(*cursor == ',');
+            ++cursor;
+        }
+    }
+    list[stringCount] = NULL;
+
+    *listP = list;
+}
+
+
+
 /*------------------------------------------------------------------------
  |  NAME          optExecute
  |
@@ -479,6 +482,15 @@ optExecute(optEntry  const opt, char *arg, int lng)
             parseNameList(arg, (struct optNameValue **)opt.arg);
 
     } break;
+    case OPT_STRINGLIST: {
+        if (arg == NULL)
+            optFatal("internal error: optExecute() called with NULL argument "
+                     "'%s'", optString(opt, lng));
+
+        if (opt.arg)
+            parseStringList(arg, (const char ***)opt.arg);
+
+    } break;
     default:
         break;
     }
@@ -502,19 +514,20 @@ optExecute(optEntry  const opt, char *arg, int lng)
  |                        that _must_ abort the program.
  */
 void
-optSetFatalFunc(void (*f)(const char *, ...))
-{
+pm_optSetFatalFunc(void (*f)(const char *, ...)) {
+
     optFatal = f;
 }
 
 
+
 /*------------------------------------------------------------------------
- |  NAME          optParseOptions
+ |  NAME          pm_optParseOptions
  |
  |  FUNCTION      Parse commandline options.
  |
  |  SYNOPSIS      #include "shhopt.h"
- |                void optParseOptions(int *argc, char *argv[],
+ |                void pm_optParseOptions(int *argc, char *argv[],
  |                                     optStruct opt[], int allowNegNum);
  |
  |  INPUT         argc    Pointer to number of options.
@@ -541,7 +554,7 @@ optSetFatalFunc(void (*f)(const char *, ...))
  |                Any error leads to program abortion.
  */
 void
-optParseOptions(int *argc, char *argv[], optStruct opt[], int allowNegNum)
+pm_optParseOptions(int *argc, char *argv[], optStruct opt[], int allowNegNum)
 {
     int  ai,        /* argv index. */
          optarg,    /* argv index of option argument, or -1 if none. */
@@ -724,13 +737,13 @@ fatalUnrecognizedLongOption(const char * const optionName,
         const char * entry;
 
         if (optEntryP->longName)
-            asprintfN(&entry, "-%s ", optEntryP->longName);
+            pm_asprintf(&entry, "-%s ", optEntryP->longName);
         else
-            asprintfN(&entry, "-%c ", optEntryP->shortName);
+            pm_asprintf(&entry, "-%c ", optEntryP->shortName);
 
         strncat(optList, entry, sizeof(optList) - strlen(optList) - 1);
 
-        strfree(entry);
+        pm_strfree(entry);
 
         if (strlen(optList) + 1 == sizeof(optList)) {
             /* Buffer is full.  Overwrite end of list with ellipsis */
@@ -809,12 +822,12 @@ parse_long_option(char *   const argv[],
 
 
 /*------------------------------------------------------------------------
- |  NAME          optParseOptions2
+ |  NAME          pm_optParseOptions2
  |
  |  FUNCTION      Parse commandline options.
  |
  |  SYNOPSIS      #include "shhopt.h"
- |                void optParseOptions2(int *argc, char *argv[],
+ |                void pm_optParseOptions2(int *argc, char *argv[],
  |                                      optStruct2 opt, unsigned long flags);
  |
  |  INPUT         argc    Pointer to number of options.
@@ -834,9 +847,9 @@ parse_long_option(char *   const argv[],
  |                extracted and stored in the variables or passed to
  |                functions pointed to by entries in opt.
  |
- |                This differs from optParseOptions in that it accepts
+ |                This differs from pm_optParseOptions in that it accepts
  |                long options with just one hyphen and doesn't accept
- |                any short options.  It also has accomodations for 
+ |                any short options.  It also has accommodations for 
  |                future expansion.
  |
  |                Options and arguments used are removed from the argv-
@@ -845,10 +858,10 @@ parse_long_option(char *   const argv[],
  |                Any error leads to program abortion.
  */
 void
-optParseOptions2(int * const argc_p, char *argv[], const optStruct2 opt, 
+pm_optParseOptions2(int * const argc_p, char *argv[], const optStruct2 opt, 
                  const unsigned long flags)
 /*----------------------------------------------------------------------------
-   This does the same thing as optParseOptions3(), except that there is no
+   This does the same thing as pm_optParseOptions3(), except that there is no
    "specified" return value.  
 
    This function exists for backward compatibility.
@@ -865,7 +878,7 @@ optParseOptions2(int * const argc_p, char *argv[], const optStruct2 opt,
         optFatal("Memory allocation failed (trying to allocate space for "
                  "new-format option table)");
     
-    optParseOptions3(argc_p, argv, opt3, sizeof(opt3), flags);
+    pm_optParseOptions3(argc_p, argv, opt3, sizeof(opt3), flags);
 
     free(opt3.opt_table);
 }
@@ -890,7 +903,7 @@ zero_specified(optEntry opt_table[]) {
 
 
 /*------------------------------------------------------------------------
- |  NAME          optParseOptions3
+ |  NAME          pm_optParseOptions3
  |
  |  FUNCTION      Parse commandline options.
  |
@@ -919,9 +932,9 @@ zero_specified(optEntry opt_table[]) {
  |                extracted and stored in the variables or passed to
  |                functions pointed to by entries in opt.
  |
- |                This differs from optParseOptions in that it accepts
+ |                This differs from pm_optParseOptions in that it accepts
  |                long options with just one hyphen and doesn't accept
- |                any short options.  It also has accomodations for 
+ |                any short options.  It also has accommodations for 
  |                future expansion.
  |
  |                Options and arguments used are removed from the argv-
@@ -930,7 +943,7 @@ zero_specified(optEntry opt_table[]) {
  |                Any error leads to program abortion.
  */
 void
-optParseOptions3(int * const argc_p, char *argv[], const optStruct3 opt, 
+pm_optParseOptions3(int * const argc_p, char *argv[], const optStruct3 opt, 
                  const unsigned int optStructSize, const unsigned long flags)
 {
     int  ai;        /* argv index. */
@@ -996,13 +1009,13 @@ optParseOptions3(int * const argc_p, char *argv[], const optStruct3 opt,
 
 
 void
-optDestroyNameValueList(struct optNameValue * const list) {
+pm_optDestroyNameValueList(struct optNameValue * const list) {
 
     unsigned int i;
 
     for (i = 0; list[i].name; ++i) {
-        strfree(list[i].name);
-        strfree(list[i].value);
+        pm_strfree(list[i].name);
+        pm_strfree(list[i].value);
     }
 
     free(list);