aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--ltrace.h31
-rw-r--r--output.c24
-rw-r--r--read_config_file.c105
4 files changed, 124 insertions, 42 deletions
diff --git a/ChangeLog b/ChangeLog
index ce34ab5..580343f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/ltrace.h b/ltrace.h
index 460167e..5561139 100644
--- a/ltrace.h
+++ b/ltrace.h
@@ -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);
diff --git a/output.c b/output.c
index 200126b..59c0807 100644
--- a/output.c
+++ b/output.c
@@ -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;
}
}