@@ -47,12 +47,11 @@ argv_extend(struct argv *a, const size_t newcap)
{
char **newargv;
size_t i;
- ALLOC_ARRAY_CLEAR(newargv, char *, newcap);
+ ALLOC_ARRAY_CLEAR_GC(newargv, char *, newcap, &a->gc);
for (i = 0; i < a->argc; ++i)
{
newargv[i] = a->argv[i];
}
- free(a->argv);
a->argv = newargv;
a->capacity = newcap;
}
@@ -64,6 +63,7 @@ argv_init(struct argv *a)
a->capacity = 0;
a->argc = 0;
a->argv = NULL;
+ a->gc = gc_new();
argv_extend(a, 8);
}
@@ -78,24 +78,21 @@ argv_new(void)
void
argv_free(struct argv *a)
{
- size_t i;
- for (i = 0; i < a->argc; ++i)
- {
- free(a->argv[i]);
- }
- free(a->argv);
+ gc_free(&a->gc);
}
static void
argv_reset(struct argv *a)
{
- size_t i;
- for (i = 0; i < a->argc; ++i)
+ if (a->argc)
{
- free(a->argv[i]);
- a->argv[i] = NULL;
+ size_t i;
+ for (i = 0; i < a->argc; ++i)
+ {
+ a->argv[i] = NULL;
+ }
+ a->argc = 0;
}
- a->argc = 0;
}
static void
@@ -107,7 +104,7 @@ argv_grow(struct argv *a, const size_t add)
}
static void
-argv_append(struct argv *a, char *str) /* str must have been malloced or be NULL */
+argv_append(struct argv *a, char *str) /* str must have been gc_malloced or be NULL */
{
argv_grow(a, 1);
a->argv[a->argc++] = str;
@@ -128,7 +125,7 @@ argv_clone(const struct argv *a, const size_t headroom)
{
for (i = 0; i < a->argc; ++i)
{
- argv_append(&r, string_alloc(a->argv[i], NULL));
+ argv_append(&r, string_alloc(a->argv[i], &r.gc));
}
}
return r;
@@ -139,7 +136,7 @@ argv_insert_head(const struct argv *a, const char *head)
{
struct argv r;
r = argv_clone(a, 1);
- r.argv[0] = string_alloc(head, NULL);
+ r.argv[0] = string_alloc(head, &r.gc);
return r;
}
@@ -251,7 +248,7 @@ argv_printf_arglist(struct argv *a, const char *format, va_list arglist)
}
size = adjust_power_of_2(len + 1);
- buf = gc_malloc(size, false, &gc);
+ buf = gc_malloc(size, false, &a->gc);
len = vsnprintf(buf, size, f, arglist);
if (len < 0 || len >= size)
{
@@ -263,11 +260,11 @@ argv_printf_arglist(struct argv *a, const char *format, va_list arglist)
while (end)
{
*end = '\0';
- argv_append(a, string_alloc(buf, NULL));
+ argv_append(a, buf);
buf = end + 1;
end = strchr(buf, delim);
}
- argv_append(a, string_alloc(buf, NULL));
+ argv_append(a, buf);
if (a->argc != argc)
{
@@ -314,23 +311,20 @@ argv_parse_cmd(struct argv *a, const char *s)
{
int nparms;
char *parms[MAX_PARMS + 1];
- struct gc_arena gc = gc_new();
argv_reset(a);
- nparms = parse_line(s, parms, MAX_PARMS, "SCRIPT-ARGV", 0, D_ARGV_PARSE_CMD, &gc);
+ nparms = parse_line(s, parms, MAX_PARMS, "SCRIPT-ARGV", 0, D_ARGV_PARSE_CMD, &a->gc);
if (nparms)
{
int i;
for (i = 0; i < nparms; ++i)
{
- argv_append(a, string_alloc(parms[i], NULL));
+ argv_append(a, parms[i]);
}
}
else
{
- argv_append(a, string_alloc(s, NULL));
+ argv_append(a, string_alloc(s, &a->gc));
}
-
- gc_free(&gc);
}
@@ -33,6 +33,7 @@
#include "buffer.h"
struct argv {
+ struct gc_arena gc;
size_t capacity;
size_t argc;
char **argv;
@@ -117,6 +117,28 @@ argv_printf__empty_parameter__argc_correct(void **state)
argv_free(&a);
}
+static void
+argv_printf__long_args__data_correct(void **state)
+{
+ int i;
+ struct argv a = argv_new();
+ const char *args[] = {
+ "good_tools_have_good_names_even_though_it_might_impair_typing",
+ "--long-opt=looooooooooooooooooooooooooooooooooooooooooooooooong",
+ "--long-cat=loooooooooooooooooooooooooooooooooooooooooooooooooooonger",
+ "file_with_very_descriptive_filename_that_leaves_no_questions_open.jpg.exe"
+ };
+
+ argv_printf(&a, "%s %s %s %s", args[0], args[1], args[2], args[3]);
+ assert_int_equal(a.argc, 4);
+ for (i = 0; i < a.argc; i++)
+ {
+ assert_string_equal(a.argv[i], args[i]);
+ }
+
+ argv_free(&a);
+}
+
static void
argv_parse_cmd__command_string__argc_correct(void **state)
{
@@ -237,6 +259,7 @@ main(void)
cmocka_unit_test(argv_printf__group_sep_in_arg__fail_no_ouput),
cmocka_unit_test(argv_printf__combined_path_with_spaces__argc_correct),
cmocka_unit_test(argv_printf__empty_parameter__argc_correct),
+ cmocka_unit_test(argv_printf__long_args__data_correct),
cmocka_unit_test(argv_parse_cmd__command_string__argc_correct),
cmocka_unit_test(argv_parse_cmd__command_and_extra_options__argc_correct),
cmocka_unit_test(argv_printf_cat__used_twice__argc_correct),