Skip to content

Commit d4e5e1e

Browse files
authored
Merge pull request #2191 from dscho/add-p-fixups
A couple of fixups for add-i-in-c-status-and-help
2 parents e3538d8 + c6746a4 commit d4e5e1e

File tree

2 files changed

+38
-32
lines changed

2 files changed

+38
-32
lines changed

add-interactive.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,15 @@ struct list_and_choose_options {
138138
void (*print_help)(struct add_i_state *s);
139139
};
140140

141+
#define LIST_AND_CHOOSE_ERROR (-1)
142+
#define LIST_AND_CHOOSE_QUIT (-2)
143+
141144
/*
142145
* Returns the selected index in singleton mode, the number of selected items
143146
* otherwise.
147+
*
148+
* If an error occurred, returns `LIST_AND_CHOOSE_ERROR`. Upon EOF,
149+
* `LIST_AND_CHOOSE_QUIT` is returned.
144150
*/
145151
static ssize_t list_and_choose(struct prefix_item **items, int *selected,
146152
size_t nr, struct add_i_state *s,
@@ -150,7 +156,7 @@ static ssize_t list_and_choose(struct prefix_item **items, int *selected,
150156
int immediate = opts->flags & IMMEDIATE;
151157

152158
struct strbuf input = STRBUF_INIT;
153-
ssize_t res = singleton ? -1 : 0;
159+
ssize_t res = singleton ? LIST_AND_CHOOSE_ERROR : 0;
154160

155161
if (!selected && !singleton)
156162
BUG("need a selected array in non-singleton mode");
@@ -174,7 +180,7 @@ static ssize_t list_and_choose(struct prefix_item **items, int *selected,
174180
if (strbuf_getline(&input, stdin) == EOF) {
175181
putchar('\n');
176182
if (immediate)
177-
res = -2;
183+
res = LIST_AND_CHOOSE_QUIT;
178184
break;
179185
}
180186
strbuf_trim(&input);
@@ -253,7 +259,8 @@ static ssize_t list_and_choose(struct prefix_item **items, int *selected,
253259
p += sep + 1;
254260
}
255261

256-
if ((immediate && res >= 0) || !strcmp(input.buf, "*"))
262+
if ((immediate && res != LIST_AND_CHOOSE_ERROR) ||
263+
!strcmp(input.buf, "*"))
257264
break;
258265
}
259266

@@ -1050,12 +1057,13 @@ int run_add_i(struct repository *r, const struct pathspec *ps)
10501057
for (;;) {
10511058
i = list_and_choose((struct prefix_item **)commands, NULL,
10521059
ARRAY_SIZE(commands), &s, &main_loop_opts);
1053-
if (i < -1 || (i >= 0 && !commands[i]->command)) {
1060+
if (i == LIST_AND_CHOOSE_QUIT ||
1061+
(i != LIST_AND_CHOOSE_ERROR && !commands[i]->command)) {
10541062
printf(_("Bye.\n"));
10551063
res = 0;
10561064
break;
10571065
}
1058-
if (i >= 0)
1066+
if (i != LIST_AND_CHOOSE_ERROR)
10591067
res = commands[i]->command(&s, ps, &files, &opts);
10601068
}
10611069

prefix-map.c

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,40 +35,40 @@ static void init_prefix_map(struct prefix_map *prefix_map,
3535
static void add_prefix_item(struct prefix_map *prefix_map,
3636
struct prefix_item *item)
3737
{
38-
struct prefix_map_entry *e = xmalloc(sizeof(*e)), *e2;
38+
struct prefix_map_entry e = { { NULL } }, *e2;
3939
int j;
4040

41-
e->item = item;
42-
e->name = e->item->name;
41+
e.item = item;
42+
e.name = item->name;
4343

44-
for (j = prefix_map->min_length; j <= prefix_map->max_length; j++) {
45-
if (!isascii(e->name[j])) {
46-
free(e);
44+
for (j = prefix_map->min_length;
45+
j <= prefix_map->max_length && e.name[j]; j++) {
46+
/* Avoid breaking UTF-8 multi-byte sequences */
47+
if (!isascii(e.name[j]))
4748
break;
48-
}
4949

50-
e->prefix_length = j;
51-
hashmap_entry_init(e, memhash(e->name, j));
52-
e2 = hashmap_get(&prefix_map->map, e, NULL);
50+
e.prefix_length = j;
51+
hashmap_entry_init(&e, memhash(e.name, j));
52+
e2 = hashmap_get(&prefix_map->map, &e, NULL);
5353
if (!e2) {
54-
/* prefix is unique so far */
55-
e->item->prefix_length = j;
56-
hashmap_add(&prefix_map->map, e);
54+
/* prefix is unique at this stage */
55+
item->prefix_length = j;
56+
add_prefix_entry(&prefix_map->map, e.name, j, item);
5757
break;
5858
}
5959

6060
if (!e2->item)
6161
continue; /* non-unique prefix */
6262

63-
if (j != e2->item->prefix_length)
64-
BUG("unexpected prefix length: %d != %d",
65-
(int)j, (int)e2->item->prefix_length);
63+
if (j != e2->item->prefix_length || memcmp(e.name, e2->name, j))
64+
BUG("unexpected prefix length: %d != %d (%s != %s)",
65+
j, (int)e2->item->prefix_length, e.name, e2->name);
6666

6767
/* skip common prefix */
68-
for (; j < prefix_map->max_length && e->name[j]; j++) {
69-
if (e->item->name[j] != e2->item->name[j])
68+
for (; j < prefix_map->max_length && e.name[j]; j++) {
69+
if (e.item->name[j] != e2->item->name[j])
7070
break;
71-
add_prefix_entry(&prefix_map->map, e->name, j + 1,
71+
add_prefix_entry(&prefix_map->map, e.name, j + 1,
7272
NULL);
7373
}
7474

@@ -83,16 +83,14 @@ static void add_prefix_item(struct prefix_map *prefix_map,
8383
e2->item->prefix_length = 0;
8484
e2->item = NULL;
8585

86-
if (j < prefix_map->max_length && e->name[j]) {
86+
if (j < prefix_map->max_length && e.name[j]) {
8787
/* found a unique prefix for the item */
88-
e->item->prefix_length = j + 1;
89-
add_prefix_entry(&prefix_map->map, e->name, j + 1,
90-
e->item);
91-
} else {
88+
e.item->prefix_length = j + 1;
89+
add_prefix_entry(&prefix_map->map, e.name, j + 1,
90+
e.item);
91+
} else
9292
/* item has no (short enough) unique prefix */
93-
e->item->prefix_length = 0;
94-
free(e);
95-
}
93+
e.item->prefix_length = 0;
9694

9795
break;
9896
}

0 commit comments

Comments
 (0)