gcc44 warns: Put input() under YY_NO_INPUT and set that if it isn't used.
[dragonfly.git] / usr.bin / bc / scan.l
CommitLineData
f2d37758
MD
1%{
2/*
db555d9a
PA
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 $
f2d37758
MD
5 */
6
7/*
8 * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
9 *
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.
13 *
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.
21 */
22
23#include <err.h>
b6d9cda5
SW
24#include <errno.h>
25#include <signal.h>
f2d37758
MD
26#include <stdbool.h>
27#include <string.h>
b6d9cda5 28#include <unistd.h>
f2d37758
MD
29
30#include "extern.h"
b6d9cda5 31#include "pathnames.h"
f2d37758
MD
32#include "y.tab.h"
33
74c418a6
SW
34#define YY_NO_INPUT
35
f2d37758 36int lineno;
db555d9a 37bool interactive;
f2d37758
MD
38
39static char *strbuf = NULL;
40static size_t strbuf_sz = 1;
41static bool dot_seen;
42
43static void init_strbuf(void);
44static void add_str(const char *);
45
46%}
47
b6d9cda5
SW
48%option always-interactive
49
f2d37758
MD
50DIGIT [0-9A-F]
51ALPHA [a-z_]
52ALPHANUM [a-z_0-9]
53
54%x comment string number
55
56%%
57
58"/*" BEGIN(comment);
59<comment>{
60 "*/" BEGIN(INITIAL);
61 \n lineno++;
62 \* ;
63 [^*\n]+ ;
64 <<EOF>> fatal("end of file in comment");
65}
66
67\" BEGIN(string); init_strbuf();
68<string>{
69 [^"\n\\\[\]]+ add_str(yytext);
70 \[ add_str("\\[");
71 \] add_str("\\]");
72 \\ add_str("\\\\");
73 \n add_str("\n"); lineno++;
74 \" BEGIN(INITIAL); yylval.str = strbuf; return STRING;
75 <<EOF>> fatal("end of file in string");
76}
77
78{DIGIT}+ {
79 BEGIN(number);
80 dot_seen = false;
81 init_strbuf();
82 add_str(yytext);
83 }
84\. {
85 BEGIN(number);
86 dot_seen = true;
87 init_strbuf();
88 add_str(".");
89 }
90<number>{
91 {DIGIT}+ add_str(yytext);
92 \. {
93 if (dot_seen) {
94 BEGIN(INITIAL);
95 yylval.str = strbuf;
96 unput('.');
97 return NUMBER;
98 } else {
99 dot_seen = true;
100 add_str(".");
101 }
102 }
103 \\\n[ \t]* lineno++;
104 [^0-9A-F\.] {
105 BEGIN(INITIAL);
106 unput(yytext[0]);
107 if (strcmp(strbuf, ".") == 0)
108 return DOT;
109 else {
110 yylval.str = strbuf;
111 return NUMBER;
112 }
113 }
114}
115
116"auto" return AUTO;
117"break" return BREAK;
118"continue" return CONTINUE;
119"define" return DEFINE;
120"else" return ELSE;
121"ibase" return IBASE;
122"if" return IF;
123"last" return DOT;
124"for" return FOR;
125"length" return LENGTH;
126"obase" return OBASE;
127"print" return PRINT;
128"quit" return QUIT;
129"return" return RETURN;
130"scale" return SCALE;
131"sqrt" return SQRT;
132"while" return WHILE;
133
134"^" return EXPONENT;
135"*" return MULTIPLY;
136"/" return DIVIDE;
137"%" return REMAINDER;
138
139"!" return BOOL_NOT;
140"&&" return BOOL_AND;
141"||" return BOOL_OR;
142
143"+" return PLUS;
144"-" return MINUS;
145
146"++" return INCR;
147"--" return DECR;
148
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;
156
157"==" return EQUALS;
158"<=" return LESS_EQ;
159">=" return GREATER_EQ;
160"!=" return UNEQUALS;
161"<" return LESS;
162">" return GREATER;
163
164"," return COMMA;
165";" return SEMICOLON;
166
167"(" return LPAR;
168")" return RPAR;
169
170"[" return LBRACKET;
171"]" return RBRACKET;
172
173"{" return LBRACE;
174"}" return RBRACE;
175
176{ALPHA}{ALPHANUM}* {
177 /* alloc an extra byte for the type marker */
178 char *p = malloc(yyleng + 2);
179 if (p == NULL)
180 err(1, NULL);
181 strlcpy(p, yytext, yyleng + 1);
182 yylval.astr = p;
183 return LETTER;
184 }
185
186\\\n lineno++;
187\n lineno++; return NEWLINE;
188
189#[^\n]* ;
190[ \t] ;
191<<EOF>> return QUIT;
192. yyerror("illegal character");
193
194%%
195
196static void
197init_strbuf(void)
198{
199 if (strbuf == NULL) {
200 strbuf = malloc(strbuf_sz);
201 if (strbuf == NULL)
202 err(1, NULL);
203 }
204 strbuf[0] = '\0';
205}
206
207static void
208add_str(const char *str)
209{
210 size_t arglen;
211
212 arglen = strlen(str);
213
214 if (strlen(strbuf) + arglen + 1 > strbuf_sz) {
215 size_t newsize;
216 char *p;
217
218 newsize = strbuf_sz + arglen + 1;
219 p = realloc(strbuf, newsize);
220 if (p == NULL) {
221 free(strbuf);
222 err(1, NULL);
223 }
224 strbuf_sz = newsize;
225 strbuf = p;
226 }
227 strlcat(strbuf, str, strbuf_sz);
228}
229
db555d9a 230/* ARGSUSED */
f2d37758
MD
231void
232abort_line(int sig)
233{
b6d9cda5
SW
234 const char str[] = "[\n]P\n";
235 int save_errno;
236
db555d9a
PA
237 save_errno = errno;
238 YY_FLUSH_BUFFER; /* XXX signal race? */
239 write(STDOUT_FILENO, str, sizeof(str) - 1);
240 errno = save_errno;
b6d9cda5
SW
241}
242
243int
244yywrap(void)
245{
246 static int state;
247 static YY_BUFFER_STATE buf;
248
249 if (fileindex == 0 && sargc > 0 && strcmp(sargv[0], _PATH_LIBB) == 0) {
250 filename = sargv[fileindex++];
251 yyin = fopen(filename, "r");
252 lineno = 1;
253 if (yyin == NULL)
254 err(1, "cannot open %s", filename);
255 return (0);
256 }
257 if (state == 0 && cmdexpr[0] != '\0') {
258 buf = yy_scan_string(cmdexpr);
259 state++;
260 lineno = 1;
261 filename = "command line";
262 return (0);
263 } else if (state == 1) {
264 yy_delete_buffer(buf);
265 free(cmdexpr);
266 state++;
267 }
db555d9a
PA
268 if (yyin != NULL && yyin != stdin)
269 fclose(yyin);
b6d9cda5
SW
270 if (fileindex < sargc) {
271 filename = sargv[fileindex++];
272 yyin = fopen(filename, "r");
273 lineno = 1;
274 if (yyin == NULL)
275 err(1, "cannot open %s", filename);
276 return (0);
277 } else if (fileindex == sargc) {
278 fileindex++;
279 yyin = stdin;
db555d9a
PA
280 if (interactive)
281 signal(SIGINT, abort_line);
b6d9cda5
SW
282 lineno = 1;
283 filename = "stdin";
284 return (0);
f2d37758 285 }
b6d9cda5 286 return (1);
f2d37758 287}