Deleted Added
full compact
scan.l (256281) scan.l (265533)
1%{
1%{
2/* $OpenBSD: scan.l,v 1.23 2009/10/27 23:59:36 deraadt Exp $ */
2/* $OpenBSD: scan.l,v 1.28 2013/09/19 16:12:01 otto Exp $ */
3
4/*
5 * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
6 *
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.
10 *
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.
18 */
19
20#include <sys/cdefs.h>
3
4/*
5 * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
6 *
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.
10 *
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.
18 */
19
20#include <sys/cdefs.h>
21__FBSDID("$FreeBSD: stable/10/usr.bin/bc/scan.l 250926 2013-05-23 05:42:35Z jkim $");
21__FBSDID("$FreeBSD: stable/10/usr.bin/bc/scan.l 265533 2014-05-07 08:06:54Z delphij $");
22
23#include <err.h>
24#include <errno.h>
25#include <histedit.h>
26#include <stdbool.h>
22
23#include <err.h>
24#include <errno.h>
25#include <histedit.h>
26#include <stdbool.h>
27#include <signal.h>
27#include <string.h>
28#include <unistd.h>
29
30#include "extern.h"
31#include "bc.h"
32#include "pathnames.h"
33
28#include <string.h>
29#include <unistd.h>
30
31#include "extern.h"
32#include "bc.h"
33#include "pathnames.h"
34
34int lineno;
35int lineno;
36bool interactive;
35
37
36bool interactive;
37HistEvent he;
38EditLine *el;
39History *hist;
40
41static char *strbuf = NULL;
38HistEvent he;
39EditLine *el;
40History *hist;
41
42static char *strbuf = NULL;
42static size_t strbuf_sz = 1;
43static bool dot_seen;
43static size_t strbuf_sz = 1;
44static bool dot_seen;
45static int use_el;
46static volatile sig_atomic_t skipchars;
44
47
45static void init_strbuf(void);
46static void add_str(const char *);
48static void init_strbuf(void);
49static void add_str(const char *);
50
47static int bc_yyinput(char *, int);
48
49#define YY_DECL int yylex(void)
50#define YY_NO_INPUT
51#undef YY_INPUT
52#define YY_INPUT(buf,retval,max) \
53 (retval = bc_yyinput(buf, max))
51static int bc_yyinput(char *, int);
52
53#define YY_DECL int yylex(void)
54#define YY_NO_INPUT
55#undef YY_INPUT
56#define YY_INPUT(buf,retval,max) \
57 (retval = bc_yyinput(buf, max))
58
54%}
55
56%option always-interactive
57
58DIGIT [0-9A-F]
59ALPHA [a-z_]
60ALPHANUM [a-z_0-9]
61

--- 35 unchanged lines hidden (view full) ---

97 }
98<number>{
99 {DIGIT}+ add_str(yytext);
100 \. {
101 if (dot_seen) {
102 BEGIN(INITIAL);
103 yylval.str = strbuf;
104 unput('.');
59%}
60
61%option always-interactive
62
63DIGIT [0-9A-F]
64ALPHA [a-z_]
65ALPHANUM [a-z_0-9]
66

--- 35 unchanged lines hidden (view full) ---

102 }
103<number>{
104 {DIGIT}+ add_str(yytext);
105 \. {
106 if (dot_seen) {
107 BEGIN(INITIAL);
108 yylval.str = strbuf;
109 unput('.');
105 return (NUMBER);
110 return NUMBER;
106 } else {
107 dot_seen = true;
108 add_str(".");
109 }
110 }
111 \\\n[ \t]* lineno++;
112 [^0-9A-F\.] {
113 BEGIN(INITIAL);
114 unput(yytext[0]);
115 if (strcmp(strbuf, ".") == 0)
111 } else {
112 dot_seen = true;
113 add_str(".");
114 }
115 }
116 \\\n[ \t]* lineno++;
117 [^0-9A-F\.] {
118 BEGIN(INITIAL);
119 unput(yytext[0]);
120 if (strcmp(strbuf, ".") == 0)
116 return (DOT);
121 return DOT;
117 else {
118 yylval.str = strbuf;
122 else {
123 yylval.str = strbuf;
119 return (NUMBER);
124 return NUMBER;
120 }
121 }
122}
123
125 }
126 }
127}
128
124"auto" return (AUTO);
125"break" return (BREAK);
126"continue" return (CONTINUE);
127"define" return (DEFINE);
128"else" return (ELSE);
129"ibase" return (IBASE);
130"if" return (IF);
131"last" return (DOT);
132"for" return (FOR);
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);
129"auto" return AUTO;
130"break" return BREAK;
131"continue" return CONTINUE;
132"define" return DEFINE;
133"else" return ELSE;
134"ibase" return IBASE;
135"if" return IF;
136"last" return DOT;
137"for" return FOR;
138"length" return LENGTH;
139"obase" return OBASE;
140"print" return PRINT;
141"quit" return QUIT;
142"return" return RETURN;
143"scale" return SCALE;
144"sqrt" return SQRT;
145"while" return WHILE;
141
146
142"^" return (EXPONENT);
143"*" return (MULTIPLY);
144"/" return (DIVIDE);
145"%" return (REMAINDER);
147"^" return EXPONENT;
148"*" return MULTIPLY;
149"/" return DIVIDE;
150"%" return REMAINDER;
146
151
147"!" return (BOOL_NOT);
148"&&" return (BOOL_AND);
149"||" return (BOOL_OR);
152"!" return BOOL_NOT;
153"&&" return BOOL_AND;
154"||" return BOOL_OR;
150
155
151"+" return (PLUS);
152"-" return (MINUS);
156"+" return PLUS;
157"-" return MINUS;
153
158
154"++" return (INCR);
155"--" return (DECR);
159"++" return INCR;
160"--" return DECR;
156
161
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);
162"=" yylval.str = ""; return ASSIGN_OP;
163"+=" yylval.str = "+"; return ASSIGN_OP;
164"-=" yylval.str = "-"; return ASSIGN_OP;
165"*=" yylval.str = "*"; return ASSIGN_OP;
166"/=" yylval.str = "/"; return ASSIGN_OP;
167"%=" yylval.str = "%"; return ASSIGN_OP;
168"^=" yylval.str = "^"; return ASSIGN_OP;
164
169
165"==" return (EQUALS);
166"<=" return (LESS_EQ);
167">=" return (GREATER_EQ);
168"!=" return (UNEQUALS);
169"<" return (LESS);
170">" return (GREATER);
170"==" return EQUALS;
171"<=" return LESS_EQ;
172">=" return GREATER_EQ;
173"!=" return UNEQUALS;
174"<" return LESS;
175">" return GREATER;
171
176
172"," return (COMMA);
173";" return (SEMICOLON);
177"," return COMMA;
178";" return SEMICOLON;
174
179
175"(" return (LPAR);
176")" return (RPAR);
180"(" return LPAR;
181")" return RPAR;
177
182
178"[" return (LBRACKET);
179"]" return (RBRACKET);
183"[" return LBRACKET;
184"]" return RBRACKET;
180
185
181"{" return (LBRACE);
182"}" return (RBRACE);
186"{" return LBRACE;
187"}" return RBRACE;
183
184{ALPHA}{ALPHANUM}* {
185 /* alloc an extra byte for the type marker */
186 char *p = malloc(yyleng + 2);
187 if (p == NULL)
188 err(1, NULL);
189 strlcpy(p, yytext, yyleng + 1);
190 yylval.astr = p;
188
189{ALPHA}{ALPHANUM}* {
190 /* alloc an extra byte for the type marker */
191 char *p = malloc(yyleng + 2);
192 if (p == NULL)
193 err(1, NULL);
194 strlcpy(p, yytext, yyleng + 1);
195 yylval.astr = p;
191 return (LETTER);
196 return LETTER;
192 }
193
194\\\n lineno++;
197 }
198
199\\\n lineno++;
195\n lineno++; return (NEWLINE);
200\n lineno++; return NEWLINE;
196
197#[^\n]* ;
198[ \t] ;
201
202#[^\n]* ;
203[ \t] ;
199<<EOF>> return (QUIT);
204<<EOF>> return QUIT;
200. yyerror("illegal character");
201
202%%
203
204static void
205init_strbuf(void)
206{
205. yyerror("illegal character");
206
207%%
208
209static void
210init_strbuf(void)
211{
207
208 if (strbuf == NULL) {
209 strbuf = malloc(strbuf_sz);
210 if (strbuf == NULL)
211 err(1, NULL);
212 }
213 strbuf[0] = '\0';
214}
215
216static void
217add_str(const char *str)
218{
219 size_t arglen;
220
221 arglen = strlen(str);
222
223 if (strlen(strbuf) + arglen + 1 > strbuf_sz) {
212 if (strbuf == NULL) {
213 strbuf = malloc(strbuf_sz);
214 if (strbuf == NULL)
215 err(1, NULL);
216 }
217 strbuf[0] = '\0';
218}
219
220static void
221add_str(const char *str)
222{
223 size_t arglen;
224
225 arglen = strlen(str);
226
227 if (strlen(strbuf) + arglen + 1 > strbuf_sz) {
224 size_t newsize;
225 char *p;
228 size_t newsize;
229 char *p;
226
227 newsize = strbuf_sz + arglen + 1;
228 p = realloc(strbuf, newsize);
229 if (p == NULL) {
230 free(strbuf);
231 err(1, NULL);
232 }
233 strbuf_sz = newsize;
234 strbuf = p;
235 }
236 strlcat(strbuf, str, strbuf_sz);
237}
238
230
231 newsize = strbuf_sz + arglen + 1;
232 p = realloc(strbuf, newsize);
233 if (p == NULL) {
234 free(strbuf);
235 err(1, NULL);
236 }
237 strbuf_sz = newsize;
238 strbuf = p;
239 }
240 strlcat(strbuf, str, strbuf_sz);
241}
242
243/* ARGSUSED */
244void
245abort_line(int sig __unused)
246{
247 static const char str1[] = "[\n]P\n";
248 static const char str2[] = "[^C\n]P\n";
249 int save_errno;
250 const LineInfo *info;
251
252 save_errno = errno;
253 if (use_el) {
254 write(STDOUT_FILENO, str2, sizeof(str2) - 1);
255 info = el_line(el);
256 skipchars = info->lastchar - info->buffer;
257 } else
258 write(STDOUT_FILENO, str1, sizeof(str1) - 1);
259 errno = save_errno;
260}
261
262/*
263 * Avoid the echo of ^D by the default code of editline and take
264 * into account skipchars to make ^D work when the cursor is at start of
265 * line after a ^C.
266 */
267unsigned char
268bc_eof(EditLine *e, int ch __unused)
269{
270 const struct lineinfo *info = el_line(e);
271
272 if (info->buffer + skipchars == info->cursor &&
273 info->cursor == info->lastchar)
274 return (CC_EOF);
275 else
276 return (CC_ERROR);
277}
278
239int
240yywrap(void)
241{
279int
280yywrap(void)
281{
242 static YY_BUFFER_STATE buf;
243 static int state;
282 static int state;
283 static YY_BUFFER_STATE buf;
244
245 if (fileindex == 0 && sargc > 0 && strcmp(sargv[0], _PATH_LIBB) == 0) {
246 filename = sargv[fileindex++];
247 yyin = fopen(filename, "r");
248 lineno = 1;
249 if (yyin == NULL)
250 err(1, "cannot open %s", filename);
251 return (0);

--- 16 unchanged lines hidden (view full) ---

268 yyin = fopen(filename, "r");
269 lineno = 1;
270 if (yyin == NULL)
271 err(1, "cannot open %s", filename);
272 return (0);
273 } else if (fileindex == sargc) {
274 fileindex++;
275 yyin = stdin;
284
285 if (fileindex == 0 && sargc > 0 && strcmp(sargv[0], _PATH_LIBB) == 0) {
286 filename = sargv[fileindex++];
287 yyin = fopen(filename, "r");
288 lineno = 1;
289 if (yyin == NULL)
290 err(1, "cannot open %s", filename);
291 return (0);

--- 16 unchanged lines hidden (view full) ---

308 yyin = fopen(filename, "r");
309 lineno = 1;
310 if (yyin == NULL)
311 err(1, "cannot open %s", filename);
312 return (0);
313 } else if (fileindex == sargc) {
314 fileindex++;
315 yyin = stdin;
316 if (interactive) {
317 signal(SIGINT, abort_line);
318 signal(SIGTSTP, tstpcont);
319 }
276 lineno = 1;
277 filename = "stdin";
278 return (0);
279 }
280 return (1);
281}
282
283static int
284bc_yyinput(char *buf, int maxlen)
285{
286 int num;
320 lineno = 1;
321 filename = "stdin";
322 return (0);
323 }
324 return (1);
325}
326
327static int
328bc_yyinput(char *buf, int maxlen)
329{
330 int num;
287 if (yyin == stdin && interactive) {
331
332 if (el != NULL)
333 el_get(el, EL_EDITMODE, &use_el);
334
335 if (yyin == stdin && interactive && use_el) {
288 const char *bp;
336 const char *bp;
337 sigset_t oset, nset;
289
290 if ((bp = el_gets(el, &num)) == NULL || num == 0)
291 return (0);
338
339 if ((bp = el_gets(el, &num)) == NULL || num == 0)
340 return (0);
341 sigemptyset(&nset);
342 sigaddset(&nset, SIGINT);
343 sigprocmask(SIG_BLOCK, &nset, &oset);
344 if (skipchars < num) {
345 bp += skipchars;
346 num -= skipchars;
347 }
348 skipchars = 0;
349 sigprocmask(SIG_SETMASK, &oset, NULL);
292 if (num > maxlen) {
350 if (num > maxlen) {
293 el_push(el, (char *)(uintptr_t)(bp) + maxlen);
351 el_push(el, bp + maxlen);
294 num = maxlen;
295 }
296 memcpy(buf, bp, num);
297 history(hist, &he, H_ENTER, bp);
352 num = maxlen;
353 }
354 memcpy(buf, bp, num);
355 history(hist, &he, H_ENTER, bp);
356 el_get(el, EL_EDITMODE, &use_el);
298 } else {
299 int c = '*';
300 for (num = 0; num < maxlen &&
301 (c = getc(yyin)) != EOF && c != '\n'; ++num)
302 buf[num] = (char) c;
303 if (c == '\n')
304 buf[num++] = (char) c;
305 if (c == EOF && ferror(yyin))
306 YY_FATAL_ERROR( "input in flex scanner failed" );
307 }
308 return (num);
309}
310
357 } else {
358 int c = '*';
359 for (num = 0; num < maxlen &&
360 (c = getc(yyin)) != EOF && c != '\n'; ++num)
361 buf[num] = (char) c;
362 if (c == '\n')
363 buf[num++] = (char) c;
364 if (c == EOF && ferror(yyin))
365 YY_FATAL_ERROR( "input in flex scanner failed" );
366 }
367 return (num);
368}
369
370