com_cs: Return a syntax error if argc > 2.
[paraslash.git] / string.c
index 07f54a07155d5ee385c0c1e044c21017906688ce..78b862c933ced61396aadb6df04f43d8185eee21 100644 (file)
--- a/string.c
+++ b/string.c
 
 /** \file string.c memory allocation and string handling functions */
 
-#include <sys/time.h> /* gettimeofday */
 #include "para.h"
+#include "string.h"
+
+#include <sys/time.h> /* gettimeofday */
 #include <regex.h>
 #include <pwd.h>
 #include <sys/utsname.h> /* uname() */
+#include <string.h>
+
 #include "error.h"
-#include "string.h"
 
 /**
  * paraslash's version of realloc()
@@ -210,8 +213,8 @@ __must_check __malloc char *para_basename(const char *name)
  * string which may contain a single string conversion specifier which gets
  * replaced by 'arg'.
  *
- * \return A string in which all matches in \a src are replaced, or NULL if \a
- * macro_name was not found in \a src.  Caller must free the result.
+ * \return A string in which all matches in \a src are replaced, or NULL if an
+ * syntax error was encountered. Caller must free the result.
  *
  * \sa regcomp(3)
  */
@@ -273,8 +276,8 @@ __must_check __malloc char *s_a_r_list(struct para_macro *macro_list, char *src)
        while (mp->name) {
                ret = s_a_r(tmp, mp->name, mp->replacement);
                free(tmp);
-               if (!ret)
-                       return src; /* FIXME: shouldn't we continue here? */
+               if (!ret) /* syntax error */
+                       return NULL;
                tmp = ret;
                mp++;
        }
@@ -374,37 +377,40 @@ __must_check __malloc char *para_homedir(void)
  * This function modifies \a args by replacing each occurance of \a delim by
  * zero. A NULL-terminated array of pointers to char* is allocated dynamically
  * and these pointers are initialized to point to the broken-up substrings
- * within \a args. A pointer to this array is returned via \a argv_ptr.
+ * within \a args. A pointer to this array is returned via \a argv_ptr. It's OK
+ * to call this function with \a args == NULL.
  *
  * \return The number of substrings found in \a args.
  */
-__must_check unsigned split_args(char *args, char ***argv_ptr, int delim)
+
+__must_check unsigned split_args(char *args, char ***argv_ptr, const char *delim)
 {
        char *p = args;
        char **argv;
-       ssize_t n = 0, i;
+       size_t n = 0, i, j;
 
-       while ((p = strchr(p, delim))) {
-               p++;
+       while ((i = strcspn(p, delim)) && (p += i)) {
+               p += strspn(p, delim);
                n++;
        }
-       *argv_ptr = para_malloc((n + 3) * sizeof(char *));
+       *argv_ptr = para_malloc((n + 1) * sizeof(char *));
        argv = *argv_ptr;
        i = 0;
        p = args;
-//     printf("split_args: a:%s\n", p);
        while (p) {
                argv[i] = p;
-               p = strchr(p, delim);
-               if (p) {
-//             printf("a:%s\n", p);
+               j = strcspn(p, delim);
+               if (!j)
+                       break;
+               p += strcspn(p, delim);
+               if (*p) {
                        *p = '\0';
-//             printf("b:\n");
                        p++;
-                       i++;
+                       p += strspn(p, delim);
                }
+               i++;
        }
-       argv[n + 1] = NULL;
+       argv[n] = NULL;
        return n;
 }