merge with 1.8.1d
[coreutils.git] / src / expr.c
blob221f5dd726445b9e5a777e982d93e8536c69a39e
1 /* expr -- evaluate expressions.
2 Copyright (C) 1986, 1991 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18 /* Author: Mike Parker.
20 This program evaluates expressions. Each token (operator, operand,
21 parenthesis) of the expression must be a seperate argument. The
22 parser used is a reasonably general one, though any incarnation of
23 it is language-specific. It is especially nice for expressions.
25 No parse tree is needed; a new node is evaluated immediately.
26 One function can handle multiple operators all of equal precedence,
27 provided they all associate ((x op x) op x).
29 Define EVAL_TRACE to print an evaluation trace. */
31 #ifdef HAVE_CONFIG_H
32 #if defined (CONFIG_BROKETS)
33 /* We use <config.h> instead of "config.h" so that a compilation
34 using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
35 (which it would do because it found this file in $srcdir). */
36 #include <config.h>
37 #else
38 #include "config.h"
39 #endif
40 #endif
42 #include <stdio.h>
43 #include <ctype.h>
44 #include <sys/types.h>
45 #include <regex.h>
47 #include "system.h"
48 #include "version.h"
50 #if !defined (isascii) || defined (STDC_HEADERS)
51 #undef isascii
52 #define isascii(c) 1
53 #endif
55 #define ISDIGIT(c) (isascii (c) && isdigit (c))
57 #if !__STDC__
58 #define const
59 #endif
61 #define NEW(type) ((type *) xmalloc (sizeof (type)))
62 #define OLD(x) free ((char *) x)
64 /* The kinds of value we can have. */
65 enum valtype
67 integer,
68 string
70 typedef enum valtype TYPE;
72 /* A value is.... */
73 struct valinfo
75 TYPE type; /* Which kind. */
76 union
77 { /* The value itself. */
78 int i;
79 char *s;
80 } u;
82 typedef struct valinfo VALUE;
84 /* The arguments given to the program, minus the program name. */
85 static char **args;
87 /* The name this program was run with. */
88 char *program_name;
90 void error ();
91 char *xstrdup ();
92 char *strstr ();
93 char *xmalloc ();
94 void parse_long_options ();
96 static VALUE *docolon ();
97 static VALUE *eval ();
98 static VALUE *int_value ();
99 static VALUE *str_value ();
100 static int isstring ();
101 static int nextarg ();
102 static int nomoreargs ();
103 static int null ();
104 static int toarith ();
105 static void freev ();
106 static void printv ();
107 static void tostring ();
109 #ifdef EVAL_TRACE
110 static void trace ();
111 #endif
113 static void
114 usage ()
116 fprintf (stderr, "Usage: %s [{--help,--version}] expression...\n",
117 program_name);
118 exit (1);
121 void
122 main (argc, argv)
123 int argc;
124 char **argv;
126 VALUE *v;
128 program_name = argv[0];
130 parse_long_options (argc, argv, usage);
132 if (argc == 1)
133 usage ();
134 args = argv + 1;
136 v = eval ();
137 if (!nomoreargs ())
138 error (2, 0, "syntax error");
139 printv (v);
141 exit (null (v));
144 /* Return a VALUE for I. */
146 static VALUE *
147 int_value (i)
148 int i;
150 VALUE *v;
152 v = NEW (VALUE);
153 v->type = integer;
154 v->u.i = i;
155 return v;
158 /* Return a VALUE for S. */
160 static VALUE *
161 str_value (s)
162 char *s;
164 VALUE *v;
166 v = NEW (VALUE);
167 v->type = string;
168 v->u.s = xstrdup (s);
169 return v;
172 /* Free VALUE V, including structure components. */
174 static void
175 freev (v)
176 VALUE *v;
178 if (v->type == string)
179 free (v->u.s);
180 OLD (v);
183 /* Print VALUE V. */
185 static void
186 printv (v)
187 VALUE *v;
189 switch (v->type)
191 case integer:
192 printf ("%d\n", v->u.i);
193 break;
194 case string:
195 printf ("%s\n", v->u.s);
196 break;
197 default:
198 abort ();
202 /* Return nonzero if V is a null-string or zero-number. */
204 static int
205 null (v)
206 VALUE *v;
208 switch (v->type)
210 case integer:
211 return v->u.i == 0;
212 case string:
213 return v->u.s[0] == '\0' || strcmp(v->u.s, "0") == 0;
214 default:
215 abort ();
219 /* Return nonzero if V is a string value. */
221 static int
222 isstring (v)
223 VALUE *v;
225 return v->type == string;
228 /* Coerce V to a string value (can't fail). */
230 static void
231 tostring (v)
232 VALUE *v;
234 char *temp;
236 switch (v->type)
238 case integer:
239 temp = xmalloc (4 * (sizeof (int) / sizeof (char)));
240 sprintf (temp, "%d", v->u.i);
241 v->u.s = temp;
242 v->type = string;
243 break;
244 case string:
245 break;
246 default:
247 abort ();
251 /* Coerce V to an integer value. Return 1 on success, 0 on failure. */
253 static int
254 toarith (v)
255 VALUE *v;
257 int i;
258 int neg;
259 char *cp;
261 switch (v->type)
263 case integer:
264 return 1;
265 case string:
266 i = 0;
267 cp = v->u.s;
268 neg = (*cp == '-');
269 if (neg)
270 cp++;
271 for (; *cp; cp++)
273 if (ISDIGIT (*cp))
274 i = i * 10 + *cp - '0';
275 else
276 return 0;
278 free (v->u.s);
279 v->u.i = i * (neg ? -1 : 1);
280 v->type = integer;
281 return 1;
282 default:
283 abort ();
287 /* Return nonzero if the next token matches STR exactly.
288 STR must not be NULL. */
290 static int
291 nextarg (str)
292 char *str;
294 if (*args == NULL)
295 return 0;
296 return strcmp (*args, str) == 0;
299 /* Return nonzero if there no more tokens. */
301 static int
302 nomoreargs ()
304 return *args == 0;
307 /* The comparison operator handling functions. */
309 #define cmpf(name, rel) \
310 static \
311 int name (l, r) VALUE *l; VALUE *r; \
313 if (isstring (l) || isstring (r)) \
315 tostring (l); \
316 tostring (r); \
317 return strcmp (l->u.s, r->u.s) rel 0; \
319 else \
320 return l->u.i rel r->u.i; \
322 cmpf (less_than, <)
323 cmpf (less_equal, <=)
324 cmpf (equal, ==)
325 cmpf (not_equal, !=)
326 cmpf (greater_equal, >=)
327 cmpf (greater_than, >)
329 #undef cmpf
331 /* The arithmetic operator handling functions. */
333 #define arithf(name, op) \
334 static \
335 int name (l, r) VALUE *l; VALUE *r; \
337 if (!toarith (l) || !toarith (r)) \
338 error (2, 0, "non-numeric argument"); \
339 return l->u.i op r->u.i; \
342 #define arithdivf(name, op) \
343 int name (l, r) VALUE *l; VALUE *r; \
345 if (!toarith (l) || !toarith (r)) \
346 error (2, 0, "non-numeric argument"); \
347 if (r->u.i == 0) \
348 error (2, 0, "division by zero"); \
349 return l->u.i op r->u.i; \
352 arithf (plus, +)
353 arithf (minus, -)
354 arithf (multiply, *)
355 arithdivf (divide, /)
356 arithdivf (mod, %)
358 #undef arithf
359 #undef arithdivf
361 #ifdef EVAL_TRACE
362 /* Print evaluation trace and args remaining. */
364 static void
365 trace (fxn)
366 char *fxn;
368 char **a;
370 printf ("%s:", fxn);
371 for (a = args; *a; a++)
372 printf (" %s", *a);
373 putchar ('\n');
375 #endif
377 /* Do the : operator.
378 SV is the VALUE for the lhs (the string),
379 PV is the VALUE for the rhs (the pattern). */
381 static VALUE *
382 docolon (sv, pv)
383 VALUE *sv;
384 VALUE *pv;
386 VALUE *v;
387 const char *errmsg;
388 struct re_pattern_buffer re_buffer;
389 struct re_registers re_regs;
390 int len;
392 tostring (sv);
393 tostring (pv);
395 len = strlen (pv->u.s);
396 re_buffer.allocated = 2 * len;
397 re_buffer.buffer = (unsigned char *) xmalloc (re_buffer.allocated);
398 re_buffer.translate = 0;
399 errmsg = re_compile_pattern (pv->u.s, len, &re_buffer);
400 if (errmsg)
401 error (2, 0, "%s", errmsg);
403 len = re_match (&re_buffer, sv->u.s, strlen (sv->u.s), 0, &re_regs);
404 if (len >= 0)
406 /* Were \(...\) used? */
407 if (re_buffer.re_nsub > 0)/* was (re_regs.start[1] >= 0) */
409 sv->u.s[re_regs.end[1]] = '\0';
410 v = str_value (sv->u.s + re_regs.start[1]);
412 else
413 v = int_value (len);
415 else
417 /* Match failed -- return the right kind of null. */
418 if (strstr (pv->u.s, "\\("))
419 v = str_value ("");
420 else
421 v = int_value (0);
423 free (re_buffer.buffer);
424 return v;
427 /* Handle bare operands and ( expr ) syntax. */
429 static VALUE *
430 eval7 ()
432 VALUE *v;
434 #ifdef EVAL_TRACE
435 trace ("eval7");
436 #endif
437 if (nomoreargs ())
438 error (2, 0, "syntax error");
440 if (nextarg ("("))
442 args++;
443 v = eval ();
444 if (!nextarg (")"))
445 error (2, 0, "syntax error");
446 args++;
447 return v;
450 if (nextarg (")"))
451 error (2, 0, "syntax error");
453 return str_value (*args++);
456 /* Handle match, substr, index, and length keywords. */
458 static VALUE *
459 eval6 ()
461 VALUE *l;
462 VALUE *r;
463 VALUE *v;
464 VALUE *i1;
465 VALUE *i2;
467 #ifdef EVAL_TRACE
468 trace ("eval6");
469 #endif
470 if (nextarg ("length"))
472 args++;
473 r = eval6 ();
474 tostring (r);
475 v = int_value (strlen (r->u.s));
476 freev (r);
477 return v;
479 else if (nextarg ("match"))
481 args++;
482 l = eval6 ();
483 r = eval6 ();
484 v = docolon (l, r);
485 freev (l);
486 freev (r);
487 return v;
489 else if (nextarg ("index"))
491 args++;
492 l = eval6 ();
493 r = eval6 ();
494 tostring (l);
495 tostring (r);
496 v = int_value (strcspn (l->u.s, r->u.s) + 1);
497 if (v->u.i == strlen (l->u.s) + 1)
498 v->u.i = 0;
499 freev (l);
500 freev (r);
501 return v;
503 else if (nextarg ("substr"))
505 args++;
506 l = eval6 ();
507 i1 = eval6 ();
508 i2 = eval6 ();
509 tostring (l);
510 if (!toarith (i1) || !toarith (i2)
511 || i1->u.i > strlen (l->u.s)
512 || i1->u.i <= 0 || i2->u.i <= 0)
513 v = str_value ("");
514 else
516 v = NEW (VALUE);
517 v->type = string;
518 v->u.s = strncpy ((char *) xmalloc (i2->u.i + 1),
519 l->u.s + i1->u.i - 1, i2->u.i);
520 v->u.s[i2->u.i] = 0;
522 freev (l);
523 freev (i1);
524 freev (i2);
525 return v;
527 else
528 return eval7 ();
531 /* Handle : operator (pattern matching).
532 Calls docolon to do the real work. */
534 static VALUE *
535 eval5 ()
537 VALUE *l;
538 VALUE *r;
539 VALUE *v;
541 #ifdef EVAL_TRACE
542 trace ("eval5");
543 #endif
544 l = eval6 ();
545 while (1)
547 if (nextarg (":"))
549 args++;
550 r = eval6 ();
551 v = docolon (l, r);
552 freev (l);
553 freev (r);
554 l = v;
556 else
557 return l;
561 /* Handle *, /, % operators. */
563 static VALUE *
564 eval4 ()
566 VALUE *l;
567 VALUE *r;
568 int (*fxn) ();
569 int val;
571 #ifdef EVAL_TRACE
572 trace ("eval4");
573 #endif
574 l = eval5 ();
575 while (1)
577 if (nextarg ("*"))
578 fxn = multiply;
579 else if (nextarg ("/"))
580 fxn = divide;
581 else if (nextarg ("%"))
582 fxn = mod;
583 else
584 return l;
585 args++;
586 r = eval5 ();
587 val = (*fxn) (l, r);
588 freev (l);
589 freev (r);
590 l = int_value (val);
594 /* Handle +, - operators. */
596 static VALUE *
597 eval3 ()
599 VALUE *l;
600 VALUE *r;
601 int (*fxn) ();
602 int val;
604 #ifdef EVAL_TRACE
605 trace ("eval3");
606 #endif
607 l = eval4 ();
608 while (1)
610 if (nextarg ("+"))
611 fxn = plus;
612 else if (nextarg ("-"))
613 fxn = minus;
614 else
615 return l;
616 args++;
617 r = eval4 ();
618 val = (*fxn) (l, r);
619 freev (l);
620 freev (r);
621 l = int_value (val);
625 /* Handle comparisons. */
627 static VALUE *
628 eval2 ()
630 VALUE *l;
631 VALUE *r;
632 int (*fxn) ();
633 int val;
635 #ifdef EVAL_TRACE
636 trace ("eval2");
637 #endif
638 l = eval3 ();
639 while (1)
641 if (nextarg ("<"))
642 fxn = less_than;
643 else if (nextarg ("<="))
644 fxn = less_equal;
645 else if (nextarg ("=") || nextarg ("=="))
646 fxn = equal;
647 else if (nextarg ("!="))
648 fxn = not_equal;
649 else if (nextarg (">="))
650 fxn = greater_equal;
651 else if (nextarg (">"))
652 fxn = greater_than;
653 else
654 return l;
655 args++;
656 r = eval3 ();
657 toarith (l);
658 toarith (r);
659 val = (*fxn) (l, r);
660 freev (l);
661 freev (r);
662 l = int_value (val);
666 /* Handle &. */
668 static VALUE *
669 eval1 ()
671 VALUE *l;
672 VALUE *r;
674 #ifdef EVAL_TRACE
675 trace ("eval1");
676 #endif
677 l = eval2 ();
678 while (1)
680 if (nextarg ("&"))
682 args++;
683 r = eval2 ();
684 if (null (l) || null (r))
686 freev (l);
687 freev (r);
688 l = int_value (0);
690 else
691 freev (r);
693 else
694 return l;
698 /* Handle |. */
700 static VALUE *
701 eval ()
703 VALUE *l;
704 VALUE *r;
706 #ifdef EVAL_TRACE
707 trace ("eval");
708 #endif
709 l = eval1 ();
710 while (1)
712 if (nextarg ("|"))
714 args++;
715 r = eval1 ();
716 if (null (l))
718 freev (l);
719 l = r;
721 else
722 freev (r);
724 else
725 return l;