* defs.h (read_command_lines, query_hook): Update prototypes.
(readline_begin_hook, readline_hook, readline_end_hook): Declare. * breakpoint.c (commands_command): Build message in temporary buffer and pass that, as well as tty control flag, to read_command_lines. * top.c (readline_begin_hook, readline_hook, readline_end_hook): Define here. (command_loop): Check for non-NULL instream before looping. (command_line_input): Use readline_hook when appropriate, to get user input from a GUI window. (read_next_line): Also build prompt if getting user input from a GUI. (recurse_read_control_structure): Fix typo in comment. (read_command_lines): Use passed in prompt and tty flag to decide how to build message. Use readline_begin_hook when appropriate, to set up a GUI interaction window. Just return head, whether NULL or not, after using readline_end_hook to complete GUI interaction. (define_command, document_command): Build message in a temporary buffer and pass it to read_command_lines, along with tty flag. * gdbtk.c (gdbtk_readline_begin, gdbtk_readline, gdbtk_readline_end): New functions. (tk_command_loop): Set instream to NULL to enable Tk user interaction. (gdbtk_init): Set readline_begin_hook, readline_hook, and readline_end_hook. * gdbtk.tcl (gdbtk_tcl_readline_begin, gdbtk_tcl_readline, gdbtk_tcl_readline_end): New functions. (tclsh): Pack scroll bar on right side of window, not left. PR 9385
This commit is contained in:
parent
4242ac27a5
commit
41756e56ee
|
@ -1,3 +1,34 @@
|
||||||
|
Sun May 19 16:49:37 1996 Fred Fish <fnf@cygnus.com>
|
||||||
|
|
||||||
|
* defs.h (read_command_lines, query_hook): Update prototypes.
|
||||||
|
(readline_begin_hook, readline_hook, readline_end_hook): Declare.
|
||||||
|
* breakpoint.c (commands_command): Build message in temporary buffer
|
||||||
|
and pass that, as well as tty control flag, to read_command_lines.
|
||||||
|
* top.c (readline_begin_hook, readline_hook, readline_end_hook):
|
||||||
|
Define here.
|
||||||
|
(command_loop): Check for non-NULL instream before looping.
|
||||||
|
(command_line_input): Use readline_hook when appropriate, to get
|
||||||
|
user input from a GUI window.
|
||||||
|
(read_next_line): Also build prompt if getting user input from a GUI.
|
||||||
|
(recurse_read_control_structure): Fix typo in comment.
|
||||||
|
(read_command_lines): Use passed in prompt and tty flag to decide how
|
||||||
|
to build message. Use readline_begin_hook when appropriate, to set
|
||||||
|
up a GUI interaction window. Just return head, whether NULL or not,
|
||||||
|
after using readline_end_hook to complete GUI interaction.
|
||||||
|
(define_command, document_command): Build message in a temporary
|
||||||
|
buffer and pass it to read_command_lines, along with tty flag.
|
||||||
|
|
||||||
|
start-sanitize-gdbtk
|
||||||
|
* gdbtk.c (gdbtk_readline_begin, gdbtk_readline, gdbtk_readline_end):
|
||||||
|
New functions.
|
||||||
|
(tk_command_loop): Set instream to NULL to enable Tk user interaction.
|
||||||
|
(gdbtk_init): Set readline_begin_hook, readline_hook,
|
||||||
|
and readline_end_hook.
|
||||||
|
* gdbtk.tcl (gdbtk_tcl_readline_begin, gdbtk_tcl_readline,
|
||||||
|
gdbtk_tcl_readline_end): New functions.
|
||||||
|
(tclsh): Pack scroll bar on right side of window, not left.
|
||||||
|
end-sanitize-gdbtk
|
||||||
|
|
||||||
Sat May 18 02:43:58 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
|
Sat May 18 02:43:58 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
|
||||||
|
|
||||||
* blockframe.c (frameless_look_for_prologue):
|
* blockframe.c (frameless_look_for_prologue):
|
||||||
|
|
|
@ -330,10 +330,9 @@ commands_command (arg, from_tty)
|
||||||
ALL_BREAKPOINTS (b)
|
ALL_BREAKPOINTS (b)
|
||||||
if (b->number == bnum)
|
if (b->number == bnum)
|
||||||
{
|
{
|
||||||
if (from_tty && input_from_terminal_p ())
|
char tmpbuf[128];
|
||||||
printf_filtered ("Type commands for when breakpoint %d is hit, one per line.\n\
|
sprintf (tmpbuf, "Type commands for when breakpoint %d is hit, one per line.", bnum);
|
||||||
End with a line saying just \"end\".\n", bnum);
|
l = read_command_lines (tmpbuf, from_tty);
|
||||||
l = read_command_lines ();
|
|
||||||
free_command_lines (&b->commands);
|
free_command_lines (&b->commands);
|
||||||
b->commands = l;
|
b->commands = l;
|
||||||
breakpoints_changed ();
|
breakpoints_changed ();
|
||||||
|
|
65
gdb/gdbtk.c
65
gdb/gdbtk.c
|
@ -183,6 +183,64 @@ gdbtk_query (query, args)
|
||||||
val = atol (interp->result);
|
val = atol (interp->result);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* VARARGS */
|
||||||
|
static void
|
||||||
|
#ifdef ANSI_PROTOTYPES
|
||||||
|
gdbtk_readline_begin (char *format, ...)
|
||||||
|
#else
|
||||||
|
gdbtk_readline_begin (va_alist)
|
||||||
|
va_dcl
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char buf[200], *merge[2];
|
||||||
|
char *command;
|
||||||
|
|
||||||
|
#ifdef ANSI_PROTOTYPES
|
||||||
|
va_start (args, format);
|
||||||
|
#else
|
||||||
|
char *format;
|
||||||
|
va_start (args);
|
||||||
|
format = va_arg (args, char *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vsprintf (buf, format, args);
|
||||||
|
merge[0] = "gdbtk_tcl_readline_begin";
|
||||||
|
merge[1] = buf;
|
||||||
|
command = Tcl_Merge (2, merge);
|
||||||
|
Tcl_Eval (interp, command);
|
||||||
|
free (command);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
gdbtk_readline (prompt)
|
||||||
|
char *prompt;
|
||||||
|
{
|
||||||
|
char *merge[2];
|
||||||
|
char *command;
|
||||||
|
|
||||||
|
merge[0] = "gdbtk_tcl_readline";
|
||||||
|
merge[1] = prompt;
|
||||||
|
command = Tcl_Merge (2, merge);
|
||||||
|
if (Tcl_Eval (interp, command) == TCL_OK)
|
||||||
|
{
|
||||||
|
return (strdup (interp -> result));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gdbtk_fputs (interp -> result, gdb_stdout);
|
||||||
|
gdbtk_fputs ("\n", gdb_stdout);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdbtk_readline_end ()
|
||||||
|
{
|
||||||
|
Tcl_Eval (interp, "gdbtk_tcl_readline_end");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
#ifdef ANSI_PROTOTYPES
|
#ifdef ANSI_PROTOTYPES
|
||||||
|
@ -1117,6 +1175,10 @@ gdbtk_call_command (cmdblk, arg, from_tty)
|
||||||
static void
|
static void
|
||||||
tk_command_loop ()
|
tk_command_loop ()
|
||||||
{
|
{
|
||||||
|
extern GDB_FILE *instream;
|
||||||
|
|
||||||
|
/* We no longer want to use stdin as the command input stream */
|
||||||
|
instream = NULL;
|
||||||
Tcl_Eval (interp, "gdbtk_tcl_preloop");
|
Tcl_Eval (interp, "gdbtk_tcl_preloop");
|
||||||
Tk_MainLoop ();
|
Tk_MainLoop ();
|
||||||
}
|
}
|
||||||
|
@ -1180,6 +1242,9 @@ gdbtk_init ()
|
||||||
interactive_hook = gdbtk_interactive;
|
interactive_hook = gdbtk_interactive;
|
||||||
target_wait_hook = gdbtk_wait;
|
target_wait_hook = gdbtk_wait;
|
||||||
call_command_hook = gdbtk_call_command;
|
call_command_hook = gdbtk_call_command;
|
||||||
|
readline_begin_hook = gdbtk_readline_begin;
|
||||||
|
readline_hook = gdbtk_readline;
|
||||||
|
readline_end_hook = gdbtk_readline_end;
|
||||||
|
|
||||||
/* Get the file descriptor for the X server */
|
/* Get the file descriptor for the X server */
|
||||||
|
|
||||||
|
|
|
@ -265,6 +265,86 @@ proc gdbtk_tcl_breakpoint {action bpnum} {
|
||||||
${action}_breakpoint $bpnum $file $line $pc
|
${action}_breakpoint $bpnum $file $line $pc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# GDB Callback:
|
||||||
|
#
|
||||||
|
# gdbtk_tcl_readline_begin (message) - Notify Tk to open an interaction
|
||||||
|
# window and start gathering user input
|
||||||
|
#
|
||||||
|
# Description:
|
||||||
|
#
|
||||||
|
# GDB calls this to notify TK that it needs to open an interaction
|
||||||
|
# window, displaying the given message, and be prepared to accept
|
||||||
|
# calls to gdbtk_tcl_readline to gather user input.
|
||||||
|
|
||||||
|
proc gdbtk_tcl_readline_begin {message} {
|
||||||
|
global readline_text
|
||||||
|
|
||||||
|
# If another readline window already exists, just bring it to the front.
|
||||||
|
if {[winfo exists .rl]} {raise .rl ; return}
|
||||||
|
|
||||||
|
# Create top level frame with scrollbar and text widget.
|
||||||
|
toplevel .rl
|
||||||
|
wm title .rl "Interaction Window"
|
||||||
|
wm iconname .rl "Input"
|
||||||
|
message .rl.msg -text $message -aspect 7500 -justify left
|
||||||
|
text .rl.text -width 80 -height 20 -setgrid true -cursor hand2 \
|
||||||
|
-yscrollcommand {.rl.scroll set}
|
||||||
|
scrollbar .rl.scroll -command {.rl.text yview}
|
||||||
|
pack .rl.msg -side top -fill x
|
||||||
|
pack .rl.scroll -side right -fill y
|
||||||
|
pack .rl.text -side left -fill both -expand true
|
||||||
|
|
||||||
|
# When the user presses return, get the text from the command start mark to the
|
||||||
|
# current insert point, stash it in the readline text variable, and update the
|
||||||
|
# command start mark to the current insert point
|
||||||
|
bind .rl.text <Return> {
|
||||||
|
set readline_text [.rl.text get cmdstart {end - 1 char}]
|
||||||
|
.rl.text mark set cmdstart insert
|
||||||
|
}
|
||||||
|
bindtags .rl.text {.rl.text Text all}
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# GDB Callback:
|
||||||
|
#
|
||||||
|
# gdbtk_tcl_readline (prompt) - Get one user input line
|
||||||
|
#
|
||||||
|
# Description:
|
||||||
|
#
|
||||||
|
# GDB calls this to get one line of input from the user interaction
|
||||||
|
# window, using "prompt" as the command line prompt.
|
||||||
|
|
||||||
|
proc gdbtk_tcl_readline {prompt} {
|
||||||
|
global readline_text
|
||||||
|
|
||||||
|
.rl.text insert end $prompt
|
||||||
|
.rl.text mark set cmdstart insert
|
||||||
|
.rl.text mark gravity cmdstart left
|
||||||
|
.rl.text see insert
|
||||||
|
|
||||||
|
# Make this window the current one for input.
|
||||||
|
focus .rl.text
|
||||||
|
grab .rl
|
||||||
|
tkwait variable readline_text
|
||||||
|
grab release .rl
|
||||||
|
return $readline_text
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# GDB Callback:
|
||||||
|
#
|
||||||
|
# gdbtk_tcl_readline_end - Terminate a user interaction
|
||||||
|
#
|
||||||
|
# Description:
|
||||||
|
#
|
||||||
|
# GDB calls this when it is done getting interactive user input.
|
||||||
|
# Destroy the interaction window.
|
||||||
|
|
||||||
|
proc gdbtk_tcl_readline_end {} {
|
||||||
|
if {[winfo exists .rl]} { destroy .rl }
|
||||||
|
}
|
||||||
|
|
||||||
proc create_breakpoints_window {} {
|
proc create_breakpoints_window {} {
|
||||||
global bpframe_lasty
|
global bpframe_lasty
|
||||||
|
|
||||||
|
@ -3149,8 +3229,8 @@ proc tclsh {} {
|
||||||
text .eval.text -width 80 -height 20 -setgrid true -cursor hand2 \
|
text .eval.text -width 80 -height 20 -setgrid true -cursor hand2 \
|
||||||
-yscrollcommand {.eval.scroll set}
|
-yscrollcommand {.eval.scroll set}
|
||||||
scrollbar .eval.scroll -command {.eval.text yview}
|
scrollbar .eval.scroll -command {.eval.text yview}
|
||||||
pack .eval.scroll -side left -fill y
|
pack .eval.scroll -side right -fill y
|
||||||
pack .eval.text -side right -fill both -expand true
|
pack .eval.text -side left -fill both -expand true
|
||||||
|
|
||||||
# Insert the tcl_prompt and initialize the cmdstart mark
|
# Insert the tcl_prompt and initialize the cmdstart mark
|
||||||
.eval.text insert insert $tcl_prompt
|
.eval.text insert insert $tcl_prompt
|
||||||
|
|
83
gdb/top.c
83
gdb/top.c
|
@ -275,7 +275,7 @@ struct cmd_list_element *showchecklist;
|
||||||
|
|
||||||
/* stdio stream that command input is being read from. Set to stdin normally.
|
/* stdio stream that command input is being read from. Set to stdin normally.
|
||||||
Set by source_command to the file we are sourcing. Set to NULL if we are
|
Set by source_command to the file we are sourcing. Set to NULL if we are
|
||||||
executing a user-defined command. */
|
executing a user-defined command or interacting via a GUI. */
|
||||||
|
|
||||||
FILE *instream;
|
FILE *instream;
|
||||||
|
|
||||||
|
@ -395,6 +395,21 @@ int (*query_hook) PARAMS (());
|
||||||
|
|
||||||
void (*flush_hook) PARAMS ((FILE *stream));
|
void (*flush_hook) PARAMS ((FILE *stream));
|
||||||
|
|
||||||
|
/* These three functions support getting lines of text from the user. They
|
||||||
|
are used in sequence. First readline_begin_hook is called with a text
|
||||||
|
string that might be (for example) a message for the user to type in a
|
||||||
|
sequence of commands to be executed at a breakpoint. If this function
|
||||||
|
calls back to a GUI, it might take this opportunity to pop up a text
|
||||||
|
interaction window with this message. Next, readline_hook is called
|
||||||
|
with a prompt that is emitted prior to collecting the user input.
|
||||||
|
It can be called multiple times. Finally, readline_end_hook is called
|
||||||
|
to notify the GUI that we are done with the interaction window and it
|
||||||
|
can close it. */
|
||||||
|
|
||||||
|
void (*readline_begin_hook) PARAMS ((char *, ...));
|
||||||
|
char * (*readline_hook) PARAMS ((char *));
|
||||||
|
void (*readline_end_hook) PARAMS ((void));
|
||||||
|
|
||||||
/* Called as appropriate to notify the interface of the specified breakpoint
|
/* Called as appropriate to notify the interface of the specified breakpoint
|
||||||
conditions. */
|
conditions. */
|
||||||
|
|
||||||
|
@ -1237,7 +1252,7 @@ command_loop ()
|
||||||
extern int display_time;
|
extern int display_time;
|
||||||
extern int display_space;
|
extern int display_space;
|
||||||
|
|
||||||
while (!feof (instream))
|
while (instream && !feof (instream))
|
||||||
{
|
{
|
||||||
if (window_hook && instream == stdin)
|
if (window_hook && instream == stdin)
|
||||||
(*window_hook) (instream, prompt);
|
(*window_hook) (instream, prompt);
|
||||||
|
@ -1962,11 +1977,18 @@ command_line_input (prrompt, repeat, annotation_suffix)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't use fancy stuff if not talking to stdin. */
|
/* Don't use fancy stuff if not talking to stdin. */
|
||||||
if (command_editing_p && instream == stdin
|
if (readline_hook && instream == NULL)
|
||||||
&& ISATTY (instream))
|
{
|
||||||
|
rl = (*readline_hook) (local_prompt);
|
||||||
|
}
|
||||||
|
else if (command_editing_p && instream == stdin && ISATTY (instream))
|
||||||
|
{
|
||||||
rl = readline (local_prompt);
|
rl = readline (local_prompt);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
rl = gdb_readline (local_prompt);
|
rl = gdb_readline (local_prompt);
|
||||||
|
}
|
||||||
|
|
||||||
if (annotation_level > 1 && instream == stdin)
|
if (annotation_level > 1 && instream == stdin)
|
||||||
{
|
{
|
||||||
|
@ -2138,7 +2160,7 @@ read_next_line (command)
|
||||||
error ("Control nesting too deep!\n");
|
error ("Control nesting too deep!\n");
|
||||||
|
|
||||||
/* Set a prompt based on the nesting of the control commands. */
|
/* Set a prompt based on the nesting of the control commands. */
|
||||||
if (instream == stdin)
|
if (instream == stdin || (instream == 0 && readline_hook != NULL))
|
||||||
{
|
{
|
||||||
for (i = 0; i < control_level; i++)
|
for (i = 0; i < control_level; i++)
|
||||||
control_prompt[i] = ' ';
|
control_prompt[i] = ' ';
|
||||||
|
@ -2220,7 +2242,7 @@ read_next_line (command)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Recursively read in the control structures and create a command_line
|
/* Recursively read in the control structures and create a command_line
|
||||||
tructure from them.
|
structure from them.
|
||||||
|
|
||||||
The parent_control parameter is the control structure in which the
|
The parent_control parameter is the control structure in which the
|
||||||
following commands are nested. */
|
following commands are nested. */
|
||||||
|
@ -2331,19 +2353,34 @@ recurse_read_control_structure (current_cmd)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read lines from the input stream and accumulate them in a chain of
|
||||||
|
struct command_line's, which is then returned. For input from a
|
||||||
|
terminal, the special command "end" is used to mark the end of the
|
||||||
|
input, and is not included in the returned chain of commands. */
|
||||||
|
|
||||||
/* Read lines from the input stream
|
#define END_MESSAGE "End with a line saying just \"end\"."
|
||||||
and accumulate them in a chain of struct command_line's
|
|
||||||
which is then returned. */
|
|
||||||
|
|
||||||
struct command_line *
|
struct command_line *
|
||||||
read_command_lines ()
|
read_command_lines (prompt, from_tty)
|
||||||
|
char *prompt;
|
||||||
|
int from_tty;
|
||||||
{
|
{
|
||||||
struct command_line *head, *tail, *next;
|
struct command_line *head, *tail, *next;
|
||||||
struct cleanup *old_chain;
|
struct cleanup *old_chain;
|
||||||
enum command_control_type ret;
|
enum command_control_type ret;
|
||||||
enum misc_command_type val;
|
enum misc_command_type val;
|
||||||
|
|
||||||
|
if (readline_begin_hook)
|
||||||
|
{
|
||||||
|
/* Note - intentional to merge messages with no newline */
|
||||||
|
(*readline_begin_hook) ("%s %s\n", prompt, END_MESSAGE);
|
||||||
|
}
|
||||||
|
else if (from_tty && input_from_terminal_p ())
|
||||||
|
{
|
||||||
|
printf_unfiltered ("%s\n%s\n", prompt, END_MESSAGE);
|
||||||
|
gdb_flush (gdb_stdout);
|
||||||
|
}
|
||||||
|
|
||||||
head = tail = NULL;
|
head = tail = NULL;
|
||||||
old_chain = NULL;
|
old_chain = NULL;
|
||||||
|
|
||||||
|
@ -2397,13 +2434,16 @@ read_command_lines ()
|
||||||
if (ret != invalid_control)
|
if (ret != invalid_control)
|
||||||
{
|
{
|
||||||
discard_cleanups (old_chain);
|
discard_cleanups (old_chain);
|
||||||
return head;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
do_cleanups (old_chain);
|
do_cleanups (old_chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
if (readline_end_hook)
|
||||||
|
{
|
||||||
|
(*readline_end_hook) ();
|
||||||
|
}
|
||||||
|
return (head);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free a chain of struct command_line's. */
|
/* Free a chain of struct command_line's. */
|
||||||
|
@ -2579,6 +2619,7 @@ define_command (comname, from_tty)
|
||||||
register struct command_line *cmds;
|
register struct command_line *cmds;
|
||||||
register struct cmd_list_element *c, *newc, *hookc = 0;
|
register struct cmd_list_element *c, *newc, *hookc = 0;
|
||||||
char *tem = comname;
|
char *tem = comname;
|
||||||
|
char tmpbuf[128];
|
||||||
#define HOOK_STRING "hook-"
|
#define HOOK_STRING "hook-"
|
||||||
#define HOOK_LEN 5
|
#define HOOK_LEN 5
|
||||||
|
|
||||||
|
@ -2626,15 +2667,9 @@ define_command (comname, from_tty)
|
||||||
for (tem = comname; *tem; tem++)
|
for (tem = comname; *tem; tem++)
|
||||||
if (isupper(*tem)) *tem = tolower(*tem);
|
if (isupper(*tem)) *tem = tolower(*tem);
|
||||||
|
|
||||||
if (from_tty)
|
|
||||||
{
|
|
||||||
printf_unfiltered ("Type commands for definition of \"%s\".\n\
|
|
||||||
End with a line saying just \"end\".\n", comname);
|
|
||||||
gdb_flush (gdb_stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
control_level = 0;
|
control_level = 0;
|
||||||
cmds = read_command_lines ();
|
sprintf (tmpbuf, "Type commands for definition of \"%s\".", comname);
|
||||||
|
cmds = read_command_lines (tmpbuf, from_tty);
|
||||||
|
|
||||||
if (c && c->class == class_user)
|
if (c && c->class == class_user)
|
||||||
free_command_lines (&c->user_commands);
|
free_command_lines (&c->user_commands);
|
||||||
|
@ -2661,6 +2696,7 @@ document_command (comname, from_tty)
|
||||||
struct command_line *doclines;
|
struct command_line *doclines;
|
||||||
register struct cmd_list_element *c;
|
register struct cmd_list_element *c;
|
||||||
char *tem = comname;
|
char *tem = comname;
|
||||||
|
char tmpbuf[128];
|
||||||
|
|
||||||
validate_comname (comname);
|
validate_comname (comname);
|
||||||
|
|
||||||
|
@ -2669,11 +2705,8 @@ document_command (comname, from_tty)
|
||||||
if (c->class != class_user)
|
if (c->class != class_user)
|
||||||
error ("Command \"%s\" is built-in.", comname);
|
error ("Command \"%s\" is built-in.", comname);
|
||||||
|
|
||||||
if (from_tty)
|
sprintf (tmpbuf, "Type documentation for \"%s\".", comname);
|
||||||
printf_unfiltered ("Type documentation for \"%s\".\n\
|
doclines = read_command_lines (tmpbuf, from_tty);
|
||||||
End with a line saying just \"end\".\n", comname);
|
|
||||||
|
|
||||||
doclines = read_command_lines ();
|
|
||||||
|
|
||||||
if (c->doc) free (c->doc);
|
if (c->doc) free (c->doc);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue