aboutsummaryrefslogtreecommitdiff
path: root/read_config_file.c
diff options
context:
space:
mode:
authorSteve Fink <sphink@gmail.com>2006-08-07 05:53:19 +0200
committerIan Wienand <ianw@debian.org>2006-08-07 05:53:19 +0200
commit6a3e24dc1709530e59dd6ae3e91ced1c221fe1b9 (patch)
tree349681978d6dcc285b054f1359561e9716193b0c /read_config_file.c
parentb2c254573fbf30189293be6b7f2ef307c499704c (diff)
downloadltrace-6a3e24dc1709530e59dd6ae3e91ced1c221fe1b9.tar.gz
implement enumerated parameters
Diffstat (limited to 'read_config_file.c')
-rw-r--r--read_config_file.c120
1 files changed, 116 insertions, 4 deletions
diff --git a/read_config_file.c b/read_config_file.c
index 15c3f39..5b114de 100644
--- a/read_config_file.c
+++ b/read_config_file.c
@@ -11,6 +11,10 @@
#include "output.h"
#include "debug.h"
+static int line_no;
+static char *filename;
+static int error_count = 0;
+
struct function *list_of_functions = NULL;
static struct list_of_pt_t {
@@ -29,6 +33,7 @@ static struct list_of_pt_t {
"file", ARGTYPE_FILE}, {
"format", ARGTYPE_FORMAT}, {
"string", ARGTYPE_STRING}, {
+ "enum", ARGTYPE_ENUM}, {
"ignore", ARGTYPE_IGNORE}, {
NULL, ARGTYPE_UNKNOWN} /* Must finish with NULL */
};
@@ -46,6 +51,7 @@ static arg_type_info arg_type_singletons[] = {
{ ARGTYPE_FORMAT },
{ ARGTYPE_STRING },
{ ARGTYPE_STRING_N },
+ { ARGTYPE_ENUM },
{ ARGTYPE_IGNORE },
{ ARGTYPE_POINTER },
{ ARGTYPE_UNKNOWN }
@@ -81,6 +87,32 @@ static void eat_spaces(char **str)
}
}
+static char *xstrndup(char *str, size_t len)
+{
+ char *ret = (char *) malloc(len + 1);
+ strncpy(ret, str, len);
+ ret[len] = 0;
+ return ret;
+}
+
+static char *parse_ident(char **str)
+{
+ char *ident = *str;
+
+ if (!isalnum(**str) && **str != '_') {
+ output_line(0, "Syntax error in `%s', line %d: Bad identifier",
+ filename, line_no);
+ error_count++;
+ return NULL;
+ }
+
+ while (**str && (isalnum(**str) || **str == '_')) {
+ ++(*str);
+ }
+
+ return xstrndup(ident, *str - ident);
+}
+
/*
Returns position in string at the left parenthesis which starts the
function's argument signature. Returns NULL on error.
@@ -119,12 +151,17 @@ static char *start_of_arg_sig(char *str)
*/
static int simple_type(enum arg_type at)
{
+ switch (at) {
+ case ARGTYPE_STRING:
+ case ARGTYPE_STRING_N:
+ case ARGTYPE_ENUM:
+ return 0;
+
+ default:
return 1;
+ }
}
-static int line_no;
-static char *filename;
-
static int parse_int(char **str)
{
char *end;
@@ -132,6 +169,7 @@ static int parse_int(char **str)
if (end == *str) {
output_line(0, "Syntax error in `%s', line %d: Bad number",
filename, line_no);
+ error_count++;
return 0;
}
@@ -191,6 +229,73 @@ static arg_type_info *parse_nonpointer_type(char **str)
switch (info->type) {
+ // Syntax: enum ( keyname=value,keyname=value,... )
+ case ARGTYPE_ENUM:{
+ struct enum_opt {
+ char *key;
+ int value;
+ struct enum_opt *next;
+ };
+ struct enum_opt *list = NULL;
+ struct enum_opt *p;
+ int entries = 0;
+ int ii;
+
+ eat_spaces(str);
+ (*str)++; // Get past open paren
+ eat_spaces(str);
+
+ while (**str && **str != ')') {
+ p = (struct enum_opt *) malloc(sizeof(*p));
+ eat_spaces(str);
+ p->key = parse_ident(str);
+ if (error_count) {
+ free(p);
+ return NULL;
+ }
+ eat_spaces(str);
+ if (**str != '=') {
+ free(p->key);
+ free(p);
+ output_line(0,
+ "Syntax error in `%s', line %d: expected '=', got '%c'",
+ filename, line_no, **str);
+ error_count++;
+ return NULL;
+ }
+ ++(*str);
+ eat_spaces(str);
+ p->value = parse_int(str);
+ p->next = list;
+ list = p;
+ ++entries;
+
+ // Skip comma
+ eat_spaces(str);
+ if (**str == ',') {
+ (*str)++;
+ eat_spaces(str);
+ }
+ }
+
+ info->u.enum_info.entries = entries;
+ info->u.enum_info.keys =
+ (char **) malloc(entries * sizeof(char *));
+ info->u.enum_info.values =
+ (int *) malloc(entries * sizeof(int));
+ for (ii = 0, p = NULL; list; ++ii, list = list->next) {
+ if (p)
+ free(p);
+ info->u.enum_info.keys[ii] = list->key;
+ info->u.enum_info.values[ii] = list->value;
+ p = list;
+ }
+ if (p)
+ free(p);
+
+ return info;
+ }
+
case ARGTYPE_STRING:
if (!isdigit(**str) && **str != '[') {
/* Oops, was just a simple string after all */
@@ -217,6 +322,7 @@ static arg_type_info *parse_nonpointer_type(char **str)
output_line(0, "Syntax error in `%s', line %d: Unknown type encountered",
filename, line_no);
free(info);
+ error_count++;
return NULL;
}
}
@@ -258,6 +364,7 @@ static struct function *process_line(char *buf)
if (!tmp) {
output_line(0, "Syntax error in `%s', line %d", filename,
line_no);
+ error_count++;
return NULL;
}
*tmp = '\0';
@@ -281,6 +388,7 @@ static struct function *process_line(char *buf)
output_line(0, "Syntax error in `%s', line %d"
": unknown argument type",
filename, line_no);
+ error_count++;
return NULL;
}
eat_spaces(&str);
@@ -294,6 +402,7 @@ static struct function *process_line(char *buf)
str[strlen(str) - 1] = '\0';
output_line(0, "Syntax error in `%s', line %d at ...\"%s\"",
filename, line_no, str);
+ error_count++;
return NULL;
}
}
@@ -318,7 +427,10 @@ void read_config_file(char *file)
}
line_no = 0;
while (fgets(buf, 1024, stream)) {
- struct function *tmp = process_line(buf);
+ struct function *tmp;
+
+ error_count = 0;
+ tmp = process_line(buf);
if (tmp) {
debug(2, "New function: `%s'", tmp->name);