aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--display_args.c23
-rw-r--r--type.c5
-rw-r--r--value.c26
-rw-r--r--value.h6
4 files changed, 38 insertions, 22 deletions
diff --git a/display_args.c b/display_args.c
index 270381d..1cfbe6d 100644
--- a/display_args.c
+++ b/display_args.c
@@ -311,8 +311,7 @@ int
format_argument(FILE *stream, struct value *value, struct value_dict *arguments)
{
switch (value->type->type) {
- struct value tmp;
- struct arg_type_info info[2];
+ struct value *tmp;
int ret;
case ARGTYPE_VOID:
@@ -362,21 +361,11 @@ format_argument(FILE *stream, struct value *value, struct value_dict *arguments)
options.strlen, 0, "\"", "\"", "");
case ARGTYPE_STRING_N:
- /* Strings are in fact char pointers. Smuggle in the
- * pointer here. */
-
- type_init_array(&info[1], type_get_simple(ARGTYPE_CHAR), 0,
- value->type->u.string_n_info.length, 0);
- type_init_pointer(&info[0], &info[1], 0);
-
- value_clone(&tmp, value);
- value_set_type(&tmp, info, 0);
-
- ret = format_argument(stream, &tmp, arguments);
-
- value_destroy(&tmp);
- type_destroy(&info[0]);
- type_destroy(&info[1]);
+ tmp = value_string_to_charp(value);
+ if (tmp == NULL)
+ return -1;
+ ret = format_argument(stream, tmp, arguments);
+ value_destroy(tmp);
return ret;
case ARGTYPE_ENUM:
diff --git a/type.c b/type.c
index cd621d3..1054659 100644
--- a/type.c
+++ b/type.c
@@ -397,6 +397,8 @@ type_sizeof(struct Process *proc, struct arg_type_info *type)
return (size_t)-1;
return size;
+ case ARGTYPE_STRING_N:
+ /* String is a char* in disguise. */
case ARGTYPE_POINTER:
return sizeof(void *);
@@ -430,9 +432,6 @@ type_sizeof(struct Process *proc, struct arg_type_info *type)
case ARGTYPE_OCTAL:
case ARGTYPE_UNKNOWN:
return sizeof(long);
-
- case ARGTYPE_STRING_N:
- return -1;
}
abort();
diff --git a/value.c b/value.c
index 5f2bf1a..6002a6b 100644
--- a/value.c
+++ b/value.c
@@ -198,6 +198,28 @@ value_clone(struct value *retp, struct value *val)
return 0;
}
+struct value *
+value_string_to_charp(struct value *value)
+{
+ struct arg_type_info *info = malloc(sizeof(*info) * 2);
+ if (info == NULL) {
+ fail:
+ free(info);
+ return NULL;
+ }
+ type_init_array(&info[1], type_get_simple(ARGTYPE_CHAR), 0,
+ value->type->u.string_n_info.length, 0);
+ type_init_pointer(&info[0], &info[1], 0);
+
+ struct value *tmp = malloc(sizeof(*tmp));
+ if (tmp == NULL)
+ goto fail;
+
+ value_clone(tmp, value);
+ value_set_type(tmp, info, 1);
+ return tmp;
+}
+
size_t
value_size(struct value *val, struct value_dict *arguments)
{
@@ -219,8 +241,8 @@ value_size(struct value *val, struct value_dict *arguments)
if (o < 0)
return (size_t)-1;
- struct arg_type_info *elt_type = val->type->u.array_info.elt_type;
- size_t elt_size = type_sizeof(val->inferior, elt_type);
+ size_t elt_size = type_sizeof(val->inferior,
+ val->type->u.array_info.elt_type);
if (elt_size == (size_t)-1)
return (size_t)-1;
diff --git a/value.h b/value.h
index e88b72a..f3238b6 100644
--- a/value.h
+++ b/value.h
@@ -149,4 +149,10 @@ struct value *value_get_parental_struct(struct value *val);
* if it isn't, <0 on error. */
int value_is_zero(struct value *val, struct value_dict *arguments);
+/* Take a VALUE of type ARGTYPE_STRING_N, and allocate a new value
+ * that is ARGTYPE_POINTER to ARGTYPE_CHAR with the same length
+ * expression. Returns NULL on failure or a value, which you need to
+ * free properly (i.e. call value_destroy and free). */
+struct value *value_string_to_charp(struct value *value);
+
#endif /* VALUE_H */