[BACK]Return to scan.l CVS log [TXT][DIR] Up to [local] / src / usr.bin / bc

Annotation of src/usr.bin/bc/scan.l, Revision 1.19

1.1       otto        1: %{
1.19    ! deraadt     2: /*      $OpenBSD: scan.l,v 1.18 2005/04/13 06:36:03 otto Exp $ */
1.1       otto        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: #ifndef lint
1.19    ! deraadt    21: static const char rcsid[] = "$OpenBSD: scan.l,v 1.18 2005/04/13 06:36:03 otto Exp $";
1.1       otto       22: #endif /* not lint */
                     23:
                     24: #include <err.h>
1.16      otto       25: #include <signal.h>
1.1       otto       26: #include <stdbool.h>
                     27: #include <string.h>
1.18      otto       28: #include <unistd.h>
1.1       otto       29:
                     30: #include "extern.h"
1.15      otto       31: #include "pathnames.h"
1.1       otto       32: #include "y.tab.h"
                     33:
                     34: int            lineno;
                     35:
1.2       deraadt    36: static char    *strbuf = NULL;
1.1       otto       37: static size_t  strbuf_sz = 1;
                     38: static bool    dot_seen;
1.16      otto       39: static volatile sig_atomic_t   interactive = 0;
1.1       otto       40:
                     41: static void    init_strbuf(void);
                     42: static void    add_str(const char *);
                     43:
                     44: %}
1.18      otto       45:
                     46: %option always-interactive
1.1       otto       47:
                     48: DIGIT          [0-9A-F]
1.14      otto       49: ALPHA          [a-z_]
                     50: ALPHANUM       [a-z_0-9]
                     51:
1.1       otto       52: %x             comment string number
                     53:
                     54: %%
                     55:
                     56: "/*"           BEGIN(comment);
                     57: <comment>{
                     58:        "*/"    BEGIN(INITIAL);
                     59:        \n      lineno++;
                     60:        \*      ;
                     61:        [^*\n]+ ;
1.5       otto       62:        <<EOF>> fatal("end of file in comment");
1.1       otto       63: }
                     64:
                     65: \"             BEGIN(string); init_strbuf();
                     66: <string>{
1.7       otto       67:        [^"\n\\\[\]]+   add_str(yytext);
                     68:        \[      add_str("\\[");
                     69:        \]      add_str("\\]");
                     70:        \\      add_str("\\\\");
1.1       otto       71:        \n      add_str("\n"); lineno++;
                     72:        \"      BEGIN(INITIAL); yylval.str = strbuf; return STRING;
1.5       otto       73:        <<EOF>> fatal("end of file in string");
1.1       otto       74: }
                     75:
                     76: {DIGIT}+       {
                     77:                        BEGIN(number);
                     78:                        dot_seen = false;
                     79:                        init_strbuf();
                     80:                        add_str(yytext);
                     81:                }
                     82: \.             {
                     83:                        BEGIN(number);
                     84:                        dot_seen = true;
                     85:                        init_strbuf();
                     86:                        add_str(".");
                     87:                }
                     88: <number>{
                     89:        {DIGIT}+        add_str(yytext);
                     90:        \.      {
                     91:                        if (dot_seen) {
                     92:                                BEGIN(INITIAL);
                     93:                                yylval.str = strbuf;
                     94:                                unput('.');
                     95:                                return NUMBER;
                     96:                        } else {
                     97:                                dot_seen = true;
                     98:                                add_str(".");
                     99:                        }
                    100:                }
                    101:        \\\n[ \t]*      lineno++;
                    102:        [^0-9A-F\.]     {
1.6       otto      103:                        BEGIN(INITIAL);
                    104:                        unput(yytext[0]);
                    105:                        if (strcmp(strbuf, ".") == 0)
                    106:                                return DOT;
1.1       otto      107:                        else {
                    108:                                yylval.str = strbuf;
                    109:                                return NUMBER;
                    110:                        }
                    111:                }
                    112: }
                    113:
                    114: "auto"         return AUTO;
1.2       deraadt   115: "break"                return BREAK;
1.8       otto      116: "continue"     return CONTINUE;
1.1       otto      117: "define"       return DEFINE;
1.8       otto      118: "else"         return ELSE;
1.1       otto      119: "ibase"                return IBASE;
                    120: "if"           return IF;
1.10      otto      121: "last"         return DOT;
1.1       otto      122: "for"          return FOR;
                    123: "length"       return LENGTH;
                    124: "obase"                return OBASE;
1.11      otto      125: "print"                return PRINT;
1.1       otto      126: "quit"         return QUIT;
                    127: "return"       return RETURN;
                    128: "scale"                return SCALE;
                    129: "sqrt"         return SQRT;
                    130: "while"                return WHILE;
                    131:
                    132: "^"            return EXPONENT;
                    133: "*"            return MULTIPLY;
                    134: "/"            return DIVIDE;
                    135: "%"            return REMAINDER;
1.13      otto      136:
                    137: "!"            return BOOL_NOT;
                    138: "&&"           return BOOL_AND;
                    139: "||"           return BOOL_OR;
1.1       otto      140:
                    141: "+"            return PLUS;
                    142: "-"            return MINUS;
                    143:
                    144: "++"           return INCR;
                    145: "--"           return DECR;
                    146:
1.4       deraadt   147: "="            yylval.str = ""; return ASSIGN_OP;
1.1       otto      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;
                    154:
                    155: "=="           return EQUALS;
                    156: "<="           return LESS_EQ;
                    157: ">="           return GREATER_EQ;
                    158: "!="           return UNEQUALS;
                    159: "<"            return LESS;
                    160: ">"            return GREATER;
                    161:
                    162: ","            return COMMA;
                    163: ";"            return SEMICOLON;
                    164:
                    165: "("            return LPAR;
                    166: ")"            return RPAR;
                    167:
                    168: "["            return LBRACKET;
                    169: "]"            return RBRACKET;
                    170:
                    171: "{"            return LBRACE;
                    172: "}"            return RBRACE;
                    173:
1.14      otto      174: {ALPHA}{ALPHANUM}* {
                    175:                        /* alloc an extra byte for the type marker */
                    176:                        char *p = malloc(yyleng + 2);
                    177:                        if (p == NULL)
                    178:                                err(1, NULL);
                    179:                        strlcpy(p, yytext, yyleng + 1);
                    180:                        yylval.astr = p;
                    181:                        return LETTER;
                    182:                }
1.1       otto      183:
                    184: \\\n           lineno++;
                    185: \n             lineno++; return NEWLINE;
                    186:
1.12      otto      187: #[^\n]*                ;
1.1       otto      188: [ \t]          ;
1.14      otto      189: <<EOF>>                return QUIT;
1.5       otto      190: .              yyerror("illegal character");
1.1       otto      191:
                    192: %%
                    193:
                    194: static void
                    195: init_strbuf(void)
                    196: {
                    197:        if (strbuf == NULL) {
                    198:                strbuf = malloc(strbuf_sz);
                    199:                if (strbuf == NULL)
1.9       otto      200:                        err(1, NULL);
1.1       otto      201:        }
                    202:        strbuf[0] = '\0';
                    203: }
                    204:
                    205: static void
                    206: add_str(const char *str)
                    207: {
                    208:        size_t arglen;
                    209:
                    210:        arglen = strlen(str);
                    211:
1.14      otto      212:        if (strlen(strbuf) + arglen + 1 > strbuf_sz) {
1.1       otto      213:                size_t newsize;
1.3       deraadt   214:                char *p;
1.1       otto      215:
                    216:                newsize = strbuf_sz + arglen + 1;
                    217:                p = realloc(strbuf, newsize);
                    218:                if (p == NULL) {
                    219:                        free(strbuf);
1.9       otto      220:                        err(1, NULL);
1.1       otto      221:                }
                    222:                strbuf_sz = newsize;
                    223:                strbuf = p;
                    224:        }
                    225:        strlcat(strbuf, str, strbuf_sz);
                    226: }
                    227:
1.19    ! deraadt   228: /* ARGSUSED */
1.1       otto      229: void
                    230: abort_line(int sig)
                    231: {
1.16      otto      232:        const char str[] = "[\n]P\n";
                    233:        int save_errno;
                    234:
                    235:        if (interactive) {
                    236:                save_errno = errno;
1.17      deraadt   237:                YY_FLUSH_BUFFER;        /* XXX signal race? */
1.16      otto      238:                write(STDOUT_FILENO, str, sizeof(str) - 1);
                    239:                errno = save_errno;
1.1       otto      240:        }
                    241: }
1.15      otto      242:
                    243: int
                    244: yywrap(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:        }
                    268:        if (fileindex < sargc) {
                    269:                filename = sargv[fileindex++];
                    270:                yyin = fopen(filename, "r");
                    271:                lineno = 1;
                    272:                if (yyin == NULL)
                    273:                        err(1, "cannot open %s", filename);
                    274:                return (0);
                    275:        } else if (fileindex == sargc) {
                    276:                fileindex++;
                    277:                yyin = stdin;
1.16      otto      278:                interactive = isatty(fileno(yyin));
1.15      otto      279:                lineno = 1;
                    280:                filename = "stdin";
                    281:                return (0);
                    282:        }
                    283:        return (1);
                    284: }
                    285: