3 * $OpenBSD: scan.l,v 1.21 2006/03/18 20:44:43 otto Exp $
7 * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
31 #include "pathnames.h"
43 static char *strbuf = NULL;
44 static size_t strbuf_sz = 1;
47 static void init_strbuf(void);
48 static void add_str(const char *);
49 static int bc_yyinput(char *, int);
52 #define YY_INPUT(buf,retval,max) \
53 (retval = bc_yyinput(buf, max))
57 %option always-interactive
63 %x comment string number
73 <<EOF>> fatal("end of file in comment");
76 \" BEGIN(string); init_strbuf();
78 [^"\n\\\[\]]+ add_str(yytext);
82 \n add_str("\n"); lineno++;
83 \" BEGIN(INITIAL); yylval.str = strbuf; return STRING;
84 <<EOF>> fatal("end of file in string");
100 {DIGIT}+ add_str(yytext);
116 if (strcmp(strbuf, ".") == 0)
126 "break" return BREAK;
127 "continue" return CONTINUE;
128 "define" return DEFINE;
130 "ibase" return IBASE;
134 "length" return LENGTH;
135 "obase" return OBASE;
136 "print" return PRINT;
138 "return" return RETURN;
139 "scale" return SCALE;
141 "while" return WHILE;
146 "%" return REMAINDER;
149 "&&" return BOOL_AND;
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;
164 "^=" yylval.str = "^"; return ASSIGN_OP;
168 ">=" return GREATER_EQ;
169 "!=" return UNEQUALS;
174 ";" return SEMICOLON;
186 /* alloc an extra byte for the type marker */
187 char *p = malloc(yyleng + 2);
190 strlcpy(p, yytext, yyleng + 1);
196 \n lineno++; return NEWLINE;
201 . 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);
243 const char str[] = "[\n]P\n";
247 YY_FLUSH_BUFFER; /* XXX signal race? */
248 write(STDOUT_FILENO, str, sizeof(str) - 1);
256 static YY_BUFFER_STATE buf;
258 if (fileindex == 0 && sargc > 0 && strcmp(sargv[0], _PATH_LIBB) == 0) {
259 filename = sargv[fileindex++];
260 yyin = fopen(filename, "r");
263 err(1, "cannot open %s", filename);
266 if (state == 0 && cmdexpr[0] != '\0') {
267 buf = yy_scan_string(cmdexpr);
270 filename = "command line";
272 } else if (state == 1) {
273 yy_delete_buffer(buf);
277 if (yyin != NULL && yyin != stdin)
279 if (fileindex < sargc) {
280 filename = sargv[fileindex++];
281 yyin = fopen(filename, "r");
284 err(1, "cannot open %s", filename);
286 } else if (fileindex == sargc) {
290 signal(SIGINT, abort_line);
299 bc_yyinput(char *buf, int maxlen)
302 if (yyin == stdin && interactive) {
305 if ((bp = el_gets(el, &num)) == NULL || num == 0)
308 el_push(el, (char *)(uintptr_t)(bp) + maxlen);
311 memcpy(buf, bp, num);
312 history(hist, &he, H_ENTER, bp);
315 for (num = 0; num < maxlen &&
316 (c = getc(yyin)) != EOF && c != '\n'; ++num)
319 buf[num++] = (char) c;
320 if (c == EOF && ferror(yyin))
321 YY_FATAL_ERROR( "input in flex scanner failed" );