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"
37 static char *strbuf = NULL;
38 static size_t strbuf_sz = 1;
41 static void init_strbuf(void);
42 static void add_str(const char *);
46 %option always-interactive
52 %x comment string number
62 <<EOF>> fatal("end of file in comment");
65 \" BEGIN(string); init_strbuf();
67 [^"\n\\\[\]]+ add_str(yytext);
71 \n add_str("\n"); lineno++;
72 \" BEGIN(INITIAL); yylval.str = strbuf; return STRING;
73 <<EOF>> fatal("end of file in string");
89 {DIGIT}+ add_str(yytext);
105 if (strcmp(strbuf, ".") == 0)
115 "break" return BREAK;
116 "continue" return CONTINUE;
117 "define" return DEFINE;
119 "ibase" return IBASE;
123 "length" return LENGTH;
124 "obase" return OBASE;
125 "print" return PRINT;
127 "return" return RETURN;
128 "scale" return SCALE;
130 "while" return WHILE;
135 "%" return REMAINDER;
138 "&&" return BOOL_AND;
147 "=" yylval.str = ""; return ASSIGN_OP;
148 "+=" yylval.str = "+"; return ASSIGN_OP;
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;
157 ">=" return GREATER_EQ;
158 "!=" return UNEQUALS;
163 ";" return SEMICOLON;
175 /* alloc an extra byte for the type marker */
176 char *p = malloc(yyleng + 2);
179 strlcpy(p, yytext, yyleng + 1);
185 \n lineno++; return NEWLINE;
190 . yyerror("illegal character");
197 if (strbuf == NULL) {
198 strbuf = malloc(strbuf_sz);
206 add_str(const char *str)
210 arglen = strlen(str);
212 if (strlen(strbuf) + arglen + 1 > strbuf_sz) {
216 newsize = strbuf_sz + arglen + 1;
217 p = realloc(strbuf, newsize);
225 strlcat(strbuf, str, strbuf_sz);
232 const char str[] = "[\n]P\n";
236 YY_FLUSH_BUFFER; /* XXX signal race? */
237 write(STDOUT_FILENO, str, sizeof(str) - 1);
245 static YY_BUFFER_STATE buf;
247 if (fileindex == 0 && sargc > 0 && strcmp(sargv[0], _PATH_LIBB) == 0) {
248 filename = sargv[fileindex++];
249 yyin = fopen(filename, "r");
252 err(1, "cannot open %s", filename);
255 if (state == 0 && cmdexpr[0] != '\0') {
256 buf = yy_scan_string(cmdexpr);
259 filename = "command line";
261 } else if (state == 1) {
262 yy_delete_buffer(buf);
266 if (yyin != NULL && yyin != stdin)
268 if (fileindex < sargc) {
269 filename = sargv[fileindex++];
270 yyin = fopen(filename, "r");
273 err(1, "cannot open %s", filename);
275 } else if (fileindex == sargc) {
279 signal(SIGINT, abort_line);