mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 05:03:43 +01:00
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 svn:r13020
This commit is contained in:
parent
c0ec281565
commit
86f5180853
@ -1926,23 +1926,22 @@ read_file_to_str(const char *filename, int flags, struct stat *stat_out)
|
||||
|
||||
/** 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 @@ parse_line_from_str(char *line, char **key_out, char **value_out)
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -265,7 +265,8 @@ int append_bytes_to_file(const char *fname, const char *str, size_t len,
|
||||
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;
|
||||
|
@ -1366,16 +1366,16 @@ config_line_append(config_line_t **lst,
|
||||
/** 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 @@ config_get_lines(char *string, config_line_t **result)
|
||||
* 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);
|
||||
|
||||
|
@ -2634,7 +2634,7 @@ const char *safe_str(const char *address);
|
||||
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);
|
||||
|
@ -682,6 +682,7 @@ test_util(void)
|
||||
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 @@ test_util(void)
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user