aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2003-08-29 07:29:30 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2003-08-29 07:29:30 +0000
commit7b8765c808641d74edd1f0a4f22c092ea21421fa (patch)
treef15b6c928209cc41ad172054caa8831e618066b4
parent23365976f8e0265adc2f21d8e330ce58e270041a (diff)
downloadbusybox-w32-7b8765c808641d74edd1f0a4f22c092ea21421fa.tar.gz
busybox-w32-7b8765c808641d74edd1f0a4f22c092ea21421fa.tar.bz2
busybox-w32-7b8765c808641d74edd1f0a4f22c092ea21421fa.zip
vodz, last patch 103
-rw-r--r--coreutils/expr.c141
-rw-r--r--shell/ash.c109
2 files changed, 114 insertions, 136 deletions
diff --git a/coreutils/expr.c b/coreutils/expr.c
index ecba825d5..f58f4b062 100644
--- a/coreutils/expr.c
+++ b/coreutils/expr.c
@@ -7,6 +7,7 @@
7 * 7 *
8 * Busybox modifications 8 * Busybox modifications
9 * Copyright (c) 2000 Edward Betts <edward@debian.org>. 9 * Copyright (c) 2000 Edward Betts <edward@debian.org>.
10 * Aug 2003 Vladimir Oleynik - reduced 464 bytes.
10 * 11 *
11 * this program is free software; you can redistribute it and/or modify 12 * this program is free software; you can redistribute it and/or modify
12 * it under the terms of the gnu general public license as published by 13 * it under the terms of the gnu general public license as published by
@@ -40,6 +41,7 @@
40#include <stdlib.h> 41#include <stdlib.h>
41#include <regex.h> 42#include <regex.h>
42#include <sys/types.h> 43#include <sys/types.h>
44#include <errno.h>
43#include "busybox.h" 45#include "busybox.h"
44 46
45 47
@@ -135,10 +137,8 @@ static int null (VALUE *v)
135 switch (v->type) { 137 switch (v->type) {
136 case integer: 138 case integer:
137 return v->u.i == 0; 139 return v->u.i == 0;
138 case string: 140 default: /* string: */
139 return v->u.s[0] == '\0' || strcmp (v->u.s, "0") == 0; 141 return v->u.s[0] == '\0' || strcmp (v->u.s, "0") == 0;
140 default:
141 abort ();
142 } 142 }
143} 143}
144 144
@@ -156,13 +156,9 @@ static void tostring (VALUE *v)
156 156
157static int toarith (VALUE *v) 157static int toarith (VALUE *v)
158{ 158{
159 if(v->type == string) {
159 int i; 160 int i;
160 161
161 switch (v->type) {
162 case integer:
163 return 1;
164 case string:
165 i = 0;
166 /* Don't interpret the empty string as an integer. */ 162 /* Don't interpret the empty string as an integer. */
167 if (v->u.s == 0) 163 if (v->u.s == 0)
168 return 0; 164 return 0;
@@ -170,10 +166,8 @@ static int toarith (VALUE *v)
170 free (v->u.s); 166 free (v->u.s);
171 v->u.i = i; 167 v->u.i = i;
172 v->type = integer; 168 v->type = integer;
173 return 1;
174 default:
175 abort ();
176 } 169 }
170 return 1;
177} 171}
178 172
179/* Return nonzero if the next token matches STR exactly. 173/* Return nonzero if the next token matches STR exactly.
@@ -189,56 +183,59 @@ nextarg (char *str)
189 183
190/* The comparison operator handling functions. */ 184/* The comparison operator handling functions. */
191 185
192#define cmpf(name, rel) \ 186static int cmp_common (VALUE *l, VALUE *r, int op)
193static int name (VALUE *l, VALUE *r) \ 187{
194{ \ 188 int cmpval;
195 if (l->type == string || r->type == string) { \
196 tostring (l); \
197 tostring (r); \
198 return strcmp (l->u.s, r->u.s) rel 0; \
199 } \
200 else \
201 return l->u.i rel r->u.i; \
202}
203 cmpf (less_than, <)
204 cmpf (less_equal, <=)
205 cmpf (equal, ==)
206 cmpf (not_equal, !=)
207 cmpf (greater_equal, >=)
208 cmpf (greater_than, >)
209 189
210#undef cmpf 190 if (l->type == string || r->type == string) {
191 tostring (l);
192 tostring (r);
193 cmpval = strcmp (l->u.s, r->u.s);
194 }
195 else
196 cmpval = l->u.i - r->u.i;
197 switch(op) {
198 case '<':
199 return cmpval < 0;
200 case ('L'+'E'):
201 return cmpval <= 0;
202 case '=':
203 return cmpval == 0;
204 case '!':
205 return cmpval != 0;
206 case '>':
207 return cmpval > 0;
208 default: /* >= */
209 return cmpval >= 0;
210 }
211}
211 212
212/* The arithmetic operator handling functions. */ 213/* The arithmetic operator handling functions. */
213 214
214#define arithf(name, op) \ 215static int arithmetic_common (VALUE *l, VALUE *r, int op)
215static \ 216{
216int name (VALUE *l, VALUE *r) \ 217 int li, ri;
217{ \ 218
218 if (!toarith (l) || !toarith (r)) \ 219 if (!toarith (l) || !toarith (r))
219 bb_error_msg_and_die ("non-numeric argument"); \ 220 bb_error_msg_and_die ("non-numeric argument");
220 return l->u.i op r->u.i; \ 221 li = l->u.i;
221} 222 ri = r->u.i;
222 223 if((op == '/' || op == '%') && ri == 0)
223#define arithdivf(name, op) \ 224 bb_error_msg_and_die ( "division by zero");
224static int name (VALUE *l, VALUE *r) \ 225 switch(op) {
225{ \ 226 case '+':
226 if (!toarith (l) || !toarith (r)) \ 227 return li + ri;
227 bb_error_msg_and_die ( "non-numeric argument"); \ 228 case '-':
228 if (r->u.i == 0) \ 229 return li - ri;
229 bb_error_msg_and_die ( "division by zero"); \ 230 case '*':
230 return l->u.i op r->u.i; \ 231 return li * ri;
232 case '/':
233 return li / ri;
234 default:
235 return li % ri;
236 }
231} 237}
232 238
233 arithf (plus, +)
234 arithf (minus, -)
235 arithf (multiply, *)
236 arithdivf (divide, /)
237 arithdivf (mod, %)
238
239#undef arithf
240#undef arithdivf
241
242/* Do the : operator. 239/* Do the : operator.
243 SV is the VALUE for the lhs (the string), 240 SV is the VALUE for the lhs (the string),
244 PV is the VALUE for the rhs (the pattern). */ 241 PV is the VALUE for the rhs (the pattern). */
@@ -408,21 +405,21 @@ static VALUE *eval5 (void)
408static VALUE *eval4 (void) 405static VALUE *eval4 (void)
409{ 406{
410 VALUE *l, *r; 407 VALUE *l, *r;
411 int (*fxn) (VALUE *, VALUE *), val; 408 int op, val;
412 409
413 l = eval5 (); 410 l = eval5 ();
414 while (1) { 411 while (1) {
415 if (nextarg ("*")) 412 if (nextarg ("*"))
416 fxn = multiply; 413 op = '*';
417 else if (nextarg ("/")) 414 else if (nextarg ("/"))
418 fxn = divide; 415 op = '/';
419 else if (nextarg ("%")) 416 else if (nextarg ("%"))
420 fxn = mod; 417 op = '%';
421 else 418 else
422 return l; 419 return l;
423 args++; 420 args++;
424 r = eval5 (); 421 r = eval5 ();
425 val = (*fxn) (l, r); 422 val = arithmetic_common (l, r, op);
426 freev (l); 423 freev (l);
427 freev (r); 424 freev (r);
428 l = int_value (val); 425 l = int_value (val);
@@ -434,19 +431,19 @@ static VALUE *eval4 (void)
434static VALUE *eval3 (void) 431static VALUE *eval3 (void)
435{ 432{
436 VALUE *l, *r; 433 VALUE *l, *r;
437 int (*fxn) (VALUE *, VALUE *), val; 434 int op, val;
438 435
439 l = eval4 (); 436 l = eval4 ();
440 while (1) { 437 while (1) {
441 if (nextarg ("+")) 438 if (nextarg ("+"))
442 fxn = plus; 439 op = '+';
443 else if (nextarg ("-")) 440 else if (nextarg ("-"))
444 fxn = minus; 441 op = '+';
445 else 442 else
446 return l; 443 return l;
447 args++; 444 args++;
448 r = eval4 (); 445 r = eval4 ();
449 val = (*fxn) (l, r); 446 val = arithmetic_common (l, r, op);
450 freev (l); 447 freev (l);
451 freev (r); 448 freev (r);
452 l = int_value (val); 449 l = int_value (val);
@@ -458,29 +455,29 @@ static VALUE *eval3 (void)
458static VALUE *eval2 (void) 455static VALUE *eval2 (void)
459{ 456{
460 VALUE *l, *r; 457 VALUE *l, *r;
461 int (*fxn) (VALUE *, VALUE *), val; 458 int op, val;
462 459
463 l = eval3 (); 460 l = eval3 ();
464 while (1) { 461 while (1) {
465 if (nextarg ("<")) 462 if (nextarg ("<"))
466 fxn = less_than; 463 op = '<';
467 else if (nextarg ("<=")) 464 else if (nextarg ("<="))
468 fxn = less_equal; 465 op = 'L'+'E';
469 else if (nextarg ("=") || nextarg ("==")) 466 else if (nextarg ("=") || nextarg ("=="))
470 fxn = equal; 467 op = '=';
471 else if (nextarg ("!=")) 468 else if (nextarg ("!="))
472 fxn = not_equal; 469 op = '!';
473 else if (nextarg (">=")) 470 else if (nextarg (">="))
474 fxn = greater_equal; 471 op = 'G'+'E';
475 else if (nextarg (">")) 472 else if (nextarg (">"))
476 fxn = greater_than; 473 op = '>';
477 else 474 else
478 return l; 475 return l;
479 args++; 476 args++;
480 r = eval3 (); 477 r = eval3 ();
481 toarith (l); 478 toarith (l);
482 toarith (r); 479 toarith (r);
483 val = (*fxn) (l, r); 480 val = cmp_common (l, r, op);
484 freev (l); 481 freev (l);
485 freev (r); 482 freev (r);
486 l = int_value (val); 483 l = int_value (val);
diff --git a/shell/ash.c b/shell/ash.c
index 547ad906b..ec33a106c 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -1625,9 +1625,8 @@ static int fmtstr(char *, size_t, const char *, ...)
1625 __attribute__((__format__(__printf__,3,4))); 1625 __attribute__((__format__(__printf__,3,4)));
1626static void xwrite(int, const void *, size_t); 1626static void xwrite(int, const void *, size_t);
1627 1627
1628static int preverrout_fd; /* save fd2 before print debug if xflag is set. */
1628 1629
1629#define outerr(f) ferror(f)
1630#define out2c(c) outcslow((c), stderr)
1631 1630
1632static void out1str(const char *p) 1631static void out1str(const char *p)
1633{ 1632{
@@ -1637,15 +1636,7 @@ static void out1str(const char *p)
1637static void out2str(const char *p) 1636static void out2str(const char *p)
1638{ 1637{
1639 outstr(p, stderr); 1638 outstr(p, stderr);
1640} 1639 flushout(stderr);
1641
1642static void out1c(char c)
1643{
1644 char s[2];
1645
1646 s[0] = c;
1647 s[1] = 0;
1648 outstr(s, stdout);
1649} 1640}
1650 1641
1651/* 1642/*
@@ -1988,6 +1979,7 @@ static int nextopt(const char *);
1988 1979
1989/* flags passed to redirect */ 1980/* flags passed to redirect */
1990#define REDIR_PUSH 01 /* save previous values of file descriptors */ 1981#define REDIR_PUSH 01 /* save previous values of file descriptors */
1982#define REDIR_SAVEFD2 03 /* set preverrout */
1991 1983
1992union node; 1984union node;
1993static void redirect(union node *, int); 1985static void redirect(union node *, int);
@@ -2674,7 +2666,6 @@ static void evalcommand(union node *, int);
2674static int evalbltin(const struct builtincmd *, int, char **); 2666static int evalbltin(const struct builtincmd *, int, char **);
2675static int evalfun(struct funcnode *, int, char **, int); 2667static int evalfun(struct funcnode *, int, char **, int);
2676static void prehash(union node *); 2668static void prehash(union node *);
2677static int eprintlist(struct strlist *, int);
2678static int bltincmd(int, char **); 2669static int bltincmd(int, char **);
2679 2670
2680 2671
@@ -2765,7 +2756,7 @@ evaltree(union node *n, int flags)
2765 default: 2756 default:
2766#ifdef DEBUG 2757#ifdef DEBUG
2767 out1fmt("Node type = %d\n", n->type); 2758 out1fmt("Node type = %d\n", n->type);
2768 flushout(stdout); 2759 fflush(stdout);
2769 break; 2760 break;
2770#endif 2761#endif
2771 case NNOT: 2762 case NNOT:
@@ -3201,7 +3192,7 @@ evalcommand(union node *cmd, int flags)
3201 struct arglist varlist; 3192 struct arglist varlist;
3202 char **argv; 3193 char **argv;
3203 int argc; 3194 int argc;
3204 struct strlist *sp; 3195 const struct strlist *sp;
3205 struct cmdentry cmdentry; 3196 struct cmdentry cmdentry;
3206 struct job *jp; 3197 struct job *jp;
3207 char *lastarg; 3198 char *lastarg;
@@ -3244,8 +3235,9 @@ evalcommand(union node *cmd, int flags)
3244 if (iflag && funcnest == 0 && argc > 0) 3235 if (iflag && funcnest == 0 && argc > 0)
3245 lastarg = nargv[-1]; 3236 lastarg = nargv[-1];
3246 3237
3238 preverrout_fd = 2;
3247 expredir(cmd->ncmd.redirect); 3239 expredir(cmd->ncmd.redirect);
3248 status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH); 3240 status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH|REDIR_SAVEFD2);
3249 3241
3250 path = vpath.text; 3242 path = vpath.text;
3251 for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) { 3243 for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
@@ -3266,14 +3258,24 @@ evalcommand(union node *cmd, int flags)
3266 3258
3267 /* Print the command if xflag is set. */ 3259 /* Print the command if xflag is set. */
3268 if (xflag) { 3260 if (xflag) {
3269 int sep; 3261 int n;
3262 const char *p = " %s";
3270 3263
3271 out2str(ps4val()); 3264 p++;
3272 sep = 0; 3265 dprintf(preverrout_fd, p, ps4val());
3273 sep = eprintlist(varlist.list, sep); 3266
3274 eprintlist(arglist.list, sep); 3267 sp = varlist.list;
3275 out2c('\n'); 3268 for(n = 0; n < 2; n++) {
3276 flushall(); 3269 while (sp) {
3270 dprintf(preverrout_fd, p, sp->text);
3271 sp = sp->next;
3272 if(*p == '%') {
3273 p--;
3274 }
3275 }
3276 sp = arglist.list;
3277 }
3278 xwrite(preverrout_fd, "\n", 1);
3277 } 3279 }
3278 3280
3279 cmd_is_exec = 0; 3281 cmd_is_exec = 0;
@@ -3418,7 +3420,7 @@ evalbltin(const struct builtincmd *cmd, int argc, char **argv) {
3418 exitstatus = (*cmd->builtin)(argc, argv); 3420 exitstatus = (*cmd->builtin)(argc, argv);
3419 flushall(); 3421 flushall();
3420cmddone: 3422cmddone:
3421 exitstatus |= outerr(stdout); 3423 exitstatus |= ferror(stdout);
3422 commandname = savecmdname; 3424 commandname = savecmdname;
3423 exsig = 0; 3425 exsig = 0;
3424 handler = savehandler; 3426 handler = savehandler;
@@ -3588,20 +3590,6 @@ execcmd(int argc, char **argv)
3588} 3590}
3589 3591
3590 3592
3591static int
3592eprintlist(struct strlist *sp, int sep)
3593{
3594 while (sp) {
3595 const char *p;
3596
3597 p = " %s" + (1 - sep);
3598 sep |= 1;
3599 fprintf(stderr, p, sp->text);
3600 sp = sp->next;
3601 }
3602
3603 return sep;
3604}
3605/* $NetBSD: exec.c,v 1.35 2003/01/22 20:36:04 dsl Exp $ */ 3593/* $NetBSD: exec.c,v 1.35 2003/01/22 20:36:04 dsl Exp $ */
3606 3594
3607/* 3595/*
@@ -3632,7 +3620,6 @@ static int builtinloc = -1; /* index in path of %builtin, or -1 */
3632 3620
3633 3621
3634static void tryexec(char *, char **, char **); 3622static void tryexec(char *, char **, char **);
3635static void printentry(struct tblentry *);
3636static void clearcmdentry(int); 3623static void clearcmdentry(int);
3637static struct tblentry *cmdlookup(const char *, int); 3624static struct tblentry *cmdlookup(const char *, int);
3638static void delete_cmd_entry(void); 3625static void delete_cmd_entry(void);
@@ -3797,9 +3784,24 @@ padvance(const char **path, const char *name)
3797} 3784}
3798 3785
3799 3786
3800
3801/*** Command hashing code ***/ 3787/*** Command hashing code ***/
3802 3788
3789static void
3790printentry(struct tblentry *cmdp)
3791{
3792 int idx;
3793 const char *path;
3794 char *name;
3795
3796 idx = cmdp->param.index;
3797 path = pathval();
3798 do {
3799 name = padvance(&path, cmdp->cmdname);
3800 stunalloc(name);
3801 } while (--idx >= 0);
3802 out1fmt("%s%s\n", name, (cmdp->rehash ? "*" : nullstr));
3803}
3804
3803 3805
3804static int 3806static int
3805hashcmd(int argc, char **argv) 3807hashcmd(int argc, char **argv)
@@ -3838,25 +3840,6 @@ hashcmd(int argc, char **argv)
3838} 3840}
3839 3841
3840 3842
3841static void
3842printentry(struct tblentry *cmdp)
3843{
3844 int idx;
3845 const char *path;
3846 char *name;
3847
3848 idx = cmdp->param.index;
3849 path = pathval();
3850 do {
3851 name = padvance(&path, cmdp->cmdname);
3852 stunalloc(name);
3853 } while (--idx >= 0);
3854 out1str(name);
3855 out1fmt(snlfmt, cmdp->rehash ? "*" : nullstr);
3856}
3857
3858
3859
3860/* 3843/*
3861 * Resolve a command name. If you change this routine, you may have to 3844 * Resolve a command name. If you change this routine, you may have to
3862 * change the shellexec routine as well. 3845 * change the shellexec routine as well.
@@ -4401,7 +4384,7 @@ describe_command(char *command)
4401 } 4384 }
4402 4385
4403out: 4386out:
4404 out1c('\n'); 4387 outstr("\n", stdout);
4405 return 0; 4388 return 0;
4406} 4389}
4407 4390
@@ -6155,7 +6138,6 @@ check:
6155 6138
6156 if (vflag) { 6139 if (vflag) {
6157 out2str(parsenextc); 6140 out2str(parsenextc);
6158 flushout(stderr);
6159 } 6141 }
6160 6142
6161 *q = savec; 6143 *q = savec;
@@ -9208,9 +9190,8 @@ nextopt(const char *optstring)
9208 return c; 9190 return c;
9209} 9191}
9210 9192
9211/* $NetBSD: output.c,v 1.27 2002/11/24 22:35:42 christos Exp $ */
9212
9213 9193
9194/* $NetBSD: output.c,v 1.27 2002/11/24 22:35:42 christos Exp $ */
9214 9195
9215void 9196void
9216outstr(const char *p, FILE *file) 9197outstr(const char *p, FILE *file)
@@ -9229,7 +9210,6 @@ flushall(void)
9229 INTON; 9210 INTON;
9230} 9211}
9231 9212
9232
9233void 9213void
9234flushout(FILE *dest) 9214flushout(FILE *dest)
9235{ 9215{
@@ -11119,6 +11099,8 @@ redirect(union node *redir, int flags)
11119 dupredirect(n, newfd); 11099 dupredirect(n, newfd);
11120 } while ((n = n->nfile.next)); 11100 } while ((n = n->nfile.next));
11121 INTON; 11101 INTON;
11102 if (flags & REDIR_SAVEFD2 && sv && sv->renamed[2] >= 0)
11103 preverrout_fd = sv->renamed[2];
11122} 11104}
11123 11105
11124 11106
@@ -12544,7 +12526,6 @@ readcmd(int argc, char **argv)
12544 } 12526 }
12545 if (prompt && isatty(0)) { 12527 if (prompt && isatty(0)) {
12546 out2str(prompt); 12528 out2str(prompt);
12547 flushall();
12548 } 12529 }
12549 if (*(ap = argptr) == NULL) 12530 if (*(ap = argptr) == NULL)
12550 error("arg count"); 12531 error("arg count");