3 * $OpenBSD: scan.l,v 1.21 2006/03/18 20:44:43 otto Exp $
4 * $DragonFly: src/usr.bin/bc/scan.l,v 1.3 2007/09/01 18:42:08 pavalos Exp $
8 * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies.
14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
31 #include "pathnames.h"
39 static char *strbuf = NULL;
40 static size_t strbuf_sz = 1;
43 static void init_strbuf(void);
44 static void add_str(const char *);
48 %option always-interactive
54 %x comment string number
64 <<EOF>> fatal("end of file in comment");
67 \" BEGIN(string); init_strbuf();
69 [^"\n\\\[\]]+ add_str(yytext);
73 \n add_str("\n"); lineno++;
74 \" BEGIN(INITIAL); yylval.str = strbuf; return STRING;
75 <<EOF>> fatal("end of file in string");
91 {DIGIT}+ add_str(yytext);
107 if (strcmp(strbuf, ".") == 0)
117 "break" return BREAK;
118 "continue" return CONTINUE;
119 "define" return DEFINE;
121 "ibase" return IBASE;
125 "length" return LENGTH;
126 "obase" return OBASE;
127 "print" return PRINT;
129 "return" return RETURN;
130 "scale" return SCALE;
132 "while" return WHILE;
137 "%" return REMAINDER;
140 "&&" return BOOL_AND;
149 "=" yylval.str = ""; return ASSIGN_OP;
150 "+=" yylval.str = "+"; return ASSIGN_OP;
151 "-=" yylval.str = "-"; return ASSIGN_OP;
152 "*=" yylval.str = "*"; return ASSIGN_OP;
153 "/=" yylval.str = "/"; return ASSIGN_OP;
154 "%=" yylval.str = "%"; return ASSIGN_OP;
155 "^=" yylval.str = "^"; return ASSIGN_OP;
159 ">=" return GREATER_EQ;
160 "!=" return UNEQUALS;
165 ";" return SEMICOLON;
177 /* alloc an extra byte for the type marker */
178 char *p = malloc(yyleng + 2);
181 strlcpy(p, yytext, yyleng + 1);
187 \n lineno++; return NEWLINE;
192 . yyerror("illegal character");
199 if (strbuf == NULL) {
200 strbuf = malloc(strbuf_sz);
208 add_str(const char *str)
212 arglen = strlen(str);
214 if (strlen(strbuf) + arglen + 1 > strbuf_sz) {
218 newsize = strbuf_sz + arglen + 1;
219 p = realloc(strbuf, newsize);
227 strlcat(strbuf, str, strbuf_sz);
234 const char str[] = "[\n]P\n";
238 YY_FLUSH_BUFFER; /* XXX signal race? */
239 write(STDOUT_FILENO, str, sizeof(str) - 1);
247 static YY_BUFFER_STATE buf;
249 if (fileindex == 0 && sargc > 0 && strcmp(sargv[0], _PATH_LIBB) == 0) {
250 filename = sargv[fileindex++];
251 yyin = fopen(filename, "r");
254 err(1, "cannot open %s", filename);
257 if (state == 0 && cmdexpr[0] != '\0') {
258 buf = yy_scan_string(cmdexpr);
261 filename = "command line";
263 } else if (state == 1) {
264 yy_delete_buffer(buf);
268 if (yyin != NULL && yyin != stdin)
270 if (fileindex < sargc) {
271 filename = sargv[fileindex++];
272 yyin = fopen(filename, "r");
275 err(1, "cannot open %s", filename);
277 } else if (fileindex == sargc) {
281 signal(SIGINT, abort_line);