X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Finterps.c;h=61db7f4bdf1724fff5b560482fa7fd0ca6596021;hb=f67c0c9171508672167b6868c67211571421a1c6;hp=6eed8f3c6c88eb2ebefa9ef10f62682ab05cecfb;hpb=3c216924d6ae534ea6c2f6bdcc4b42238af52ab1;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/interps.c b/gdb/interps.c index 6eed8f3c6c..61db7f4bdf 100644 --- a/gdb/interps.c +++ b/gdb/interps.c @@ -1,6 +1,6 @@ /* Manages interpreters for GDB, the GNU debugger. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. Written by Jim Ingham of Apple Computer, Inc. @@ -72,62 +72,29 @@ get_current_interp_info (void) return get_interp_info (current_ui); } -struct interp -{ - /* This is the name in "-i=" and set interpreter. */ - const char *name; - - /* Interpreters are stored in a linked list, this is the next - one... */ - struct interp *next; - - /* This is a cookie that an instance of the interpreter can use. - This is a bit confused right now as the exact initialization - sequence for it, and how it relates to the interpreter's uiout - object is a bit confused. */ - void *data; - - /* Has the init_proc been run? */ - int inited; - - const struct interp_procs *procs; - int quiet_p; -}; - /* The magic initialization routine for this module. */ -void _initialize_interpreter (void); - static struct interp *interp_lookup_existing (struct ui *ui, const char *name); -/* interp_new - This allocates space for a new interpreter, - fills the fields from the inputs, and returns a pointer to the - interpreter. */ -struct interp * -interp_new (const char *name, const struct interp_procs *procs, void *data) +interp::interp (const char *name) { - struct interp *new_interp; - - new_interp = XNEW (struct interp); - - new_interp->name = xstrdup (name); - new_interp->data = data; - new_interp->quiet_p = 0; - new_interp->procs = procs; - new_interp->inited = 0; - - /* Check for required procs. */ - gdb_assert (procs->command_loop_proc != NULL); - - return new_interp; + this->name = xstrdup (name); + this->inited = false; } +interp::~interp () +{} + /* An interpreter factory. Maps an interpreter name to the factory function that instantiates an interpreter by that name. */ struct interp_factory { + interp_factory (const char *name_, interp_factory_func func_) + : name (name_), func (func_) + {} + /* This is the name in "-i=INTERP" and "interpreter-exec INTERP". */ const char *name; @@ -135,35 +102,24 @@ struct interp_factory interp_factory_func func; }; -typedef struct interp_factory *interp_factory_p; -DEF_VEC_P(interp_factory_p); - /* The registered interpreter factories. */ -static VEC(interp_factory_p) *interpreter_factories = NULL; +static std::vector interpreter_factories; /* See interps.h. */ void interp_factory_register (const char *name, interp_factory_func func) { - struct interp_factory *f; - int ix; - /* Assert that no factory for NAME is already registered. */ - for (ix = 0; - VEC_iterate (interp_factory_p, interpreter_factories, ix, f); - ++ix) - if (strcmp (f->name, name) == 0) + for (const interp_factory &f : interpreter_factories) + if (strcmp (f.name, name) == 0) { internal_error (__FILE__, __LINE__, _("interpreter factory already registered: \"%s\"\n"), name); } - f = XNEW (struct interp_factory); - f->name = name; - f->func = func; - VEC_safe_push (interp_factory_p, interpreter_factories, f); + interpreter_factories.emplace_back (name, func); } /* Add interpreter INTERP to the gdb interpreter list. The @@ -180,11 +136,7 @@ interp_add (struct ui *ui, struct interp *interp) } /* This sets the current interpreter to be INTERP. If INTERP has not - been initialized, then this will also run the init proc. If the - init proc is successful, return 1, if it fails, set the old - interpreter back in place and return 0. If we can't restore the - old interpreter, then raise an internal error, since we are in - pretty bad shape at this point. + been initialized, then this will also run the init method. The TOP_LEVEL parameter tells if this new interpreter is the top-level one. The top-level is what is requested @@ -193,13 +145,12 @@ interp_add (struct ui *ui, struct interp *interp) MI is the top-level interpreter, then it will always report events such as target stops and new thread creation, even if they are caused by CLI commands. */ -int -interp_set (struct interp *interp, int top_level) + +static void +interp_set (struct interp *interp, bool top_level) { struct ui_interp_info *ui_interp = get_current_interp_info (); struct interp *old_interp = ui_interp->current_interpreter; - int first_time = 0; - char buffer[64]; /* If we already have an interpreter, then trying to set top level interpreter is kinda pointless. */ @@ -208,17 +159,8 @@ interp_set (struct interp *interp, int top_level) if (old_interp != NULL) { - ui_out_flush (current_uiout); - if (old_interp->procs->suspend_proc - && !old_interp->procs->suspend_proc (old_interp->data)) - { - error (_("Could not suspend interpreter \"%s\"."), - old_interp->name); - } - } - else - { - first_time = 1; + current_uiout->flush (); + old_interp->suspend (); } ui_interp->current_interpreter = interp; @@ -235,41 +177,20 @@ interp_set (struct interp *interp, int top_level) interpreter_p = xstrdup (interp->name); } - /* Run the init proc. If it fails, try to restore the old interp. */ - + /* Run the init proc. */ if (!interp->inited) { - if (interp->procs->init_proc != NULL) - { - interp->data = interp->procs->init_proc (interp, top_level); - } - interp->inited = 1; + interp->init (top_level); + interp->inited = true; } /* Do this only after the interpreter is initialized. */ - current_uiout = interp->procs->ui_out_proc (interp); + current_uiout = interp->interp_ui_out (); /* Clear out any installed interpreter hooks/event handlers. */ clear_interpreter_hooks (); - if (interp->procs->resume_proc != NULL - && (!interp->procs->resume_proc (interp->data))) - { - if (old_interp == NULL || !interp_set (old_interp, 0)) - internal_error (__FILE__, __LINE__, - _("Failed to initialize new interp \"%s\" %s"), - interp->name, "and could not restore old interp!\n"); - return 0; - } - - if (!first_time && !interp_quiet_p (interp)) - { - xsnprintf (buffer, sizeof (buffer), - "Switching to interpreter \"%.24s\".\n", interp->name); - ui_out_text (current_uiout, buffer); - } - - return 1; + interp->resume (); } /* Look up the interpreter for NAME. If no such interpreter exists, @@ -297,24 +218,18 @@ interp_lookup_existing (struct ui *ui, const char *name) struct interp * interp_lookup (struct ui *ui, const char *name) { - struct interp_factory *factory; - struct interp *interp; - int ix; - if (name == NULL || strlen (name) == 0) return NULL; /* Only create each interpreter once per top level. */ - interp = interp_lookup_existing (ui, name); + struct interp *interp = interp_lookup_existing (ui, name); if (interp != NULL) return interp; - for (ix = 0; - VEC_iterate (interp_factory_p, interpreter_factories, ix, factory); - ++ix) - if (strcmp (factory->name, name) == 0) + for (const interp_factory &factory : interpreter_factories) + if (strcmp (factory.name, name) == 0) { - interp = factory->func (name); + interp = factory.func (name); interp_add (ui, interp); return interp; } @@ -322,6 +237,20 @@ interp_lookup (struct ui *ui, const char *name) return NULL; } +/* See interps.h. */ + +void +set_top_level_interpreter (const char *name) +{ + /* Find it. */ + struct interp *interp = interp_lookup (current_ui, name); + + if (interp == NULL) + error (_("Interpreter `%s' unrecognized"), name); + /* Install it. */ + interp_set (interp, true); +} + /* Returns the current interpreter. */ struct ui_out * @@ -331,26 +260,22 @@ interp_ui_out (struct interp *interp) if (interp == NULL) interp = ui_interp->current_interpreter; - return interp->procs->ui_out_proc (interp); + return interp->interp_ui_out (); } -int -current_interp_set_logging (int start_log, struct ui_file *out, - struct ui_file *logfile) +void +current_interp_set_logging (ui_file_up logfile, + bool logging_redirect) { struct ui_interp_info *ui_interp = get_current_interp_info (); struct interp *interp = ui_interp->current_interpreter; - if (interp == NULL - || interp->procs->set_logging_proc == NULL) - return 0; - - return interp->procs->set_logging_proc (interp, start_log, out, logfile); + interp->set_logging (std::move (logfile), logging_redirect); } /* Temporarily overrides the current interpreter. */ struct interp * -interp_set_temp (const char *name) +scoped_restore_interp::set_interp (const char *name) { struct ui_interp_info *ui_interp = get_current_interp_info (); struct interp *interp = interp_lookup (current_ui, name); @@ -361,14 +286,6 @@ interp_set_temp (const char *name) return old_interp; } -/* Returns the interpreter's cookie. */ - -void * -interp_data (struct interp *interp) -{ - return interp->data; -} - /* Returns the interpreter's name. */ const char * @@ -411,16 +328,14 @@ command_interp (void) return ui_interp->current_interpreter; } -/* Run the current command interpreter's main loop. */ +/* See interps.h. */ + void -current_interp_command_loop (void) +interp_pre_command_loop (struct interp *interp) { - struct ui_interp_info *ui_interp = get_current_interp_info (); - struct interp *interp = ui_interp->current_interpreter; - - gdb_assert (ui_interp->current_interpreter != NULL); + gdb_assert (interp != NULL); - interp->procs->command_loop_proc (interp->data); + interp->pre_command_loop (); } /* See interp.h */ @@ -428,29 +343,7 @@ current_interp_command_loop (void) int interp_supports_command_editing (struct interp *interp) { - if (interp->procs->supports_command_editing_proc != NULL) - return interp->procs->supports_command_editing_proc (interp); - return 0; -} - -int -interp_quiet_p (struct interp *interp) -{ - struct ui_interp_info *ui_interp = get_current_interp_info (); - - if (interp != NULL) - return interp->quiet_p; - else - return ui_interp->current_interpreter->quiet_p; -} - -static int -interp_set_quiet (struct interp *interp, int quiet) -{ - int old_val = interp->quiet_p; - - interp->quiet_p = quiet; - return old_val; + return interp->supports_command_editing (); } /* interp_exec - This executes COMMAND_STR in the current @@ -464,13 +357,11 @@ interp_exec (struct interp *interp, const char *command_str) struct gdb_exception ex; struct interp *save_command_interp; - gdb_assert (interp->procs->exec_proc != NULL); - /* See `command_interp' for why we do this. */ save_command_interp = ui_interp->command_interpreter; ui_interp->command_interpreter = interp; - ex = interp->procs->exec_proc (interp->data, command_str); + ex = interp->exec (command_str); ui_interp->command_interpreter = save_command_interp; @@ -497,26 +388,18 @@ clear_interpreter_hooks (void) } static void -interpreter_exec_cmd (char *args, int from_tty) +interpreter_exec_cmd (const char *args, int from_tty) { struct ui_interp_info *ui_interp = get_current_interp_info (); struct interp *old_interp, *interp_to_use; - char **prules = NULL; - char **trule = NULL; unsigned int nrules; unsigned int i; - int old_quiet, use_quiet; - struct cleanup *cleanup; if (args == NULL) error_no_arg (_("interpreter-exec command")); - prules = gdb_buildargv (args); - cleanup = make_cleanup_freeargv (prules); - - nrules = 0; - for (trule = prules; *trule != NULL; trule++) - nrules++; + gdb_argv prules (args); + nrules = prules.count (); if (nrules < 2) error (_("usage: interpreter-exec [ ... ]")); @@ -527,12 +410,7 @@ interpreter_exec_cmd (char *args, int from_tty) if (interp_to_use == NULL) error (_("Could not find interpreter \"%s\"."), prules[0]); - /* Temporarily set interpreters quiet. */ - old_quiet = interp_set_quiet (old_interp, 1); - use_quiet = interp_set_quiet (interp_to_use, 1); - - if (!interp_set (interp_to_use, 0)) - error (_("Could not switch to interpreter \"%s\"."), prules[0]); + interp_set (interp_to_use, false); for (i = 1; i < nrules; i++) { @@ -541,58 +419,30 @@ interpreter_exec_cmd (char *args, int from_tty) if (e.reason < 0) { interp_set (old_interp, 0); - interp_set_quiet (interp_to_use, use_quiet); - interp_set_quiet (old_interp, old_quiet); error (_("error in command: \"%s\"."), prules[i]); } } interp_set (old_interp, 0); - interp_set_quiet (interp_to_use, use_quiet); - interp_set_quiet (old_interp, old_quiet); - - do_cleanups (cleanup); } -/* List the possible interpreters which could complete the given text. */ -static VEC (char_ptr) * +/* See interps.h. */ + +void interpreter_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, const char *text, const char *word) { - struct interp_factory *interp; - int textlen; - VEC (char_ptr) *matches = NULL; - int ix; - - textlen = strlen (text); - for (ix = 0; - VEC_iterate (interp_factory_p, interpreter_factories, ix, interp); - ++ix) + int textlen = strlen (text); + + for (const interp_factory &interp : interpreter_factories) { - if (strncmp (interp->name, text, textlen) == 0) + if (strncmp (interp.name, text, textlen) == 0) { - char *match; - - match = (char *) xmalloc (strlen (word) + strlen (interp->name) + 1); - if (word == text) - strcpy (match, interp->name); - else if (word > text) - { - /* Return some portion of interp->name. */ - strcpy (match, interp->name + (word - text)); - } - else - { - /* Return some of text plus interp->name. */ - strncpy (match, word, text - word); - match[text - word] = '\0'; - strcat (match, interp->name); - } - VEC_safe_push (char_ptr, matches, match); + tracker.add_completion + (make_completion_match_str (interp.name, text, word)); } } - - return matches; } struct interp * @@ -603,14 +453,14 @@ top_level_interpreter (void) return ui_interp->top_level_interpreter; } -void * -top_level_interpreter_data (void) +/* See interps.h. */ + +struct interp * +current_interpreter (void) { - struct interp *interp; + struct ui_interp_info *ui_interp = get_interp_info (current_ui); - interp = top_level_interpreter (); - gdb_assert (interp != NULL); - return interp->data; + return ui_interp->current_interpreter; } /* This just adds the "interpreter-exec" command. */