scan.l revision 215704
1168054Sflz%{ 2168054Sflz/* $OpenBSD: scan.l,v 1.23 2009/10/27 23:59:36 deraadt Exp $ */ 3168266Sgabor 4168266Sgabor/* 5168266Sgabor * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net> 6168266Sgabor * 7168266Sgabor * Permission to use, copy, modify, and distribute this software for any 8168266Sgabor * purpose with or without fee is hereby granted, provided that the above 9168266Sgabor * copyright notice and this permission notice appear in all copies. 10168266Sgabor * 11168054Sflz * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12168054Sflz * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13168064Sflz * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14168064Sflz * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15168064Sflz * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16168064Sflz * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17168064Sflz * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18168064Sflz */ 19168064Sflz 20168064Sflz#include <sys/cdefs.h> 21168064Sflz__FBSDID("$FreeBSD: head/usr.bin/bc/scan.l 215704 2010-11-22 20:10:48Z brucec $"); 22168064Sflz 23168064Sflz#include <err.h> 24168064Sflz#include <errno.h> 25168064Sflz#include <histedit.h> 26168064Sflz#include <stdbool.h> 27168054Sflz#include <string.h> 28168054Sflz#include <unistd.h> 29168064Sflz 30168054Sflz#include "extern.h" 31168188Sgabor#include "bc.h" 32168357Syar#include "pathnames.h" 33168673Sjulian 34168188Sgaborint lineno; 35168263Sru 36168194Simpbool interactive; 37168357SyarHistEvent he; 38168188SgaborEditLine *el; 39168188SgaborHistory *hist; 40168188Sgabor 41168188Sgaborstatic char *strbuf = NULL; 42168188Sgaborstatic size_t strbuf_sz = 1; 43168188Sgaborstatic bool dot_seen; 44168188Sgabor 45168202Sumestatic void init_strbuf(void); 46168188Sgaborstatic void add_str(const char *); 47168188Sgaborstatic int bc_yyinput(char *, int); 48168202Sume 49168188Sgabor#define YY_NO_INPUT 50168127Sdwmalone#undef YY_INPUT 51168054Sflz#define YY_INPUT(buf,retval,max) \ 52168054Sflz (retval = bc_yyinput(buf, max)) 53168054Sflz%} 54168054Sflz 55168215Sache%option always-interactive 56208793Sae 57168149SimpDIGIT [0-9A-F] 58168149SimpALPHA [a-z_] 59207017SanchieALPHANUM [a-z_0-9] 60168179Sgabor 61212260Sandreast%x comment string number 62210361Sandrew 63168083Sjkim%% 64176001Santoine 65168123Snetchild"/*" BEGIN(comment); 66188752Savg<comment>{ 67168080Smlaier "*/" BEGIN(INITIAL); 68168195Sbenno \n lineno++; 69168131Sbmah \* ; 70168183Sgabor [^*\n]+ ; 71168080Smlaier <<EOF>> fatal("end of file in comment"); 72168309Sbrian} 73168308Sbrian 74203168Sbrucec\" BEGIN(string); init_strbuf(); 75168150Srwatson<string>{ 76168149Simp [^"\n\\\[\]]+ add_str(yytext); 77203555Sbschmidt \[ add_str("\\["); 78168150Srwatson \] add_str("\\]"); 79168263Sru \\ add_str("\\\\"); 80180232Scokane \n add_str("\n"); lineno++; 81168054Sflz \" BEGIN(INITIAL); yylval.str = strbuf; return STRING; 82168183Sgabor <<EOF>> fatal("end of file in string"); 83168674Sjulian} 84168060Sdds 85168108Srafan{DIGIT}+ { 86168083Sjkim BEGIN(number); 87168153Simp dot_seen = false; 88168080Smlaier init_strbuf(); 89212025Sdim add_str(yytext); 90168149Simp } 91168127Sdwmalone\. { 92179207Sed BEGIN(number); 93175201Sedwin dot_seen = true; 94168263Sru init_strbuf(); 95168180Srwatson add_str("."); 96168149Simp } 97179830Seri<number>{ 98189932Sfabient {DIGIT}+ add_str(yytext); 99168127Sdwmalone \. { 100169252Sfjoe if (dot_seen) { 101168054Sflz BEGIN(INITIAL); 102203370Sgabor yylval.str = strbuf; 103168370Sgad unput('.'); 104168631Sticso return (NUMBER); 105200313Sgavin } else { 106168183Sgabor dot_seen = true; 107168672Smav add_str("."); 108168150Srwatson } 109168195Sbenno } 110168081Sle \\\n[ \t]* lineno++; 111168154Sgshapiro [^0-9A-F\.] { 112168127Sdwmalone BEGIN(INITIAL); 113168144Simp unput(yytext[0]); 114179767Sivoras if (strcmp(strbuf, ".") == 0) 115168308Sbrian return (DOT); 116187937Sjamie else { 117168183Sgabor yylval.str = strbuf; 118208394Sjchandra return (NUMBER); 119208394Sjchandra } 120197776Sjh } 121208394Sjchandra} 122192607Sjilles 123168150Srwatson"auto" return (AUTO); 124168153Simp"break" return (BREAK); 125168083Sjkim"continue" return (CONTINUE); 126172389Skaiw"define" return (DEFINE); 127168111Smatteo"else" return (ELSE); 128168149Simp"ibase" return (IBASE); 129168151Sphk"if" return (IF); 130168149Simp"last" return (DOT); 131168673Sjulian"for" return (FOR); 132172389Skaiw"length" return (LENGTH); 133168180Srwatson"obase" return (OBASE); 134168535Skevlo"print" return (PRINT); 135200356Skib"quit" return (QUIT); 136168150Srwatson"return" return (RETURN); 137168081Sle"scale" return (SCALE); 138168180Srwatson"sqrt" return (SQRT); 139183643Slstewart"while" return (WHILE); 140172984Slulf 141180222Smarcel"^" return (EXPONENT); 142192775Smarkm"*" return (MULTIPLY); 143168167Sphilip"/" return (DIVIDE); 144168918Sbrueffer"%" return (REMAINDER); 145168142Srwatson 146168672Smav"!" return (BOOL_NOT); 147168263Sru"&&" return (BOOL_AND); 148208807Smdf"||" return (BOOL_OR); 149168143Smjacob 150168080Smlaier"+" return (PLUS); 151168149Simp"-" return (MINUS); 152168130Sdelphij 153198183Sneel"++" return (INCR); 154168123Snetchild"--" return (DECR); 155168171Sphilip 156194197Snork"=" yylval.str = ""; return (ASSIGN_OP); 157193775Snp"+=" yylval.str = "+"; return (ASSIGN_OP); 158180227Snwhitehorn"-=" yylval.str = "-"; return (ASSIGN_OP); 159168097Sle"*=" yylval.str = "*"; return (ASSIGN_OP); 160176318Solli"/=" yylval.str = "/"; return (ASSIGN_OP); 161168149Simp"%=" yylval.str = "%"; return (ASSIGN_OP); 162168127Sdwmalone"^=" yylval.str = "^"; return (ASSIGN_OP); 163168183Sgabor 164168111Smatteo"==" return (EQUALS); 165168151Sphk"<=" return (LESS_EQ); 166203610Sbrueffer">=" return (GREATER_EQ); 167168321Spjd"!=" return (UNEQUALS); 168168183Sgabor"<" return (LESS); 169168101Sandre">" return (GREATER); 170168108Srafan 171206988Srandi"," return (COMMA); 172168149Simp";" return (SEMICOLON); 173168149Simp 174168149Simp"(" return (LPAR); 175183282Srnoland")" return (RPAR); 176182009Sroberto 177172343Srpaulo"[" return (LBRACKET); 178168140Srwatson"]" return (RBRACKET); 179168118Srse 180206945Srstone"{" return (LBRACE); 181168263Sru"}" return (RBRACE); 182168140Srwatson 183168080Smlaier{ALPHA}{ALPHANUM}* { 184168149Simp /* alloc an extra byte for the type marker */ 185171026Sscf char *p = malloc(yyleng + 2); 186168081Sle if (p == NULL) 187168167Sphilip err(1, NULL); 188168149Simp strlcpy(p, yytext, yyleng + 1); 189168115Ssimon yylval.astr = p; 190168263Sru return (LETTER); 191191822Ssnb } 192180366Ssson 193168198Sume\\\n lineno++; 194168150Srwatson\n lineno++; return (NEWLINE); 195168149Simp 196168080Smlaier#[^\n]* ; 197168631Sticso[ \t] ; 198210200Stijl<<EOF>> return (QUIT); 199182006Strasz. yyerror("illegal character"); 200168180Srwatson 201193759Stuexen%% 202168198Sume 203203126Suqsstatic void 204180705Svanhuinit_strbuf(void) 205184913Sversus{ 206175039Sweongyo 207168271Swes if (strbuf == NULL) { 208168141Swilko strbuf = malloc(strbuf_sz); 209168180Srwatson if (strbuf == NULL) 210168356Syar err(1, NULL); 211168238Syongari } 212183150Szec strbuf[0] = '\0'; 213168054Sflz} 214168151Sphk 215168151Sphkstatic void 216168151Sphkadd_str(const char *str) 217168054Sflz{ 218168064Sflz size_t arglen; 219168064Sflz 220168054Sflz arglen = strlen(str); 221168151Sphk 222168151Sphk if (strlen(strbuf) + arglen + 1 > strbuf_sz) { 223168151Sphk size_t newsize; 224168151Sphk char *p; 225168151Sphk 226168151Sphk newsize = strbuf_sz + arglen + 1; 227168151Sphk p = realloc(strbuf, newsize); 228168101Sandre if (p == NULL) { 229168101Sandre free(strbuf); 230168083Sjkim err(1, NULL); 231168083Sjkim } 232168195Sbenno strbuf_sz = newsize; 233168195Sbenno strbuf = p; 234168152Srwatson } 235168152Srwatson strlcat(strbuf, str, strbuf_sz); 236168152Srwatson} 237168152Srwatson 238168152Srwatsonint 239168152Srwatsonyywrap(void) 240168152Srwatson{ 241168152Srwatson static YY_BUFFER_STATE buf; 242168352Sru static int state; 243168080Smlaier 244168080Smlaier if (fileindex == 0 && sargc > 0 && strcmp(sargv[0], _PATH_LIBB) == 0) { 245168080Smlaier filename = sargv[fileindex++]; 246168309Sbrian yyin = fopen(filename, "r"); 247168309Sbrian lineno = 1; 248168152Srwatson if (yyin == NULL) 249187937Sjamie err(1, "cannot open %s", filename); 250168152Srwatson return (0); 251206904Sanchie } 252187937Sjamie if (state == 0 && cmdexpr[0] != '\0') { 253168140Srwatson buf = yy_scan_string(cmdexpr); 254168140Srwatson state++; 255168101Sandre lineno = 1; 256206988Srandi filename = "command line"; 257168115Ssimon return (0); 258168101Sandre } else if (state == 1) { 259168152Srwatson yy_delete_buffer(buf); 260168152Srwatson free(cmdexpr); 261203370Sgabor state++; 262168108Srafan } 263168108Srafan if (yyin != NULL && yyin != stdin) 264168083Sjkim fclose(yyin); 265168147Sdes if (fileindex < sargc) { 266168147Sdes filename = sargv[fileindex++]; 267176318Solli yyin = fopen(filename, "r"); 268168263Sru lineno = 1; 269168083Sjkim if (yyin == NULL) 270184913Sversus err(1, "cannot open %s", filename); 271184913Sversus return (0); 272168352Sru } else if (fileindex == sargc) { 273168352Sru fileindex++; 274191822Ssnb yyin = stdin; 275168352Sru lineno = 1; 276212025Sdim filename = "stdin"; 277200313Sgavin return (0); 278192607Sjilles } 279200356Skib return (1); 280203953Suqs} 281192607Sjilles 282168147Sdesstatic int 283168140Srwatsonbc_yyinput(char *buf, int maxlen) 284168140Srwatson{ 285206945Srstone int num; 286206945Srstone if (yyin == stdin && interactive) { 287168918Sbrueffer const char *bp; 288168918Sbrueffer 289168631Sticso if ((bp = el_gets(el, &num)) == NULL || num == 0) 290168631Sticso return (0); 291168352Sru if (num > maxlen) { 292168352Sru el_push(el, (char *)(uintptr_t)(bp) + maxlen); 293168127Sdwmalone num = maxlen; 294168672Smav } 295168672Smav memcpy(buf, bp, num); 296168140Srwatson history(hist, &he, H_ENTER, bp); 297168140Srwatson } else { 298179767Sivoras int c = '*'; 299180705Svanhu for (num = 0; num < maxlen && 300183643Slstewart (c = getc(yyin)) != EOF && c != '\n'; ++num) 301193775Snp buf[num] = (char) c; 302168140Srwatson if (c == '\n') 303175205Sedwin buf[num++] = (char) c; 304168352Sru if (c == EOF && ferror(yyin)) 305168352Sru YY_FATAL_ERROR( "input in flex scanner failed" ); 306168149Simp } 307168149Simp return (num); 308168156Sbmah} 309168149Simp 310168149Simp