*** empty log message ***
[coreutils.git] / src / expr.c
bloba5781373b2401efa8cca4bceac1821a7a3b963df
1 /* expr -- evaluate expressions.
2 Copyright (C) 86, 1991-1997, 1999-2002 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 Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 #include <config.h>
32 #include <stdio.h>
33 #include <sys/types.h>
34 #include "system.h"
36 #include <regex.h>
37 #include "long-options.h"
38 #include "error.h"
39 #include "closeout.h"
40 #include "inttostr.h"
42 /* The official name of this program (e.g., no `g' prefix). */
43 #define PROGRAM_NAME "expr"
45 #define AUTHORS "Mike Parker"
47 #undef NEW
48 #define NEW(Type) XMALLOC (Type, 1)
49 #define OLD(x) free ((char *) x)
51 /* The kinds of value we can have. */
52 enum valtype
54 integer,
55 string
57 typedef enum valtype TYPE;
59 /* A value is.... */
60 struct valinfo
62 TYPE type; /* Which kind. */
63 union
64 { /* The value itself. */
65 intmax_t i;
66 char *s;
67 } u;
69 typedef struct valinfo VALUE;
71 /* The arguments given to the program, minus the program name. */
72 static char **args;
74 /* The name this program was run with. */
75 char *program_name;
77 static VALUE *eval (void);
78 static int nomoreargs (void);
79 static int null (VALUE *v);
80 static void printv (VALUE *v);
82 void
83 usage (int status)
85 if (status != 0)
86 fprintf (stderr, _("Try `%s --help' for more information.\n"),
87 program_name);
88 else
90 printf (_("\
91 Usage: %s EXPRESSION\n\
92 or: %s OPTION\n\
93 "),
94 program_name, program_name);
95 fputs ("\n", stdout);
96 fputs (HELP_OPTION_DESCRIPTION, stdout);
97 fputs (VERSION_OPTION_DESCRIPTION, stdout);
98 fputs (_("\
99 \n\
100 Print the value of EXPRESSION to standard output. A blank line below\n\
101 separates increasing precedence groups. EXPRESSION may be:\n\
103 ARG1 | ARG2 ARG1 if it is neither null nor 0, otherwise ARG2\n\
105 ARG1 & ARG2 ARG1 if neither argument is null or 0, otherwise 0\n\
106 "), stdout);
107 fputs (_("\
109 ARG1 < ARG2 ARG1 is less than ARG2\n\
110 ARG1 <= ARG2 ARG1 is less than or equal to ARG2\n\
111 ARG1 = ARG2 ARG1 is equal to ARG2\n\
112 ARG1 != ARG2 ARG1 is unequal to ARG2\n\
113 ARG1 >= ARG2 ARG1 is greater than or equal to ARG2\n\
114 ARG1 > ARG2 ARG1 is greater than ARG2\n\
115 "), stdout);
116 fputs (_("\
118 ARG1 + ARG2 arithmetic sum of ARG1 and ARG2\n\
119 ARG1 - ARG2 arithmetic difference of ARG1 and ARG2\n\
120 "), stdout);
121 fputs (_("\
123 ARG1 * ARG2 arithmetic product of ARG1 and ARG2\n\
124 ARG1 / ARG2 arithmetic quotient of ARG1 divided by ARG2\n\
125 ARG1 % ARG2 arithmetic remainder of ARG1 divided by ARG2\n\
126 "), stdout);
127 fputs (_("\
129 STRING : REGEXP anchored pattern match of REGEXP in STRING\n\
131 match STRING REGEXP same as STRING : REGEXP\n\
132 substr STRING POS LENGTH substring of STRING, POS counted from 1\n\
133 index STRING CHARS index in STRING where any CHARS is found, or 0\n\
134 length STRING length of STRING\n\
135 "), stdout);
136 fputs (_("\
137 + TOKEN interpret TOKEN as a string, even if it is a\n\
138 keyword like `match' or an operator like `/'\n\
140 ( EXPRESSION ) value of EXPRESSION\n\
141 "), stdout);
142 fputs (_("\
144 Beware that many operators need to be escaped or quoted for shells.\n\
145 Comparisons are arithmetic if both ARGs are numbers, else lexicographical.\n\
146 Pattern matches return the string matched between \\( and \\) or null; if\n\
147 \\( and \\) are not used, they return the number of characters matched or 0.\n\
148 "), stdout);
149 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
151 exit (status);
155 main (int argc, char **argv)
157 VALUE *v;
159 program_name = argv[0];
160 setlocale (LC_ALL, "");
161 bindtextdomain (PACKAGE, LOCALEDIR);
162 textdomain (PACKAGE);
164 atexit (close_stdout);
166 parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION,
167 AUTHORS, usage);
168 /* The above handles --help and --version.
169 Since there is no other invocation of getopt, handle `--' here. */
170 if (argc > 1 && STREQ (argv[1], "--"))
172 --argc;
173 ++argv;
176 if (argc == 1)
178 error (0, 0, _("too few arguments"));
179 usage (EXIT_FAILURE);
182 args = argv + 1;
184 v = eval ();
185 if (!nomoreargs ())
186 error (2, 0, _("syntax error"));
187 printv (v);
189 exit (null (v));
192 /* Return a VALUE for I. */
194 static VALUE *
195 int_value (intmax_t i)
197 VALUE *v;
199 v = NEW (VALUE);
200 v->type = integer;
201 v->u.i = i;
202 return v;
205 /* Return a VALUE for S. */
207 static VALUE *
208 str_value (char *s)
210 VALUE *v;
212 v = NEW (VALUE);
213 v->type = string;
214 v->u.s = xstrdup (s);
215 return v;
218 /* Free VALUE V, including structure components. */
220 static void
221 freev (VALUE *v)
223 if (v->type == string)
224 free (v->u.s);
225 OLD (v);
228 /* Print VALUE V. */
230 static void
231 printv (VALUE *v)
233 char *p;
234 char buf[INT_STRLEN_BOUND (intmax_t) + 1];
236 switch (v->type)
238 case integer:
239 p = imaxtostr (v->u.i, buf);
240 break;
241 case string:
242 p = v->u.s;
243 break;
244 default:
245 abort ();
248 puts (p);
251 /* Return nonzero if V is a null-string or zero-number. */
253 static int
254 null (VALUE *v)
256 switch (v->type)
258 case integer:
259 return v->u.i == 0;
260 case string:
261 return v->u.s[0] == '\0' || strcmp (v->u.s, "0") == 0;
262 default:
263 abort ();
267 /* Coerce V to a string value (can't fail). */
269 static void
270 tostring (VALUE *v)
272 char buf[INT_STRLEN_BOUND (intmax_t) + 1];
274 switch (v->type)
276 case integer:
277 v->u.s = xstrdup (imaxtostr (v->u.i, buf));
278 v->type = string;
279 break;
280 case string:
281 break;
282 default:
283 abort ();
287 /* Coerce V to an integer value. Return 1 on success, 0 on failure. */
289 static int
290 toarith (VALUE *v)
292 intmax_t i;
293 int neg;
294 char *cp;
296 switch (v->type)
298 case integer:
299 return 1;
300 case string:
301 i = 0;
302 cp = v->u.s;
303 neg = (*cp == '-');
304 if (neg)
305 cp++;
309 if (ISDIGIT (*cp))
310 i = i * 10 + *cp - '0';
311 else
312 return 0;
314 while (*++cp);
316 free (v->u.s);
317 v->u.i = i * (neg ? -1 : 1);
318 v->type = integer;
319 return 1;
320 default:
321 abort ();
325 /* Return nonzero and advance if the next token matches STR exactly.
326 STR must not be NULL. */
328 static int
329 nextarg (char *str)
331 if (*args == NULL)
332 return 0;
333 else
335 int r = strcoll (*args, str) == 0;
336 args += r;
337 return r;
341 /* Return nonzero if there no more tokens. */
343 static int
344 nomoreargs (void)
346 return *args == 0;
349 #ifdef EVAL_TRACE
350 /* Print evaluation trace and args remaining. */
352 static void
353 trace (fxn)
354 char *fxn;
356 char **a;
358 printf ("%s:", fxn);
359 for (a = args; *a; a++)
360 printf (" %s", *a);
361 putchar ('\n');
363 #endif
365 /* Do the : operator.
366 SV is the VALUE for the lhs (the string),
367 PV is the VALUE for the rhs (the pattern). */
369 static VALUE *
370 docolon (VALUE *sv, VALUE *pv)
372 VALUE *v;
373 const char *errmsg;
374 struct re_pattern_buffer re_buffer;
375 struct re_registers re_regs;
376 size_t len;
377 int matchlen;
379 tostring (sv);
380 tostring (pv);
382 if (pv->u.s[0] == '^')
384 error (0, 0, _("\
385 warning: unportable BRE: `%s': using `^' as the first character\n\
386 of the basic regular expression is not portable; it is being ignored"),
387 pv->u.s);
390 len = strlen (pv->u.s);
391 memset (&re_buffer, 0, sizeof (re_buffer));
392 memset (&re_regs, 0, sizeof (re_regs));
393 re_buffer.allocated = 2 * len;
394 if (re_buffer.allocated < len)
395 xalloc_die ();
396 re_buffer.buffer = (unsigned char *) xmalloc (re_buffer.allocated);
397 re_buffer.translate = 0;
398 re_syntax_options = RE_SYNTAX_POSIX_BASIC;
399 errmsg = re_compile_pattern (pv->u.s, len, &re_buffer);
400 if (errmsg)
401 error (2, 0, "%s", errmsg);
403 matchlen = re_match (&re_buffer, sv->u.s, strlen (sv->u.s), 0, &re_regs);
404 if (0 <= matchlen)
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 (matchlen);
415 else
417 /* Match failed -- return the right kind of null. */
418 if (re_buffer.re_nsub > 0)
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 (void)
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 v = eval ();
443 if (!nextarg (")"))
444 error (2, 0, _("syntax error"));
445 return v;
448 if (nextarg (")"))
449 error (2, 0, _("syntax error"));
451 return str_value (*args++);
454 /* Handle match, substr, index, and length keywords, and quoting "+". */
456 static VALUE *
457 eval6 (void)
459 VALUE *l;
460 VALUE *r;
461 VALUE *v;
462 VALUE *i1;
463 VALUE *i2;
465 #ifdef EVAL_TRACE
466 trace ("eval6");
467 #endif
468 if (nextarg ("+"))
470 if (nomoreargs ())
471 error (2, 0, _("syntax error"));
472 return str_value (*args++);
474 else if (nextarg ("length"))
476 r = eval6 ();
477 tostring (r);
478 v = int_value (strlen (r->u.s));
479 freev (r);
480 return v;
482 else if (nextarg ("match"))
484 l = eval6 ();
485 r = eval6 ();
486 v = docolon (l, r);
487 freev (l);
488 freev (r);
489 return v;
491 else if (nextarg ("index"))
493 l = eval6 ();
494 r = eval6 ();
495 tostring (l);
496 tostring (r);
497 v = int_value (strcspn (l->u.s, r->u.s) + 1);
498 if (v->u.i == strlen (l->u.s) + 1)
499 v->u.i = 0;
500 freev (l);
501 freev (r);
502 return v;
504 else if (nextarg ("substr"))
506 l = eval6 ();
507 i1 = eval6 ();
508 i2 = eval6 ();
509 tostring (l);
510 if (!toarith (i1) || !toarith (i2)
511 || strlen (l->u.s) < i1->u.i
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 (void)
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 r = eval6 ();
550 v = docolon (l, r);
551 freev (l);
552 freev (r);
553 l = v;
555 else
556 return l;
560 /* Handle *, /, % operators. */
562 static VALUE *
563 eval4 (void)
565 VALUE *l;
566 VALUE *r;
567 enum { multiply, divide, mod } fxn;
568 intmax_t val;
570 #ifdef EVAL_TRACE
571 trace ("eval4");
572 #endif
573 l = eval5 ();
574 while (1)
576 if (nextarg ("*"))
577 fxn = multiply;
578 else if (nextarg ("/"))
579 fxn = divide;
580 else if (nextarg ("%"))
581 fxn = mod;
582 else
583 return l;
584 r = eval5 ();
585 if (!toarith (l) || !toarith (r))
586 error (2, 0, _("non-numeric argument"));
587 if (fxn == multiply)
588 val = l->u.i * r->u.i;
589 else
591 if (r->u.i == 0)
592 error (2, 0, _("division by zero"));
593 val = fxn == divide ? l->u.i / r->u.i : l->u.i % r->u.i;
595 freev (l);
596 freev (r);
597 l = int_value (val);
601 /* Handle +, - operators. */
603 static VALUE *
604 eval3 (void)
606 VALUE *l;
607 VALUE *r;
608 enum { plus, minus } fxn;
609 intmax_t val;
611 #ifdef EVAL_TRACE
612 trace ("eval3");
613 #endif
614 l = eval4 ();
615 while (1)
617 if (nextarg ("+"))
618 fxn = plus;
619 else if (nextarg ("-"))
620 fxn = minus;
621 else
622 return l;
623 r = eval4 ();
624 if (!toarith (l) || !toarith (r))
625 error (2, 0, _("non-numeric argument"));
626 val = fxn == plus ? l->u.i + r->u.i : l->u.i - r->u.i;
627 freev (l);
628 freev (r);
629 l = int_value (val);
633 /* Handle comparisons. */
635 static VALUE *
636 eval2 (void)
638 VALUE *l;
639 VALUE *r;
640 enum
642 less_than, less_equal, equal, not_equal, greater_equal, greater_than
643 } fxn;
644 int val;
645 intmax_t lval;
646 intmax_t rval;
648 #ifdef EVAL_TRACE
649 trace ("eval2");
650 #endif
651 l = eval3 ();
652 while (1)
654 if (nextarg ("<"))
655 fxn = less_than;
656 else if (nextarg ("<="))
657 fxn = less_equal;
658 else if (nextarg ("=") || nextarg ("=="))
659 fxn = equal;
660 else if (nextarg ("!="))
661 fxn = not_equal;
662 else if (nextarg (">="))
663 fxn = greater_equal;
664 else if (nextarg (">"))
665 fxn = greater_than;
666 else
667 return l;
668 r = eval3 ();
669 tostring (l);
670 tostring (r);
671 lval = strcoll (l->u.s, r->u.s);
672 rval = 0;
673 if (toarith (l) && toarith (r))
675 lval = l->u.i;
676 rval = r->u.i;
678 switch (fxn)
680 case less_than: val = (lval < rval); break;
681 case less_equal: val = (lval <= rval); break;
682 case equal: val = (lval == rval); break;
683 case not_equal: val = (lval != rval); break;
684 case greater_equal: val = (lval >= rval); break;
685 case greater_than: val = (lval > rval); break;
686 default: abort ();
688 freev (l);
689 freev (r);
690 l = int_value (val);
694 /* Handle &. */
696 static VALUE *
697 eval1 (void)
699 VALUE *l;
700 VALUE *r;
702 #ifdef EVAL_TRACE
703 trace ("eval1");
704 #endif
705 l = eval2 ();
706 while (1)
708 if (nextarg ("&"))
710 r = eval2 ();
711 if (null (l) || null (r))
713 freev (l);
714 freev (r);
715 l = int_value (0);
717 else
718 freev (r);
720 else
721 return l;
725 /* Handle |. */
727 static VALUE *
728 eval (void)
730 VALUE *l;
731 VALUE *r;
733 #ifdef EVAL_TRACE
734 trace ("eval");
735 #endif
736 l = eval1 ();
737 while (1)
739 if (nextarg ("|"))
741 r = eval1 ();
742 if (null (l))
744 freev (l);
745 l = r;
747 else
748 freev (r);
750 else
751 return l;