diff options
author | Petr Machata <pmachata@redhat.com> | 2012-01-06 21:04:03 +0100 |
---|---|---|
committer | Petr Machata <pmachata@redhat.com> | 2012-08-29 19:02:06 +0200 |
commit | 2bea8615d97097a334449ee95112c8a59277103e (patch) | |
tree | 2317da478386582761075a4778b9cb45e4430d60 | |
parent | 88a30210f32add54af498bf6f127b2b9773bdf8e (diff) | |
download | ltrace-2bea8615d97097a334449ee95112c8a59277103e.tar.gz |
Drop ARGTYPE_STRING, all strings now have length (sometimes "zero")
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | display_args.c | 4 | ||||
-rw-r--r-- | read_config_file.c | 116 | ||||
-rw-r--r-- | type.c | 16 | ||||
-rw-r--r-- | type.h | 7 |
5 files changed, 117 insertions, 37 deletions
@@ -1,5 +1,16 @@ 2012-01-06 Petr Machata <pmachata@redhat.com> + * common.h (enum arg_type): Drop ARGTYPE_STRING + * common.c, common.h (type_init_string): New function + * read_config_file.c (parse_string): New function, parses all the + string syntax that we support + (parse_alias): New function, dispatches to everything that has + non-obvious syntax + (parse_nonpointer_type): Call parse_alias. Drop ARGTYPE_STRING + * display_args.c: Drop ARGTYPE_STRING + +2012-01-06 Petr Machata <pmachata@redhat.com> + * display_args.c, type.c, type.h: Drop ARGTYPE_ADDR, ARGTYPE_FILE * read_config_file.c: Likewise (init_global_config): Add default typedefs for "file" and "addr" diff --git a/display_args.c b/display_args.c index 00f74cb..9b27155 100644 --- a/display_args.c +++ b/display_args.c @@ -145,7 +145,6 @@ format_char(FILE *stream, struct value *value, struct value_dict *arguments) * string, and we need to display quotes. */ int quote = !(value->parent != NULL && (value->parent->type->type == ARGTYPE_ARRAY - || value->parent->type->type == ARGTYPE_STRING || value->parent->type->type == ARGTYPE_STRING_N)); int written = 0; if (quote && acc_fprintf(&written, stream, "'") < 0) @@ -362,8 +361,7 @@ format_argument(FILE *stream, struct value *value, struct value_dict *arguments) case ARGTYPE_STRING_N: length = value->type->u.string_n_info.length; /* fall-through */ - case ARGTYPE_FORMAT: - case ARGTYPE_STRING: { + case ARGTYPE_FORMAT: { /* Strings are in fact char pointers. Smuggle in the * pointer here. */ diff --git a/read_config_file.c b/read_config_file.c index 140b0f8..fe45894 100644 --- a/read_config_file.c +++ b/read_config_file.c @@ -39,7 +39,6 @@ static int line_no; static char *filename; -static int error_count = 0; static struct arg_type_info *parse_type(char **str); @@ -454,6 +453,90 @@ parse_struct(char **str, struct arg_type_info *info) } } +static int +parse_string(char **str, struct arg_type_info **retp) +{ + struct arg_type_info *info = malloc(sizeof(*info)); + if (info == NULL) { + fail: + free(info); + return -1; + } + + struct expr_node *length; + int own_length; + + if (isdigit(**str)) { + /* string0 is string[retval], length is zero(retval) + * stringN is string[argN], length is zero(argN) */ + long l; + if (parse_int(str, &l) < 0 + || check_int(l) < 0) + goto fail; + + struct expr_node *length_arg = malloc(sizeof(*length_arg)); + if (length_arg == NULL) + goto fail; + + if (l == 0) + expr_init_named(length_arg, "retval", 0); + else + expr_init_argno(length_arg, l - 1); + + length = build_zero_w_arg(length_arg, 1); + if (length == NULL) { + expr_destroy(length_arg); + free(length_arg); + goto fail; + } + own_length = 1; + + } else { + eat_spaces(str); + if (**str == '[') { + (*str)++; + eat_spaces(str); + + length = parse_argnum(str, 1); + if (length == NULL) + goto fail; + own_length = 1; + + eat_spaces(str); + parse_char(str, ']'); + + } else { + /* It was just a simple string after all. */ + length = expr_node_zero(); + own_length = 0; + } + } + + /* String is a pointer to array of chars. */ + type_init_string(info, length, own_length); + + *retp = info; + return 0; +} + +static int +parse_alias(char **str, struct arg_type_info **retp, int *ownp) +{ + /* For backward compatibility, we need to support things like + * stringN (which is like string[argN], string[N], and also + * bare string. We might, in theory, replace this by + * preprocessing configure file sources with M4, but for now, + * "string" is syntax. */ + if (strncmp(*str, "string", 6) == 0) { + (*str) += 6; + return parse_string(str, retp); + + } else { + *retp = NULL; + return 0; + } +} + /* Syntax: enum ( keyname=value,keyname=value,... ) */ static int parse_enum(char **str, struct arg_type_info *info) @@ -530,6 +613,11 @@ parse_nonpointer_type(char **str) { struct arg_type_info *simple; struct arg_type_info *info; + int own; + if (parse_alias(str, &simple, &own) < 0) + return NULL; + if (simple != NULL) + return simple; if (strncmp(*str, "typedef", 7) == 0) { parse_typedef(str); return lookup_prototype(ARGTYPE_UNKNOWN); @@ -569,29 +657,6 @@ parse_nonpointer_type(char **str) { parser = parse_enum; break; - case ARGTYPE_STRING: - if (!isdigit(**str) && **str != '[') { - /* Oops, was just a simple string after all */ - free(info); - return simple; - } - - info->type = ARGTYPE_STRING_N; - - /* Backwards compatibility for string0, string1, ... */ - if (isdigit(**str)) { - info->u.string_n_info.length = parse_argnum(str, 1); - return info; - } - - (*str)++; // Skip past opening [ - eat_spaces(str); - info->u.string_n_info.length = parse_argnum(str, 1); - eat_spaces(str); - (*str)++; // Skip past closing ] - return info; - - // Syntax: struct ( type,type,type,... ) case ARGTYPE_STRUCT: parser = parse_struct; break; @@ -762,7 +827,7 @@ process_line(char *buf) { assert(fun->num_params < allocd); memcpy(&fun->params[fun->num_params++], extra_param, sizeof(*extra_param)); - } + } return fun; } @@ -800,7 +865,6 @@ read_config_file(char *file) { while (fgets(buf, 1024, stream)) { Function *tmp; - error_count = 0; tmp = process_line(buf); if (tmp) { @@ -53,7 +53,6 @@ type_get_simple(enum arg_type type) #undef HANDLE - case ARGTYPE_STRING: case ARGTYPE_STRING_N: case ARGTYPE_COUNT: @@ -238,6 +237,15 @@ type_init_array(struct arg_type_info *info, info->u.array_info.own_length = own_length; } +void +type_init_string(struct arg_type_info *info, + struct expr_node *length, int own_length) +{ + info->type = ARGTYPE_STRING_N; + info->u.string_n_info.length = length; + info->u.string_n_info.own_length = own_length; +} + static void type_array_destroy(struct arg_type_info *info) { @@ -318,7 +326,6 @@ type_destroy(struct arg_type_info *info) break; case ARGTYPE_FORMAT: - case ARGTYPE_STRING: case ARGTYPE_COUNT: break; } @@ -430,7 +437,6 @@ type_sizeof(struct Process *proc, struct arg_type_info *type) return sizeof(long); case ARGTYPE_FORMAT: - case ARGTYPE_STRING: case ARGTYPE_STRING_N: case ARGTYPE_COUNT: return -1; @@ -501,7 +507,6 @@ type_offsetof(struct Process *proc, struct arg_type_info *type, size_t emt) assert(type->type == ARGTYPE_STRUCT || type->type == ARGTYPE_ARRAY /* XXX Temporary, this will be removed. */ - || type->type == ARGTYPE_STRING || type->type == ARGTYPE_STRING_N); switch (type->type) { @@ -518,7 +523,6 @@ type_offsetof(struct Process *proc, struct arg_type_info *type, size_t emt) return emt * align(size, alignment); - case ARGTYPE_STRING: case ARGTYPE_STRING_N: return emt; @@ -538,7 +542,6 @@ type_element(struct arg_type_info *info, size_t emt) assert(info->type == ARGTYPE_STRUCT || info->type == ARGTYPE_ARRAY /* XXX Temporary, this will be removed. */ - || info->type == ARGTYPE_STRING || info->type == ARGTYPE_STRING_N); switch (info->type) { @@ -549,7 +552,6 @@ type_element(struct arg_type_info *info, size_t emt) assert(emt < type_struct_size(info)); return type_struct_get(info, emt); - case ARGTYPE_STRING: case ARGTYPE_STRING_N: return type_get_simple(ARGTYPE_CHAR); @@ -40,7 +40,6 @@ enum arg_type { ARGTYPE_FLOAT, /* float value, may require index */ ARGTYPE_DOUBLE, /* double value, may require index */ ARGTYPE_FORMAT, /* printf-like format */ - ARGTYPE_STRING, /* NUL-terminated string */ ARGTYPE_STRING_N, /* String of known maxlen */ ARGTYPE_ARRAY, /* Series of values in memory */ ARGTYPE_ENUM, /* Enumeration */ @@ -139,6 +138,12 @@ void type_init_array(struct arg_type_info *info, struct arg_type_info *element_info, int own_info, struct expr_node *length, int own_length); +/* Initialize INFO so it becomes ARGTYPE_STRING_N. Length is passed + * in LENGTH_EXPR. If OWN_LENGTH is true, the length is owned and + * destroyed together with INFO. */ +void type_init_string(struct arg_type_info *info, + struct expr_node *length, int own_length); + /* Initialize INFO so it becomes ARGTYPE_POINTER. The pointee type is * passed in POINTEE_INFO. If OWN_INFO, the pointee type is owned and * destroyed together with INFO. */ |