mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 23:53:32 +01:00
Add code to read configuration lines from a string as well as a file
svn:r2676
This commit is contained in:
parent
831c988ea1
commit
9d604ec615
@ -875,7 +875,7 @@ char *read_file_to_str(const char *filename, int bin) {
|
|||||||
int
|
int
|
||||||
parse_line_from_file(char *line, size_t maxlen, FILE *f,
|
parse_line_from_file(char *line, size_t maxlen, FILE *f,
|
||||||
char **key_out, char **value_out) {
|
char **key_out, char **value_out) {
|
||||||
char *s, *key, *end, *value;
|
char *s;
|
||||||
|
|
||||||
try_next_line:
|
try_next_line:
|
||||||
if(!fgets(line, maxlen, f)) {
|
if(!fgets(line, maxlen, f)) {
|
||||||
@ -883,6 +883,17 @@ try_next_line:
|
|||||||
return 0;
|
return 0;
|
||||||
return -1; /* real error */
|
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 */
|
if((s = strchr(line,'#'))) /* strip comments */
|
||||||
*s = 0; /* stop the line there */
|
*s = 0; /* stop the line there */
|
||||||
@ -920,6 +931,73 @@ try_next_line:
|
|||||||
log_fn(LOG_DEBUG,"got keyword '%s', value '%s'", key, value);
|
log_fn(LOG_DEBUG,"got keyword '%s', value '%s'", key, value);
|
||||||
*key_out = key, *value_out = value;
|
*key_out = key, *value_out = value;
|
||||||
return 1;
|
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
|
/** Expand any homedir prefix on 'filename'; return a newly allocated
|
||||||
|
@ -92,6 +92,7 @@ int write_bytes_to_file(const char *fname, const char *str, size_t len,
|
|||||||
int bin);
|
int bin);
|
||||||
char *read_file_to_str(const char *filename, 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);
|
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);
|
char *expand_filename(const char *filename);
|
||||||
|
|
||||||
/* Net helpers */
|
/* Net helpers */
|
||||||
|
@ -489,7 +489,7 @@ test_util(void) {
|
|||||||
int i;
|
int i;
|
||||||
uint32_t u32;
|
uint32_t u32;
|
||||||
uint16_t u16;
|
uint16_t u16;
|
||||||
char *cp;
|
char *cp, *k, *v;
|
||||||
|
|
||||||
start.tv_sec = 5;
|
start.tv_sec = 5;
|
||||||
start.tv_usec = 5000;
|
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(10L, tor_parse_long("10",10,0,100,NULL,NULL));
|
||||||
test_eq(0L, tor_parse_long("10",10,50,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. */
|
/* XXXX test older functions. */
|
||||||
smartlist_free(sl);
|
smartlist_free(sl);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user