[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r13020: Push the strdups used for parsing configuration lines into p (in tor/trunk: . src/common src/or)



Author: nickm
Date: 2008-01-02 01:59:12 -0500 (Wed, 02 Jan 2008)
New Revision: 13020

Modified:
   tor/trunk/
   tor/trunk/src/common/util.c
   tor/trunk/src/common/util.h
   tor/trunk/src/or/config.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/test.c
Log:
 r15786@tombo:  nickm | 2008-01-02 01:11:51 -0500
 Push the strdups used for parsing configuration lines into parse_line_from_string().  This will make it easier to parse more complex value formats, which in turn will help fix bug 557



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r15786] on d9e39d38-0f13-419c-a857-e10a0ce2aa0c

Modified: tor/trunk/src/common/util.c
===================================================================
--- tor/trunk/src/common/util.c	2008-01-02 05:38:53 UTC (rev 13019)
+++ tor/trunk/src/common/util.c	2008-01-02 06:59:12 UTC (rev 13020)
@@ -1926,23 +1926,22 @@
 
 /** Given a string containing part of a configuration file or similar format,
  * advance past comments and whitespace and try to parse a single line.  If we
- * parse a line successfully, set *<b>key_out</b> to the key portion and
- * *<b>value_out</b> to the value portion of the line, and return a pointer to
- * the start of the next line.  If we run out of data, return a pointer to the
- * end of the string.  If we encounter an error, return NULL.
- *
- * NOTE: We modify *<b>line</b> as we parse it, by inserting NULs
- * to terminate the key and value.
+ * parse a line successfully, set *<b>key_out</b> to a new string holding the
+ * key portion and *<b>value_out</b> to a new string holding the value portion
+ * of the line, and return a pointer to the start of the next line.  If we run
+ * out of data, return a pointer to the end of the string.  If we encounter an
+ * error, return NULL.
  */
-char *
-parse_line_from_str(char *line, char **key_out, char **value_out)
+const char *
+parse_config_line_from_str(const char *line, char **key_out, char **value_out)
 {
-  char *key, *val, *cp;
+  const char *key, *val, *cp;
 
   tor_assert(key_out);
   tor_assert(value_out);
 
-  *key_out = *value_out = key = val = NULL;
+  *key_out = *value_out = NULL;
+  key = val = NULL;
   /* Skip until the first keyword. */
   while (1) {
     while (TOR_ISSPACE(*line))
@@ -1964,35 +1963,36 @@
   key = line;
   while (*line && !TOR_ISSPACE(*line) && *line != '#')
     ++line;
+  *key_out = tor_strndup(key, line-key);
 
   /* Skip until the value, writing nuls so key will be nul-terminated */
   while (*line == ' ' || *line == '\t')
-    *line++ = '\0';
+    ++line;
 
   val = line;
 
   /* Find the end of the line. */
   while (*line && *line != '\n' && *line != '#')
     ++line;
-  if (*line == '\n')
+  if (*line == '\n') {
     cp = line++;
-  else {
-    cp = line-1;
+  } else {
+    cp = line;
   }
-  while (cp>=val && TOR_ISSPACE(*cp))
-    *cp-- = '\0';
+  while (cp>val && TOR_ISSPACE(*(cp-1)))
+    --cp;
 
+  tor_assert(cp >= val);
+  *value_out = tor_strndup(val, cp-val);
+
   if (*line == '#') {
     do {
-      *line++ = '\0';
+      ++line;
     } while (*line && *line != '\n');
     if (*line == '\n')
       ++line;
   }
 
-  *key_out = key;
-  *value_out = val;
-
   return line;
 }
 

Modified: tor/trunk/src/common/util.h
===================================================================
--- tor/trunk/src/common/util.h	2008-01-02 05:38:53 UTC (rev 13019)
+++ tor/trunk/src/common/util.h	2008-01-02 06:59:12 UTC (rev 13020)
@@ -265,7 +265,8 @@
 struct stat;
 char *read_file_to_str(const char *filename, int flags, struct stat *stat_out)
   ATTR_MALLOC;
-char *parse_line_from_str(char *line, char **key_out, char **value_out);
+const char *parse_config_line_from_str(const char *line,
+                                       char **key_out, char **value_out);
 char *expand_filename(const char *filename);
 struct smartlist_t *tor_listdir(const char *dirname);
 int path_is_relative(const char *filename) ATTR_PURE;

Modified: tor/trunk/src/or/config.c
===================================================================
--- tor/trunk/src/or/config.c	2008-01-02 05:38:53 UTC (rev 13019)
+++ tor/trunk/src/or/config.c	2008-01-02 06:59:12 UTC (rev 13020)
@@ -1366,16 +1366,16 @@
 /** Helper: parse the config string and strdup into key/value
  * strings. Set *result to the list, or NULL if parsing the string
  * failed.  Return 0 on success, -1 on failure. Warn and ignore any
- * misformatted lines. Modifies the contents of <b>string</b>. */
+ * misformatted lines. */
 int
-config_get_lines(char *string, config_line_t **result)
+config_get_lines(const char *string, config_line_t **result)
 {
   config_line_t *list = NULL, **next;
   char *k, *v;
 
   next = &list;
   do {
-    string = parse_line_from_str(string, &k, &v);
+    string = parse_config_line_from_str(string, &k, &v);
     if (!string) {
       config_free_lines(list);
       return -1;
@@ -1385,10 +1385,13 @@
        * rather than using config_line_append over and over and getting
        * n^2 performance. */
       *next = tor_malloc(sizeof(config_line_t));
-      (*next)->key = tor_strdup(k);
-      (*next)->value = tor_strdup(v);
+      (*next)->key = k;
+      (*next)->value = v;
       (*next)->next = NULL;
       next = &((*next)->next);
+    } else {
+      tor_free(k);
+      tor_free(v);
     }
   } while (*string);
 

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2008-01-02 05:38:53 UTC (rev 13019)
+++ tor/trunk/src/or/or.h	2008-01-02 06:59:12 UTC (rev 13020)
@@ -2634,7 +2634,7 @@
 const char *escaped_safe_str(const char *address);
 const char *get_version(void);
 
-int config_get_lines(char *string, config_line_t **result);
+int config_get_lines(const char *string, config_line_t **result);
 void config_free_lines(config_line_t *front);
 int options_trial_assign(config_line_t *list, int use_defaults,
                          int clear_first, char **msg);

Modified: tor/trunk/src/or/test.c
===================================================================
--- tor/trunk/src/or/test.c	2008-01-02 05:38:53 UTC (rev 13019)
+++ tor/trunk/src/or/test.c	2008-01-02 06:59:12 UTC (rev 13020)
@@ -682,6 +682,7 @@
   uint32_t u32;
   uint16_t u16;
   char *cp, *k, *v;
+  const char *str;
 
   start.tv_sec = 5;
   start.tv_usec = 5000;
@@ -821,52 +822,60 @@
                U64_PRINTF_ARG(U64_LITERAL(12345678901)));
   test_streq(buf, "x!12345678901!x");
 
-  /* Test parse_line_from_str */
+  /* Test parse_config_line_from_str */
   strlcpy(buf, "k v\n" " key    value with spaces   \n" "keykey val\n"
           "k2\n"
           "k3 \n" "\n" "   \n" "#comment\n"
           "k4#a\n" "k5#abc\n" "k6 val #with comment\n", sizeof(buf));
-  cp = buf;
+  str = buf;
 
-  cp = parse_line_from_str(cp, &k, &v);
+  str = parse_config_line_from_str(str, &k, &v);
   test_streq(k, "k");
   test_streq(v, "v");
-  test_assert(!strcmpstart(cp, " key    value with"));
+  tor_free(k); tor_free(v);
+  test_assert(!strcmpstart(str, " key    value with"));
 
-  cp = parse_line_from_str(cp, &k, &v);
+  str = parse_config_line_from_str(str, &k, &v);
   test_streq(k, "key");
   test_streq(v, "value with spaces");
-  test_assert(!strcmpstart(cp, "keykey"));
+  tor_free(k); tor_free(v);
+  test_assert(!strcmpstart(str, "keykey"));
 
-  cp = parse_line_from_str(cp, &k, &v);
+  str = parse_config_line_from_str(str, &k, &v);
   test_streq(k, "keykey");
   test_streq(v, "val");
-  test_assert(!strcmpstart(cp, "k2\n"));
+  tor_free(k); tor_free(v);
+  test_assert(!strcmpstart(str, "k2\n"));
 
-  cp = parse_line_from_str(cp, &k, &v);
+  str = parse_config_line_from_str(str, &k, &v);
   test_streq(k, "k2");
   test_streq(v, "");
-  test_assert(!strcmpstart(cp, "k3 \n"));
+  tor_free(k); tor_free(v);
+  test_assert(!strcmpstart(str, "k3 \n"));
 
-  cp = parse_line_from_str(cp, &k, &v);
+  str = parse_config_line_from_str(str, &k, &v);
   test_streq(k, "k3");
   test_streq(v, "");
-  test_assert(!strcmpstart(cp, "\n   \n"));
+  tor_free(k); tor_free(v);
+  test_assert(!strcmpstart(str, "\n   \n"));
 
-  cp = parse_line_from_str(cp, &k, &v);
+  str = parse_config_line_from_str(str, &k, &v);
   test_streq(k, "k4");
   test_streq(v, "");
-  test_assert(!strcmpstart(cp, "k5#abc"));
+  tor_free(k); tor_free(v);
+  test_assert(!strcmpstart(str, "k5#abc"));
 
-  cp = parse_line_from_str(cp, &k, &v);
+  str = parse_config_line_from_str(str, &k, &v);
   test_streq(k, "k5");
   test_streq(v, "");
-  test_assert(!strcmpstart(cp, "k6"));
+  tor_free(k); tor_free(v);
+  test_assert(!strcmpstart(str, "k6"));
 
-  cp = parse_line_from_str(cp, &k, &v);
+  str = parse_config_line_from_str(str, &k, &v);
   test_streq(k, "k6");
   test_streq(v, "val");
-  test_streq(cp, "");
+  tor_free(k); tor_free(v);
+  test_streq(str, "");
 
   /* Test for strcmpstart and strcmpend. */
   test_assert(strcmpstart("abcdef", "abcdef")==0);