| 1 |  |  | %{ | 
    
    | 2 |  |  | /* $OpenBSD: tokenizer.l,v 1.10 2017/06/17 01:55:16 bcallah Exp $ */ | 
    
    | 3 |  |  | /* | 
    
    | 4 |  |  |  * Copyright (c) 2004 Marc Espie <espie@cvs.openbsd.org> | 
    
    | 5 |  |  |  * | 
    
    | 6 |  |  |  * Permission to use, copy, modify, and distribute this software for any | 
    
    | 7 |  |  |  * purpose with or without fee is hereby granted, provided that the above | 
    
    | 8 |  |  |  * copyright notice and this permission notice appear in all copies. | 
    
    | 9 |  |  |  * | 
    
    | 10 |  |  |  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | 
    
    | 11 |  |  |  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | 
    
    | 12 |  |  |  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | 
    
    | 13 |  |  |  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 
    
    | 14 |  |  |  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | 
    
    | 15 |  |  |  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | 
    
    | 16 |  |  |  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 
    
    | 17 |  |  |  */ | 
    
    | 18 |  |  | #include "parser.h" | 
    
    | 19 |  |  | #include <assert.h> | 
    
    | 20 |  |  | #include <stdlib.h> | 
    
    | 21 |  |  | #include <errno.h> | 
    
    | 22 |  |  | #include <stdint.h> | 
    
    | 23 |  |  | #include <limits.h> | 
    
    | 24 |  |  |  | 
    
    | 25 |  |  | extern void m4_warnx(const char *, ...); | 
    
    | 26 |  |  | extern int mimic_gnu; | 
    
    | 27 |  |  | extern int32_t yylval; | 
    
    | 28 |  |  |  | 
    
    | 29 |  |  | int32_t number(void); | 
    
    | 30 |  |  | int32_t parse_radix(void); | 
    
    | 31 |  |  | %} | 
    
    | 32 |  |  |  | 
    
    | 33 |  |  | delim 	[ \t\n] | 
    
    | 34 |  |  | ws	{delim}+ | 
    
    | 35 |  |  | hex	0[xX][0-9a-fA-F]+ | 
    
    | 36 |  |  | oct	0[0-7]* | 
    
    | 37 |  |  | dec	[1-9][0-9]* | 
    
    | 38 |  |  | radix	0[rR][0-9]+:[0-9a-zA-Z]+ | 
    
    | 39 |  |  |  | 
    
    | 40 |  |  | %option noyywrap | 
    
    | 41 |  |  |  | 
    
    | 42 |  |  | %% | 
    
    | 43 |  |  | {ws}			{/* just skip it */} | 
    
    | 44 |  |  | {hex}|{oct}|{dec}	{ yylval = number(); return(NUMBER); } | 
    
    | 45 |  |  | {radix}			{ if (mimic_gnu) { | 
    
    | 46 |  |  | 				yylval = parse_radix(); return(NUMBER); | 
    
    | 47 |  |  | 			  } else { | 
    
    | 48 |  |  | 			  	return(ERROR); | 
    
    | 49 |  |  | 			  } | 
    
    | 50 |  |  | 			} | 
    
    | 51 |  |  | "<="			{ return(LE); } | 
    
    | 52 |  |  | ">="			{ return(GE); } | 
    
    | 53 |  |  | "<<"			{ return(LSHIFT); } | 
    
    | 54 |  |  | ">>"			{ return(RSHIFT); } | 
    
    | 55 |  |  | "=="			{ return(EQ); } | 
    
    | 56 |  |  | "!="			{ return(NE); } | 
    
    | 57 |  |  | "&&"			{ return(LAND); } | 
    
    | 58 |  |  | "||"			{ return(LOR); } | 
    
    | 59 |  |  | "**"			{ if (mimic_gnu) { return (EXPONENT); } } | 
    
    | 60 |  |  | .			{ return yytext[0]; } | 
    
    | 61 |  |  | %% | 
    
    | 62 |  |  |  | 
    
    | 63 |  |  | int32_t | 
    
    | 64 |  |  | number() | 
    
    | 65 |  |  | { | 
    
    | 66 |  |  | 	long l; | 
    
    | 67 |  |  |  | 
    
    | 68 |  |  | 	errno = 0; | 
    
    | 69 |  | 252 | 	l = strtol(yytext, NULL, 0); | 
    
    | 70 |  | 126 | 	if (((l == LONG_MAX || l == LONG_MIN) && errno == ERANGE) || | 
    
    | 71 | ✗✓✗✗ 
 | 126 | 	    l > INT32_MAX || l < INT32_MIN) | 
    
    | 72 | ✗✓ | 126 | 		m4_warnx("numeric overflow in expr: %s", yytext); | 
    
    | 73 |  |  | 	return l; | 
    
    | 74 |  | 126 | } | 
    
    | 75 |  |  |  | 
    
    | 76 |  |  | int32_t | 
    
    | 77 |  |  | parse_radix() | 
    
    | 78 |  |  | { | 
    
    | 79 |  |  | 	long base; | 
    
    | 80 |  |  | 	char *next; | 
    
    | 81 |  |  | 	long l; | 
    
    | 82 |  |  | 	int d; | 
    
    | 83 |  |  |  | 
    
    | 84 |  |  | 	l = 0; | 
    
    | 85 |  |  | 	base = strtol(yytext+2, &next, 0); | 
    
    | 86 |  |  | 	if (base > 36 || next == NULL) { | 
    
    | 87 |  |  | 		m4_warnx("error in number %s", yytext); | 
    
    | 88 |  |  | 	} else { | 
    
    | 89 |  |  | 		next++; | 
    
    | 90 |  |  | 		while (*next != 0) { | 
    
    | 91 |  |  | 			if (*next >= '0' && *next <= '9') | 
    
    | 92 |  |  | 				d = *next - '0'; | 
    
    | 93 |  |  | 			else if (*next >= 'a' && *next <= 'z') | 
    
    | 94 |  |  | 				d = *next - 'a' + 10; | 
    
    | 95 |  |  | 			else { | 
    
    | 96 |  |  | 				assert(*next >= 'A' && *next <= 'Z'); | 
    
    | 97 |  |  | 				d = *next - 'A' + 10; | 
    
    | 98 |  |  | 			} | 
    
    | 99 |  |  | 			if (d >= base) { | 
    
    | 100 |  |  | 				m4_warnx("error in number %s", yytext); | 
    
    | 101 |  |  | 				return 0; | 
    
    | 102 |  |  | 			} | 
    
    | 103 |  |  | 			l = base * l + d; | 
    
    | 104 |  |  | 			next++; | 
    
    | 105 |  |  | 		} | 
    
    | 106 |  |  | 	} | 
    
    | 107 |  |  | 	return l; | 
    
    | 108 |  |  | } | 
    
    | 109 |  |  |  |