diff options
author | Steve Fink <sphink@gmail.com> | 2006-08-07 04:22:06 +0200 |
---|---|---|
committer | Ian Wienand <ianw@debian.org> | 2006-08-07 04:22:06 +0200 |
commit | b0315a0acbd219de2c7f02228d7fda5c14fb47ef (patch) | |
tree | 1b28f0419563df3d3957828a461750ad3a126b34 | |
parent | 3fc0189c9b07744f7c1224e1472a922495eb0139 (diff) | |
download | ltrace-b0315a0acbd219de2c7f02228d7fda5c14fb47ef.tar.gz |
prepare types for further changes
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | ltrace.h | 31 | ||||
-rw-r--r-- | output.c | 24 | ||||
-rw-r--r-- | read_config_file.c | 105 |
4 files changed, 124 insertions, 42 deletions
@@ -1,3 +1,9 @@ +2006-08-07 Steve Fink <sphink@gmail.com> + + * ltrace.h, output.c, read_config_file.c : use arg_type_info in + place of arg_type in order to eventually be able to record + properties along with types. + 2006-07-20 Steve Fink <sphink@gmail.com> * testsuite/lib/ltrace.exp: better quoting and error detection for @@ -41,14 +41,26 @@ enum arg_type { ARGTYPE_FILE, ARGTYPE_FORMAT, /* printf-like format */ ARGTYPE_STRING, - ARGTYPE_STRING0, /* stringN: string up to (arg N) bytes */ - ARGTYPE_STRING1, - ARGTYPE_STRING2, - ARGTYPE_STRING3, - ARGTYPE_STRING4, - ARGTYPE_STRING5 + ARGTYPE_STRING_N, /* stringN: string up to (arg N) bytes */ + ARGTYPE_STRING0, + ARGTYPE_STRING1, + ARGTYPE_STRING2, + ARGTYPE_STRING3, + ARGTYPE_STRING4, + ARGTYPE_STRING5, + ARGTYPE_COUNT /* number of ARGTYPE_* values */ }; +typedef struct arg_type_info_t { + enum arg_type type; + union { + // ARGTYPE_STRING_N + struct { + int size_spec; + } string_n_info; + } u; +} arg_type_info; + enum tof { LT_TOF_NONE = 0, LT_TOF_FUNCTION, /* A real library function */ @@ -59,9 +71,9 @@ enum tof { struct function { const char *name; - enum arg_type return_type; + arg_type_info *return_info; int num_params; - enum arg_type arg_types[MAX_ARGS]; + arg_type_info *arg_info[MAX_ARGS]; int params_right; struct function *next; }; @@ -160,7 +172,7 @@ extern struct event *wait_for_something(void); extern void process_event(struct event *event); extern void execute_program(struct process *, char **); extern int display_arg(enum tof type, struct process *proc, int arg_num, - enum arg_type at); + arg_type_info *info); extern struct breakpoint *address2bpstruct(struct process *proc, void *addr); extern void breakpoints_init(struct process *proc); extern void insert_breakpoint(struct process *proc, void *addr, @@ -173,6 +185,7 @@ extern void reinitialize_breakpoints(struct process *); extern struct process *open_program(char *filename, pid_t pid); extern void open_pid(pid_t pid, int verbose); extern void show_summary(void); +extern arg_type_info *lookup_singleton(enum arg_type at); /* Arch-dependent stuff: */ extern char *pid2name(pid_t pid); @@ -164,6 +164,9 @@ static void tabto(int col) void output_left(enum tof type, struct process *proc, char *function_name) { struct function *func; + static arg_type_info *arg_unknown = NULL; + if (arg_unknown == NULL) + arg_unknown = lookup_singleton(ARGTYPE_UNKNOWN); if (opt_c) { return; @@ -190,21 +193,21 @@ void output_left(enum tof type, struct process *proc, char *function_name) int i; for (i = 0; i < 4; i++) { current_column += - display_arg(type, proc, i, ARGTYPE_UNKNOWN); + display_arg(type, proc, i, arg_unknown); current_column += fprintf(output, ", "); } - current_column += display_arg(type, proc, 4, ARGTYPE_UNKNOWN); + current_column += display_arg(type, proc, 4, arg_unknown); return; } else { int i; for (i = 0; i < func->num_params - func->params_right - 1; i++) { current_column += - display_arg(type, proc, i, func->arg_types[i]); + display_arg(type, proc, i, func->arg_info[i]); current_column += fprintf(output, ", "); } if (func->num_params > func->params_right) { current_column += - display_arg(type, proc, i, func->arg_types[i]); + display_arg(type, proc, i, func->arg_info[i]); if (func->params_right) { current_column += fprintf(output, ", "); } @@ -218,6 +221,9 @@ void output_left(enum tof type, struct process *proc, char *function_name) void output_right(enum tof type, struct process *proc, char *function_name) { struct function *func = name2func(function_name); + static arg_type_info *arg_unknown = NULL; + if (arg_unknown == NULL) + arg_unknown = lookup_singleton(ARGTYPE_UNKNOWN); if (opt_c) { struct opt_c_struct *st; @@ -273,26 +279,26 @@ void output_right(enum tof type, struct process *proc, char *function_name) current_column += fprintf(output, ") "); tabto(opt_a - 1); fprintf(output, "= "); - display_arg(type, proc, -1, ARGTYPE_UNKNOWN); + display_arg(type, proc, -1, arg_unknown); } else { int i; for (i = func->num_params - func->params_right; i < func->num_params - 1; i++) { current_column += - display_arg(type, proc, i, func->arg_types[i]); + display_arg(type, proc, i, func->arg_info[i]); current_column += fprintf(output, ", "); } if (func->params_right) { current_column += - display_arg(type, proc, i, func->arg_types[i]); + display_arg(type, proc, i, func->arg_info[i]); } current_column += fprintf(output, ") "); tabto(opt_a - 1); fprintf(output, "= "); - if (func->return_type == ARGTYPE_VOID) { + if (func->return_info->type == ARGTYPE_VOID) { fprintf(output, "<void>"); } else { - display_arg(type, proc, -1, func->return_type); + display_arg(type, proc, -1, func->return_info); } } if (opt_T) { diff --git a/read_config_file.c b/read_config_file.c index 2c54f44..089d69a 100644 --- a/read_config_file.c +++ b/read_config_file.c @@ -11,19 +11,6 @@ #include "output.h" #include "debug.h" -/* - * "void" ARGTYPE_VOID - * "int" ARGTYPE_INT - * "uint" ARGTYPE_UINT - * "long" ARGTYPE_LONG - * "ulong" ARGTYPE_ULONG - * "octal" ARGTYPE_OCTAL - * "char" ARGTYPE_CHAR - * "string" ARGTYPE_STRING - * "format" ARGTYPE_FORMAT - * "addr" ARGTYPE_ADDR - */ - struct function *list_of_functions = NULL; static struct list_of_pt_t { @@ -51,7 +38,37 @@ static struct list_of_pt_t { NULL, ARGTYPE_UNKNOWN} /* Must finish with NULL */ }; -static enum arg_type str2type(char **str) +static arg_type_info arg_type_singletons[] = { + { ARGTYPE_VOID }, + { ARGTYPE_INT }, + { ARGTYPE_UINT }, + { ARGTYPE_LONG }, + { ARGTYPE_ULONG }, + { ARGTYPE_OCTAL }, + { ARGTYPE_CHAR }, + { ARGTYPE_ADDR }, + { ARGTYPE_FILE }, + { ARGTYPE_FORMAT }, + { ARGTYPE_STRING }, + { ARGTYPE_STRING_N }, + { ARGTYPE_STRING0 }, + { ARGTYPE_STRING1 }, + { ARGTYPE_STRING2 }, + { ARGTYPE_STRING3 }, + { ARGTYPE_STRING4 }, + { ARGTYPE_STRING5 }, + { ARGTYPE_UNKNOWN } +}; + +arg_type_info *lookup_singleton(enum arg_type at) +{ + if (at >= 0 && at <= ARGTYPE_COUNT) + return &arg_type_singletons[at]; + else + return &arg_type_singletons[ARGTYPE_COUNT]; /* UNKNOWN */ +} + +static arg_type_info *str2type(char **str) { struct list_of_pt_t *tmp = &list_of_pt[0]; @@ -59,11 +76,11 @@ static enum arg_type str2type(char **str) if (!strncmp(*str, tmp->name, strlen(tmp->name)) && index(" ,)#", *(*str + strlen(tmp->name)))) { *str += strlen(tmp->name); - return tmp->pt; + return lookup_singleton(tmp->pt); } tmp++; } - return ARGTYPE_UNKNOWN; + return lookup_singleton(ARGTYPE_UNKNOWN); } static void eat_spaces(char **str) @@ -105,9 +122,46 @@ static char *start_of_arg_sig(char *str) return (stacked == 0) ? pos : NULL; } +/* + Decide whether a type needs any additional parameters. + For now, we do not parse any nontrivial argument types. +*/ +static int simple_type(enum arg_type at) +{ + return 1; +} + static int line_no; static char *filename; +static arg_type_info *parse_type(char **str) +{ + arg_type_info *simple; + arg_type_info *info; + + simple = str2type(str); + if (simple->type == ARGTYPE_UNKNOWN) { + return simple; // UNKNOWN + } + + if (simple_type(simple->type)) + return simple; + + info = malloc(sizeof(*info)); + info->type = simple->type; + + /* Code to parse parameterized types will go into the following + switch statement. */ + + switch (info->type) { + default: + output_line(0, "Syntax error in `%s', line %d: Unknown type encountered", + filename, line_no); + free(info); + return NULL; + } +} + static struct function *process_line(char *buf) { struct function fun; @@ -119,12 +173,12 @@ static struct function *process_line(char *buf) line_no++; debug(3, "Reading line %d of `%s'", line_no, filename); eat_spaces(&str); - fun.return_type = str2type(&str); - if (fun.return_type == ARGTYPE_UNKNOWN) { + fun.return_info = parse_type(&str); + if (fun.return_info == NULL) { debug(3, " Skipping line %d", line_no); return NULL; } - debug(4, " return_type = %d", fun.return_type); + debug(4, " return_type = %d", fun.return_info->type); eat_spaces(&str); tmp = start_of_arg_sig(str); if (!tmp) { @@ -148,9 +202,10 @@ static struct function *process_line(char *buf) } else if (fun.params_right) { fun.params_right++; } - fun.arg_types[i] = str2type(&str); - if (fun.return_type == ARGTYPE_UNKNOWN) { - output_line(0, "Syntax error in `%s', line %d", + fun.arg_info[i] = parse_type(&str); + if (fun.arg_info[i] == NULL) { + output_line(0, "Syntax error in `%s', line %d" + ": unknown argument type", filename, line_no); return NULL; } @@ -161,8 +216,10 @@ static struct function *process_line(char *buf) } else if (*str == ')') { continue; } else { - output_line(0, "Syntax error in `%s', line %d", - filename, line_no); + if (str[strlen(str) - 1] == '\n') + str[strlen(str) - 1] = '\0'; + output_line(0, "Syntax error in `%s', line %d at ...\"%s\"", + filename, line_no, str); return NULL; } } |