1 %{
2 
3 /*
4  * (C) Copyright 2014, Stephen M. Cameron.
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License version 2 as
8  *  published by the Free Software Foundation.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
20 
21 #include <stdio.h>
22 #include <string.h>
23 #include "y.tab.h"
24 
25 #define YYSTYPE PARSER_VALUE_TYPE
26 
27 extern int lexer_input(char *buffer, unsigned int *nbytes, int buffersize);
28 
29 #undef YY_INPUT
30 #define YY_INPUT(buffer, bytes_read, bytes_requested)			\
31 ({									\
32 	int __ret;							\
33 	unsigned int __bread = bytes_read;				\
34 	__ret = lexer_input((buffer), &__bread, (bytes_requested));	\
35 	bytes_read = __bread;						\
36 	__ret;								\
37 })
38 
39 extern int yyerror(long long *result, double *dresult,
40 		int *has_error, int *units_specified, const char *msg);
41 
42 static void __attribute__((unused)) yyunput(int c, char *buf_ptr);
43 static int __attribute__((unused)) input(void);
44 
45 /* set by parser -- this is another thing which makes the parser thread-unsafe :(. */
46 int lexer_value_is_time = 0; /* for determining if "m" suffix means mega- or minutes */
47 
48 #define set_suffix_value(yylval, i_val, d_val, has_d_val) \
49 	(yylval).v.dval = (d_val); \
50 	(yylval).v.ival = (i_val); \
51 	(yylval).v.has_dval = (has_d_val); \
52 	(yylval).v.has_error = 0;
53 
54 %}
55 
56 %%
57 
58 
59 [kK]|[kK][bB] 	{
60 			set_suffix_value(yylval, 1024, 1024.0, 0);
61 			return SUFFIX;
62 		}
63 [Mm][bB]	{
64 			set_suffix_value(yylval, 1024 * 1024, 1024.0 * 1024.0, 0);
65 			return SUFFIX;
66 		}
67 [mM][sS]	{
68 			set_suffix_value(yylval, 1000, 1000.0, 1);
69 			return SUFFIX;
70 		}
71 [uU][sS]	{
72 			set_suffix_value(yylval, 1, 1.0, 1);
73 			return SUFFIX;
74 		}
75 [gG]|[Gg][Bb]	{
76 			set_suffix_value(yylval, 1024LL * 1024 * 1024, 1024.0 * 1024.0 * 1024, 0);
77 			return SUFFIX;
78 		}
79 [tT]|[tT][bB]	{
80 			set_suffix_value(yylval, 1024LL * 1024 * 1024 * 1024,
81 						1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024, 0);
82 			return SUFFIX;
83 		}
84 [pP]|[pP][bB]	{
85 			set_suffix_value(yylval, 1024LL * 1024 * 1024 * 1024 * 1024,
86 					1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0, 0);
87 			return SUFFIX;
88 		}
89 [kK][iI][Bb]	{
90 			set_suffix_value(yylval, 1000LL, 1000.0, 0);
91 			return SUFFIX;
92 		}
93 [mM][Ii][bB]	{
94 			set_suffix_value(yylval, 1000000LL, 1000000.0 , 0);
95 			return SUFFIX;
96 		}
97 [gG][iI][Bb]	{
98 			set_suffix_value(yylval, 1000000000LL, 1000000000.0 , 0);
99 			return SUFFIX;
100 		}
101 [pP][iI][Bb]	{
102 			set_suffix_value(yylval, 1000000000000LL, 1000000000000.0 , 0);
103 			return SUFFIX;
104 		}
105 [sS]		{
106 			set_suffix_value(yylval, 1000000LL, 1000000.0 , 0);
107 			return SUFFIX;
108 		}
109 [mM]		{
110 			if (!lexer_value_is_time) {
111 				set_suffix_value(yylval, 1024 * 1024, 1024.0 * 1024.0, 0);
112 			} else {
113 				set_suffix_value(yylval, 60LL * 1000000LL, 60.0 * 1000000.0, 0);
114 			}
115 			return SUFFIX;
116 		}
117 [dD]		{
118 			set_suffix_value(yylval, 60LL * 60LL * 24LL * 1000000LL,
119 						60.0 * 60.0 * 24.0 * 1000000.0, 0);
120 			return SUFFIX;
121 		}
122 [hH]		{
123 			set_suffix_value(yylval, 60LL * 60LL * 1000000LL,
124 					60.0 * 60.0 * 1000000.0, 0);
125 			return SUFFIX;
126 		}
127 [ \t] ; /* ignore whitespace */
128 [#:,].* ; /* ignore comments, and everything after colons and commas */
129 [0-9]*[.][0-9]+|[0-9]*[.]?[0-9]+[eE][-+]*[0-9]+ {
130 			int rc;
131 			double dval;
132 
133 			rc = sscanf(yytext, "%lf", &dval);
134 			if (rc == 1) {
135 				yylval.v.dval = dval;
136 				yylval.v.ival = (long long) dval;
137 				yylval.v.has_dval = 1;
138 				yylval.v.has_error = 0;
139 				return NUMBER;
140 			} else {
141 				yyerror(0, 0, 0, 0, "bad number\n");
142 				yylval.v.has_error = 1;
143 				return NUMBER;
144 			}
145 		}
146 0x[0-9a-fA-F]+ {
147 		int rc, intval;
148 		rc = sscanf(yytext, "%x", &intval);
149 		if (rc == 1) {
150 			yylval.v.ival = intval;
151 			yylval.v.dval = (double) intval;
152 			yylval.v.has_dval = 0;
153 			yylval.v.has_error = 0;
154 			return NUMBER;
155 		} else {
156 			yyerror(0, 0, 0, 0, "bad number\n");
157 			yylval.v.has_error = 1;
158 			return NUMBER;
159 		}
160 	}
161 [0-9]+	{
162 		int rc, intval;
163 		rc = sscanf(yytext, "%d", &intval);
164 		if (rc == 1) {
165 			yylval.v.ival = intval;
166 			yylval.v.dval = (double) intval;
167 			yylval.v.has_dval = 0;
168 			yylval.v.has_error = 0;
169 			return NUMBER;
170 		} else {
171 			yyerror(0, 0, 0, 0, "bad number\n");
172 			yylval.v.has_error = 1;
173 			return NUMBER;
174 		}
175 	}
176 \n	return 0;
177 [+-/*()^%]	return yytext[0];
178 
179 .	{
180 		yylval.v.has_error = 1;
181 		return NUMBER;
182 	}
183 %%
184 
185