id: fix infinite loop on some systems
[coreutils/ericb.git] / src / expr.c
blob65e74af9f453dd3d7d874ef9555b7a0d33b2baaa
1 /* expr -- evaluate expressions.
2 Copyright (C) 86, 1991-1997, 1999-2008 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 3 of the License, or
7 (at your option) 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, see <http://www.gnu.org/licenses/>. */
17 /* Author: Mike Parker.
18 Modified for arbitrary-precision calculation by James Youngman.
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 "error.h"
38 #include "long-options.h"
39 #include "quotearg.h"
40 #include "strnumcmp.h"
41 #include "xstrtol.h"
43 /* Various parts of this code assume size_t fits into unsigned long
44 int, the widest unsigned type that GMP supports. */
45 verify (SIZE_MAX <= ULONG_MAX);
47 static void integer_overflow (char) ATTRIBUTE_NORETURN;
49 #ifndef HAVE_GMP
50 # define HAVE_GMP 0
51 #endif
53 #if HAVE_GMP
54 # include <gmp.h>
55 #else
56 /* Approximate gmp.h well enough for expr.c's purposes. */
57 typedef intmax_t mpz_t[1];
58 static void mpz_clear (mpz_t z) {}
59 static void mpz_init_set_ui (mpz_t z, unsigned long int i) { z[0] = i; }
60 static int
61 mpz_init_set_str (mpz_t z, char *s, int base)
63 return xstrtoimax (s, NULL, base, z, NULL) == LONGINT_OK ? 0 : -1;
65 static void
66 mpz_add (mpz_t r, mpz_t a0, mpz_t b0)
68 intmax_t a = a0[0];
69 intmax_t b = b0[0];
70 intmax_t val = a + b;
71 if ((val < a) != (b < 0))
72 integer_overflow ('+');
73 r[0] = val;
75 static void
76 mpz_sub (mpz_t r, mpz_t a0, mpz_t b0)
78 intmax_t a = a0[0];
79 intmax_t b = b0[0];
80 intmax_t val = a - b;
81 if ((a < val) != (b < 0))
82 integer_overflow ('-');
83 r[0] = val;
85 static void
86 mpz_mul (mpz_t r, mpz_t a0, mpz_t b0)
88 intmax_t a = a0[0];
89 intmax_t b = b0[0];
90 intmax_t val = a * b;
91 if (! (a == 0 || b == 0
92 || ((val < 0) == ((a < 0) ^ (b < 0)) && val / a == b)))
93 integer_overflow ('*');
94 r[0] = val;
96 static void
97 mpz_tdiv_q (mpz_t r, mpz_t a0, mpz_t b0)
99 intmax_t a = a0[0];
100 intmax_t b = b0[0];
102 /* Some x86-style hosts raise an exception for INT_MIN / -1. */
103 if (a < - INTMAX_MAX && b == -1)
104 integer_overflow ('/');
105 r[0] = a / b;
107 static void
108 mpz_tdiv_r (mpz_t r, mpz_t a0, mpz_t b0)
110 intmax_t a = a0[0];
111 intmax_t b = b0[0];
113 /* Some x86-style hosts raise an exception for INT_MIN % -1. */
114 r[0] = a < - INTMAX_MAX && b == -1 ? 0 : a % b;
116 static char *
117 mpz_get_str (char const *str, int base, mpz_t z)
119 char buf[INT_BUFSIZE_BOUND (intmax_t)];
120 return xstrdup (imaxtostr (z[0], buf));
122 static int
123 mpz_sgn (mpz_t z)
125 return z[0] < 0 ? -1 : 0 < z[0];
127 static int
128 mpz_fits_ulong_p (mpz_t z)
130 return 0 <= z[0] && z[0] <= ULONG_MAX;
132 static unsigned long int
133 mpz_get_ui (mpz_t z)
135 return z[0];
137 static int
138 mpz_out_str (FILE *stream, int base, mpz_t z)
140 char buf[INT_BUFSIZE_BOUND (intmax_t)];
141 return fputs (imaxtostr (z[0], buf), stream) != EOF;
143 #endif
145 /* The official name of this program (e.g., no `g' prefix). */
146 #define PROGRAM_NAME "expr"
148 #define AUTHORS \
149 proper_name ("Mike Parker"), \
150 proper_name ("James Youngman"), \
151 proper_name ("Paul Eggert")
153 /* Exit statuses. */
154 enum
156 /* Invalid expression: e.g., its form does not conform to the
157 grammar for expressions. Our grammar is an extension of the
158 POSIX grammar. */
159 EXPR_INVALID = 2,
161 /* An internal error occurred, e.g., arithmetic overflow, storage
162 exhaustion. */
163 EXPR_FAILURE
166 /* The kinds of value we can have. */
167 enum valtype
169 integer,
170 string
172 typedef enum valtype TYPE;
174 /* A value is.... */
175 struct valinfo
177 TYPE type; /* Which kind. */
178 union
179 { /* The value itself. */
180 mpz_t i;
181 char *s;
182 } u;
184 typedef struct valinfo VALUE;
186 /* The arguments given to the program, minus the program name. */
187 static char **args;
189 static VALUE *eval (bool);
190 static bool nomoreargs (void);
191 static bool null (VALUE *v);
192 static void printv (VALUE *v);
194 void
195 usage (int status)
197 if (status != EXIT_SUCCESS)
198 fprintf (stderr, _("Try `%s --help' for more information.\n"),
199 program_name);
200 else
202 printf (_("\
203 Usage: %s EXPRESSION\n\
204 or: %s OPTION\n\
206 program_name, program_name);
207 putchar ('\n');
208 fputs (HELP_OPTION_DESCRIPTION, stdout);
209 fputs (VERSION_OPTION_DESCRIPTION, stdout);
210 fputs (_("\
212 Print the value of EXPRESSION to standard output. A blank line below\n\
213 separates increasing precedence groups. EXPRESSION may be:\n\
215 ARG1 | ARG2 ARG1 if it is neither null nor 0, otherwise ARG2\n\
217 ARG1 & ARG2 ARG1 if neither argument is null or 0, otherwise 0\n\
218 "), stdout);
219 fputs (_("\
221 ARG1 < ARG2 ARG1 is less than ARG2\n\
222 ARG1 <= ARG2 ARG1 is less than or equal to ARG2\n\
223 ARG1 = ARG2 ARG1 is equal to ARG2\n\
224 ARG1 != ARG2 ARG1 is unequal to ARG2\n\
225 ARG1 >= ARG2 ARG1 is greater than or equal to ARG2\n\
226 ARG1 > ARG2 ARG1 is greater than ARG2\n\
227 "), stdout);
228 fputs (_("\
230 ARG1 + ARG2 arithmetic sum of ARG1 and ARG2\n\
231 ARG1 - ARG2 arithmetic difference of ARG1 and ARG2\n\
232 "), stdout);
233 /* Tell xgettext that the "% A" below is not a printf-style
234 format string: xgettext:no-c-format */
235 fputs (_("\
237 ARG1 * ARG2 arithmetic product of ARG1 and ARG2\n\
238 ARG1 / ARG2 arithmetic quotient of ARG1 divided by ARG2\n\
239 ARG1 % ARG2 arithmetic remainder of ARG1 divided by ARG2\n\
240 "), stdout);
241 fputs (_("\
243 STRING : REGEXP anchored pattern match of REGEXP in STRING\n\
245 match STRING REGEXP same as STRING : REGEXP\n\
246 substr STRING POS LENGTH substring of STRING, POS counted from 1\n\
247 index STRING CHARS index in STRING where any CHARS is found, or 0\n\
248 length STRING length of STRING\n\
249 "), stdout);
250 fputs (_("\
251 + TOKEN interpret TOKEN as a string, even if it is a\n\
252 keyword like `match' or an operator like `/'\n\
254 ( EXPRESSION ) value of EXPRESSION\n\
255 "), stdout);
256 fputs (_("\
258 Beware that many operators need to be escaped or quoted for shells.\n\
259 Comparisons are arithmetic if both ARGs are numbers, else lexicographical.\n\
260 Pattern matches return the string matched between \\( and \\) or null; if\n\
261 \\( and \\) are not used, they return the number of characters matched or 0.\n\
262 "), stdout);
263 fputs (_("\
265 Exit status is 0 if EXPRESSION is neither null nor 0, 1 if EXPRESSION is null\n\
266 or 0, 2 if EXPRESSION is syntactically invalid, and 3 if an error occurred.\n\
267 "), stdout);
268 emit_bug_reporting_address ();
270 exit (status);
273 /* Report a syntax error and exit. */
274 static void
275 syntax_error (void)
277 error (EXPR_INVALID, 0, _("syntax error"));
280 /* Report an integer overflow for operation OP and exit. */
281 static void
282 integer_overflow (char op)
284 error (EXPR_FAILURE, ERANGE, "%c", op);
285 abort (); /* notreached */
288 static void die (int errno_val, char const *msg)
289 ATTRIBUTE_NORETURN;
290 static void
291 die (int errno_val, char const *msg)
293 error (EXPR_FAILURE, errno_val, "%s", msg);
294 abort (); /* notreached */
298 main (int argc, char **argv)
300 VALUE *v;
302 initialize_main (&argc, &argv);
303 set_program_name (argv[0]);
304 setlocale (LC_ALL, "");
305 bindtextdomain (PACKAGE, LOCALEDIR);
306 textdomain (PACKAGE);
308 initialize_exit_failure (EXPR_FAILURE);
309 atexit (close_stdout);
311 parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, VERSION,
312 usage, AUTHORS, (char const *) NULL);
313 /* The above handles --help and --version.
314 Since there is no other invocation of getopt, handle `--' here. */
315 if (argc > 1 && STREQ (argv[1], "--"))
317 --argc;
318 ++argv;
321 if (argc <= 1)
323 error (0, 0, _("missing operand"));
324 usage (EXPR_INVALID);
327 args = argv + 1;
329 v = eval (true);
330 if (!nomoreargs ())
331 syntax_error ();
332 printv (v);
334 exit (null (v));
337 /* Return a VALUE for I. */
339 static VALUE *
340 int_value (unsigned long int i)
342 VALUE *v = xmalloc (sizeof *v);
343 v->type = integer;
344 mpz_init_set_ui (v->u.i, i);
345 return v;
348 /* Return a VALUE for S. */
350 static VALUE *
351 str_value (char const *s)
353 VALUE *v = xmalloc (sizeof *v);
354 v->type = string;
355 v->u.s = xstrdup (s);
356 return v;
359 /* Free VALUE V, including structure components. */
361 static void
362 freev (VALUE *v)
364 if (v->type == string)
365 free (v->u.s);
366 else
367 mpz_clear (v->u.i);
368 free (v);
371 /* Print VALUE V. */
373 static void
374 printv (VALUE *v)
376 switch (v->type)
378 case integer:
379 mpz_out_str (stdout, 10, v->u.i);
380 putchar ('\n');
381 break;
382 case string:
383 puts (v->u.s);
384 break;
385 default:
386 abort ();
390 /* Return true if V is a null-string or zero-number. */
392 static bool
393 null (VALUE *v)
395 switch (v->type)
397 case integer:
398 return mpz_sgn (v->u.i) == 0;
399 case string:
401 char const *cp = v->u.s;
402 if (*cp == '\0')
403 return true;
405 cp += (*cp == '-');
409 if (*cp != '0')
410 return false;
412 while (*++cp);
414 return true;
416 default:
417 abort ();
421 /* Return true if CP takes the form of an integer. */
423 static bool
424 looks_like_integer (char const *cp)
426 cp += (*cp == '-');
429 if (! ISDIGIT (*cp))
430 return false;
431 while (*++cp);
433 return true;
436 /* Coerce V to a string value (can't fail). */
438 static void
439 tostring (VALUE *v)
441 switch (v->type)
443 case integer:
445 char *s = mpz_get_str (NULL, 10, v->u.i);
446 mpz_clear (v->u.i);
447 v->u.s = s;
448 v->type = string;
450 break;
451 case string:
452 break;
453 default:
454 abort ();
458 /* Coerce V to an integer value. Return true on success, false on failure. */
460 static bool
461 toarith (VALUE *v)
463 switch (v->type)
465 case integer:
466 return true;
467 case string:
469 char *s = v->u.s;
471 if (! looks_like_integer (s))
472 return false;
473 if (mpz_init_set_str (v->u.i, s, 10) != 0 && !HAVE_GMP)
474 error (EXPR_FAILURE, ERANGE, "%s", s);
475 free (s);
476 v->type = integer;
477 return true;
479 default:
480 abort ();
484 /* Extract a size_t value from a integer value I.
485 If the value is negative, return SIZE_MAX.
486 If the value is too large, return SIZE_MAX - 1. */
487 static size_t
488 getsize (mpz_t i)
490 if (mpz_sgn (i) < 0)
491 return SIZE_MAX;
492 if (mpz_fits_ulong_p (i))
494 unsigned long int ul = mpz_get_ui (i);
495 if (ul < SIZE_MAX)
496 return ul;
498 return SIZE_MAX - 1;
501 /* Return true and advance if the next token matches STR exactly.
502 STR must not be NULL. */
504 static bool
505 nextarg (char const *str)
507 if (*args == NULL)
508 return false;
509 else
511 bool r = STREQ (*args, str);
512 args += r;
513 return r;
517 /* Return true if there no more tokens. */
519 static bool
520 nomoreargs (void)
522 return *args == 0;
525 #ifdef EVAL_TRACE
526 /* Print evaluation trace and args remaining. */
528 static void
529 trace (fxn)
530 char *fxn;
532 char **a;
534 printf ("%s:", fxn);
535 for (a = args; *a; a++)
536 printf (" %s", *a);
537 putchar ('\n');
539 #endif
541 /* Do the : operator.
542 SV is the VALUE for the lhs (the string),
543 PV is the VALUE for the rhs (the pattern). */
545 static VALUE *
546 docolon (VALUE *sv, VALUE *pv)
548 VALUE *v IF_LINT (= NULL);
549 const char *errmsg;
550 struct re_pattern_buffer re_buffer;
551 char fastmap[UCHAR_MAX + 1];
552 struct re_registers re_regs;
553 regoff_t matchlen;
555 tostring (sv);
556 tostring (pv);
558 re_regs.num_regs = 0;
559 re_regs.start = NULL;
560 re_regs.end = NULL;
562 re_buffer.buffer = NULL;
563 re_buffer.allocated = 0;
564 re_buffer.fastmap = fastmap;
565 re_buffer.translate = NULL;
566 re_syntax_options =
567 RE_SYNTAX_POSIX_BASIC & ~RE_CONTEXT_INVALID_DUP & ~RE_NO_EMPTY_RANGES;
568 errmsg = re_compile_pattern (pv->u.s, strlen (pv->u.s), &re_buffer);
569 if (errmsg)
570 error (EXPR_INVALID, 0, "%s", errmsg);
571 re_buffer.newline_anchor = 0;
573 matchlen = re_match (&re_buffer, sv->u.s, strlen (sv->u.s), 0, &re_regs);
574 if (0 <= matchlen)
576 /* Were \(...\) used? */
577 if (re_buffer.re_nsub > 0)
579 sv->u.s[re_regs.end[1]] = '\0';
580 v = str_value (sv->u.s + re_regs.start[1]);
582 else
583 v = int_value (matchlen);
585 else if (matchlen == -1)
587 /* Match failed -- return the right kind of null. */
588 if (re_buffer.re_nsub > 0)
589 v = str_value ("");
590 else
591 v = int_value (0);
593 else
594 error (EXPR_FAILURE,
595 (matchlen == -2 ? errno : EOVERFLOW),
596 _("error in regular expression matcher"));
598 if (0 < re_regs.num_regs)
600 free (re_regs.start);
601 free (re_regs.end);
603 re_buffer.fastmap = NULL;
604 regfree (&re_buffer);
605 return v;
608 /* Handle bare operands and ( expr ) syntax. */
610 static VALUE *
611 eval7 (bool evaluate)
613 VALUE *v;
615 #ifdef EVAL_TRACE
616 trace ("eval7");
617 #endif
618 if (nomoreargs ())
619 syntax_error ();
621 if (nextarg ("("))
623 v = eval (evaluate);
624 if (!nextarg (")"))
625 syntax_error ();
626 return v;
629 if (nextarg (")"))
630 syntax_error ();
632 return str_value (*args++);
635 /* Handle match, substr, index, and length keywords, and quoting "+". */
637 static VALUE *
638 eval6 (bool evaluate)
640 VALUE *l;
641 VALUE *r;
642 VALUE *v;
643 VALUE *i1;
644 VALUE *i2;
646 #ifdef EVAL_TRACE
647 trace ("eval6");
648 #endif
649 if (nextarg ("+"))
651 if (nomoreargs ())
652 syntax_error ();
653 return str_value (*args++);
655 else if (nextarg ("length"))
657 r = eval6 (evaluate);
658 tostring (r);
659 v = int_value (strlen (r->u.s));
660 freev (r);
661 return v;
663 else if (nextarg ("match"))
665 l = eval6 (evaluate);
666 r = eval6 (evaluate);
667 if (evaluate)
669 v = docolon (l, r);
670 freev (l);
672 else
673 v = l;
674 freev (r);
675 return v;
677 else if (nextarg ("index"))
679 size_t pos;
681 l = eval6 (evaluate);
682 r = eval6 (evaluate);
683 tostring (l);
684 tostring (r);
685 pos = strcspn (l->u.s, r->u.s);
686 v = int_value (l->u.s[pos] ? pos + 1 : 0);
687 freev (l);
688 freev (r);
689 return v;
691 else if (nextarg ("substr"))
693 size_t llen;
694 l = eval6 (evaluate);
695 i1 = eval6 (evaluate);
696 i2 = eval6 (evaluate);
697 tostring (l);
698 llen = strlen (l->u.s);
700 if (!toarith (i1) || !toarith (i2))
701 v = str_value ("");
702 else
704 size_t pos = getsize (i1->u.i);
705 size_t len = getsize (i2->u.i);
707 if (llen < pos || pos == 0 || len == 0 || len == SIZE_MAX)
708 v = str_value ("");
709 else
711 size_t vlen = MIN (len, llen - pos + 1);
712 char *vlim;
713 v = xmalloc (sizeof *v);
714 v->type = string;
715 v->u.s = xmalloc (vlen + 1);
716 vlim = mempcpy (v->u.s, l->u.s + pos - 1, vlen);
717 *vlim = '\0';
720 freev (l);
721 freev (i1);
722 freev (i2);
723 return v;
725 else
726 return eval7 (evaluate);
729 /* Handle : operator (pattern matching).
730 Calls docolon to do the real work. */
732 static VALUE *
733 eval5 (bool evaluate)
735 VALUE *l;
736 VALUE *r;
737 VALUE *v;
739 #ifdef EVAL_TRACE
740 trace ("eval5");
741 #endif
742 l = eval6 (evaluate);
743 while (1)
745 if (nextarg (":"))
747 r = eval6 (evaluate);
748 if (evaluate)
750 v = docolon (l, r);
751 freev (l);
752 l = v;
754 freev (r);
756 else
757 return l;
761 /* Handle *, /, % operators. */
763 static VALUE *
764 eval4 (bool evaluate)
766 VALUE *l;
767 VALUE *r;
768 enum { multiply, divide, mod } fxn;
770 #ifdef EVAL_TRACE
771 trace ("eval4");
772 #endif
773 l = eval5 (evaluate);
774 while (1)
776 if (nextarg ("*"))
777 fxn = multiply;
778 else if (nextarg ("/"))
779 fxn = divide;
780 else if (nextarg ("%"))
781 fxn = mod;
782 else
783 return l;
784 r = eval5 (evaluate);
785 if (evaluate)
787 if (!toarith (l) || !toarith (r))
788 error (EXPR_INVALID, 0, _("non-numeric argument"));
789 if (fxn != multiply && mpz_sgn (r->u.i) == 0)
790 error (EXPR_INVALID, 0, _("division by zero"));
791 ((fxn == multiply ? mpz_mul
792 : fxn == divide ? mpz_tdiv_q
793 : mpz_tdiv_r)
794 (l->u.i, l->u.i, r->u.i));
796 freev (r);
800 /* Handle +, - operators. */
802 static VALUE *
803 eval3 (bool evaluate)
805 VALUE *l;
806 VALUE *r;
807 enum { plus, minus } fxn;
809 #ifdef EVAL_TRACE
810 trace ("eval3");
811 #endif
812 l = eval4 (evaluate);
813 while (1)
815 if (nextarg ("+"))
816 fxn = plus;
817 else if (nextarg ("-"))
818 fxn = minus;
819 else
820 return l;
821 r = eval4 (evaluate);
822 if (evaluate)
824 if (!toarith (l) || !toarith (r))
825 error (EXPR_INVALID, 0, _("non-numeric argument"));
826 (fxn == plus ? mpz_add : mpz_sub) (l->u.i, l->u.i, r->u.i);
828 freev (r);
832 /* Handle comparisons. */
834 static VALUE *
835 eval2 (bool evaluate)
837 VALUE *l;
839 #ifdef EVAL_TRACE
840 trace ("eval2");
841 #endif
842 l = eval3 (evaluate);
843 while (1)
845 VALUE *r;
846 enum
848 less_than, less_equal, equal, not_equal, greater_equal, greater_than
849 } fxn;
850 bool val = false;
852 if (nextarg ("<"))
853 fxn = less_than;
854 else if (nextarg ("<="))
855 fxn = less_equal;
856 else if (nextarg ("=") || nextarg ("=="))
857 fxn = equal;
858 else if (nextarg ("!="))
859 fxn = not_equal;
860 else if (nextarg (">="))
861 fxn = greater_equal;
862 else if (nextarg (">"))
863 fxn = greater_than;
864 else
865 return l;
866 r = eval3 (evaluate);
868 if (evaluate)
870 int cmp;
871 tostring (l);
872 tostring (r);
874 if (looks_like_integer (l->u.s) && looks_like_integer (r->u.s))
875 cmp = strintcmp (l->u.s, r->u.s);
876 else
878 errno = 0;
879 cmp = strcoll (l->u.s, r->u.s);
881 if (errno)
883 error (0, errno, _("string comparison failed"));
884 error (0, 0, _("set LC_ALL='C' to work around the problem"));
885 error (EXPR_INVALID, 0,
886 _("the strings compared were %s and %s"),
887 quotearg_n_style (0, locale_quoting_style, l->u.s),
888 quotearg_n_style (1, locale_quoting_style, r->u.s));
892 switch (fxn)
894 case less_than: val = (cmp < 0); break;
895 case less_equal: val = (cmp <= 0); break;
896 case equal: val = (cmp == 0); break;
897 case not_equal: val = (cmp != 0); break;
898 case greater_equal: val = (cmp >= 0); break;
899 case greater_than: val = (cmp > 0); break;
900 default: abort ();
904 freev (l);
905 freev (r);
906 l = int_value (val);
910 /* Handle &. */
912 static VALUE *
913 eval1 (bool evaluate)
915 VALUE *l;
916 VALUE *r;
918 #ifdef EVAL_TRACE
919 trace ("eval1");
920 #endif
921 l = eval2 (evaluate);
922 while (1)
924 if (nextarg ("&"))
926 r = eval2 (evaluate & ~ null (l));
927 if (null (l) || null (r))
929 freev (l);
930 freev (r);
931 l = int_value (0);
933 else
934 freev (r);
936 else
937 return l;
941 /* Handle |. */
943 static VALUE *
944 eval (bool evaluate)
946 VALUE *l;
947 VALUE *r;
949 #ifdef EVAL_TRACE
950 trace ("eval");
951 #endif
952 l = eval1 (evaluate);
953 while (1)
955 if (nextarg ("|"))
957 r = eval1 (evaluate & null (l));
958 if (null (l))
960 freev (l);
961 l = r;
962 if (null (l))
964 freev (l);
965 l = int_value (0);
968 else
969 freev (r);
971 else
972 return l;