summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-11-04 22:29:45 +0000
committerNick Mathewson <nickm@torproject.org>2004-11-04 22:29:45 +0000
commit9d604ec6156c70149c8eb208c4f185b495fcac85 (patch)
tree2482ee237bbce8804dcb77094f0c65497df4fc3f
parent831c988ea1b5104a31ef9cad295bf8a56b10b2e8 (diff)
downloadtor-9d604ec6156c70149c8eb208c4f185b495fcac85.tar.gz
tor-9d604ec6156c70149c8eb208c4f185b495fcac85.zip
Add code to read configuration lines from a string as well as a file
svn:r2676
-rw-r--r--src/common/util.c80
-rw-r--r--src/common/util.h1
-rw-r--r--src/or/test.c49
3 files changed, 128 insertions, 2 deletions
diff --git a/src/common/util.c b/src/common/util.c
index 76b7254cd3..cc00ff9792 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -875,7 +875,7 @@ char *read_file_to_str(const char *filename, int bin) {
int
parse_line_from_file(char *line, size_t maxlen, FILE *f,
char **key_out, char **value_out) {
- char *s, *key, *end, *value;
+ char *s;
try_next_line:
if(!fgets(line, maxlen, f)) {
@@ -883,6 +883,17 @@ try_next_line:
return 0;
return -1; /* real error */
}
+ line[maxlen-1] = '\0';
+
+ s = parse_line_from_str(line, key_out, value_out);
+ if (!s)
+ return -1;
+ if (!*key_out)
+ goto try_next_line;
+
+ return 1;
+
+#if 0
if((s = strchr(line,'#'))) /* strip comments */
*s = 0; /* stop the line there */
@@ -920,6 +931,73 @@ try_next_line:
log_fn(LOG_DEBUG,"got keyword '%s', value '%s'", key, value);
*key_out = key, *value_out = value;
return 1;
+#endif
+}
+
+
+/** DOCDOC.
+ *
+ * Return next line or end of string on success, NULL on failure.
+ */
+char *
+parse_line_from_str(char *line, char **key_out, char **value_out)
+{
+ char *key, *val, *cp;
+
+ tor_assert(key_out);
+ tor_assert(value_out);
+
+ *key_out = *value_out = key = val = NULL;
+ /* Skip until the first keyword. */
+ while (1) {
+ while (isspace(*line))
+ ++line;
+ if (*line == '#') {
+ while (*line && *line != '\n')
+ ++line;
+ } else {
+ break;
+ }
+ }
+
+ if (!*line) { /* End of string? */
+ *key_out = *value_out = NULL;
+ return line;
+ }
+
+ /* Skip until the next space. */
+ key = line;
+ while (*line && !isspace(*line) && *line != '#')
+ ++line;
+
+ /* Skip until the value */
+ while (*line == ' ' || *line == '\t')
+ *line++ = '\0';
+ val = line;
+
+ /* Find the end of the line. */
+ while (*line && *line != '\n' && *line != '#')
+ ++line;
+ if (*line == '\n')
+ cp = line++;
+ else {
+ cp = line-1;
+ }
+ while (cp>=val && isspace(*cp))
+ *cp-- = '\0';
+
+ if (*line == '#') {
+ do {
+ *line++ = '\0';
+ } while (*line && *line != '\n');
+ if (*line == '\n')
+ ++line;
+ }
+
+ *key_out = key;
+ *value_out = val;
+
+ return line;
}
/** Expand any homedir prefix on 'filename'; return a newly allocated
diff --git a/src/common/util.h b/src/common/util.h
index dba95e456d..5674afc6be 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -92,6 +92,7 @@ int write_bytes_to_file(const char *fname, const char *str, size_t len,
int bin);
char *read_file_to_str(const char *filename, int bin);
int parse_line_from_file(char *line, size_t maxlen, FILE *f, char **key_out, char **value_out);
+char *parse_line_from_str(char *line, char **key_out, char **value_out);
char *expand_filename(const char *filename);
/* Net helpers */
diff --git a/src/or/test.c b/src/or/test.c
index 2cece29d76..f1d1d6545f 100644
--- a/src/or/test.c
+++ b/src/or/test.c
@@ -489,7 +489,7 @@ test_util(void) {
int i;
uint32_t u32;
uint16_t u16;
- char *cp;
+ char *cp, *k, *v;
start.tv_sec = 5;
start.tv_usec = 5000;
@@ -674,6 +674,53 @@ test_util(void) {
test_eq(10L, tor_parse_long("10",10,0,100,NULL,NULL));
test_eq(0L, tor_parse_long("10",10,50,100,NULL,NULL));
+ /* Test parse_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;
+
+ cp = parse_line_from_str(cp, &k, &v);
+ test_streq(k, "k");
+ test_streq(v, "v");
+ test_assert(!strcmpstart(cp, " key value with"));
+
+ cp = parse_line_from_str(cp, &k, &v);
+ test_streq(k, "key");
+ test_streq(v, "value with spaces");
+ test_assert(!strcmpstart(cp, "keykey"));
+
+ cp = parse_line_from_str(cp, &k, &v);
+ test_streq(k, "keykey");
+ test_streq(v, "val");
+ test_assert(!strcmpstart(cp, "k2\n"));
+
+ cp = parse_line_from_str(cp, &k, &v);
+ test_streq(k, "k2");
+ test_streq(v, "");
+ test_assert(!strcmpstart(cp, "k3 \n"));
+
+ cp = parse_line_from_str(cp, &k, &v);
+ test_streq(k, "k3");
+ test_streq(v, "");
+ test_assert(!strcmpstart(cp, "\n \n"));
+
+ cp = parse_line_from_str(cp, &k, &v);
+ test_streq(k, "k4");
+ test_streq(v, "");
+ test_assert(!strcmpstart(cp, "k5#abc"));
+
+ cp = parse_line_from_str(cp, &k, &v);
+ test_streq(k, "k5");
+ test_streq(v, "");
+ test_assert(!strcmpstart(cp, "k6"));
+
+ cp = parse_line_from_str(cp, &k, &v);
+ test_streq(k, "k6");
+ test_streq(v, "val");
+ test_streq(cp, "");
+
/* XXXX test older functions. */
smartlist_free(sl);
}