Blame SOURCES/github_0f65ae0c_readline_tab_completion.patch

7ef056
commit 0f65ae0c36bf04e22219f28c32c3ae0cdee5acfe
7ef056
Author: Dave Anderson <anderson@redhat.com>
7ef056
Date:   Fri Dec 7 15:17:37 2018 -0500
7ef056
7ef056
    Implemented a new plugin function for the readline library's tab
7ef056
    completion feature.  Without the patch, the use of the default plugin
7ef056
    from the embedded gdb module has been seen to cause segmentation
7ef056
    violations or other fatal malloc/free/corruption assertions.  The new
7ef056
    plugin takes gdb out of the picture entirely, and also restricts the
7ef056
    matching options to just symbol names, so as not to clutter the
7ef056
    results with irrelevant filenames.
7ef056
    (anderson@redhat.com)
7ef056
7ef056
diff --git a/cmdline.c b/cmdline.c
7ef056
index cf3e150..665f48c 100644
7ef056
--- a/cmdline.c
7ef056
+++ b/cmdline.c
7ef056
@@ -40,6 +40,8 @@ int shell_command(char *);
7ef056
 static void modify_orig_line(char *, struct args_input_file *);
7ef056
 static void modify_expression_arg(char *, char **, struct args_input_file *);
7ef056
 static int verify_args_input_file(char *);
7ef056
+static char *crash_readline_completion_generator(const char *, int);
7ef056
+static char **crash_readline_completer(const char *, int, int);
7ef056
 
7ef056
 #define READLINE_LIBRARY
7ef056
 
7ef056
@@ -2071,6 +2073,9 @@ readline_init(void)
7ef056
 	if (STREQ(pc->editing_mode, "emacs")) {
7ef056
         	rl_editing_mode = emacs_mode;
7ef056
 	}
7ef056
+
7ef056
+	rl_attempted_completion_function = crash_readline_completer;
7ef056
+	rl_attempted_completion_over = 1;
7ef056
 }
7ef056
 
7ef056
 /*
7ef056
@@ -2605,3 +2610,27 @@ exec_args_input_file(struct command_table_entry *ct, struct args_input_file *aif
7ef056
 	fclose(pc->args_ifile);
7ef056
 	pc->args_ifile = NULL;
7ef056
 }
7ef056
+
7ef056
+static char *
7ef056
+crash_readline_completion_generator(const char *match, int state)
7ef056
+{
7ef056
+	static struct syment *sp_match;
7ef056
+
7ef056
+	if (state == 0)
7ef056
+		sp_match = NULL;
7ef056
+
7ef056
+	sp_match = symbol_complete_match(match, sp_match);
7ef056
+
7ef056
+	if (sp_match)
7ef056
+		return(strdup(sp_match->name));
7ef056
+	else
7ef056
+		return NULL;
7ef056
+}
7ef056
+
7ef056
+static char **
7ef056
+crash_readline_completer(const char *match, int start, int end)
7ef056
+{
7ef056
+	rl_attempted_completion_over = 1;
7ef056
+	return rl_completion_matches(match, crash_readline_completion_generator);
7ef056
+}
7ef056
+
7ef056
diff --git a/defs.h b/defs.h
7ef056
index 9ce32c1..a3cb5a4 100644
7ef056
--- a/defs.h
7ef056
+++ b/defs.h
7ef056
@@ -5138,6 +5138,7 @@ void parse_for_member_extended(struct datatype_member *, ulong);
7ef056
 void add_to_downsized(char *);
7ef056
 int is_downsized(char *);
7ef056
 int is_string(char *, char *);
7ef056
+struct syment *symbol_complete_match(const char *, struct syment *);
7ef056
 
7ef056
 /*  
7ef056
  *  memory.c 
7ef056
diff --git a/symbols.c b/symbols.c
7ef056
index 05628ff..0769294 100644
7ef056
--- a/symbols.c
7ef056
+++ b/symbols.c
7ef056
@@ -13071,3 +13071,73 @@ is_downsized(char *name)
7ef056
 
7ef056
 	return FALSE;
7ef056
 }
7ef056
+
7ef056
+struct syment *
7ef056
+symbol_complete_match(const char *match, struct syment *sp_last)
7ef056
+{
7ef056
+	int i;
7ef056
+	struct syment *sp, *sp_end, *sp_start;
7ef056
+	struct load_module *lm;
7ef056
+	int search_init;
7ef056
+
7ef056
+	if (sp_last) {
7ef056
+		sp_start = next_symbol(NULL, sp_last);
7ef056
+		if (!sp_start)
7ef056
+			return NULL;
7ef056
+	} else	
7ef056
+		sp_start = st->symtable;
7ef056
+
7ef056
+	if ((sp_start >= st->symtable) && (sp_start < st->symend)) {
7ef056
+		for (sp = sp_start; sp < st->symend; sp++) {
7ef056
+			if (STRNEQ(sp->name, match))
7ef056
+				return sp;
7ef056
+		}
7ef056
+		sp_start = NULL;
7ef056
+	}
7ef056
+
7ef056
+	search_init = FALSE;
7ef056
+
7ef056
+	for (i = 0; i < st->mods_installed; i++) {
7ef056
+		lm = &st->load_modules[i];
7ef056
+		if (lm->mod_flags & MOD_INIT)
7ef056
+			search_init = TRUE;
7ef056
+		sp_end = lm->mod_symend;
7ef056
+		if (!sp_start)
7ef056
+			sp_start = lm->mod_symtable;
7ef056
+
7ef056
+		if ((sp_start >= lm->mod_symtable) && (sp_start < sp_end)) {
7ef056
+			for (sp = sp_start; sp < sp_end; sp++) {
7ef056
+				if (MODULE_START(sp))
7ef056
+					continue;
7ef056
+	
7ef056
+				if (STRNEQ(sp->name, match))
7ef056
+					return sp;
7ef056
+			}
7ef056
+			sp_start = NULL;
7ef056
+		}
7ef056
+	}
7ef056
+
7ef056
+	if (!search_init)
7ef056
+		return NULL;
7ef056
+	
7ef056
+	for (i = 0; i < st->mods_installed; i++) {
7ef056
+		lm = &st->load_modules[i];
7ef056
+		if (!lm->mod_init_symtable)
7ef056
+			continue;
7ef056
+		sp_end = lm->mod_init_symend;
7ef056
+		if (!sp_start)
7ef056
+			sp_start = lm->mod_init_symtable;
7ef056
+
7ef056
+		if ((sp_start >= lm->mod_init_symtable) && (sp_start < sp_end)) {
7ef056
+			for (sp = sp_start; sp < sp_end; sp++) {
7ef056
+				if (MODULE_START(sp))
7ef056
+					continue;
7ef056
+	
7ef056
+				if (STRNEQ(sp->name, match))
7ef056
+					return sp;
7ef056
+			}
7ef056
+		}
7ef056
+	}
7ef056
+
7ef056
+	return NULL;
7ef056
+}