Browse Source

Make split function smarter; add a strcmpstart function so we can stop bungling strcmp(x, y, strlen(y));

svn:r2325
Nick Mathewson 21 years ago
parent
commit
f311206d1d
2 changed files with 35 additions and 11 deletions
  1. 31 10
      src/common/util.c
  2. 4 1
      src/common/util.h

+ 31 - 10
src/common/util.c

@@ -482,12 +482,16 @@ void smartlist_insert(smartlist_t *sl, int idx, void *val)
 }
 
 /**
- * Split a string <b>str</b> along all occurences of <b>sep</b>, adding the
- * split strings, in order, to <b>sl</b>.  If <b>skipSpace</b> is true,
- * remove initial and trailing space from each entry.
+ * Split a string <b>str</b> along all occurences of <b>sep</b>,
+ * adding the split strings, in order, to <b>sl</b>.  If
+ * <b>flags</b>&amp;SPLIT_SKIP_SPACE is true, remove initial and
+ * trailing space from each entry.  If
+ * <b>flags</b>&amp;SPLIT_IGNORE_BLANK is true, remove any entries of
+ * length 0.  If max>0, divide the string into no more than <b>max</b>
+ * pieces.
  */
 int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep,
-                           int skipSpace)
+                           int flags, int max)
 {
   const char *cp, *end, *next;
   int n = 0;
@@ -496,23 +500,31 @@ int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep,
 
   cp = str;
   while (1) {
-    if (skipSpace) {
+    if (flags&SPLIT_SKIP_SPACE) {
       while (isspace((int)*cp)) ++cp;
     }
-    end = strstr(cp,sep);
-    if (!end) {
+
+    if (max>0 && n == max-1) {
       end = strchr(cp,'\0');
+    } else {
+      end = strstr(cp,sep);
+      if (!end)
+        end = strchr(cp,'\0');
+    }
+    if (!*end) {
       next = NULL;
     } else {
       next = end+strlen(sep);
     }
 
-    if (skipSpace) {
+    if (flags&SPLIT_SKIP_SPACE) {
       while (end > cp && isspace((int)*(end-1)))
         --end;
     }
-    smartlist_add(sl, tor_strndup(cp, end-cp));
-    ++n;
+    if (end != cp || !(flags&SPLIT_IGNORE_BLANK)) {
+      smartlist_add(sl, tor_strndup(cp, end-cp));
+      ++n;
+    }
     if (!next)
       break;
     cp = next;
@@ -799,6 +811,15 @@ void tor_strlower(char *s)
   }
 }
 
+/* Compares the first strlen(s2) characters of s1 with s2.  Returns as for
+ * strcmp.
+ */
+int strcmpstart(const char *s1, const char *s2)
+{
+  size_t n = strlen(s2);
+  return strncmp(s1, s2, n);
+}
+
 
 /** Return a pointer to the first char of s that is not whitespace and
  * not a comment, or to the terminating NUL if no such character exists.

+ 4 - 1
src/common/util.h

@@ -86,6 +86,7 @@ char *tor_strdup(const char *s);
 char *tor_strndup(const char *s, size_t n);
 #define tor_free(p) do {if(p) {free(p); (p)=NULL;}} while(0)
 void tor_strlower(char *s);
+int strcmpstart(const char *s1, const char *s2);
 
 /* Some platforms segfault when you try to access a multi-byte type
  * that isn't aligned to a word boundary.  The macros and/or functions
@@ -153,8 +154,10 @@ void *smartlist_del(smartlist_t *sl, int idx);
 void *smartlist_del_keeporder(smartlist_t *sl, int idx);
 void smartlist_insert(smartlist_t *sl, int idx, void *val);
 int smartlist_len(const smartlist_t *sl);
+#define SPLIT_SKIP_SPACE   0x01
+#define SPLIT_IGNORE_BLANK 0x02
 int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep,
-  int skipSpace);
+                           int flags, int max);
 
 #define SMARTLIST_FOREACH(sl, type, var, cmd)                   \
   do {                                                          \