diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2008-08-21 21:00:15 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2008-08-21 21:00:15 +0000 |
commit | 941d9a3ae19d7dd0b7479dcc1c0c6e0c20bac4b9 (patch) | |
tree | a672ce9d39e0800d5c8e708f6a630be4356314f9 /usr.bin | |
parent | 639a4702116d39b8b4c67096ba5adff43bd46acd (diff) |
gnu extension: 0rN:az for baseN numbers.
okay otto@
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/m4/parser.y | 3 | ||||
-rw-r--r-- | usr.bin/m4/tokenizer.l | 37 |
2 files changed, 38 insertions, 2 deletions
diff --git a/usr.bin/m4/parser.y b/usr.bin/m4/parser.y index 6276f8fe672..2c63ae92d4c 100644 --- a/usr.bin/m4/parser.y +++ b/usr.bin/m4/parser.y @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: parser.y,v 1.5 2008/08/16 12:23:50 espie Exp $ */ +/* $OpenBSD: parser.y,v 1.6 2008/08/21 21:00:14 espie Exp $ */ /* * Copyright (c) 2004 Marc Espie <espie@cvs.openbsd.org> * @@ -22,6 +22,7 @@ extern int yylex(void); extern int yyerror(const char *); %} %token NUMBER +%token ERROR %left LOR %left LAND %left '|' diff --git a/usr.bin/m4/tokenizer.l b/usr.bin/m4/tokenizer.l index 9e038d8c42b..2d0d169672c 100644 --- a/usr.bin/m4/tokenizer.l +++ b/usr.bin/m4/tokenizer.l @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: tokenizer.l,v 1.5 2008/08/16 12:23:50 espie Exp $ */ +/* $OpenBSD: tokenizer.l,v 1.6 2008/08/21 21:00:14 espie Exp $ */ /* * Copyright (c) 2004 Marc Espie <espie@cvs.openbsd.org> * @@ -21,9 +21,11 @@ #include <stdint.h> #include <limits.h> +extern int mimic_gnu; extern int32_t yylval; int32_t number(void); +int32_t parse_radix(void); %} delim [ \t\n] @@ -31,10 +33,17 @@ ws {delim}+ hex 0[xX][0-9a-fA-F]+ oct 0[0-7]* dec [1-9][0-9]* +radix 0[rR][0-9]+:[0-9a-zA-Z]+ %% {ws} {/* just skip it */} {hex}|{oct}|{dec} { yylval = number(); return(NUMBER); } +{radix} { if (mimic_gnu) { + yylval = parse_radix(); return(NUMBER); + } else { + return(ERROR); + } + } "<=" { return(LE); } ">=" { return(GE); } "<<" { return(LSHIFT); } @@ -58,5 +67,31 @@ number() fprintf(stderr, "m4: numeric overflow in expr: %s\n", yytext); } return l; +} + +int32_t +parse_radix() +{ + long base; + char *next; + long l; + l = 0; + base = strtol(yytext+2, &next, 0); + if (base > 36 || next == NULL) { + fprintf(stderr, "m4: error in number %s\n", yytext); + } else { + next++; + while (*next != 0) { + if (*next >= '0' && *next <= '9') + l = base * l + *next - '0'; + else if (*next >= 'a' && *next <= 'z') + l = base * l + *next - 'a' + 10; + else if (*next >= 'A' && *next <= 'Z') + l = base * l + *next - 'A' + 10; + next++; + } + } + return l; } + |