xref: /dragonfly/bin/expr/expr.y (revision 5de36205)
1 %{
2 /* Written by Pace Willisson (pace@blitz.com)
3  * and placed in the public domain.
4  *
5  * Largely rewritten by J.T. Conklin (jtc@wimsey.com)
6  *
7  * $FreeBSD: src/bin/expr/expr.y,v 1.14.2.3 2001/08/01 02:37:46 obrien Exp $
8  * $DragonFly: src/bin/expr/expr.y,v 1.5 2004/11/07 20:54:51 eirikn Exp $
9  */
10 
11 #include <sys/types.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <locale.h>
16 #include <ctype.h>
17 #include <err.h>
18 #include <errno.h>
19 #include <regex.h>
20 #include <limits.h>
21 
22 enum valtype {
23 	integer, numeric_string, string
24 } ;
25 
26 struct val {
27 	enum valtype type;
28 	union {
29 		char *s;
30 		quad_t i;
31 	} u;
32 } ;
33 
34 struct val *result;
35 
36 int		chk_div (quad_t, quad_t);
37 int		chk_minus (quad_t, quad_t, quad_t);
38 int		chk_plus (quad_t, quad_t, quad_t);
39 int		chk_times (quad_t, quad_t, quad_t);
40 void		free_value (struct val *);
41 int		is_zero_or_null (struct val *);
42 int		isstring (struct val *);
43 int		main (int, char **);
44 struct val	*make_integer (quad_t);
45 struct val	*make_str (const char *);
46 struct val	*op_and (struct val *, struct val *);
47 struct val	*op_colon (struct val *, struct val *);
48 struct val	*op_div (struct val *, struct val *);
49 struct val	*op_eq (struct val *, struct val *);
50 struct val	*op_ge (struct val *, struct val *);
51 struct val	*op_gt (struct val *, struct val *);
52 struct val	*op_le (struct val *, struct val *);
53 struct val	*op_lt (struct val *, struct val *);
54 struct val	*op_minus (struct val *, struct val *);
55 struct val	*op_ne (struct val *, struct val *);
56 struct val	*op_or (struct val *, struct val *);
57 struct val	*op_plus (struct val *, struct val *);
58 struct val	*op_rem (struct val *, struct val *);
59 struct val	*op_times (struct val *, struct val *);
60 quad_t		to_integer (struct val *);
61 void		to_string (struct val *);
62 int		yyerror (const char *);
63 int		yylex (void);
64 int		yyparse (void);
65 
66 char **av;
67 %}
68 
69 %union
70 {
71 	struct val *val;
72 }
73 
74 %left <val> '|'
75 %left <val> '&'
76 %left <val> '=' '>' '<' GE LE NE
77 %left <val> '+' '-'
78 %left <val> '*' '/' '%'
79 %left <val> ':'
80 
81 %token <val> TOKEN
82 %type <val> start expr
83 
84 %%
85 
86 start: expr { result = $$; }
87 
88 expr:	TOKEN
89 	| '(' expr ')' { $$ = $2; }
90 	| expr '|' expr { $$ = op_or ($1, $3); }
91 	| expr '&' expr { $$ = op_and ($1, $3); }
92 	| expr '=' expr { $$ = op_eq ($1, $3); }
93 	| expr '>' expr { $$ = op_gt ($1, $3); }
94 	| expr '<' expr { $$ = op_lt ($1, $3); }
95 	| expr GE expr  { $$ = op_ge ($1, $3); }
96 	| expr LE expr  { $$ = op_le ($1, $3); }
97 	| expr NE expr  { $$ = op_ne ($1, $3); }
98 	| expr '+' expr { $$ = op_plus ($1, $3); }
99 	| expr '-' expr { $$ = op_minus ($1, $3); }
100 	| expr '*' expr { $$ = op_times ($1, $3); }
101 	| expr '/' expr { $$ = op_div ($1, $3); }
102 	| expr '%' expr { $$ = op_rem ($1, $3); }
103 	| expr ':' expr { $$ = op_colon ($1, $3); }
104 	;
105 
106 
107 %%
108 
109 struct val *
110 make_integer (i)
111 quad_t i;
112 {
113 	struct val *vp;
114 
115 	vp = (struct val *) malloc (sizeof (*vp));
116 	if (vp == NULL) {
117 		errx (2, "malloc() failed");
118 	}
119 
120 	vp->type = integer;
121 	vp->u.i  = i;
122 	return vp;
123 }
124 
125 struct val *
126 make_str (s)
127 const char *s;
128 {
129 	struct val *vp;
130 	size_t i;
131 	int isint;
132 
133 	vp = (struct val *) malloc (sizeof (*vp));
134 	if (vp == NULL || ((vp->u.s = strdup (s)) == NULL)) {
135 		errx (2, "malloc() failed");
136 	}
137 
138 	for(i = 1, isint = isdigit(s[0]) || s[0] == '-';
139 	    isint && i < strlen(s);
140 	    i++)
141 	{
142 		if(!isdigit(s[i]))
143 			 isint = 0;
144 	}
145 
146 	if (isint)
147 		vp->type = numeric_string;
148 	else
149 		vp->type = string;
150 
151 	return vp;
152 }
153 
154 
155 void
156 free_value (vp)
157 struct val *vp;
158 {
159 	if (vp->type == string || vp->type == numeric_string)
160 		free (vp->u.s);
161 }
162 
163 
164 quad_t
165 to_integer (vp)
166 struct val *vp;
167 {
168 	quad_t i;
169 
170 	if (vp->type == integer)
171 		return 1;
172 
173 	if (vp->type == string)
174 		return 0;
175 
176 	/* vp->type == numeric_string, make it numeric */
177 	errno = 0;
178 	i  = strtoll(vp->u.s, (char**)NULL, 10);
179 	if (errno != 0) {
180 		errx (2, "overflow");
181 	}
182 	free (vp->u.s);
183 	vp->u.i = i;
184 	vp->type = integer;
185 	return 1;
186 }
187 
188 void
189 to_string (vp)
190 struct val *vp;
191 {
192 	char *tmp;
193 
194 	if (vp->type == string || vp->type == numeric_string)
195 		return;
196 
197 	tmp = malloc ((size_t)25);
198 	if (tmp == NULL) {
199 		errx (2, "malloc() failed");
200 	}
201 
202 	sprintf (tmp, "%lld", (long long)vp->u.i);
203 	vp->type = string;
204 	vp->u.s  = tmp;
205 }
206 
207 
208 int
209 isstring (vp)
210 struct val *vp;
211 {
212 	/* only TRUE if this string is not a valid integer */
213 	return (vp->type == string);
214 }
215 
216 
217 int
218 yylex ()
219 {
220 	char *p;
221 
222 	if (*av == NULL)
223 		return (0);
224 
225 	p = *av++;
226 
227 	if (strlen (p) == 1) {
228 		if (strchr ("|&=<>+-*/%:()", *p))
229 			return (*p);
230 	} else if (strlen (p) == 2 && p[1] == '=') {
231 		switch (*p) {
232 		case '>': return (GE);
233 		case '<': return (LE);
234 		case '!': return (NE);
235 		}
236 	}
237 
238 	yylval.val = make_str (p);
239 	return (TOKEN);
240 }
241 
242 int
243 is_zero_or_null (vp)
244 struct val *vp;
245 {
246 	if (vp->type == integer) {
247 		return (vp->u.i == 0);
248 	} else {
249 		return (*vp->u.s == 0 || (to_integer (vp) && vp->u.i == 0));
250 	}
251 	/* NOTREACHED */
252 }
253 
254 int
255 main (argc, argv)
256 int argc __unused;
257 char **argv;
258 {
259 	setlocale (LC_ALL, "");
260 
261 	av = argv + 1;
262 
263 	yyparse ();
264 
265 	if (result->type == integer)
266 		printf ("%lld\n", (long long)result->u.i);
267 	else
268 		printf ("%s\n", result->u.s);
269 
270 	return (is_zero_or_null (result));
271 }
272 
273 int
274 yyerror (s)
275 const char *s __unused;
276 {
277 	errx (2, "syntax error");
278 }
279 
280 
281 struct val *
282 op_or (a, b)
283 struct val *a, *b;
284 {
285 	if (is_zero_or_null (a)) {
286 		free_value (a);
287 		return (b);
288 	} else {
289 		free_value (b);
290 		return (a);
291 	}
292 }
293 
294 struct val *
295 op_and (a, b)
296 struct val *a, *b;
297 {
298 	if (is_zero_or_null (a) || is_zero_or_null (b)) {
299 		free_value (a);
300 		free_value (b);
301 		return (make_integer ((quad_t)0));
302 	} else {
303 		free_value (b);
304 		return (a);
305 	}
306 }
307 
308 struct val *
309 op_eq (a, b)
310 struct val *a, *b;
311 {
312 	struct val *r;
313 
314 	if (isstring (a) || isstring (b)) {
315 		to_string (a);
316 		to_string (b);
317 		r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) == 0));
318 	} else {
319 		to_integer(a);
320 		to_integer(b);
321 		r = make_integer ((quad_t)(a->u.i == b->u.i));
322 	}
323 
324 	free_value (a);
325 	free_value (b);
326 	return r;
327 }
328 
329 struct val *
330 op_gt (a, b)
331 struct val *a, *b;
332 {
333 	struct val *r;
334 
335 	if (isstring (a) || isstring (b)) {
336 		to_string (a);
337 		to_string (b);
338 		r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) > 0));
339 	} else {
340 		to_integer(a);
341 		to_integer(b);
342 		r = make_integer ((quad_t)(a->u.i > b->u.i));
343 	}
344 
345 	free_value (a);
346 	free_value (b);
347 	return r;
348 }
349 
350 struct val *
351 op_lt (a, b)
352 struct val *a, *b;
353 {
354 	struct val *r;
355 
356 	if (isstring (a) || isstring (b)) {
357 		to_string (a);
358 		to_string (b);
359 		r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) < 0));
360 	} else {
361 		to_integer(a);
362 		to_integer(b);
363 		r = make_integer ((quad_t)(a->u.i < b->u.i));
364 	}
365 
366 	free_value (a);
367 	free_value (b);
368 	return r;
369 }
370 
371 struct val *
372 op_ge (a, b)
373 struct val *a, *b;
374 {
375 	struct val *r;
376 
377 	if (isstring (a) || isstring (b)) {
378 		to_string (a);
379 		to_string (b);
380 		r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) >= 0));
381 	} else {
382 		to_integer(a);
383 		to_integer(b);
384 		r = make_integer ((quad_t)(a->u.i >= b->u.i));
385 	}
386 
387 	free_value (a);
388 	free_value (b);
389 	return r;
390 }
391 
392 struct val *
393 op_le (a, b)
394 struct val *a, *b;
395 {
396 	struct val *r;
397 
398 	if (isstring (a) || isstring (b)) {
399 		to_string (a);
400 		to_string (b);
401 		r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) <= 0));
402 	} else {
403 		to_integer(a);
404 		to_integer(b);
405 		r = make_integer ((quad_t)(a->u.i <= b->u.i));
406 	}
407 
408 	free_value (a);
409 	free_value (b);
410 	return r;
411 }
412 
413 struct val *
414 op_ne (a, b)
415 struct val *a, *b;
416 {
417 	struct val *r;
418 
419 	if (isstring (a) || isstring (b)) {
420 		to_string (a);
421 		to_string (b);
422 		r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) != 0));
423 	} else {
424 		to_integer(a);
425 		to_integer(b);
426 		r = make_integer ((quad_t)(a->u.i != b->u.i));
427 	}
428 
429 	free_value (a);
430 	free_value (b);
431 	return r;
432 }
433 
434 int
435 chk_plus (a, b, r)
436 quad_t a, b, r;
437 {
438 	/* sum of two positive numbers must be positive */
439 	if (a > 0 && b > 0 && r <= 0)
440 		return 1;
441 	/* sum of two negative numbers must be negative */
442 	if (a < 0 && b < 0 && r >= 0)
443 		return 1;
444 	/* all other cases are OK */
445 	return 0;
446 }
447 
448 struct val *
449 op_plus (a, b)
450 struct val *a, *b;
451 {
452 	struct val *r;
453 
454 	if (!to_integer (a) || !to_integer (b)) {
455 		errx (2, "non-numeric argument");
456 	}
457 
458 	r = make_integer (/*(quad_t)*/(a->u.i + b->u.i));
459 	if (chk_plus (a->u.i, b->u.i, r->u.i)) {
460 		errx (2, "overflow");
461 	}
462 	free_value (a);
463 	free_value (b);
464 	return r;
465 }
466 
467 int
468 chk_minus (a, b, r)
469 quad_t a, b, r;
470 {
471 	/* special case subtraction of QUAD_MIN */
472 	if (b == QUAD_MIN) {
473 		if (a >= 0)
474 			return 1;
475 		else
476 			return 0;
477 	}
478 	/* this is allowed for b != QUAD_MIN */
479 	return chk_plus (a, -b, r);
480 }
481 
482 struct val *
483 op_minus (a, b)
484 struct val *a, *b;
485 {
486 	struct val *r;
487 
488 	if (!to_integer (a) || !to_integer (b)) {
489 		errx (2, "non-numeric argument");
490 	}
491 
492 	r = make_integer (/*(quad_t)*/(a->u.i - b->u.i));
493 	if (chk_minus (a->u.i, b->u.i, r->u.i)) {
494 		errx (2, "overflow");
495 	}
496 	free_value (a);
497 	free_value (b);
498 	return r;
499 }
500 
501 int
502 chk_times (a, b, r)
503 quad_t a, b, r;
504 {
505 	/* special case: first operand is 0, no overflow possible */
506 	if (a == 0)
507 		return 0;
508 	/* cerify that result of division matches second operand */
509 	if (r / a != b)
510 		return 1;
511 	return 0;
512 }
513 
514 struct val *
515 op_times (a, b)
516 struct val *a, *b;
517 {
518 	struct val *r;
519 
520 	if (!to_integer (a) || !to_integer (b)) {
521 		errx (2, "non-numeric argument");
522 	}
523 
524 	r = make_integer (/*(quad_t)*/(a->u.i * b->u.i));
525 	if (chk_times (a->u.i, b->u.i, r->u.i)) {
526 		errx (2, "overflow");
527 	}
528 	free_value (a);
529 	free_value (b);
530 	return (r);
531 }
532 
533 int
534 chk_div (a, b)
535 quad_t a, b;
536 {
537 	/* div by zero has been taken care of before */
538 	/* only QUAD_MIN / -1 causes overflow */
539 	if (a == QUAD_MIN && b == -1)
540 		return 1;
541 	/* everything else is OK */
542 	return 0;
543 }
544 
545 struct val *
546 op_div (a, b)
547 struct val *a, *b;
548 {
549 	struct val *r;
550 
551 	if (!to_integer (a) || !to_integer (b)) {
552 		errx (2, "non-numeric argument");
553 	}
554 
555 	if (b->u.i == 0) {
556 		errx (2, "division by zero");
557 	}
558 
559 	r = make_integer (/*(quad_t)*/(a->u.i / b->u.i));
560 	if (chk_div (a->u.i, b->u.i)) {
561 		errx (2, "overflow");
562 	}
563 	free_value (a);
564 	free_value (b);
565 	return r;
566 }
567 
568 struct val *
569 op_rem (a, b)
570 struct val *a, *b;
571 {
572 	struct val *r;
573 
574 	if (!to_integer (a) || !to_integer (b)) {
575 		errx (2, "non-numeric argument");
576 	}
577 
578 	if (b->u.i == 0) {
579 		errx (2, "division by zero");
580 	}
581 
582 	r = make_integer (/*(quad_t)*/(a->u.i % b->u.i));
583 	/* chk_rem necessary ??? */
584 	free_value (a);
585 	free_value (b);
586 	return r;
587 }
588 
589 struct val *
590 op_colon (a, b)
591 struct val *a, *b;
592 {
593 	regex_t rp;
594 	regmatch_t rm[2];
595 	char errbuf[256];
596 	int eval;
597 	struct val *v;
598 
599 	/* coerce to both arguments to strings */
600 	to_string(a);
601 	to_string(b);
602 
603 	/* compile regular expression */
604 	if ((eval = regcomp (&rp, b->u.s, 0)) != 0) {
605 		regerror (eval, &rp, errbuf, sizeof(errbuf));
606 		errx (2, "%s", errbuf);
607 	}
608 
609 	/* compare string against pattern */
610 	/* remember that patterns are anchored to the beginning of the line */
611 	if (regexec(&rp, a->u.s, (size_t)2, rm, 0) == 0 && rm[0].rm_so == 0) {
612 		if (rm[1].rm_so >= 0) {
613 			*(a->u.s + rm[1].rm_eo) = '\0';
614 			v = make_str (a->u.s + rm[1].rm_so);
615 
616 		} else {
617 			v = make_integer ((quad_t)(rm[0].rm_eo - rm[0].rm_so));
618 		}
619 	} else {
620 		if (rp.re_nsub == 0) {
621 			v = make_integer ((quad_t)0);
622 		} else {
623 			v = make_str ("");
624 		}
625 	}
626 
627 	/* free arguments and pattern buffer */
628 	free_value (a);
629 	free_value (b);
630 	regfree (&rp);
631 
632 	return v;
633 }
634