Re: Use external editor in 'commands' command

dgutson
2009-01-22T03:25:16Z

Hi Alfredo,

I find the function too long. You might want to split it in more
functions, such as one to export a bp to a text file, another one to import
it, etc., so this function becomes more modular.

My 2 cents.

Daniel.

Alfredo Ortega wrote:
>
> 2009/1/14 Eli Zaretskii <eliz@gnu.org>
>>
>> > Date: Wed, 14 Jan 2009 19:47:50 -0200
>> > From: Alfredo Ortega <ortegaalfredo@gmail.com>
>> >
>> > I have made a small patch to the 'commands' command to allow the use
>> > of an external editor to add or modify commands. This is convenient if
>> > you are dealing with many commands per breakpoint.
>> > The editor follows the behavior of the 'edit' command (/bin/ex by
>> > default, or the 'EDITOR' environment variable)
>> >
>> > Tested on i686-pc-linux-gnu, please tell me what do you think about it.
>>
>> If this is accepted, we will need a suitable patch for the manual.
>
> I see. This updated patch contains my proposed documentation changes
> to gdb.texinfo and refcard.tex. I hope that the patch format is
> adequate
>
> diff -upr OLD/gdb/breakpoint.c NEW/gdb/breakpoint.c
> --- OLD/gdb/breakpoint.c 2009-01-14 17:46:26.000000000 -0200
> +++ NEW/gdb/breakpoint.c 2009-01-14 19:32:40.000000000 -0200
> @@ -585,14 +585,20 @@ condition_command (char *arg, int from_t
> error (_("No breakpoint number %d."), bnum);
> }
>
> +#define COMMANDS_EDCOMMAND "edit"
> +
> static void
> commands_command (char *arg, int from_tty)
> {
> struct breakpoint *b;
> char *p;
> - int bnum;
> + int bnum,fsize;
> struct command_line *l;
> -
> + char vitmp[50];
> + char cmdline[100];
> + FILE *tmpstream=NULL;
> + char *editor;
> +
> /* If we allowed this, we would have problems with when to
> free the storage, if we change the commands currently
> being read from. */
> @@ -602,6 +608,41 @@ commands_command (char *arg, int from_tt
>
> p = arg;
> bnum = get_number (&p);
> + vitmp[0]=0;
> + /* Edit commands with external editor */
> + if (!strcmp(COMMANDS_EDCOMMAND,p)) {
> + /* Generates the temporal file name*/
> + /* vitmp = tempnam(NULL,".gdb"); this is more secure according to man
> mkstemp, but gcc complains... */
> + p=NULL;
> + strcpy(vitmp,"/tmp/.gdbXXXXXX");
> + if (mkstemp(vitmp)<0) return;
> + ALL_BREAKPOINTS (b)
> + if (b->number == bnum)
> + {
> + if (&b->commands) {
> + /* commands exists, must dump them to the temporal file */
> + tmpstream=fopen(vitmp,"w");
> + l = b->commands;
> + while(l) {
> + fsize=0;
> + fsize+=fwrite(l->line,1,strlen(l->line),tmpstream);
> + fsize+=fwrite("\n",1,strlen("\n"),tmpstream);
> + if (fsize<strlen(l->line)+1) {
> + fclose(tmpstream);
> + unlink(vitmp);
> + return;
> + };
> + l = l->next;
> + }
> + fclose(tmpstream);
> + }
> + /* Edit the file */
> + if ((editor = (char *) getenv ("EDITOR")) == NULL)
> + editor = "/bin/ex";
> + snprintf(cmdline,sizeof(cmdline),"%s \"%s\"",editor,vitmp);
> + if (system(cmdline)<0) return;
> + }
> + }
>
> if (p && *p)
> error (_("Unexpected extra arguments following breakpoint number."));
> @@ -609,17 +650,31 @@ commands_command (char *arg, int from_tt
> ALL_BREAKPOINTS (b)
> if (b->number == bnum)
> {
> - char *tmpbuf = xstrprintf ("Type commands for when breakpoint %d is hit,
> one per line.",
> + if(vitmp[0]) {
> + /* redirect instream */
> + tmpstream=instream;
> + instream=fopen(vitmp,"r");
> + l = read_command_lines (NULL, from_tty, 1);
> + }
> + else {
> + char *tmpbuf = xstrprintf ("Type commands for when breakpoint %d is
> hit, one per line.",
> bnum);
> - struct cleanup *cleanups = make_cleanup (xfree, tmpbuf);
> - l = read_command_lines (tmpbuf, from_tty, 1);
> - do_cleanups (cleanups);
> + struct cleanup *cleanups = make_cleanup (xfree, tmpbuf);
> + l = read_command_lines (tmpbuf, from_tty, 1);
> + do_cleanups (cleanups);
> + }
> free_command_lines (&b->commands);
> b->commands = l;
> breakpoints_changed ();
> observer_notify_breakpoint_modified (b->number);
> + if(vitmp[0]) {
> + /* restore instream */
> + instream=tmpstream;
> + /* erase temporal file */
> + unlink(vitmp);
> + }
> return;
> - }
> + }
> error (_("No breakpoint number %d."), bnum);
> }
>
> @@ -8103,6 +8158,9 @@ Usage is `ignore N COUNT'."));
> add_com ("commands", class_breakpoint, commands_command, _("\
> Set commands to be executed when a breakpoint is hit.\n\
> Give breakpoint number as argument after \"commands\".\n\
> +After the command number you can enter the `edit' keyword, and then you
> can \n\
> +use the external editor to add or modify commands.\n\
> +Uses EDITOR environment variable contents as editor (or ex as
> default).\n\
> With no argument, the targeted breakpoint is the last one set.\n\
> The commands themselves follow starting on the next line.\n\
> Type a line containing \"end\" to indicate the end of them.\n\
> diff -upr OLD/gdb/doc/gdb.texinfo NEW/gdb/doc/gdb.texinfo
> --- OLD/gdb/doc/gdb.texinfo 2009-01-14 17:46:18.000000000 -0200
> +++ NEW/gdb/doc/gdb.texinfo 2009-01-14 22:21:29.000000000 -0200
> @@ -3976,6 +3976,8 @@ follow it immediately with @code{end}; t
> With no @var{bnum} argument, @code{commands} refers to the last
> breakpoint, watchpoint, or catchpoint set (not to the breakpoint most
> recently encountered).
> +@item commands @r{[}@var{bnum}@r{]} edit
> +This spawns an external editor for adding or editing commands. the final
> @code{end} is not necessary in this case. @xref{Choosing your Editor}.
> @end table
>
> Pressing @key{RET} as a means of repeating the last @value{GDBN} command
> is
> @@ -5587,6 +5589,7 @@ Edit the file containing @var{function}
>
> @end table
>
> +@node Choosing your Editor
> @subsection Choosing your Editor
> You can customize @value{GDBN} to use any editor you want
> @footnote{
> diff -upr OLD/gdb/doc/refcard.tex NEW/gdb/doc/refcard.tex
> --- OLD/gdb/doc/refcard.tex 2009-01-14 17:46:18.000000000 -0200
> +++ NEW/gdb/doc/refcard.tex 2009-01-14 22:21:35.000000000 -0200
> @@ -355,10 +355,10 @@ delete when reached
> ignore {\it n} {\it count}&ignore breakpoint {\it n}, {\it count}
> times\cr
> \cr
> -commands {\it n}\par
> +commands {\it n} \opt{{\it edit}} \par
> \qquad \opt{\tt silent}\par
> -\qquad {\it command-list}&execute GDB {\it command-list} every time
> breakpoint {\it n} is reached. \opt{{\tt silent} suppresses default
> -display}\cr
> +\qquad {\it command-list}&execute GDB {\it command-list} every time
> breakpoint {\it n} is reached. \opt{{\tt silent} suppresses default
> display} \opt{{\tt edit} use external editor for commands}
> +\cr
> end&end of {\it command-list}\cr
> \endsec
>
>
>

--
View this message in context: http://www.nabble.com/Use-external-editor-in-%27commands%27-command-tp21465971p21593783.html
Sent from the Sourceware - gdb-patches mailing list archive at Nabble.com.