From: espie Date: Thu, 21 Aug 2008 21:00:14 +0000 (+0000) Subject: gnu extension: 0rN:az for baseN numbers. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=81e4efa89c59753051d6a72233541460c787b60d;p=openbsd gnu extension: 0rN:az for baseN numbers. okay otto@ --- 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 * @@ -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 * @@ -21,9 +21,11 @@ #include #include +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; } +