Skip to content

Commit

Permalink
fix dictionary string parser
Browse files Browse the repository at this point in the history
I didn't notice that multiple key=value pairs were possible in a single
string. Here's a new implementation that does it, with the ability to
parse the whole default_config string as well as command line args.
  • Loading branch information
npitre committed Mar 22, 2021
1 parent 97ef903 commit d76c766
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 28 deletions.
7 changes: 1 addition & 6 deletions src/conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,7 @@ const char default_config[] =
// argument rather than using user_conf_d directly.

void store_default_config_values() {
const char *line = default_config;

do {
parse_str(user_conf_d, line, 0);
line = strchr(line, '\n');
} while(line && *++line != 0);
parse_str(user_conf_d, default_config, 0);

// Calculate GMT offset (not on Solaris, doesn't have tm_gmtoff)
#if defined(USELOCALE) && !defined(__sun)
Expand Down
10 changes: 1 addition & 9 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -551,15 +551,7 @@ void read_argv(int argc, char ** argv) {
int i;
for (i = 1; i < argc; i++) {
if ( ! strncmp(argv[i], "--", 2) ) { // it was passed a parameter
char *dup = strdup(argv[i]);
char *rest = dup;
char *name = strsep(&rest, "=");
if (rest) {
put(user_conf_d, &name[2], rest); // --parameter=value
} else {
put(user_conf_d, &name[2], "1"); // --parameter
}
free(dup);
parse_str(user_conf_d, argv[i] + 2, 0);
} else { // it was passed a file
strncpy(loadingfile, argv[i], PATHLEN-1);
}
Expand Down
60 changes: 48 additions & 12 deletions src/utils/dictionary.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,32 +204,68 @@ char * get_key_name(struct dictionary * d, const char * value) {
*
* \param[in] d
* \param[in] str
* \param[in] blank_space
* \param[in] split_on_blanks
*
* \return dictionary
*/

void parse_str(struct dictionary * d, const char * str, int no_blanks) {
void parse_str(struct dictionary *d, const char *str, int split_on_blanks) {
char key[90];
char value[90];
int i;

while (*str != '\0') {
while (*str != 0) {
/* remove leading field separators */
if (*str == ' ' || *str == '\n') {
str++;
continue;
}

/* collect the key */
i = 0;
while (*str != 0 && *str != '=' && *str != '\n' && i < sizeof(key) && *str != ' ') {
for (;;) {
if (*str == '=') {
/* we are done with the key */
key[i] = 0;
break;
}
if (*str == 0 || *str == '\n' || (split_on_blanks && *str == ' ')) {
/* got only a key: pretend the value is 1 */
key[i] = 0;
put(d, key, "1");
break;
}
if (*str == ' ') {
/* spaces in the key are invalid */
return;
}
if (i >= sizeof(key) - 1) {
/* won't have room for final '\0' */
return;
}
key[i++] = *str++;
}
if (i >= sizeof(key) || *str++ != '=') continue;
key[i] = 0;

if (*str != '=') {
/* no value to collect */
continue;
}
str++;

/* collect the value */
i = 0;
while (*str != 0 && *str != '\n' && i < sizeof(value) && !(no_blanks && *str == ' ')) {
for (;;) {
if (*str == 0 || *str == '\n' || (split_on_blanks && *str == ' ')) {
/* we are done with the value */
value[i] = 0;
put(d, key, value);
break;
}
if (i >= sizeof(value) - 1) {
/* won't have room for final '\0' */
return;
}
value[i++] = *str++;
}
if (i >= sizeof(value)) return;
value[i] = 0;

// Create the dictionary
put(d, key, value);
}
}
2 changes: 1 addition & 1 deletion src/utils/dictionary.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,5 @@ void destroy_dictionary(struct dictionary * d);
char * get(struct dictionary * d, const char * key);
int get_int(struct dictionary * d, const char * key);
//char * get_key_name(struct dictionary * d, const char * value);
void parse_str(struct dictionary * d, const char * str, int no_blanks);
void parse_str(struct dictionary * d, const char * str, int split_on_blanks);
int get_dict_buffer_size(struct dictionary * d);

0 comments on commit d76c766

Please sign in to comment.