#define RESTOREINT(v) \
({ \
xbarrier(); \
- if ((suppressint = (v)) == 0 && intpending) onint(); \
+ suppressint = (v); \
+ if (suppressint == 0 && intpending) onint(); \
0; \
})
#define EXSIGON() \
static struct var **hashvar(const char *);
-static int varequal(const char *a, const char *b) {
+static int varequal(const char *a, const char *b)
+{
return !varcmp(a, b);
}
static char *stputs(const char *, char *);
-static char *_STPUTC(int c, char *p) {
+static char *_STPUTC(int c, char *p)
+{
if (p == sstrend)
p = growstackstr();
*p++ = c;
* This routine is called when an error or an interrupt occurs in an
* interactive shell and control is returned to the main command loop.
*/
-
static void
reset(void)
{
return 0;
}
while ((n = *++argv) != NULL) {
- if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */
- if ((ap = *__lookupalias(n)) == NULL) {
+ v = strchr(n+1, '=');
+ if (v == NULL) { /* n+1: funny ksh stuff */
+ ap = *__lookupalias(n);
+ if (ap == NULL) {
fprintf(stderr, "%s: %s not found\n", "alias", n);
ret = 1;
} else
goto step7;
if (*dest == '.') {
c = dest[1];
-dotdot:
+ dotdot:
switch (c) {
case '\0':
case '/':
}
if (!*dest)
dest = ".";
- if (!(path = bltinlookup("CDPATH"))) {
-step6:
-step7:
+ path = bltinlookup("CDPATH");
+ if (!path) {
+ step6:
+ step7:
p = dest;
goto docd;
}
if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
if (c && c != ':')
flags |= CD_PRINT;
-docd:
+ docd:
if (!docd(p, flags))
goto out;
break;
} while (path);
sh_error("can't cd to %s", dest);
/* NOTREACHED */
-out:
+ out:
if (flags & CD_PRINT)
out1fmt(snlfmt, curdir);
return 0;
* Update curdir (the name of the current directory) in response to a
* cd command.
*/
-
static const char * updatepwd(const char *dir)
{
char *new;
return stackblock();
}
+
/*
* Actually do the chdir. We also call hashcd to let the routines in exec.c
* know that the current directory has changed.
*/
-
static int
docd(const char *dest, int flags)
{
goto out;
setpwd(dir, 1);
hashcd();
-out:
+ out:
INTON;
return err;
}
* just do a longjmp to the exception handler. The type of exception is
* stored in the global variable "exception".
*/
-
static void
exraise(int e)
{
* are held using the INTOFF macro. (The test for iflag is just
* defensive programming.)
*/
-
static void
onint(void) {
int i;
va_end(ap);
}
+
/*
* error/warning routines for external builtins
*/
-
static void
sh_warnx(const char *fmt, ...)
{
* pointer to a static buffer that will be overwritten on the next call.
* Action describes the operation that got the error.
*/
-
static const char *
errmsg(int e, const char *em)
{
/*
* The eval command.
*/
-
static int
evalcmd(int argc, char **argv)
{
ap = argv + 2;
for (;;) {
concat = stputs(p, concat);
- if ((p = *ap++) == NULL)
+ p = *ap++;
+ if (p == NULL)
break;
STPUTC(' ', concat);
}
/*
* Execute a command or commands contained in a string.
*/
-
static int
evalstring(char *s, int mask)
{
* Evaluate a parse tree. The value is left in the global variable
* exitstatus.
*/
-
static void
evaltree(union node *n, int flags)
{
goto setstatus;
case NCMD:
evalfn = evalcommand;
-checkexit:
+ checkexit:
if (eflag && !(flags & EV_TESTED))
checkexit = ~0;
goto calleval;
break;
if (!evalskip) {
n = n->nbinary.ch2;
-evaln:
+ evaln:
evalfn = evaltree;
-calleval:
+ calleval:
evalfn(n, flags);
break;
}
goto success;
case NDEFUN:
defun(n->narg.text, n->narg.next);
-success:
+ success:
status = 0;
-setstatus:
+ setstatus:
exitstatus = status;
break;
}
-out:
+ out:
if ((checkexit & exitstatus))
evalskip |= SKIPEVAL;
else if (pendingsigs && dotrap())
goto exexit;
if (flags & EV_EXIT) {
-exexit:
+ exexit:
exraise(EXEXIT);
}
}
evaltree(n->nbinary.ch1, EV_TESTED);
if (evalskip) {
-skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
+ skipping:
+ if (evalskip == SKIPCONT && --skipcount <= 0) {
evalskip = 0;
continue;
}
}
}
loopnest--;
-out:
+ out:
popstackmark(&smark);
}
-
static void
evalcase(union node *n, int flags)
{
}
}
}
-out:
+ out:
popstackmark(&smark);
}
/*
* Kick off a subshell to evaluate a tree.
*/
-
static void
evalsubshell(union node *n, int flags)
{
/*
* Compute the names of the files in a redirection list.
*/
-
static void
expredir(union node *n)
{
* of the shell, which make the last process in a pipeline the parent
* of all the rest.)
*/
-
static void
evalpipe(union node *n, int flags)
{
* we fork off a subprocess and get the output of the command via a pipe.
* Should be called with interrupts off.
*/
-
static void
evalbackcmd(union node *n, struct backcmd *result)
{
result->jp = jp;
}
herefd = saveherefd;
-out:
+ out:
TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
result->fd, result->buf, result->nleft, result->jp));
}
return 0;
if (*cp++ != '-')
break;
- if (!(c = *cp++))
+ c = *cp++;
+ if (!c)
break;
if (c == '-' && !*cp) {
argv++;
/*
* Execute a simple command.
*/
-
static void
evalcommand(union node *cmd, int flags)
{
/* We have a redirection error. */
if (spclbltin > 0)
exraise(EXERROR);
-bail:
+ bail:
exitstatus = status;
goto out;
}
exitstatus = exit_status;
if (i == EXINT || spclbltin > 0) {
-raise:
+ raise:
longjmp(handler->loc, 1);
}
FORCEINTON;
break;
}
-out:
+ out:
popredir(cmd_is_exec);
if (lastarg)
/* dsl: I think this is intended to be used to support
}
static int
-evalbltin(const struct builtincmd *cmd, int argc, char **argv) {
+evalbltin(const struct builtincmd *cmd, int argc, char **argv)
+{
char *volatile savecmdname;
struct jmploc *volatile savehandler;
struct jmploc jmploc;
int i;
savecmdname = commandname;
- if ((i = setjmp(jmploc.loc)))
+ i = setjmp(jmploc.loc);
+ if (i)
goto cmddone;
savehandler = handler;
handler = &jmploc;
optptr = NULL; /* initialize nextopt */
exitstatus = (*cmd->builtin)(argc, argv);
flushall();
-cmddone:
+ cmddone:
exitstatus |= ferror(stdout);
clearerr(stdout);
commandname = savecmdname;
saveparam = shellparam;
savelocalvars = localvars;
- if ((e = setjmp(jmploc.loc))) {
+ e = setjmp(jmploc.loc);
+ if (e) {
goto funcdone;
}
INTOFF;
return !*endofname(p);
}
+
/*
* Search for a command. This is called before we fork so that the
* location of the command will be available in the parent as well as
* the child. The check for "goodname" is an overly conservative
* check that the name will not be subject to expansion.
*/
-
static void
prehash(union node *n)
{
/*
* No command given.
*/
-
static int
bltincmd(int argc, char **argv)
{
/*
* The return command.
*/
-
static int
returncmd(int argc, char **argv)
{
#define ARB 1 /* actual size determined at run time */
-
struct tblentry {
struct tblentry *next; /* next entry in hash chain */
union param param; /* definition of builtin function */
}
#endif
-repeat:
+ repeat:
#ifdef SYSV
do {
execve(cmd, argv, envp);
}
-
/*
* Do a path search. The variable path (passed by reference) should be
* set to the start of the path before the first call; padvance will update
* pathopt will be set to point to it; otherwise pathopt will be set to
* NULL.
*/
-
static char *
padvance(const char **path, const char *name)
{
}
c = 0;
while ((name = *argptr) != NULL) {
- if ((cmdp = cmdlookup(name, 0)) != NULL
+ cmdp = cmdlookup(name, 0);
+ if (cmdp != NULL
&& (cmdp->cmdtype == CMDNORMAL
|| (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)))
delete_cmd_entry();
* Resolve a command name. If you change this routine, you may have to
* change the shellexec routine as well.
*/
-
static void
find_command(char *name, struct cmdentry *entry, int act, const char *path)
{
}
/* If name is in the table, check answer will be ok */
- if ((cmdp = cmdlookup(name, 0)) != NULL) {
+ cmdp = cmdlookup(name, 0);
+ if (cmdp != NULL) {
int bit;
switch (cmdp->cmdtype) {
e = ENOENT;
idx = -1;
-loop:
+ loop:
while ((fullname = padvance(&path, name)) != NULL) {
stunalloc(fullname);
idx++;
if (pathopt) { /* this is a %func directory */
stalloc(strlen(fullname) + 1);
readcmdfile(fullname);
- if ((cmdp = cmdlookup(name, 0)) == NULL ||
- cmdp->cmdtype != CMDFUNCTION)
+ cmdp = cmdlookup(name, 0);
+ if (cmdp == NULL || cmdp->cmdtype != CMDFUNCTION)
sh_error("%s not defined in %s", name, fullname);
stunalloc(fullname);
goto success;
entry->cmdtype = CMDUNKNOWN;
return;
-builtin_success:
+ builtin_success:
if (!updatetbl) {
entry->cmdtype = CMDBUILTIN;
entry->u.cmd = bcmd;
cmdp->cmdtype = CMDBUILTIN;
cmdp->param.cmd = bcmd;
INTON;
-success:
+ success:
cmdp->rehash = 0;
entry->cmdtype = cmdp->cmdtype;
entry->u = cmdp->param;
return strcmp((const char *) a, (*(const char *const *) b) + 1);
}
+
/*
* Search the table of builtin commands.
*/
-
static struct builtincmd *
find_builtin(const char *name)
{
* Called when a cd is done. Marks all commands so the next time they
* are executed they will be rehashed.
*/
-
static void
hashcd(void)
{
* pathval() still returns the old value at this point.
* Called with interrupts off.
*/
-
static void
changepath(const char *newval)
{
* Clear out command entries. The argument specifies the first entry in
* PATH which has changed.
*/
-
static void
clearcmdentry(int firstchange)
{
}
-
/*
* Locate a command in the command hash table. If "add" is nonzero,
* add the command to the table if it is not already present. The
*
* Interrupts must be off if called with add != 0.
*/
-
static struct tblentry **lastcmdentry;
-
static struct tblentry *
cmdlookup(const char *name, int add)
{
return cmdp;
}
+
/*
* Delete the command entry returned on the last lookup.
*/
-
static void
delete_cmd_entry(void)
{
* Add a new command entry, replacing any existing command entry for
* the same name - except special builtins.
*/
-
static void addcmdentry(char *name, struct cmdentry *entry)
{
struct tblentry *cmdp;
cmdp->rehash = 0;
}
+
/*
* Make a copy of a parse tree.
*/
-
static struct funcnode * copyfunc(union node *n)
{
struct funcnode *f;
return f;
}
+
/*
* Define a shell function.
*/
-
static void
defun(char *name, union node *func)
{
/*
* Delete a function if it exists.
*/
-
static void
unsetfunc(const char *name)
{
/*
* Locate and print what a word is...
*/
-
-
#if ENABLE_ASH_CMDCMD
static int
describe_command(char *command, int describe_command_verbose)
#if ENABLE_ASH_ALIAS
/* Then look at the aliases */
- if ((ap = lookupalias(command, 0)) != NULL) {
+ ap = lookupalias(command, 0);
+ if (ap != NULL) {
if (describe_command_verbose) {
out1fmt(" is an alias for %s", ap->val);
} else {
}
#endif
/* Then check if it is a tracked alias */
- if ((cmdp = cmdlookup(command, 0)) != NULL) {
+ cmdp = cmdlookup(command, 0);
+ if (cmdp != NULL) {
entry.cmdtype = cmdp->cmdtype;
entry.u = cmdp->param;
} else {
}
return 127;
}
-
-out:
+ out:
outstr("\n", stdout);
return 0;
}
* Returns an stalloced string.
*/
-static char * preglob(const char *pattern, int quoted, int flag) {
+static char * preglob(const char *pattern, int quoted, int flag)
+{
flag |= RMESCAPE_GLOB;
if (quoted) {
flag |= RMESCAPE_QUOTED;
* perform splitting and file name expansion. When arglist is NULL, perform
* here document expansion.
*/
-
-void
+static void
expandarg(union node *arg, struct arglist *arglist, int flag)
{
struct strlist *sp;
* characters to allow for further processing. Otherwise treat
* $@ like $* since no splitting will be performed.
*/
-
static void
argstr(char *p, int flag)
{
char *q;
flag &= ~EXP_TILDE;
-tilde:
+ tilde:
q = p;
if (*q == CTLESC && (flag & EXP_QWORD))
q++;
if (*q == '~')
p = exptilde(p, q, flag);
}
-start:
+ start:
startloc = expdest - (char *)stackblock();
for (;;) {
length += strcspn(p + length, reject);
goto start;
}
inquotes = !inquotes;
-addquote:
+ addquote:
if (quotes) {
p--;
length++;
#endif
}
}
-breakloop:
+ breakloop:
;
}
goto done;
}
}
-done:
+ done:
*p = '\0';
if (*name == '\0') {
home = lookupvar(homestr);
} else {
- if ((pw = getpwnam(name)) == NULL)
+ pw = getpwnam(name);
+ if (pw == NULL)
goto lose;
home = pw->pw_dir;
}
strtodest(home, SQSYNTAX, quotes);
recordregion(startloc, expdest - (char *)stackblock(), 0);
return p;
-lose:
+ lose:
*p = c;
return startp;
}
}
#endif
+
/*
* Expand stuff in backwards quotes.
*/
-
static void
expbackq(union node *cmd, int quoted, int quotes)
{
goto read;
for (;;) {
memtodest(p, i, syntax, quotes);
-read:
+ read:
if (in.fd < 0)
break;
i = safe_read(in.fd, buf, sizeof(buf));
startloc = expdest - (char *)stackblock();
p = strchr(p, '=') + 1;
-again:
+ again:
varlen = varvalue(var, varflags, flag);
if (varflags & VSNUL)
varlen--;
}
if (subtype == VSMINUS) {
-vsplus:
+ vsplus:
if (varlen < 0) {
argstr(
p, flag | EXP_TILDE |
if (subtype == VSNORMAL) {
if (!easy)
goto end;
-record:
+ record:
recordregion(startloc, expdest - (char *)stackblock(), quoted);
goto end;
}
goto record;
}
-end:
+ end:
if (subtype != VSNORMAL) { /* skip to end of alternative */
int nesting = 1;
for (;;) {
- if ((c = *p++) == CTLESC)
+ c = *p++;
+ if (c == CTLESC)
p++;
else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) {
if (varlen >= 0)
/*
* Put a string on the stack.
*/
-
static void
memtodest(const char *p, size_t len, int syntax, int quotes) {
char *q = expdest;
/*
* Add the value of a specialized variable to the stack string.
*/
-
static ssize_t
varvalue(char *name, int varflags, int flags)
{
num = backgndpid;
if (num == 0)
return -1;
-numvar:
+ numvar:
len = cvtnum(num);
break;
case '-':
sep = ifsset() ? SC2INT(ifsval()[0]) : ' ';
if (quotes && (SIT(sep, syntax) == CCTL || SIT(sep, syntax) == CBACK))
sepq = 1;
-param:
- if (!(ap = shellparam.p))
+ param:
+ ap = shellparam.p;
+ if (!ap)
return -1;
while ((p = *ap++)) {
size_t partlen;
goto value;
default:
p = lookupvar(name);
-value:
+ value:
if (!p)
return -1;
* Record the fact that we have to scan this region of the
* string for IFS characters.
*/
-
static void
recordregion(int start, int end, int nulonly)
{
if (!*start)
return;
-add:
+ add:
sp = (struct strlist *)stalloc(sizeof(*sp));
sp->text = start;
*arglist->lastp = sp;
/*
* no matches
*/
-nometa:
+ nometa:
*exparg.lastp = str;
rmescapes(str->text);
exparg.lastp = &str->next;
}
}
+
/*
* Add a file name to the list.
*/
-
static void
addfname(const char *name)
{
/*
* Do metacharacter (i.e. *, ?, [...]) expansion.
*/
-
static void
expmeta(char *enddir, char *name)
{
start = p + 1;
}
}
-out:
+ out:
if (metaflag == 0) { /* we've reached the end of the file name */
if (enddir != expdir)
metaflag++;
cp = expdir;
enddir[-1] = '\0';
}
- if ((dirp = opendir(cp)) == NULL)
+ dirp = opendir(cp);
+ if (dirp == NULL)
return;
if (enddir != expdir)
enddir[-1] = '/';
endname[-1] = '/';
}
+
/*
* Sort the results of file name expansion. It calculates the number of
* strings to sort and then calls msort (short for merge sort) to do the
* work.
*/
-
static struct strlist *
expsort(struct strlist *str)
{
{
*lpp = p;
lpp = &p->next;
- if ((p = *lpp) == NULL) {
+ p = *lpp;
+ if (p == NULL) {
*lpp = q;
break;
}
} else {
*lpp = q;
lpp = &q->next;
- if ((q = *lpp) == NULL) {
+ q = *lpp;
+ if (q == NULL) {
*lpp = p;
break;
}
/*
* Returns true if the pattern matches the string.
*/
-
static int patmatch(char *pattern, const char *string)
{
return pmatch(preglob(pattern, 0, 0), string);
/*
* Remove any CTLESC characters from a string.
*/
-
static char *
_rmescapes(char *str, int flag)
{
}
}
notescaped = globbing;
-copy:
+ copy:
*q++ = *p++;
}
*q = '\0';
/*
* See if a pattern matches in a case statement.
*/
-
-int
+static int
casematch(union node *pattern, char *val)
{
struct stackmark smark;
return result;
}
+
/*
* Our own itoa().
*/
-
static int
cvtnum(arith_t num)
{
char *buf = parsefile->buf;
parsenextc = buf;
-retry:
+ retry:
#if ENABLE_FEATURE_EDITING
if (!iflag || parsefile->fd)
nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
* 3) If the is more stuff in this buffer, use it else call read to fill it.
* 4) Process input up to the next newline, deleting nul characters.
*/
-
-int
+static int
preadbuffer(void)
{
char *q;
more = parselleft;
if (more <= 0) {
-again:
- if ((more = preadfd()) <= 0) {
+ again:
+ more = preadfd();
+ if (more <= 0) {
parselleft = parsenleft = EOF_NLEFT;
return PEOF;
}
* Undo the last call to pgetc. Only one character may be pushed back.
* PEOF may be pushed back.
*/
-
-void
+static void
pungetc(void)
{
parsenleft++;
* Push a string back onto the input at this current parsefile level.
* We handle aliases this way.
*/
-void
+static void
pushstring(char *s, void *ap)
{
struct strpush *sp;
INTON;
}
-void
+static void
popstring(void)
{
struct strpush *sp = parsefile->strpush;
INTON;
}
+
/*
* Set the input to take input from a file. If push is set, push the
* old input onto the stack first.
*/
-
static int
setinputfile(const char *fname, int flags)
{
int fd2;
INTOFF;
- if ((fd = open(fname, O_RDONLY)) < 0) {
+ fd = open(fname, O_RDONLY);
+ if (fd < 0) {
if (flags & INPUT_NOFILE_OK)
goto out;
sh_error("Can't open %s", fname);
fd = fd2;
}
setinputfd(fd, flags & INPUT_PUSH_FILE);
-out:
+ out:
INTON;
return fd;
}
* Like setinputfile, but takes an open file descriptor. Call this with
* interrupts off.
*/
-
static void
setinputfd(int fd, int push)
{
/*
* Like setinputfile, but takes input from a string.
*/
-
static void
setinputstring(char *string)
{
* To handle the "." command, a stack of input files is used. Pushfile
* adds a new entry to the stack and popfile restores the previous level.
*/
-
static void
pushfile(void)
{
/*
* Return to top level.
*/
-
static void
popallfiles(void)
{
* Close the file(s) that the shell is reading commands from. Called
* after a fork is done.
*/
-
static void
closescript(void)
{
*
* Called with interrupts off.
*/
-
-void
+static void
setjobctl(int on)
{
int fd;
goto out;
fcntl(fd, F_SETFD, FD_CLOEXEC);
do { /* while we are in the background */
- if ((pgrp = tcgetpgrp(fd)) < 0) {
-out:
+ pgrp = tcgetpgrp(fd);
+ if (pgrp < 0) {
+ out:
sh_warnx("can't access tty; job control turned off");
mflag = on = 0;
goto close;
setsignal(SIGTSTP);
setsignal(SIGTTOU);
setsignal(SIGTTIN);
-close:
+ close:
close(fd);
fd = -1;
}
struct job *jp;
if (argc <= 1) {
-usage:
+ usage:
sh_error(
"Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n"
"kill -l [exitstatus]"
ps->status = -1;
}
} while (ps++, --i);
-out:
+ out:
status = (mode == FORK_FG) ? waitforjob(jp) : 0;
INTON;
return status;
else
col = fmtstr(s, 16, "Done");
}
-
-out:
+ out:
return col;
}
do {
/* for each process */
col = fmtstr(s, 48, " |\n%*c%d ", indent, ' ', ps->pid) - 3;
-
-start:
+ start:
fprintf(out, "%s%*c%s",
s, 33 - col >= 0 ? 33 - col : 0, ' ', ps->cmd
);
* Print a list of jobs. If "change" is nonzero, only print jobs whose
* statuses have changed since the last call to showjobs.
*/
-
static void
showjobs(FILE *out, int mode)
{
}
#endif /* JOBS */
+
/*
* Mark a job structure as unused.
*/
-
static void
freejob(struct job *jp)
{
if (job->ps[job->nprocs - 1].pid == pid)
break;
job = job->prev_job;
-start:
+ start:
if (!job)
goto repeat;
} while (1);
dowait(DOWAIT_BLOCK, 0);
job->waited = 1;
retval = getstatus(job);
-repeat:
+ repeat:
;
} while (*++argv);
-out:
+ out:
return retval;
}
/*
* Convert a job name to a job structure.
*/
-
static struct job *
getjob(const char *name, int getctl)
{
if (!p[1]) {
if (c == '+' || c == '%') {
-currentjob:
+ currentjob:
err_msg = "No current job";
goto check;
} else if (c == '-') {
if (jp)
jp = jp->prev_job;
err_msg = "No previous job";
-check:
+ check:
if (!jp)
goto err;
goto gotit;
jp = jp->prev_job;
}
-gotit:
+ gotit:
#if JOBS
err_msg = "job %s not created under job control";
if (getctl && jp->jobctl == 0)
goto err;
#endif
return jp;
-err:
+ err:
sh_error(err_msg, name);
}
*
* Called with interrupts off.
*/
-
static void forkchild(struct job *jp, union node *n, int mode)
{
int oldlvl;
return pid;
}
+
/*
* Wait for job to finish.
*
*
* Called with interrupts off.
*/
-
-int
+static int
waitforjob(struct job *jp)
{
int st;
* (as opposed to running a builtin command or just typing return),
* and the jobs command may give out of date information.
*/
-
static int waitproc(int block, int *status)
{
int flags = 0;
return wait3(status, flags, (struct rusage *)NULL);
}
+
/*
* Wait for a process to terminate.
*/
-
static int
dowait(int block, struct job *job)
{
jobless--;
goto out;
-gotjob:
+ gotjob:
if (state != JOBRUNNING) {
thisjob->changed = 1;
}
}
-out:
+ out:
INTON;
if (thisjob && thisjob == job) {
/*
* return 1 if there are stopped jobs, otherwise 0
*/
-
int
stoppedjobs(void)
{
* Return a string identifying a command (to be printed by the
* jobs command).
*/
-
#if JOBS
static char *cmdnextc;
goto binop;
case NOR:
p = " || ";
-binop:
+ binop:
cmdtxt(n->nbinary.ch1);
cmdputs(p);
n = n->nbinary.ch2;
case NNOT:
cmdputs("!");
n = n->nnot.com;
-donode:
+ donode:
cmdtxt(n);
break;
case NIF:
goto until;
case NUNTIL:
p = "until ";
-until:
+ until:
cmdputs(p);
cmdtxt(n->nbinary.ch1);
n = n->nbinary.ch2;
p = "; done";
-dodo:
+ dodo:
cmdputs("; do ");
-dotail:
+ dotail:
cmdtxt(n);
goto dotail2;
case NFOR:
break;
case NARG:
p = n->narg.text;
-dotail2:
+ dotail2:
cmdputs(p);
break;
case NHERE:
goto redir;
case NFROMTO:
p = "<>";
-redir:
+ redir:
s[0] = n->nfile.fd + '0';
s[1] = '\0';
cmdputs(s);
break;
}
USTPUTC(c, nextc);
-checkstr:
+ checkstr:
if (!str)
continue;
-dostr:
+ dostr:
while ((c = *str++)) {
USTPUTC(c, nextc);
}
static int mail_var_path_changed;
-
/*
* Print appropriate message(s) if mail has arrived.
* If mail_var_path_changed is set,
* then the value of MAIL has mail_var_path_changed,
* so we just update the values.
*/
-
static void
chkmail(void)
{
* exception occurs. When an exception occurs the variable "state"
* is used to figure out how far we had gotten.
*/
-
int ash_main(int argc, char **argv);
int ash_main(int argc, char **argv)
{
if (isloginsh) {
state = 1;
read_profile("/etc/profile");
-state1:
+ state1:
state = 2;
read_profile(".profile");
}
-state2:
+ state2:
state = 3;
if (
#ifndef linux
#endif
iflag
) {
- if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') {
+ shinit = lookupvar("ENV");
+ if (shinit != NULL && *shinit != '\0') {
read_profile(shinit);
}
}
-state3:
+ state3:
state = 4;
if (minusc)
evalstring(minusc, 0);
* Read and execute commands. "Top" is nonzero for the top level command
* loop; it turns on prompting if the shell is interactive.
*/
-
static int
cmdloop(int top)
{
/*
* Read /etc/profile or .profile. Return on error.
*/
-
static void
read_profile(const char *name)
{
/*
* Read a file containing shell functions.
*/
-
static void
readcmdfile(char *name)
{
* Take commands from a file. To be compatible we should do a path
* search for the file, which is necessary to find sub-commands.
*/
-
static char * find_dot_file(char *name)
{
char *fullname;
/*
* Same for malloc, realloc, but returns an error when out of space.
*/
-
static pointer
ckrealloc(pointer p, size_t nbytes)
{
/*
* Make a copy of a string in safe storage.
*/
-
static char *
savestr(const char *s)
{
* The size 504 was chosen because the Ultrix malloc handles that size
* well.
*/
-
-
static pointer
stalloc(size_t nbytes)
{
}
-void
+static void
stunalloc(pointer p)
{
#if DEBUG
}
-void
+static void
setstackmark(struct stackmark *mark)
{
mark->stackp = stackp;
}
-void
+static void
popstackmark(struct stackmark *mark)
{
struct stack_block *sp;
* possibly moving it (like realloc). Grabstackblock actually allocates the
* part of the block that has been used.
*/
-
-void
+static void
growstackblock(void)
{
size_t newlen;
stacknleft -= len;
}
+
/*
* The following routines are somewhat easier to use than the above.
* The user declares a variable of type STACKSTR, which may be declared
* CHECKSTACKSPACE can be called before USTPUTC to ensure that there
* is space for at least one character.
*/
-
-void *
+static void *
growstackstr(void)
{
size_t len = stackblocksize();
/*
* Called from CHECKSTRSPACE.
*/
-
-char *
+static char *
makestrspace(size_t newlen, char *p)
{
size_t len = p - stacknxt;
return stackblock() + len;
}
-char *
+static char *
stnputs(const char *s, size_t n, char *p)
{
p = makestrspace(n, p);
return p;
}
-char *
+static char *
stputs(const char *s, char *p)
{
return stnputs(s, strlen(s), p);
/*
* prefix -- see if pfx is a prefix of string.
*/
-
-char *
+static char *
prefix(const char *string, const char *pfx)
{
while (*pfx) {
* Convert a string of digits to an integer, printing an error message on
* failure.
*/
-
-int
+static int
number(const char *s)
{
-
if (! is_number(s))
sh_error(illnum, s);
return atoi(s);
/*
* Check for a valid number. This should be elsewhere.
*/
-
-int
+static int
is_number(const char *p)
{
do {
* Produce a possibly single quoted string suitable as input to the shell.
* The return string is allocated on the stack.
*/
-
-char *
-single_quote(const char *s) {
+static char *
+single_quote(const char *s)
+{
char *p;
STARTSTACKSTR(p);
return stackblock();
}
+
/*
* Like strdup but works with the ash stack.
*/
-
-char *
+static char *
sstrdup(const char *p)
{
size_t len = strlen(p) + 1;
/*
* Free a parse tree.
*/
-
static void
freefunc(struct funcnode *f)
{
/*
* Process the shell command line arguments.
*/
-
-void
+static void
procargs(int argc, char **argv)
{
int i;
goto setarg0;
} else if (!sflag) {
setinputfile(*xargv, 0);
-setarg0:
+ setarg0:
arg0 = *xargv++;
commandname = arg0;
}
}
-void
+static void
optschanged(void)
{
#if DEBUG
}
}
+
/*
* Process shell options. The global variable argptr contains a pointer
* to the argument list; we advance it past the options.
*/
-
static void
options(int cmdline)
{
minusc = NULL;
while ((p = *argptr) != NULL) {
argptr++;
- if ((c = *p++) == '-') {
+ c = *p++;
+ if (c == '-') {
val = 1;
if (p[0] == '\0' || LONE_DASH(p)) {
if (!cmdline) {
/*
* Set the shell parameters.
*/
-
-void
+static void
setparam(char **argv)
{
char **newparam;
/*
* Free the list of positional parameters.
*/
-
-void
+static void
freeparam(volatile struct shparam *param)
{
char **ap;
/*
* The shift builtin command.
*/
-
-int
+static int
shiftcmd(int argc, char **argv)
{
int n;
/*
* The set command builtin.
*/
-
-int
+static int
setcmd(int argc, char **argv)
{
if (argc == 1)
/* Current word is done, advance */
p = *optnext;
if (p == NULL || *p != '-' || *++p == '\0') {
-atend:
+ atend:
p = NULL;
done = 1;
goto out;
p = NULL;
} else
err |= setvarsafe("OPTARG", nullstr, 0);
-
-out:
+ out:
*optoff = p ? p - *(optnext - 1) : -1;
*param_optind = optnext - optfirst + 1;
fmtstr(s, sizeof(s), "%d", *param_optind);
return done;
}
+
/*
* The getopts builtin. Shellparam.optnext points to the next argument
* to be processed. Shellparam.optptr points to the next character to
* be processed in the current argument. If shellparam.optnext is NULL,
* then it's the first time getopts has been called.
*/
-
-int
+static int
getoptscmd(int argc, char **argv)
{
char **optbase;
shellparam.optind = 1;
shellparam.optoff = -1;
}
- }
- else {
+ } else {
optbase = &argv[3];
if (shellparam.optind > argc - 2) {
shellparam.optind = 1;
* other arguments are unnecessary. It return the character, or '\0' on
* end of input.
*/
-
static int
nextopt(const char *optstring)
{
const char *q;
char c;
- if ((p = optptr) == NULL || *p == '\0') {
+ p = optptr;
+ if (p == NULL || *p == '\0') {
p = *argptr;
if (p == NULL || *p != '-' || *++p == '\0')
return '\0';
/* output.c */
-void
+static void
outstr(const char *p, FILE *file)
{
INTOFF;
INTON;
}
-void
+static void
flushall(void)
{
INTOFF;
INTON;
}
-void
+static void
flusherr(void)
{
INTOFF;
}
-int
+static int
fmtstr(char *outbuf, size_t length, const char *fmt, ...)
{
va_list ap;
* Read and parse a command. Returns NEOF on end of file. (NULL is a
* valid parse tree indicating a blank line.)
*/
-
union node *
parsecmd(int interact)
{
}
if (n1 == NULL) {
n1 = n2;
- }
- else {
+ } else {
n3 = (union node *)stalloc(sizeof(struct nbinary));
n3->type = NSEMI;
n3->nbinary.ch1 = n1;
n1 = pipeline();
for (;;) {
- if ((t = readtoken()) == TAND) {
+ t = readtoken();
+ if (t == TAND) {
t = NAND;
} else if (t == TOR) {
t = NOR;
if (lasttoken != TIN)
synexpect(TIN);
cpp = &n1->ncase.cases;
-next_case:
+ next_case:
checkkwd = CHKNL | CHKKWD;
t = readtoken();
while (t != TESAC) {
cpp = &cp->nclist.next;
checkkwd = CHKNL | CHKKWD;
- if ((t = readtoken()) != TESAC) {
+ t = readtoken();
+ if (t != TESAC) {
if (t != TENDCASE)
synexpect(TENDCASE);
else
if (readtoken() != t)
synexpect(t);
-redir:
+ redir:
/* Now check for redirection which may follow command */
checkkwd = CHKKWD | CHKALIAS;
rpp = rpp2;
}
n1->nredir.redirect = redir;
}
-
return n1;
}
goto out;
}
}
-out:
+ out:
*app = NULL;
*vpp = NULL;
*rpp = NULL;
return n;
}
-void fixredir(union node *n, const char *text, int err)
+static void fixredir(union node *n, const char *text, int err)
{
TRACE(("Fix redir %s %d\n", text, err));
if (!err)
if (quoteflag == 0)
n->type = NXHERE;
TRACE(("Here document %d\n", n->type));
- if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)
+ if (!noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)
synerror("Illegal eof marker for << redirection");
rmescapes(wordtext);
here->eofmark = wordtext;
if (heredoclist == NULL)
heredoclist = here;
else {
- for (p = heredoclist ; p->next ; p = p->next);
+ for (p = heredoclist; p->next; p = p->next);
p->next = here;
}
} else if (n->type == NTOFD || n->type == NFROMFD) {
/*
* Input any here documents.
*/
-
static void
parseheredoc(void)
{
#endif
#if ENABLE_ASH_ALIAS
-top:
+ top:
#endif
t = xxreadtoken();
if (checkkwd & CHKKWD) {
const char *const *pp;
- if ((pp = findkwd(wordtext))) {
+ pp = findkwd(wordtext);
+ if (pp) {
lasttoken = t = pp - tokname_array;
TRACE(("keyword %s recognized\n", tokname(t)));
goto out;
if (checkkwd & CHKALIAS) {
#if ENABLE_ASH_ALIAS
struct alias *ap;
- if ((ap = lookupalias(wordtext, 1)) != NULL) {
+ ap = lookupalias(wordtext, 1);
+ if (ap != NULL) {
if (*ap->val) {
pushstring(ap->val, ap);
}
}
#endif
}
-out:
+ out:
checkkwd = 0;
#if DEBUG
if (!alreadyseen)
}
}
}
-
return lasttoken = xxreadtoken_tokens[p - xxreadtoken_chars];
}
}
- }
+ } /* for */
}
goto breakloop;
}
}
-breakloop:
+ breakloop:
return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
#undef RETURN
}
* is called, c is set to the first character of the next input line. If
* we are at the end of the here document, this routine sets the c to PEOF.
*/
-
checkend: {
if (eofmark) {
#if ENABLE_ASH_ALIAS
* specifying the fd to be redirected. The variable "c" contains the
* first character of the redirection operator.
*/
-
parseredir: {
char fd = *out;
union node *np;
}
} else { /* c == '<' */
np->nfile.fd = 0;
- switch (c = pgetc()) {
+ c = pgetc();
+ switch (c) {
case '<':
if (sizeof(struct nfile) != sizeof(struct nhere)) {
np = (union node *)stalloc(sizeof(struct nhere));
np->type = NHERE;
heredoc = (struct heredoc *)stalloc(sizeof(struct heredoc));
heredoc->here = np;
- if ((c = pgetc()) == '-') {
+ c = pgetc();
+ if (c == '-') {
heredoc->striptabs = 1;
} else {
heredoc->striptabs = 0;
* Parse a substitution. At this point, we have read the dollar sign
* and nothing else.
*/
-
parsesub: {
int subtype;
int typeloc;
if (c == '{') {
c = pgetc();
if (c == '#') {
- if ((c = pgetc()) == '}')
+ c = pgetc();
+ if (c == '}')
c = '#';
else
subtype = VSLENGTH;
- }
- else
+ } else
subtype = 0;
}
if (c > PEOA_OR_PEOF && is_name(c)) {
* list of commands (passed by reference), and savelen is the number of
* characters on the top of the stack which must be preserved.
*/
-
parsebackq: {
struct nodelist **nlpp;
int savepbq;
if (needprompt) {
setprompt(2);
}
- switch (pc = pgetc()) {
+ pc = pgetc();
+ switch (pc) {
case '`':
goto done;
case '\\':
- if ((pc = pgetc()) == '\n') {
+ pc = pgetc();
+ if (pc == '\n') {
plinno++;
if (doprompt)
setprompt(2);
}
STPUTC(pc, pout);
}
-done:
+ done:
STPUTC('\0', pout);
psavelen = pout - (char *)stackblock();
if (psavelen > 0) {
* Returns true if the text contains nothing to expand (no dollar signs
* or backquotes).
*/
-
static int
noexpand(char *text)
{
* Return of a legal variable name (a letter or underscore followed by zero or
* more letters, underscores, and digits).
*/
-
static char *
endofname(const char *name)
{
* is the token that is expected, or -1 if more than one type of token can
* occur at this point.
*/
-
static void synexpect(int token)
{
char msg[64];
* called by editline -- any expansions to the prompt
* should be added here.
*/
-
#if ENABLE_ASH_EXPAND_PRMT
static const char *
expandstr(const char *ps)
return -1;
}
+
/*
* Handle here documents. Normally we fork off a process to write the
* data to a pipe. If the document is short, we can stuff the data in
* the pipe without forking.
*/
-
static int openhere(union node *redir)
{
int pip[2];
expandhere(redir->nhere.doc, pip[1]);
_exit(0);
}
-out:
+ out:
close(pip[1]);
return pip[0];
}
switch (redir->nfile.type) {
case NFROM:
fname = redir->nfile.expfname;
- if ((f = open(fname, O_RDONLY)) < 0)
+ f = open(fname, O_RDONLY);
+ if (f < 0)
goto eopen;
break;
case NFROMTO:
fname = redir->nfile.expfname;
- if ((f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
+ f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666);
+ if (f < 0)
goto ecreate;
break;
case NTO:
/* Take care of noclobber mode. */
if (Cflag) {
fname = redir->nfile.expfname;
- if ((f = noclobberopen(fname)) < 0)
+ f = noclobberopen(fname);
+ if (f < 0)
goto ecreate;
break;
}
/* FALLTHROUGH */
case NCLOBBER:
fname = redir->nfile.expfname;
- if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
+ f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+ if (f < 0)
goto ecreate;
break;
case NAPPEND:
fname = redir->nfile.expfname;
- if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
+ f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666);
+ if (f < 0)
goto ecreate;
break;
default:
}
return f;
-ecreate:
+ ecreate:
sh_error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
-eopen:
+ eopen:
sh_error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
}
}
}
+
/*
* Process a list of redirection commands. If the REDIR_PUSH flag is set,
* old file descriptors are stashed away so that the redirection can be
* standard output, and the standard error if it becomes a duplicate of
* stdout, is saved in memory.
*/
-
static void
redirect(union node *redir, int flags)
{
/*
* Undo the effects of the last redirection.
*/
-
-void
+static void
popredir(int drop)
{
struct redirtab *rp;
/*
* Discard all saved file descriptors.
*/
-
-void
+static void
clearredir(int drop)
{
for (;;) {
* if the source file descriptor is closed, EMPTY if there are no unused
* file descriptors left.
*/
-
-int
+static int
copyfd(int from, int to)
{
int newfd;
}
-int
+static int
redirectsafe(union node *redir, int flags)
{
int err;
struct jmploc jmploc;
SAVEINT(saveint);
- if (!(err = setjmp(jmploc.loc) * 2)) {
+ err = setjmp(jmploc.loc) * 2;
+ if (!err) {
handler = &jmploc;
redirect(redir, flags);
}
static void trstring(char *);
-void
+static void
showtree(union node *n)
{
trputs("showtree called\n");
goto binop;
case NOR:
s = " || ";
-binop:
+ binop:
shtree(n->nbinary.ch1, ind, NULL, fp);
/* if (ind < 0) */
fputs(s, fp);
*/
-FILE *tracefile;
+static FILE *tracefile;
-void
+static void
trputc(int c)
{
if (debug != 1)
putc(c, tracefile);
}
-void
+static void
trace(const char *fmt, ...)
{
va_list va;
va_end(va);
}
-void
+static void
tracev(const char *fmt, va_list va)
{
if (debug != 1)
}
-void
+static void
trputs(const char *s)
{
if (debug != 1)
case CTLVAR+CTLQUOTE: c = 'V'; goto backslash;
case CTLBACKQ: c = 'q'; goto backslash;
case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash;
-backslash: putc('\\', tracefile);
+ backslash: putc('\\', tracefile);
putc(c, tracefile);
break;
default:
}
-void
+static void
trargs(char **ap)
{
if (debug != 1)
}
-void
+static void
opentrace(void)
{
char s[100];
return;
}
} else {
- if ((tracefile = fopen(s, "a")) == NULL) {
+ tracefile = fopen(s, "a");
+ if (tracefile == NULL) {
fprintf(stderr, "Can't open %s\n", s);
debug = 0;
return;
}
}
#ifdef O_APPEND
- if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
+ flags = fcntl(fileno(tracefile), F_GETFL, 0);
+ if (flags >= 0)
fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
#endif
setlinebuf(tracefile);
/*
* The trap builtin.
*/
-
-int
+static int
trapcmd(int argc, char **argv)
{
char *action;
else
action = *ap++;
while (*ap) {
- if ((signo = get_signum(*ap)) < 0)
+ signo = get_signum(*ap);
+ if (signo < 0)
sh_error("%s: bad trap", *ap);
INTOFF;
if (action) {
/*
* Clear traps on a fork.
*/
-
-void
+static void
clear_traps(void)
{
char **tp;
* Set the signal handler for the specified signal. The routine figures
* out what it should be set to.
*/
-
-void
+static void
setsignal(int signo)
{
int action;
char *t, tsig;
struct sigaction act;
- if ((t = trap[signo]) == NULL)
+ t = trap[signo];
+ if (t == NULL)
action = S_DFL;
else if (*t != '\0')
action = S_CATCH;
sigaction(signo, &act, 0);
}
+
/*
* Ignore a signal.
*/
-
-void
+static void
ignoresig(int signo)
{
if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
/*
* Signal handler.
*/
-
-void
+static void
onsig(int signo)
{
gotsig[signo - 1] = 1;
* Called to execute a trap. Perhaps we should avoid entering new trap
* handlers while we are executing a trap handler.
*/
-
-int
+static int
dotrap(void)
{
char *p;
/*
* Controls whether the shell is interactive or not.
*/
-
-void
+static void
setinteractive(int on)
{
static int is_interactive;
}
#endif /* FEATURE_SH_EXTRA_QUIET */
+
/*
* Called to exit the shell.
*/
-
-void
+static void
exitshell(void)
{
struct jmploc loc;
goto out;
}
handler = &loc;
- if ((p = trap[0])) {
+ p = trap[0];
+ if (p) {
trap[0] = NULL;
evalstring(p, 0);
}
flushall();
-out:
+ out:
setjobctl(0);
_exit(status);
/* NOTREACHED */
/*
* Safe version of setvar, returns 1 on success 0 on failure.
*/
-
-int
+static int
setvarsafe(const char *name, const char *val, int flags)
{
int err;
}
#endif
+
/*
* Set the value of a variable. The flags argument is ored with the
* flags of the variable. If val is NULL, the variable is unset.
*/
-
static void
setvar(const char *name, const char *val, int flags)
{
* will go away.
* Called with interrupts off.
*/
-
-void
+static void
setvareq(char *s, int flags)
{
struct var *vp, **vpp;
/*
* Process a linked list of variable assignments.
*/
-
static void
listsetvar(struct strlist *list_set_var, int flags)
{
/*
* Find the value of a variable. Returns NULL if not set.
*/
-
static char *
lookupvar(const char *name)
{
struct var *v;
- if ((v = *findvar(hashvar(name), name))) {
+ v = *findvar(hashvar(name), name);
+ if (v) {
#ifdef DYNAMIC_VAR
/*
* Dynamic variables are implemented roughly the same way they are
/*
* Search the environment of a builtin command.
*/
-
static char *
bltinlookup(const char *name)
{
/*
* Generate a list of variables satisfying the given conditions.
*/
-
static char **
listvars(int on, int off, char ***end)
{
* instead of hashed lists.
* For now just roll 'em through qsort for printing...
*/
-
static int
showvars(const char *sep_prefix, int on, int off)
{
/*
* The export and readonly commands.
*/
-
static int
exportcmd(int argc, char **argv)
{
notp = nextopt("p") - 'p';
if (notp && ((name = *(aptr = argptr)))) {
do {
- if ((p = strchr(name, '=')) != NULL) {
+ p = strchr(name, '=');
+ if (p != NULL) {
p++;
} else {
- if ((vp = *findvar(hashvar(name), name))) {
+ vp = *findvar(hashvar(name), name);
+ if (vp) {
vp->flags |= flag;
continue;
}
* will be restored when the shell function returns. We handle the name
* "-" as a special case.
*/
-
static void mklocal(char *name)
{
struct localvar *lvp;
INTON;
}
+
/*
* The "local" command.
*/
-
static int
localcmd(int argc, char **argv)
{
* Called after a function returns.
* Interrupts must be off.
*/
-
static void
poplocalvars(void)
{
* variable to allow a function to be unset when there is a readonly variable
* with the same name.
*/
-
-int
+static int
unsetcmd(int argc, char **argv)
{
char **ap;
/*
* Unset the specified variable.
*/
-
-int
+static int
unsetvar(const char *s)
{
struct var **vpp;
ok:
retval = 0;
}
-
-out:
+ out:
return retval;
}
/*
* Find the appropriate entry in the hash table from the name.
*/
-
static struct var **
hashvar(const char *p)
{
* string must be terminated by '='; the second may be terminated by
* either '=' or '\0'.
*/
-
-int
+static int
varcmp(const char *p, const char *q)
{
int c, d;
c = 0;
if (d == '=')
d = 0;
-out:
+ out:
return c - d;
}
*
* Copyright (C) 2003 Vladimir Oleynik <dzo@simtreas.ru>
*/
-
static int
letcmd(int argc, char **argv)
{
*
* This uses unbuffered input, which may be avoidable in some cases.
*/
-
static int
readcmd(int argc, char **argv)
{
if (prompt && isatty(0)) {
out2str(prompt);
}
- if (*(ap = argptr) == NULL)
+ ap = argptr;
+ if (*ap == NULL)
sh_error("arg count");
- if ((ifs = bltinlookup("IFS")) == NULL)
+ ifs = bltinlookup("IFS");
+ if (ifs == NULL)
ifs = defifs;
#if ENABLE_ASH_READ_NCHARS
if (nch_flag || silent) {
startword = 1;
STARTSTACKSTR(p);
} else {
-put:
+ put:
STPUTC(c, p);
}
}
umask(mask);
INTON;
- if ((ap = *argptr) == NULL) {
+ ap = *argptr;
+ if (ap == NULL) {
if (symbolic_mode) {
char buf[18];
char *p = buf;
*perrcode = errcode = 0;
while (1) {
- if ((arithval = *expr) == 0) {
+ arithval = *expr;
+ if (arithval == 0) {
if (p == endexpression) {
/* Null expression. */
return 0;
/* Skip whitespace */
goto prologue;
}
- if ((p = endofname(expr)) != expr) {
+ p = endofname(expr);
+ if (p != expr) {
size_t var_name_size = (p-expr) + 1; /* trailing zero */
numstackptr->var = alloca(var_name_size);