aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--display_args.c4
-rw-r--r--read_config_file.c116
-rw-r--r--type.c16
-rw-r--r--type.h7
5 files changed, 117 insertions, 37 deletions
diff --git a/ChangeLog b/ChangeLog
index dda4178..2bb29d0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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) {
diff --git a/type.c b/type.c
index 4db625d..cf44d81 100644
--- a/type.c
+++ b/type.c
@@ -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);
diff --git a/type.h b/type.h
index 8c754c4..b46427c 100644
--- a/type.h
+++ b/type.h
@@ -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. */