/* These are here to work with glibc -- Don't change these... */
#undef FNMATCH_BROKEN
#undef GLOB_BROKEN
+#define IFS_BROKEN
#include <assert.h>
#include <stddef.h>
__attribute__((__format__(__printf__,1,2)));
static int xwrite (int, const char *, int);
-#define outstr(p,file) fputs(p, file)
+static inline void outstr (const char *p, FILE *file) { fputs(p, file); }
static void out1str(const char *p) { outstr(p, stdout); }
static void out2str(const char *p) { outstr(p, stderr); }
* written implementation written by Aaron Lehmann <aaronl@vitelus.com>.
* This is now part of libbb, so that it can be used by all the shells
* in busybox. */
-#define ARITH_NUM 257
-#define ARITH_LPAREN 258
-#define ARITH_RPAREN 259
-#define ARITH_OR 260
-#define ARITH_AND 261
-#define ARITH_BOR 262
-#define ARITH_BXOR 263
-#define ARITH_BAND 264
-#define ARITH_EQ 265
-#define ARITH_NE 266
-#define ARITH_LT 267
-#define ARITH_GT 268
-#define ARITH_GE 269
-#define ARITH_LE 270
-#define ARITH_LSHIFT 271
-#define ARITH_RSHIFT 272
-#define ARITH_ADD 273
-#define ARITH_SUB 274
-#define ARITH_MUL 275
-#define ARITH_DIV 276
-#define ARITH_REM 277
-#define ARITH_UNARYMINUS 278
-#define ARITH_UNARYPLUS 279
-#define ARITH_NOT 280
-#define ARITH_BNOT 281
-
static void expari (int);
#endif
* of all the rest.)
*/
-static inline void
-evalpipe(n)
- union node *n;
+static inline void evalpipe(union node *n)
{
struct job *jp;
struct nodelist *lp;
* PEOF may be pushed back.
*/
-static void
-pungetc() {
+static void pungetc(void)
+{
parsenleft++;
parsenextc--;
}
* after a fork is done.
*/
-static void
-closescript() {
+static void closescript(void)
+{
popallfiles();
if (parsefile->fd > 0) {
close(parsefile->fd);
* interrupts off.
*/
-static void
-setinputfd(fd, push)
- int fd, push;
+static void setinputfd(int fd, int push)
{
(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
if (push) {
* input string.
*/
-static inline char *
-evalvar(p, flag)
- char *p;
- int flag;
+static inline char * evalvar(char *p, int flag)
{
int subtype;
int varflags;
#ifdef ASH_ALIAS
static int
-pgetc2()
+pgetc2(void)
{
int c;
do {
/* Return true if fd 0 has already been redirected at least once. */
static inline int
-fd0_redirected_p () {
+fd0_redirected_p (void)
+{
return fd0_redirected != 0;
}
cmdnextc = q;
}
-//#define CMDTXT_TABLE
+#define CMDTXT_TABLE
#ifdef CMDTXT_TABLE
/*
* To collect a lot of redundant code in cmdtxt() case statements, we
do {
if (*p & CMDTXT_STRING) { /* output fixed string */
cmdputs(cmdtxt_strings[((int)(*p & CMDTXT_OFFSETMASK) >> 1)]);
- } else if (*p & CMDTXT_CHARPTR) { /* output dynamic string */
- cmdputs(((const char *) n) + ((int)(*p & CMDTXT_OFFSETMASK)));
- } else { /* output field */
- cmdtxt((const union node *)
- (((const char *) n) + ((int)(*p & CMDTXT_OFFSETMASK))));
+ } else {
+ const char *pf = ((const char *) n)
+ + ((int)(*p & CMDTXT_OFFSETMASK));
+ if (*p & CMDTXT_CHARPTR) { /* output dynamic string */
+ cmdputs(*((const char **) pf));
+ } else { /* output field */
+ cmdtxt(*((const union node **) pf));
+ }
}
} while (!(*p++ & CMDTXT_NOMORE));
} else if (n->type == NCMD) {
break;
}
}
-#endif
+#endif /* CMDTXT_TABLE */
static char *
commandtext(const union node *n)
static inline char *
-find_dot_file(mybasename)
- char *mybasename;
+find_dot_file(char *mybasename)
{
char *fullname;
const char *path = pathval();
static struct nodelist *copynodelist (const struct nodelist *);
static char *nodesavestr (const char *);
-//#define CALCSIZE_TABLE
-//#define COPYNODE_TABLE
+#define CALCSIZE_TABLE
+#define COPYNODE_TABLE
#if defined(CALCSIZE_TABLE) || defined(COPYNODE_TABLE)
/*
* To collect a lot of redundant code in case statements for copynode()
union node *new;
const unsigned char *p;
- if (n == NULL)
- return NULL;
+ if (n == NULL) {
+ return NULL;
+ }
new = funcblock;
new->type = n->type;
funcblock = (char *) funcblock + (int) nodesize[n->type];
const char *no = ((const char *) n) + ((int)(*p & NODE_OFFSETMASK));
if (!(*p & NODE_MBRMASK)) { /* standard node */
- (union node *) nn = copynode((const union node *) no);
+ *((union node **)nn) = copynode(*((const union node **) no));
} else if ((*p & NODE_MBRMASK) == NODE_CHARPTR) { /* string */
- nn = nodesavestr(no);
+ *((const char **)nn) = nodesavestr(*((const char **)no));
} else if (*p & NODE_NODELIST) { /* nodelist */
- (struct nodelist *) nn
- = copynodelist((const struct nodelist *) no);
+ *((struct nodelist **)nn)
+ = copynodelist(*((const struct nodelist **) no));
} else { /* integer */
*((int *) nn) = *((int *) no);
}
union node *new;
if (n == NULL)
- return NULL;
+ return NULL;
new = funcblock;
funcblock = (char *) funcblock + nodesize[n->type];
switch (n->type) {
const char *no = ((const char *) n) + ((int)(*p & NODE_OFFSETMASK));
if (!(*p & NODE_MBRMASK)) { /* standard node */
- calcsize((const union node *) no);
+ calcsize(*((const union node **) no));
} else if ((*p & NODE_MBRMASK) == NODE_CHARPTR) { /* string */
- funcstringsize += strlen(no) + 1;
+ funcstringsize += strlen(*((const char **)no)) + 1;
} else if (*p & NODE_NODELIST) { /* nodelist */
- sizenodelist((const struct nodelist *) no);
- }
+ sizenodelist(*((const struct nodelist **) no));
+ } /* else integer -- ignore */
} while (!(*p++ & NODE_NOMORE));
}
#else /* CALCSIZE_TABLE */
n1 = NULL;
rpp = &redir;
+ /* Check for redirection which may precede command */
+ while (readtoken() == TREDIR) {
+ *rpp = n2 = redirnode;
+ rpp = &n2->nfile.next;
+ parsefname();
+ }
+ tokpushback++;
+
switch (readtoken()) {
case TIF:
n1 = (union node *)stalloc(sizeof (struct nif));
if (!redir)
synexpect(-1);
case TWORD:
- case TREDIR:
tokpushback++;
n1 = simplecmd();
return n1;
* have parseword (readtoken1?) handle both words and redirection.]
*/
+#define NEW_xxreadtoken
+#ifdef NEW_xxreadtoken
+
+static const char xxreadtoken_chars[] = "\n()&|;"; /* singles must be first! */
+static const char xxreadtoken_tokens[] = {
+ TNL, TLP, TRP, /* only single occurrence allowed */
+ TBACKGND, TPIPE, TSEMI, /* if single occurrence */
+ TEOF, /* corresponds to trailing nul */
+ TAND, TOR, TENDCASE, /* if double occurrence */
+};
+
+#define xxreadtoken_doubles \
+ (sizeof(xxreadtoken_tokens) - sizeof(xxreadtoken_chars))
+#define xxreadtoken_singles \
+ (sizeof(xxreadtoken_chars) - xxreadtoken_doubles - 1)
+
+static int
+xxreadtoken() {
+ int c;
+
+ if (tokpushback) {
+ tokpushback = 0;
+ return lasttoken;
+ }
+ if (needprompt) {
+ setprompt(2);
+ needprompt = 0;
+ }
+ startlinno = plinno;
+ for (;;) { /* until token or start of word found */
+ c = pgetc_macro();
+
+ if ((c!=' ') && (c!='\t')
+#ifdef ASH_ALIAS
+ && (c!=PEOA)
+#endif
+ ) {
+ if (c=='#') {
+ while ((c = pgetc()) != '\n' && c != PEOF);
+ pungetc();
+ } else if (c=='\\') {
+ if (pgetc() != '\n') {
+ pungetc();
+ goto READTOKEN1;
+ }
+ startlinno = ++plinno;
+ setprompt(doprompt ? 2 : 0);
+ } else {
+ const char *p
+ = xxreadtoken_chars + sizeof(xxreadtoken_chars) - 1;
+
+ if (c!=PEOF) {
+ if (c=='\n') {
+ plinno++;
+ needprompt = doprompt;
+ }
+
+ p = strchr(xxreadtoken_chars, c);
+ if (p == NULL) {
+ READTOKEN1:
+ return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
+ }
+
+ if (p-xxreadtoken_chars >= xxreadtoken_singles) {
+ if (pgetc() == *p) { /* double occurrence? */
+ p += xxreadtoken_doubles + 1;
+ } else {
+ pungetc();
+ }
+ }
+ }
+
+ return lasttoken = xxreadtoken_tokens[p-xxreadtoken_chars];
+ }
+ }
+ }
+}
+
+
+#else
#define RETURN(token) return lasttoken = token
static int
return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
#undef RETURN
}
-
+#endif
/*
/*
* Copyright (c) 1999 Herbert Xu <herbert@debian.org>
* This file contains code for the times builtin.
- * $Id: ash.c,v 1.21 2001/08/10 21:11:56 andersen Exp $
+ * $Id: ash.c,v 1.27 2001/10/19 00:08:17 andersen Exp $
*/
static int timescmd (int argc, char **argv)
{