5 * The contents of this file are subject to the terms of the
6 * Common Development and Distribution License, Version 1.0 only
7 * (the "License"). You may not use this file except in compliance
10 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11 * or http://www.opensolaris.org/os/licensing.
12 * See the License for the specific language governing permissions
13 * and limitations under the License.
15 * When distributing Covered Code, include this CDDL HEADER in each
16 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17 * If applicable, add the following below this CDDL HEADER, with the
18 * fields enclosed by brackets "[]" replaced with your own identifying
19 * information: Portions Copyright [yyyy] [name of copyright owner]
25 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
29 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
30 /* All Rights Reserved */
33 #pragma ident "%Z%%M% %I% %E% SMI"
36 /* Yacc productions for "expr" command: */
39 typedef
char *yystype
;
40 #define YYSTYPE yystype
43 %token OR AND ADD SUBT MULT DIV REM EQ GT GEQ LT LEQ NEQ
44 %token A_STRING SUBSTR LENGTH INDEX NOARG MATCH
46 /* operators listed below in increasing precedence: */
49 %left EQ LT GT GEQ LEQ NEQ
58 /* a single `expression' is evaluated and printed: */
60 expression: expr NOARG
= {
62 exit
((!strcmp
($1,"0")||
!strcmp
($1,"\0"))?
1: 0);
67 expr: '(' expr
')' = { $$
= $2; }
68 | expr OR expr
= { $$
= conj
(OR
, $1, $3); }
69 | expr AND expr
= { $$
= conj
(AND
, $1, $3); }
70 | expr EQ expr
= { $$
= rel
(EQ
, $1, $3); }
71 | expr GT expr
= { $$
= rel
(GT
, $1, $3); }
72 | expr GEQ expr
= { $$
= rel
(GEQ
, $1, $3); }
73 | expr LT expr
= { $$
= rel
(LT
, $1, $3); }
74 | expr LEQ expr
= { $$
= rel
(LEQ
, $1, $3); }
75 | expr NEQ expr
= { $$
= rel
(NEQ
, $1, $3); }
76 | expr ADD expr
= { $$
= arith
(ADD
, $1, $3); }
77 | expr SUBT expr
= { $$
= arith
(SUBT
, $1, $3); }
78 | expr MULT expr
= { $$
= arith
(MULT
, $1, $3); }
79 | expr DIV expr
= { $$
= arith
(DIV
, $1, $3); }
80 | expr REM expr
= { $$
= arith
(REM
, $1, $3); }
81 | expr MCH expr
= { $$
= match
($1, $3); }
82 | MATCH expr expr
= { $$
= match
($2, $3); }
83 | SUBSTR expr expr expr
= { $$
= substr
($2, $3, $4); }
84 | LENGTH expr
= { $$
= length
($2); }
85 | INDEX expr expr
= { $$
= index
($2, $3); }
91 #define EQL(x,y) !strcmp(x,y)
93 #define INIT char *sp = instring;
94 #define GETC() (*sp++)
96 #define UNGETC(c) (--sp)
97 #define RETURN(c) return(c)
98 #define ERROR(c) errxx(c)
109 char Mstring
[1][128];
113 "|", "&", "+", "-", "*", "/", "%", ":",
114 "=", "==", "<", "<=", ">", ">=", "!=",
115 "match", "substr", "length", "index", "\0" };
117 OR
, AND
, ADD
, SUBT
, MULT
, DIV
, REM
, MCH
,
118 EQ
, EQ
, LT
, LEQ
, GT
, GEQ
, NEQ
,
119 MATCH
, SUBSTR
, LENGTH
, INDEX
};
126 if
(Argi
>= Ac
) return NOARG
;
130 if
((*p
== '(' ||
*p
== ')') && p
[1] == '\0' )
132 for
(i
= 0; *operator
[i
]; ++i
)
133 if
(EQL
(operator
[i
], p
))
141 rel
(int oper
, char *r1
, char *r2
)
145 if
(ematch
(r1
, "-\\{0,1\\}[0-9]*$") && ematch
(r2
, "-\\{0,1\\}[0-9]*$"))
146 i
= atol
(r1
) - atol
(r2
);
172 char *arith
(oper
, r1
, r2
) char *r1
, *r2
;
177 if
(!(ematch
(r1
, "-\\{0,1\\}[0-9]*$") && ematch
(r2
, "-\\{0,1\\}[0-9]*$")))
178 yyerror("non-numeric argument");
194 yyerror("division by zero");
199 yyerror("division by zero");
204 (void) strcpy
(rv
, ltoa
(i1
));
207 char *conj
(oper
, r1
, r2
) char *r1
, *r2
;
239 substr
(char *v
, char *s
, char *w
)
246 while
(--si
) if
(*v
) ++v
;
250 while
(wi
--) if
(*v
) ++v
;
257 index
(char *s
, char *t
)
262 for
(i
= 0; s
[i
] ; ++i
)
263 for
(j
= 0; t
[j
] ; ++j
)
265 (void) strcpy
(rv
= malloc
(8), ltoa
(++i
));
280 (void) strcpy
(rv
, ltoa
(i
));
285 match
(char *s
, char *p
)
289 (void) strcpy
(rv
=malloc
(8), ltoa
((long)ematch
(s
, p
)));
291 rv
= malloc
((unsigned) strlen
(Mstring
[0]) + 1);
292 (void) strcpy
(rv
, Mstring
[0]);
298 ematch
(char *s
, char *p
)
300 static char expbuf
[ESIZE
];
303 extern
char *braslist
[], *braelist
[], *loc2
;
305 compile
(p
, expbuf
, &expbuf
[ESIZE
], 0);
307 yyerror("Too many '\\('s");
308 if
(advance
(s
, expbuf
)) {
311 num
= braelist
[0] - p
;
312 if
((num
> 127) ||
(num
< 0)) yyerror("Paren problem");
313 (void) strncpy
(Mstring
[0], p
, num
);
314 Mstring
[0][num
] = '\0';
328 message
= "Range endpoint too large";
331 message
= "Bad number";
334 message
= "``\\digit'' out of range";
337 message
= "Illegal or missing delimiter";
340 message
= "No remembered search string";
343 message
= "\\( \\) imbalance";
346 message
= "Too many \\(";
349 message
= "More than 2 numbers given in \\{ \\}";
352 message
= "} expected after \\";
355 message
= "First number exceeds second in \\{ \\}";
358 message
= "[ ] imbalance";
361 message
= "Regular expression too long";
364 message
= "Unknown regexp error code!!";
375 (void) write
(2, "expr: ", 6);
376 (void) write
(2, s
, (unsigned) strlen
(s
));
377 (void) write
(2, "\n", 1);
392 return
"-2147483648";
410 main
(int argc
, char **argv
)