]> git.ipfire.org Git - thirdparty/git.git/commitdiff
clean: do not use strbuf_split*() [part 1]
authorJunio C Hamano <gitster@pobox.com>
Thu, 31 Jul 2025 22:54:25 +0000 (15:54 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sun, 3 Aug 2025 05:37:06 +0000 (22:37 -0700)
builtin/clean.c:parse_choice() is fed a single line of input, which
is space or comma separated list of tokens, and a list of menu
items.  It parses the tokens into number ranges (e.g. 1-3 that means
the first three items) or string prefix (e.g. 's' to choose the menu
item "(s)elect") that specify the elements in the menu item list,
and tells the caller which ones are chosen.

For parsing the input string, it uses strbuf_split() to split it
into bunch of strbufs.  Instead use string_list_split_in_place(),
for a few reasons.

 * strbuf_split() is a bad API function to use, that yields an array
   of strbuf that is a bad data structure to use in general.

 * string_list_split_in_place() allows you to split with "comma or
   space"; the current code has to preprocess the input string to
   replace comma with space because strbuf_split() does not allow
   this.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/clean.c

index 224551537e3b6721e0cb2c5b94f0ac39308537d0..708cd9344ca905d9528c73f13fb6aebff8e9880b 100644 (file)
@@ -480,40 +480,36 @@ static int parse_choice(struct menu_stuff *menu_stuff,
                        struct strbuf *input,
                        int **chosen)
 {
-       struct strbuf **choice_list, **ptr;
+       struct string_list choice = STRING_LIST_INIT_NODUP;
+       struct string_list_item *item;
        int nr = 0;
        int i;
 
-       if (is_single) {
-               choice_list = strbuf_split_max(input, '\n', 0);
-       } else {
-               char *p = input->buf;
-               do {
-                       if (*p == ',')
-                               *p = ' ';
-               } while (*p++);
-               choice_list = strbuf_split_max(input, ' ', 0);
-       }
+       string_list_split_in_place_f(&choice, input->buf,
+                                    is_single ? "\n" : ", ", -1,
+                                    STRING_LIST_SPLIT_TRIM);
 
-       for (ptr = choice_list; *ptr; ptr++) {
-               char *p;
-               int choose = 1;
+       for_each_string_list_item(item, &choice) {
+               const char *string;
+               int choose;
                int bottom = 0, top = 0;
                int is_range, is_number;
 
-               strbuf_trim(*ptr);
-               if (!(*ptr)->len)
+               string = item->string;
+               if (!*string)
                        continue;
 
                /* Input that begins with '-'; unchoose */
-               if (*(*ptr)->buf == '-') {
+               if (string[0] == '-') {
                        choose = 0;
-                       strbuf_remove((*ptr), 0, 1);
+                       string++;
+               } else {
+                       choose = 1;
                }
 
                is_range = 0;
                is_number = 1;
-               for (p = (*ptr)->buf; *p; p++) {
+               for (const char *p = string; *p; p++) {
                        if ('-' == *p) {
                                if (!is_range) {
                                        is_range = 1;
@@ -531,27 +527,27 @@ static int parse_choice(struct menu_stuff *menu_stuff,
                }
 
                if (is_number) {
-                       bottom = atoi((*ptr)->buf);
+                       bottom = atoi(string);
                        top = bottom;
                } else if (is_range) {
-                       bottom = atoi((*ptr)->buf);
+                       bottom = atoi(string);
                        /* a range can be specified like 5-7 or 5- */
-                       if (!*(strchr((*ptr)->buf, '-') + 1))
+                       if (!*(strchr(string, '-') + 1))
                                top = menu_stuff->nr;
                        else
-                               top = atoi(strchr((*ptr)->buf, '-') + 1);
-               } else if (!strcmp((*ptr)->buf, "*")) {
+                               top = atoi(strchr(string, '-') + 1);
+               } else if (!strcmp(string, "*")) {
                        bottom = 1;
                        top = menu_stuff->nr;
                } else {
-                       bottom = find_unique((*ptr)->buf, menu_stuff);
+                       bottom = find_unique(string, menu_stuff);
                        top = bottom;
                }
 
                if (top <= 0 || bottom <= 0 || top > menu_stuff->nr || bottom > top ||
                    (is_single && bottom != top)) {
                        clean_print_color(CLEAN_COLOR_ERROR);
-                       printf(_("Huh (%s)?\n"), (*ptr)->buf);
+                       printf(_("Huh (%s)?\n"), string);
                        clean_print_color(CLEAN_COLOR_RESET);
                        continue;
                }
@@ -560,7 +556,7 @@ static int parse_choice(struct menu_stuff *menu_stuff,
                        (*chosen)[i-1] = choose;
        }
 
-       strbuf_list_free(choice_list);
+       string_list_clear(&choice, 0);
 
        for (i = 0; i < menu_stuff->nr; i++)
                nr += (*chosen)[i];