make-dfsg/commands.c

563 lines
13 KiB
C
Raw Normal View History

1991-10-08 20:20:29 +00:00
/* Command processing for GNU Make.
1997-08-27 20:30:54 +00:00
Copyright (C) 1988,89,91,92,93,94,95,96,97 Free Software Foundation, Inc.
1991-10-08 20:20:29 +00:00
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Make is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Make; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
1991-10-08 20:20:29 +00:00
#include "make.h"
#include "dep.h"
#include "filedef.h"
1991-10-08 20:20:29 +00:00
#include "variable.h"
#include "job.h"
#include "commands.h"
1991-10-08 20:20:29 +00:00
extern int remote_kill PARAMS ((int id, int sig));
1991-10-08 20:20:29 +00:00
1992-06-11 05:12:44 +00:00
#ifndef HAVE_UNISTD_H
1991-10-08 20:20:29 +00:00
extern int getpid ();
#endif
/* Set FILE's automatic variables up. */
static void
set_file_variables (file)
register struct file *file;
{
register char *p;
char *at, *percent, *star, *less;
#ifndef NO_ARCHIVES
/* If the target is an archive member `lib(member)',
then $@ is `lib' and $% is `member'. */
if (ar_name (file->name))
{
1993-02-21 20:05:54 +00:00
unsigned int len;
p = strchr (file->name, '(');
1993-01-28 23:01:09 +00:00
at = (char *) alloca (p - file->name + 1);
bcopy (file->name, at, p - file->name);
at[p - file->name] = '\0';
1993-02-21 20:05:54 +00:00
len = strlen (p + 1);
percent = (char *) alloca (len);
bcopy (p + 1, percent, len - 1);
percent[len - 1] = '\0';
1991-10-08 20:20:29 +00:00
}
else
#endif /* NO_ARCHIVES. */
{
1993-01-28 23:01:09 +00:00
at = file->name;
1991-10-08 20:20:29 +00:00
percent = "";
}
/* $* is the stem from an implicit or static pattern rule. */
if (file->stem == 0)
{
/* In Unix make, $* is set to the target name with
any suffix in the .SUFFIXES list stripped off for
explicit rules. We store this in the `stem' member. */
register struct dep *d;
1992-03-31 00:24:58 +00:00
char *name;
unsigned int len;
#ifndef NO_ARCHIVES
if (ar_name (file->name))
{
name = strchr (file->name, '(') + 1;
1992-03-31 00:24:58 +00:00
len = strlen (name) - 1;
}
else
#endif
{
name = file->name;
len = strlen (name);
}
1991-10-08 20:20:29 +00:00
for (d = enter_file (".SUFFIXES")->deps; d != 0; d = d->next)
{
unsigned int slen = strlen (dep_name (d));
if (len > slen && strneq (dep_name (d), name + (len - slen), slen))
1991-10-08 20:20:29 +00:00
{
1992-03-31 00:24:58 +00:00
file->stem = savestring (name, len - slen);
1991-10-08 20:20:29 +00:00
break;
}
}
if (d == 0)
file->stem = "";
}
star = file->stem;
/* $< is the first dependency. */
less = file->deps != 0 ? dep_name (file->deps) : "";
if (file->cmds == default_file->cmds)
/* This file got its commands from .DEFAULT.
In this case $< is the same as $@. */
less = at;
1993-01-28 23:01:09 +00:00
#define DEFINE_VARIABLE(name, len, value) \
(void) define_variable_for_file (name,len,value,o_automatic,0,file)
1991-10-08 20:20:29 +00:00
1993-01-28 23:01:09 +00:00
/* Define the variables. */
DEFINE_VARIABLE ("<", 1, less);
DEFINE_VARIABLE ("*", 1, star);
DEFINE_VARIABLE ("@", 1, at);
DEFINE_VARIABLE ("%", 1, percent);
1991-10-08 20:20:29 +00:00
/* Compute the values for $^, $+, and $?. */
1991-10-08 20:20:29 +00:00
{
register unsigned int qmark_len, plus_len;
char *caret_value, *plus_value;
1993-01-28 23:01:09 +00:00
register char *cp;
char *qmark_value;
register char *qp;
1991-10-08 20:20:29 +00:00
register struct dep *d;
unsigned int len;
/* Compute first the value for $+, which is supposed to contain
duplicate dependencies as they were listed in the makefile. */
plus_len = 0;
for (d = file->deps; d != 0; d = d->next)
plus_len += strlen (dep_name (d)) + 1;
len = plus_len == 0 ? 1 : plus_len;
cp = plus_value = (char *) alloca (len);
qmark_len = plus_len; /* Will be this or less. */
1991-10-08 20:20:29 +00:00
for (d = file->deps; d != 0; d = d->next)
{
char *c = dep_name (d);
#ifndef NO_ARCHIVES
if (ar_name (c))
{
c = strchr (c, '(') + 1;
len = strlen (c) - 1;
}
else
#endif
len = strlen (c);
bcopy (c, cp, len);
cp += len;
#if VMS
*cp++ = ',';
#else
*cp++ = ' ';
#endif
if (! d->changed)
qmark_len -= len + 1; /* Don't space in $? for this one. */
1991-10-08 20:20:29 +00:00
}
/* Kill the last space and define the variable. */
cp[cp > plus_value ? -1 : 0] = '\0';
DEFINE_VARIABLE ("+", 1, plus_value);
/* Make sure that no dependencies are repeated. This does not
really matter for the purpose of updating targets, but it
might make some names be listed twice for $^ and $?. */
uniquize_deps (file->deps);
/* Compute the values for $^ and $?. */
cp = caret_value = plus_value; /* Reuse the buffer; it's big enough. */
1991-10-08 20:20:29 +00:00
len = qmark_len == 0 ? 1 : qmark_len;
1992-10-09 17:50:59 +00:00
qp = qmark_value = (char *) alloca (len);
1991-10-08 20:20:29 +00:00
for (d = file->deps; d != 0; d = d->next)
{
1993-01-28 23:01:09 +00:00
char *c = dep_name (d);
1992-07-13 21:51:47 +00:00
#ifndef NO_ARCHIVES
if (ar_name (c))
{
c = strchr (c, '(') + 1;
1992-07-13 21:51:47 +00:00
len = strlen (c) - 1;
}
else
#endif
len = strlen (c);
1991-10-08 20:20:29 +00:00
bcopy (c, cp, len);
cp += len;
#if VMS
*cp++ = ',';
#else
1991-10-08 20:20:29 +00:00
*cp++ = ' ';
#endif
1991-10-08 20:20:29 +00:00
if (d->changed)
{
bcopy (c, qp, len);
qp += len;
#if VMS
*qp++ = ',';
#else
1991-10-08 20:20:29 +00:00
*qp++ = ' ';
#endif
1991-10-08 20:20:29 +00:00
}
}
/* Kill the last spaces and define the variables. */
cp[cp > caret_value ? -1 : 0] = '\0';
DEFINE_VARIABLE ("^", 1, caret_value);
qp[qp > qmark_value ? -1 : 0] = '\0';
DEFINE_VARIABLE ("?", 1, qmark_value);
}
#undef DEFINE_VARIABLE
}
1993-02-05 22:34:51 +00:00
/* Chop CMDS up into individual command lines if necessary.
Also set the `lines_flag' and `any_recurse' members. */
1991-10-08 20:20:29 +00:00
void
chop_commands (cmds)
register struct commands *cmds;
{
register char *p;
unsigned int nlines, idx;
char **lines;
/* If we don't have any commands,
or we already parsed them, never mind. */
if (!cmds || cmds->command_lines != 0)
return;
/* Chop CMDS->commands up into lines in CMDS->command_lines.
1993-02-05 22:34:51 +00:00
Also set the corresponding CMDS->lines_flags elements,
1991-10-08 20:20:29 +00:00
and the CMDS->any_recurse flag. */
nlines = 5;
lines = (char **) xmalloc (5 * sizeof (char *));
idx = 0;
p = cmds->commands;
while (*p != '\0')
{
char *end = p;
find_end:;
end = strchr (end, '\n');
if (end == 0)
end = p + strlen (p);
else if (end > p && end[-1] == '\\')
{
int backslash = 1;
register char *b;
for (b = end - 2; b >= p && *b == '\\'; --b)
backslash = !backslash;
if (backslash)
{
++end;
goto find_end;
}
}
if (idx == nlines)
{
nlines += 2;
lines = (char **) xrealloc ((char *) lines,
nlines * sizeof (char *));
}
lines[idx++] = savestring (p, end - p);
p = end;
if (*p != '\0')
++p;
}
1991-10-08 20:20:29 +00:00
if (idx != nlines)
{
nlines = idx;
lines = (char **) xrealloc ((char *) lines,
nlines * sizeof (char *));
}
1991-10-08 20:20:29 +00:00
cmds->ncommand_lines = nlines;
cmds->command_lines = lines;
1993-02-05 22:34:51 +00:00
cmds->any_recurse = 0;
cmds->lines_flags = (char *) xmalloc (nlines);
for (idx = 0; idx < nlines; ++idx)
{
int flags = 0;
for (p = lines[idx];
isblank (*p) || *p == '-' || *p == '@' || *p == '+';
++p)
switch (*p)
{
case '+':
flags |= COMMANDS_RECURSE;
break;
case '@':
flags |= COMMANDS_SILENT;
break;
case '-':
flags |= COMMANDS_NOERROR;
break;
}
if (!(flags & COMMANDS_RECURSE))
{
unsigned int len = strlen (p);
if (sindex (p, len, "$(MAKE)", 7) != 0
|| sindex (p, len, "${MAKE}", 7) != 0)
flags |= COMMANDS_RECURSE;
}
cmds->lines_flags[idx] = flags;
cmds->any_recurse |= flags & COMMANDS_RECURSE;
1991-10-08 20:20:29 +00:00
}
}
/* Execute the commands to remake FILE. If they are currently executing,
return or have already finished executing, just return. Otherwise,
fork off a child process to run the first command line in the sequence. */
void
execute_file_commands (file)
struct file *file;
{
register char *p;
/* Don't go through all the preparations if
the commands are nothing but whitespace. */
for (p = file->cmds->commands; *p != '\0'; ++p)
if (!isspace ((unsigned char)*p) && *p != '-' && *p != '@')
1991-10-08 20:20:29 +00:00
break;
if (*p == '\0')
{
/* If there are no commands, assume everything worked. */
set_command_state (file, cs_running);
1991-10-08 20:20:29 +00:00
file->update_status = 0;
notice_finished_file (file);
return;
}
/* First set the automatic variables according to this file. */
initialize_file_variables (file, 0);
1991-10-08 20:20:29 +00:00
set_file_variables (file);
/* Start the commands running. */
new_job (file);
}
1993-05-06 21:30:42 +00:00
/* This is set while we are inside fatal_error_signal,
so things can avoid nonreentrant operations. */
int handling_fatal_signal = 0;
1991-10-08 20:20:29 +00:00
/* Handle fatal signals. */
1992-06-11 05:12:44 +00:00
RETSIGTYPE
1991-10-08 20:20:29 +00:00
fatal_error_signal (sig)
int sig;
{
1997-04-07 07:21:16 +00:00
#ifdef __MSDOS__
extern int dos_status, dos_command_running;
if (dos_command_running)
{
/* That was the child who got the signal, not us. */
dos_status |= (sig << 8);
return;
}
remove_intermediates (1);
1999-06-14 05:26:28 +00:00
exit (EXIT_FAILURE);
1997-04-07 07:21:16 +00:00
#else /* not __MSDOS__ */
Thu May 9 13:54:49 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> * GNUmakefile (globfiles): Add AmigaDOS support files. (distfiles): Add $(amigafiles). (amigafiles): New variable. Thu Nov 7 10:18:16 1995 Aaron Digulla <digulla@fh-konstanz.de> * Added Amiga support in commands.c, dir.c, function.c, job.c, main.c, make.h, read.c, remake.c * commands.c: Amiga has neither SIGHUP nor SIGQUIT * dir.c: Amiga has filenames with Upper- and Lowercase, but "FileName" is the same as "filename". Added strieq() which is use to compare filenames. This is like streq() on all other systems. Also there is no such thing as "." under AmigaDOS. * function.c: On Amiga, the environment is not passed as envp, there are no pipes and Amiga can't fork. Use my own function to create a new child. * job.c: default_shell is "" (The system automatically chooses a shell for me). Have to use the same workaround as MSDOS for running batch commands. Added HAVE_SYS_PARAM_H. NOFILE isn't known on Amiga. Cloned code to run children from MSDOS. Own version of sh_chars[] and sh_cmds[]. No dup2() or dup() on Amiga. * main.c: Force stack to 20000 bytes. Read environment from ENV: device. On Amiga, exec_command() does return, so I exit() afterwards. * make.h: Added strieq() to compare filenames. * read.c: Amiga needs special extension to have passwd. Only one include-dir. "Makefile" and "makefile" are the same. Added "SMakefile". Added special code to handle device names (xxx:) and "./" in rules. * remake.c: Only one lib-dir. Amiga link-libs are named "%s.lib" instead of "lib%s.a". * main.c, rule.c, variable.c: Avoid floats at all costs. * vpath.c: Get rid of as many alloca()s as possible.
1996-05-09 18:02:06 +00:00
#ifdef _AMIGA
1997-04-07 07:21:16 +00:00
remove_intermediates (1);
Thu May 9 13:54:49 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> * GNUmakefile (globfiles): Add AmigaDOS support files. (distfiles): Add $(amigafiles). (amigafiles): New variable. Thu Nov 7 10:18:16 1995 Aaron Digulla <digulla@fh-konstanz.de> * Added Amiga support in commands.c, dir.c, function.c, job.c, main.c, make.h, read.c, remake.c * commands.c: Amiga has neither SIGHUP nor SIGQUIT * dir.c: Amiga has filenames with Upper- and Lowercase, but "FileName" is the same as "filename". Added strieq() which is use to compare filenames. This is like streq() on all other systems. Also there is no such thing as "." under AmigaDOS. * function.c: On Amiga, the environment is not passed as envp, there are no pipes and Amiga can't fork. Use my own function to create a new child. * job.c: default_shell is "" (The system automatically chooses a shell for me). Have to use the same workaround as MSDOS for running batch commands. Added HAVE_SYS_PARAM_H. NOFILE isn't known on Amiga. Cloned code to run children from MSDOS. Own version of sh_chars[] and sh_cmds[]. No dup2() or dup() on Amiga. * main.c: Force stack to 20000 bytes. Read environment from ENV: device. On Amiga, exec_command() does return, so I exit() afterwards. * make.h: Added strieq() to compare filenames. * read.c: Amiga needs special extension to have passwd. Only one include-dir. "Makefile" and "makefile" are the same. Added "SMakefile". Added special code to handle device names (xxx:) and "./" in rules. * remake.c: Only one lib-dir. Amiga link-libs are named "%s.lib" instead of "lib%s.a". * main.c, rule.c, variable.c: Avoid floats at all costs. * vpath.c: Get rid of as many alloca()s as possible.
1996-05-09 18:02:06 +00:00
if (sig == SIGINT)
fputs (_("*** Break.\n"), stderr);
Thu May 9 13:54:49 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> * GNUmakefile (globfiles): Add AmigaDOS support files. (distfiles): Add $(amigafiles). (amigafiles): New variable. Thu Nov 7 10:18:16 1995 Aaron Digulla <digulla@fh-konstanz.de> * Added Amiga support in commands.c, dir.c, function.c, job.c, main.c, make.h, read.c, remake.c * commands.c: Amiga has neither SIGHUP nor SIGQUIT * dir.c: Amiga has filenames with Upper- and Lowercase, but "FileName" is the same as "filename". Added strieq() which is use to compare filenames. This is like streq() on all other systems. Also there is no such thing as "." under AmigaDOS. * function.c: On Amiga, the environment is not passed as envp, there are no pipes and Amiga can't fork. Use my own function to create a new child. * job.c: default_shell is "" (The system automatically chooses a shell for me). Have to use the same workaround as MSDOS for running batch commands. Added HAVE_SYS_PARAM_H. NOFILE isn't known on Amiga. Cloned code to run children from MSDOS. Own version of sh_chars[] and sh_cmds[]. No dup2() or dup() on Amiga. * main.c: Force stack to 20000 bytes. Read environment from ENV: device. On Amiga, exec_command() does return, so I exit() afterwards. * make.h: Added strieq() to compare filenames. * read.c: Amiga needs special extension to have passwd. Only one include-dir. "Makefile" and "makefile" are the same. Added "SMakefile". Added special code to handle device names (xxx:) and "./" in rules. * remake.c: Only one lib-dir. Amiga link-libs are named "%s.lib" instead of "lib%s.a". * main.c, rule.c, variable.c: Avoid floats at all costs. * vpath.c: Get rid of as many alloca()s as possible.
1996-05-09 18:02:06 +00:00
exit (10);
1997-04-07 07:21:16 +00:00
#else /* not Amiga */
1993-05-06 21:30:42 +00:00
handling_fatal_signal = 1;
/* Set the handling for this signal to the default.
It is blocked now while we run this handler. */
1991-10-08 20:20:29 +00:00
signal (sig, SIG_DFL);
/* A termination signal won't be sent to the entire
process group, but it means we want to kill the children. */
if (sig == SIGTERM)
{
register struct child *c;
for (c = children; c != 0; c = c->next)
if (!c->remote)
(void) kill (c->pid, SIGTERM);
}
/* If we got a signal that means the user
wanted to kill make, remove pending targets. */
Thu May 9 13:54:49 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> * GNUmakefile (globfiles): Add AmigaDOS support files. (distfiles): Add $(amigafiles). (amigafiles): New variable. Thu Nov 7 10:18:16 1995 Aaron Digulla <digulla@fh-konstanz.de> * Added Amiga support in commands.c, dir.c, function.c, job.c, main.c, make.h, read.c, remake.c * commands.c: Amiga has neither SIGHUP nor SIGQUIT * dir.c: Amiga has filenames with Upper- and Lowercase, but "FileName" is the same as "filename". Added strieq() which is use to compare filenames. This is like streq() on all other systems. Also there is no such thing as "." under AmigaDOS. * function.c: On Amiga, the environment is not passed as envp, there are no pipes and Amiga can't fork. Use my own function to create a new child. * job.c: default_shell is "" (The system automatically chooses a shell for me). Have to use the same workaround as MSDOS for running batch commands. Added HAVE_SYS_PARAM_H. NOFILE isn't known on Amiga. Cloned code to run children from MSDOS. Own version of sh_chars[] and sh_cmds[]. No dup2() or dup() on Amiga. * main.c: Force stack to 20000 bytes. Read environment from ENV: device. On Amiga, exec_command() does return, so I exit() afterwards. * make.h: Added strieq() to compare filenames. * read.c: Amiga needs special extension to have passwd. Only one include-dir. "Makefile" and "makefile" are the same. Added "SMakefile". Added special code to handle device names (xxx:) and "./" in rules. * remake.c: Only one lib-dir. Amiga link-libs are named "%s.lib" instead of "lib%s.a". * main.c, rule.c, variable.c: Avoid floats at all costs. * vpath.c: Get rid of as many alloca()s as possible.
1996-05-09 18:02:06 +00:00
if (sig == SIGTERM || sig == SIGINT
#ifdef SIGHUP
|| sig == SIGHUP
#endif
#ifdef SIGQUIT
|| sig == SIGQUIT
#endif
)
1991-10-08 20:20:29 +00:00
{
register struct child *c;
/* Remote children won't automatically get signals sent
to the process group, so we must send them. */
for (c = children; c != 0; c = c->next)
if (c->remote)
(void) remote_kill (c->pid, sig);
for (c = children; c != 0; c = c->next)
delete_child_targets (c);
/* Clean up the children. We don't just use the call below because
we don't want to print the "Waiting for children" message. */
1992-04-21 07:50:13 +00:00
while (job_slots_used > 0)
reap_children (1, 0);
1991-10-08 20:20:29 +00:00
}
else
/* Wait for our children to die. */
1992-04-21 07:50:13 +00:00
while (job_slots_used > 0)
reap_children (1, 1);
1991-10-08 20:20:29 +00:00
/* Delete any non-precious intermediate files that were made. */
remove_intermediates (1);
#ifdef SIGQUIT
1991-10-08 20:20:29 +00:00
if (sig == SIGQUIT)
/* We don't want to send ourselves SIGQUIT, because it will
cause a core dump. Just exit instead. */
exit (EXIT_FAILURE);
#endif
1991-10-08 20:20:29 +00:00
/* Signal the same code; this time it will really be fatal. The signal
will be unblocked when we return and arrive then to kill us. */
1991-10-08 20:20:29 +00:00
if (kill (getpid (), sig) < 0)
pfatal_with_name ("kill");
1997-04-07 07:21:16 +00:00
#endif /* not Amiga */
#endif /* not __MSDOS__ */
1991-10-08 20:20:29 +00:00
}
1994-01-25 21:51:25 +00:00
/* Delete FILE unless it's precious or not actually a file (phony),
and it has changed on disk since we last stat'd it. */
static void
delete_target (file, on_behalf_of)
struct file *file;
char *on_behalf_of;
{
1994-02-16 21:09:47 +00:00
struct stat st;
if (file->precious || file->phony)
1994-01-25 21:51:25 +00:00
return;
#ifndef NO_ARCHIVES
if (ar_name (file->name))
{
1998-10-03 05:39:55 +00:00
if (ar_member_date (file->name) != FILE_TIMESTAMP_S (file->last_mtime))
1994-01-25 21:51:25 +00:00
{
if (on_behalf_of)
error (NILF, _("*** [%s] Archive member `%s' may be bogus; not deleted"),
1994-01-25 21:51:25 +00:00
on_behalf_of, file->name);
else
error (NILF, _("*** Archive member `%s' may be bogus; not deleted"),
1994-01-25 21:51:25 +00:00
file->name);
}
return;
}
#endif
1995-12-12 03:26:08 +00:00
if (stat (file->name, &st) == 0
1994-01-25 21:51:25 +00:00
&& S_ISREG (st.st_mode)
1998-10-03 05:39:55 +00:00
&& FILE_TIMESTAMP_STAT_MODTIME (st) != file->last_mtime)
1994-01-25 21:51:25 +00:00
{
if (on_behalf_of)
error (NILF, _("*** [%s] Deleting file `%s'"), on_behalf_of, file->name);
1994-01-25 21:51:25 +00:00
else
error (NILF, _("*** Deleting file `%s'"), file->name);
if (unlink (file->name) < 0
&& errno != ENOENT) /* It disappeared; so what. */
1994-01-25 21:51:25 +00:00
perror_with_name ("unlink: ", file->name);
}
}
1995-12-12 03:26:08 +00:00
1994-01-25 21:51:25 +00:00
1991-10-08 20:20:29 +00:00
/* Delete all non-precious targets of CHILD unless they were already deleted.
Set the flag in CHILD to say they've been deleted. */
void
delete_child_targets (child)
struct child *child;
{
struct dep *d;
if (child->deleted)
return;
1994-01-25 21:51:25 +00:00
/* Delete the target file if it changed. */
delete_target (child->file, (char *) 0);
1991-10-08 20:20:29 +00:00
1994-01-25 21:51:25 +00:00
/* Also remove any non-precious targets listed in the `also_make' member. */
1991-10-08 20:20:29 +00:00
for (d = child->file->also_make; d != 0; d = d->next)
1994-01-25 21:51:25 +00:00
delete_target (d->file, child->file->name);
1991-10-08 20:20:29 +00:00
child->deleted = 1;
}
/* Print out the commands in CMDS. */
void
print_commands (cmds)
register struct commands *cmds;
{
register char *s;
fputs (_("# commands to execute"), stdout);
1991-10-08 20:20:29 +00:00
1998-10-03 05:39:55 +00:00
if (cmds->fileinfo.filenm == 0)
puts (_(" (built-in):"));
1991-10-08 20:20:29 +00:00
else
printf (_(" (from `%s', line %lu):\n"),
1998-10-03 05:39:55 +00:00
cmds->fileinfo.filenm, cmds->fileinfo.lineno);
1991-10-08 20:20:29 +00:00
s = cmds->commands;
while (*s != '\0')
{
char *end;
while (isspace ((unsigned char)*s))
1991-10-08 20:20:29 +00:00
++s;
end = strchr (s, '\n');
1991-10-08 20:20:29 +00:00
if (end == 0)
end = s + strlen (s);
1993-01-06 22:57:24 +00:00
printf ("\t%.*s\n", (int) (end - s), s);
1991-10-08 20:20:29 +00:00
s = end;
}
}