2 /* $OpenBSD: scan.l,v 1.23 2009/10/27 23:59:36 deraadt Exp $ */
5 * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include <sys/cdefs.h>
21 __FBSDID("$FreeBSD$");
32 #include "pathnames.h"
41 static char *strbuf = NULL;
42 static size_t strbuf_sz = 1;
45 static void init_strbuf(void);
46 static void add_str(const char *);
47 static int bc_yyinput(char *, int);
49 #define YY_DECL int yylex(void)
52 #define YY_INPUT(buf,retval,max) \
53 (retval = bc_yyinput(buf, max))
56 %option always-interactive
62 %x comment string number
72 <<EOF>> fatal("end of file in comment");
75 \" BEGIN(string); init_strbuf();
77 [^"\n\\\[\]]+ add_str(yytext);
81 \n add_str("\n"); lineno++;
82 \" BEGIN(INITIAL); yylval.str = strbuf; return STRING;
83 <<EOF>> fatal("end of file in string");
99 {DIGIT}+ add_str(yytext);
115 if (strcmp(strbuf, ".") == 0)
124 "auto" return (AUTO);
125 "break" return (BREAK);
126 "continue" return (CONTINUE);
127 "define" return (DEFINE);
128 "else" return (ELSE);
129 "ibase" return (IBASE);
133 "length" return (LENGTH);
134 "obase" return (OBASE);
135 "print" return (PRINT);
136 "quit" return (QUIT);
137 "return" return (RETURN);
138 "scale" return (SCALE);
139 "sqrt" return (SQRT);
140 "while" return (WHILE);
142 "^" return (EXPONENT);
143 "*" return (MULTIPLY);
145 "%" return (REMAINDER);
147 "!" return (BOOL_NOT);
148 "&&" return (BOOL_AND);
149 "||" return (BOOL_OR);
157 "=" yylval.str = ""; return (ASSIGN_OP);
158 "+=" yylval.str = "+"; return (ASSIGN_OP);
159 "-=" yylval.str = "-"; return (ASSIGN_OP);
160 "*=" yylval.str = "*"; return (ASSIGN_OP);
161 "/=" yylval.str = "/"; return (ASSIGN_OP);
162 "%=" yylval.str = "%"; return (ASSIGN_OP);
163 "^=" yylval.str = "^"; return (ASSIGN_OP);
165 "==" return (EQUALS);
166 "<=" return (LESS_EQ);
167 ">=" return (GREATER_EQ);
168 "!=" return (UNEQUALS);
170 ">" return (GREATER);
173 ";" return (SEMICOLON);
178 "[" return (LBRACKET);
179 "]" return (RBRACKET);
185 /* alloc an extra byte for the type marker */
186 char *p = malloc(yyleng + 2);
189 strlcpy(p, yytext, yyleng + 1);
195 \n lineno++; return (NEWLINE);
199 <<EOF>> return (QUIT);
200 . yyerror("illegal character");
208 if (strbuf == NULL) {
209 strbuf = malloc(strbuf_sz);
217 add_str(const char *str)
221 arglen = strlen(str);
223 if (strlen(strbuf) + arglen + 1 > strbuf_sz) {
227 newsize = strbuf_sz + arglen + 1;
228 p = realloc(strbuf, newsize);
236 strlcat(strbuf, str, strbuf_sz);
242 static YY_BUFFER_STATE buf;
245 if (fileindex == 0 && sargc > 0 && strcmp(sargv[0], _PATH_LIBB) == 0) {
246 filename = sargv[fileindex++];
247 yyin = fopen(filename, "r");
250 err(1, "cannot open %s", filename);
253 if (state == 0 && cmdexpr[0] != '\0') {
254 buf = yy_scan_string(cmdexpr);
257 filename = "command line";
259 } else if (state == 1) {
260 yy_delete_buffer(buf);
264 if (yyin != NULL && yyin != stdin)
266 if (fileindex < sargc) {
267 filename = sargv[fileindex++];
268 yyin = fopen(filename, "r");
271 err(1, "cannot open %s", filename);
273 } else if (fileindex == sargc) {
284 bc_yyinput(char *buf, int maxlen)
287 if (yyin == stdin && interactive) {
290 if ((bp = el_gets(el, &num)) == NULL || num == 0)
293 el_push(el, (char *)(uintptr_t)(bp) + maxlen);
296 memcpy(buf, bp, num);
297 history(hist, &he, H_ENTER, bp);
300 for (num = 0; num < maxlen &&
301 (c = getc(yyin)) != EOF && c != '\n'; ++num)
304 buf[num++] = (char) c;
305 if (c == EOF && ferror(yyin))
306 YY_FATAL_ERROR( "input in flex scanner failed" );