menuconfig: Assign jump keys per-page instead of globally

At the moment, keys 1-9 are assigned to the first 9 search results. This patch
makes them assigned to the first 9 results per-page instead. We are much less
likely to run out of keys that way.

Signed-off-by: Benjamin Poirier <bpoirier@suse.de>
Signed-off-by: Michal Marek <mmarek@suse.cz>
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index a524185..a3cade6 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -507,12 +507,12 @@
 		return "";
 }
 
-static int get_prompt_str(struct gstr *r, struct property *prop, struct menu
-			  **jumps, int jump_nb)
+static void get_prompt_str(struct gstr *r, struct property *prop,
+			   struct jk_head *head)
 {
 	int i, j;
-	char header[4];
 	struct menu *submenu[8], *menu, *location = NULL;
+	struct jump_key *jump;
 
 	str_printf(r, _("Prompt: %s\n"), _(prop->text));
 	str_printf(r, _("  Defined at %s:%d\n"), prop->menu->file->name,
@@ -530,7 +530,9 @@
 		if (location == NULL && accessible)
 			location = menu;
 	}
-	if (jumps && jump_nb < JUMP_NB && location) {
+	if (head && location) {
+		jump = malloc(sizeof(struct jump_key));
+
 		if (menu_is_visible(prop->menu)) {
 			/*
 			 * There is not enough room to put the hint at the
@@ -538,19 +540,26 @@
 			 * last "Location" line even when it would belong on
 			 * the former.
 			 */
-			jumps[jump_nb] = prop->menu;
+			jump->target = prop->menu;
 		} else
-			jumps[jump_nb] = location;
-		snprintf(header, 4, "(%d)", jump_nb + 1);
-	} else
-		location = NULL;
+			jump->target = location;
+
+		if (CIRCLEQ_EMPTY(head))
+			jump->index = 0;
+		else
+			jump->index = CIRCLEQ_LAST(head)->index + 1;
+
+		CIRCLEQ_INSERT_TAIL(head, jump, entries);
+	}
 
 	if (i > 0) {
 		str_printf(r, _("  Location:\n"));
-		for (j = 1; --i >= 0; j += 2) {
+		for (j = 4; --i >= 0; j += 2) {
 			menu = submenu[i];
-			str_printf(r, "%s%*c-> %s", menu == location ? header
-				   : "   ", j, ' ', _(menu_get_prompt(menu)));
+			if (head && location && menu == location)
+				jump->offset = r->len - 1;
+			str_printf(r, "%*c-> %s", j, ' ',
+				   _(menu_get_prompt(menu)));
 			if (menu->sym) {
 				str_printf(r, " (%s [=%s])", menu->sym->name ?
 					menu->sym->name : _("<choice>"),
@@ -559,20 +568,15 @@
 			str_append(r, "\n");
 		}
 	}
-
-	return location ? 1 : 0;
 }
 
 /*
- * jumps is optional and may be NULL
- * returns the number of jumps inserted
+ * head is optional and may be NULL
  */
-int get_symbol_str(struct gstr *r, struct symbol *sym, struct menu **jumps,
-		   int jump_nb)
+void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head)
 {
 	bool hit;
 	struct property *prop;
-	int i = 0;
 
 	if (sym && sym->name) {
 		str_printf(r, "Symbol: %s [=%s]\n", sym->name,
@@ -588,7 +592,7 @@
 		}
 	}
 	for_all_prompts(sym, prop)
-		i += get_prompt_str(r, prop, jumps, jump_nb + i);
+		get_prompt_str(r, prop, head);
 	hit = false;
 	for_all_properties(sym, prop, P_SELECT) {
 		if (!hit) {
@@ -606,18 +610,16 @@
 		str_append(r, "\n");
 	}
 	str_append(r, "\n\n");
-
-	return i;
 }
 
-struct gstr get_relations_str(struct symbol **sym_arr, struct menu **jumps)
+struct gstr get_relations_str(struct symbol **sym_arr, struct jk_head *head)
 {
 	struct symbol *sym;
 	struct gstr res = str_new();
-	int i, jump_nb = 0;
+	int i;
 
 	for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
-		jump_nb += get_symbol_str(&res, sym, jumps, jump_nb);
+		get_symbol_str(&res, sym, head);
 	if (!i)
 		str_append(&res, _("No matches found.\n"));
 	return res;
@@ -636,5 +638,5 @@
 	}
 	str_printf(help, "%s\n", _(help_text));
 	if (sym)
-		get_symbol_str(help, sym, NULL, 0);
+		get_symbol_str(help, sym, NULL);
 }