Blame SOURCES/github_0f65ae0c_readline_tab_completion.patch

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