root/src/noit_tokenizer.c

Revision 6210da7ee0e2ed143d71a8e00b709f16e71059f8, 6.2 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 5 years ago)

various changes to avoid dereferencing type-punned pointers and breaking strict-aliasing rules, refs #34

  • Property mode set to 100644
Line 
1 /* Generated by re2c 0.13.2 on Tue Mar 17 15:37:18 2009 */
2 #line 1 "noit_tokenizer.re"
3 #include "noit_defines.h"
4 #include <stdlib.h>
5 #include <string.h>
6
7 struct token {
8   char *token;
9   const char *start;
10   const char *end;
11   const char *next;
12   enum { NT_IDENT, NT_DQSTRING, NT_SPACE, NT_UNKNOWN, NT_EOF } type;
13 };
14 #define SET_TOKEN(t,a) (t)->next = (a)
15
16 static void c_unescape(char *p, char *only) {
17   char *bt = p;
18 #define ASSIGN(a) *(bt++) = (a)
19   while(p[0] != '\0') {
20     if(p[0] == '\\' && p[1] != '\0' && (!only || p[1] == *only)) {
21       switch(p[1]) {
22         case ' ': ASSIGN(' '); p+=2; break;
23         case '"': ASSIGN('"'); p+=2; break;
24         case 'n': ASSIGN('\n'); p+=2; break;
25         case 'r': ASSIGN('\r'); p+=2; break;
26         case 't': ASSIGN('\t'); p+=2; break;
27         case 'a': ASSIGN('\a'); p+=2; break;
28         case 'b': ASSIGN('\b'); p+=2; break;
29         case 'v': ASSIGN('\v'); p+=2; break;
30         case 'f': ASSIGN('\f'); p+=2; break;
31         case '0': ASSIGN('\0'); p+=2; break;
32         case '\\': ASSIGN('\\'); p+=2; break;
33         default: ASSIGN(*p); p++; ASSIGN(*p); p++; break;
34       }
35     }
36     else {
37       ASSIGN(*p); p++;
38     }
39   }
40   *bt = '\0';
41 }
42
43 #define BAIL_UNKNOWN do { t->type = NT_UNKNOWN; return -1; } while(0)
44 static int token_scan(struct token *t)
45 {
46   t->start = t->end = t->next;
47
48  mainpattern:
49
50 #line 51 "noit_tokenizer.c"
51         {
52                 unsigned char yych;
53
54                 yych = (unsigned char)*t->next;
55                 switch (yych) {
56                 case 0x00:      goto yy10;
57                 case 0x09:
58                 case 0x0A:
59                 case 0x0D:
60                 case ' ':       goto yy2;
61                 case '"':       goto yy4;
62                 case '\'':      goto yy6;
63                 default:        goto yy8;
64                 }
65 yy2:
66                 ++t->next;
67                 yych = (unsigned char)*t->next;
68                 goto yy17;
69 yy3:
70 #line 54 "noit_tokenizer.re"
71                 { t->token = NULL;
72                       t->end = t->next;
73                       t->type = NT_SPACE;
74                       return 1; }
75 #line 76 "noit_tokenizer.c"
76 yy4:
77                 ++t->next;
78 #line 58 "noit_tokenizer.re"
79                 { t->type = NT_DQSTRING;
80                       if(t->start != t->end) {
81                         t->start++;
82                         t->end = t->next - 1;
83                         t->token = malloc(t->end-t->start + 1);
84                         strlcpy(t->token, t->start, t->end-t->start + 1);
85                         c_unescape(t->token, NULL);
86                         return 1;
87                       }
88                       else
89                         goto dqstring;
90                     }
91 #line 92 "noit_tokenizer.c"
92 yy6:
93                 ++t->next;
94 #line 70 "noit_tokenizer.re"
95                 { t->type = NT_IDENT;
96                       if(t->start != t->end) {
97                         t->start++;
98                         t->end = t->next - 1;
99                         t->token = malloc(t->end-t->start + 1);
100                         strlcpy(t->token, t->start, t->end-t->start + 1);
101                         return 1;
102                       }
103                       else
104                         goto sqstring;
105                     }
106 #line 107 "noit_tokenizer.c"
107 yy8:
108                 ++t->next;
109                 yych = (unsigned char)*t->next;
110                 goto yy13;
111 yy9:
112 #line 82 "noit_tokenizer.re"
113                 { char only = ' ';
114                       t->end = t->next;
115                       t->type = NT_IDENT;
116                       t->token = malloc(t->end-t->start + 1);
117                       strlcpy(t->token, t->start, t->end-t->start + 1);
118                       c_unescape(t->token, &only);
119                       return 1;
120                     }
121 #line 122 "noit_tokenizer.c"
122 yy10:
123                 ++t->next;
124 #line 90 "noit_tokenizer.re"
125                 { t->token = NULL;
126                       t->type = NT_EOF;
127                       return 0;
128                     }
129 #line 130 "noit_tokenizer.c"
130 yy12:
131                 ++t->next;
132                 yych = (unsigned char)*t->next;
133 yy13:
134                 switch (yych) {
135                 case 0x00:
136                 case 0x09:
137                 case 0x0A:
138                 case 0x0D:
139                 case ' ':       goto yy9;
140                 case '\\':      goto yy14;
141                 default:        goto yy12;
142                 }
143 yy14:
144                 ++t->next;
145                 yych = (unsigned char)*t->next;
146                 switch (yych) {
147                 case 0x00:
148                 case 0x09:
149                 case 0x0A:
150                 case 0x0D:      goto yy9;
151                 case '\\':      goto yy14;
152                 default:        goto yy12;
153                 }
154 yy16:
155                 ++t->next;
156                 yych = (unsigned char)*t->next;
157 yy17:
158                 switch (yych) {
159                 case 0x09:
160                 case 0x0A:
161                 case 0x0D:
162                 case ' ':       goto yy16;
163                 default:        goto yy3;
164                 }
165         }
166 #line 95 "noit_tokenizer.re"
167
168
169  sqstring:
170
171 #line 172 "noit_tokenizer.c"
172         {
173                 unsigned char yych;
174                 yych = (unsigned char)*t->next;
175                 switch (yych) {
176                 case 0x00:      goto yy23;
177                 case '\'':      goto yy20;
178                 default:        goto yy21;
179                 }
180 yy20:
181 #line 99 "noit_tokenizer.re"
182                 { t->end = t->next;
183                       goto mainpattern; }
184 #line 185 "noit_tokenizer.c"
185 yy21:
186                 ++t->next;
187                 yych = (unsigned char)*t->next;
188                 switch (yych) {
189                 case 0x00:
190                 case '\'':      goto yy20;
191                 default:        goto yy21;
192                 }
193 yy23:
194                 ++t->next;
195 #line 101 "noit_tokenizer.re"
196                 { BAIL_UNKNOWN; }
197 #line 198 "noit_tokenizer.c"
198         }
199 #line 102 "noit_tokenizer.re"
200
201
202  dqstring:
203
204 #line 205 "noit_tokenizer.c"
205         {
206                 unsigned char yych;
207                 yych = (unsigned char)*t->next;
208                 switch (yych) {
209                 case 0x00:      goto yy33;
210                 case '"':       goto yy29;
211                 case '\\':      goto yy27;
212                 default:        goto yy31;
213                 }
214 yy27:
215                 yych = (unsigned char)*++t->next;
216                 switch (yych) {
217                 case 0x00:      goto yy28;
218                 case '"':
219                 case '0':
220                 case '\\':
221                 case 'a':
222                 case 'b':
223                 case 'f':
224                 case 'n':
225                 case 'r':
226                 case 't':
227                 case 'v':       goto yy37;
228                 default:        goto yy35;
229                 }
230 yy28:
231 yy29:
232                 ++t->next;
233 #line 110 "noit_tokenizer.re"
234                 { t->end = t->next--;
235                       goto mainpattern;
236                     }
237 #line 238 "noit_tokenizer.c"
238 yy31:
239                 ++t->next;
240 #line 113 "noit_tokenizer.re"
241                 { goto dqstring; }
242 #line 243 "noit_tokenizer.c"
243 yy33:
244                 ++t->next;
245 #line 114 "noit_tokenizer.re"
246                 { BAIL_UNKNOWN; }
247 #line 248 "noit_tokenizer.c"
248 yy35:
249                 ++t->next;
250 #line 109 "noit_tokenizer.re"
251                 { goto dqstring; }
252 #line 253 "noit_tokenizer.c"
253 yy37:
254                 ++t->next;
255 #line 107 "noit_tokenizer.re"
256                 { goto dqstring; }
257 #line 258 "noit_tokenizer.c"
258         }
259 #line 115 "noit_tokenizer.re"
260
261 }
262
263 int noit_tokenize(const char *input, char **vector, int *cnt) {
264   struct token t;
265   int i = 0;
266
267   SET_TOKEN(&t, input);
268   while(token_scan(&t) != -1) {
269     switch(t.type) {
270       case NT_IDENT:
271       case NT_DQSTRING:
272         if(i<*cnt) vector[i] = t.token;
273         i++;
274         break;
275       case NT_SPACE:
276         break;
277       case NT_EOF:
278         if(i<*cnt) *cnt = i;
279         return i;
280       case NT_UNKNOWN:
281         /* UNREACHED */
282         goto failure;
283     }
284   }
285  failure:
286   if(i<*cnt) *cnt = i;
287   return input - t.next;
288 }
Note: See TracBrowser for help on using the browser.