If we don't get any OS information, remove the old OS information.
[metze/wireshark/wip.git] / wiretap / ascend_scanner.l
1 /*
2  * We want a reentrant scanner.
3  */
4 %option reentrant
5
6 /*
7  * We want to generate code that can be used by a reentrant parser
8  * generated by Bison or Berkeley YACC.
9  */
10 %option bison-bridge
11
12 /*
13  * We don't read interactively from the terminal.
14  */
15 %option never-interactive
16
17 /*
18  * We want to stop processing when we get to the end of the input.
19  */
20 %option noyywrap
21
22 /*
23  * The type for the state we keep for the scanner (and parser).
24  */
25 %option extra-type="ascend_state_t *"
26
27 /*
28  * Prefix scanner routines with "ascend" rather than "yy", so this scanner
29  * can coexist with other scanners.
30  */
31 %option prefix="ascend"
32
33 /*
34  * We have to override the memory allocators so that we don't get
35  * "unused argument" warnings from the yyscanner argument (which
36  * we don't use, as we have a global memory allocator).
37  *
38  * We provide, as macros, our own versions of the routines generated by Flex,
39  * which just call malloc()/realloc()/free() (as the Flex versions do),
40  * discarding the extra argument.
41  */
42 %option noyyalloc
43 %option noyyrealloc
44 %option noyyfree
45
46 %{
47 /* ascend_scanner.l
48  *
49  * Wiretap Library
50  * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
51  *
52  * This program is free software; you can redistribute it and/or
53  * modify it under the terms of the GNU General Public License
54  * as published by the Free Software Foundation; either version 2
55  * of the License, or (at your option) any later version.
56  *
57  * This program is distributed in the hope that it will be useful,
58  * but WITHOUT ANY WARRANTY; without even the implied warranty of
59  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
60  * GNU General Public License for more details.
61  *
62  * You should have received a copy of the GNU General Public License
63  * along with this program; if not, write to the Free Software
64  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
65  */
66
67 #include "config.h"
68
69 #include <stdlib.h>
70 #include <string.h>
71
72 #include "wtap-int.h"
73 #include "ascendtext.h"
74 #include "ascend-int.h"
75 #include "ascend.h"
76 #include "file_wrappers.h"
77
78 #define YY_INPUT(buf,result,max_size) { \
79         ascend_state_t *parser_state = ascendget_extra(yyscanner); \
80         int c = file_getc(parser_state->fh); \
81         if (c == EOF) { \
82                 *(parser_state->err) = file_error(parser_state->fh, \
83                     parser_state->err_info); \
84                 if (*(parser_state->err) == 0) \
85                         *(parser_state->err) = WTAP_ERR_SHORT_READ; \
86                 result = YY_NULL; \
87         } else { \
88                 buf[0] = c; \
89                 result = 1; \
90         } \
91 }
92
93 #define NO_USER "<none>"
94
95 #ifndef HAVE_UNISTD_H
96 #define YY_NO_UNISTD_H
97 #endif
98
99 /*
100  * Sleazy hack to suppress compiler warnings in yy_fatal_error().
101  */
102 #define YY_EXIT_FAILURE ((void)yyscanner, 2)
103
104 /*
105  * Macros for the allocators, to discard the extra argument.
106  */
107 #define ascendalloc(size, yyscanner)            (void *)malloc(size)
108 #define ascendrealloc(ptr, size, yyscanner)     (void *)realloc((char *)(ptr), (size))
109 #define ascendfree(ptr, yyscanner)              free((char *)ptr)
110
111 %}
112
113 D [0-9]
114 H [A-Fa-f0-9]
115
116 PPP_XPFX PPP-OUT
117 PPP_RPFX PPP-IN
118 ISDN_XPFX PRI-XMIT-
119 ISDN_RPFX PRI-RCV-
120 WAN_XPFX XMIT[\-:]*
121 WAN_RPFX RECV[\-:]*
122 ETHER_PFX ETHER
123
124 WDD_DATE    "Date:"
125 WDD_TIME    "Time:"
126 WDD_CAUSE   "Cause an attempt to place call to "
127 WDD_CALLNUM [^\n\r\t ]+
128 WDD_CHUNK   "WD_DIALOUT_DISP: chunk"
129 WDD_TYPE    "type "[^\n\r\t ]+
130
131 %s sc_gen_task
132 %s sc_gen_time_s
133 %s sc_gen_time_u
134 %s sc_gen_octets
135 %s sc_gen_counter
136 %s sc_gen_byte
137
138 %s sc_wds_user
139 %s sc_wds_sess
140
141 %s sc_wdd_date_d
142 %s sc_wdd_date_m
143 %s sc_wdd_date_y
144 %s sc_wdd_time
145 %s sc_wdd_time_h
146 %s sc_wdd_time_m
147 %s sc_wdd_time_s
148 %s sc_wdd_cause
149 %s sc_wdd_callnum
150 %s sc_wdd_chunk
151 %s sc_wdd_chunknum
152 %s sc_wdd_type
153
154 %s sc_chardisp
155
156 %s sc_isdn_call
157 %s sc_ether_direction
158
159 %%
160
161 <INITIAL,sc_gen_byte>{ETHER_PFX} {
162   BEGIN(sc_ether_direction);
163   yylval->d = ASCEND_PFX_ETHER;
164   return ETHER_PREFIX;
165 }
166
167 <INITIAL,sc_gen_byte>{ISDN_XPFX} {
168   BEGIN(sc_isdn_call);
169   yylval->d = ASCEND_PFX_ISDN_X;
170   return ISDN_PREFIX;
171 }
172
173 <INITIAL,sc_gen_byte>{ISDN_RPFX} {
174   BEGIN(sc_isdn_call);
175   yylval->d = ASCEND_PFX_ISDN_R;
176   return ISDN_PREFIX;
177 }
178
179 <INITIAL,sc_gen_byte>{WAN_XPFX} {
180   BEGIN(sc_wds_user);
181   yylval->d = ASCEND_PFX_WDS_X;
182   return WDS_PREFIX;
183 }
184
185 <INITIAL,sc_gen_byte>{WAN_RPFX} {
186   BEGIN(sc_wds_user);
187   yylval->d = ASCEND_PFX_WDS_R;
188   return WDS_PREFIX;
189 }
190
191 <INITIAL,sc_gen_byte>{PPP_XPFX} {
192   BEGIN(sc_wds_user);
193   yylval->d = ASCEND_PFX_WDS_X;
194   return WDS_PREFIX;
195 }
196
197 <INITIAL,sc_gen_byte>{PPP_RPFX} {
198   BEGIN(sc_wds_user);
199   yylval->d = ASCEND_PFX_WDS_R;
200   return WDS_PREFIX;
201 }
202
203 <sc_ether_direction>[^\(]{2,20} {
204   BEGIN(sc_gen_task);
205   return STRING;
206 }
207
208 <sc_isdn_call>[^\/\(:]{2,20} {
209   BEGIN(sc_gen_task);
210   return DECNUM;
211 }
212
213 <sc_wds_user>[^:]{2,20} {
214   char *atcopy = g_strdup(yytext);
215   char colon = input(yyscanner);
216   char after = input(yyscanner);
217   int retval = STRING;
218
219   unput(after); unput(colon);
220
221   if (after != '(' && after != ' ') {
222     BEGIN(sc_wds_sess);
223     if (yyextra->pseudo_header != NULL) {
224       g_strlcpy(yyextra->pseudo_header->user, atcopy, ASCEND_MAX_STR_LEN);
225     }
226   } else {      /* We have a version 7 file */
227     BEGIN(sc_gen_task);
228     if (yyextra->pseudo_header != NULL) {
229       g_strlcpy(yyextra->pseudo_header->user, NO_USER, ASCEND_MAX_STR_LEN);
230     }
231     /* Are valid values ever > 2^32? If so we need to adjust YYSTYPE and a lot of */
232     /* upstream code accordingly. */
233     yylval->d = (guint32) strtoul(yytext, NULL, 10);
234     retval = DECNUM;
235   }
236   g_free (atcopy);
237   return retval;
238 }
239
240 <sc_wds_sess>{D}* {
241   BEGIN(sc_gen_task);
242   yylval->d = (guint32) strtoul(yytext, NULL, 10);
243   return DECNUM;
244 }
245
246 <sc_gen_task>(0x|0X)?{H}{2,8} {
247   BEGIN(sc_gen_time_s);
248   yylval->d = (guint32) strtoul(yytext, NULL, 16);
249   return HEXNUM;
250 }
251
252 <sc_gen_task>\"[A-Za-z0-9_ ]+\" {
253   return STRING;
254 }
255
256 <sc_gen_time_s>{D}{1,10} {
257   BEGIN(sc_gen_time_u);
258   yylval->d = (guint32) strtoul(yytext, NULL, 10);
259   return DECNUM;
260 }
261
262 <sc_gen_time_u>{D}{1,6} {
263   char *atcopy = g_strdup(yytext);
264   BEGIN(sc_gen_octets);
265   /* only want the most significant 2 digits. convert to usecs */
266   if (strlen(atcopy) > 2)
267     atcopy[2] = '\0';
268   yylval->d = (guint32) strtoul(atcopy, NULL, 10) * 10000;
269   g_free(atcopy);
270   return DECNUM;
271 }
272
273 <sc_gen_octets>{D}{1,10} {
274   BEGIN(sc_gen_counter);
275   yylval->d = (guint32) strtoul(yytext, NULL, 10);
276   return DECNUM;
277 }
278
279 <sc_gen_counter,sc_gen_byte>"["{H}{4}"]:" {
280   BEGIN(sc_gen_byte);
281   return COUNTER;
282 }
283
284 <sc_gen_byte>{H}{2} {
285   yylval->b = (guint8)(guint32) strtoul(yytext, NULL, 16);
286   return HEXBYTE;
287 }
288
289 <sc_gen_byte>" "{4} {
290   BEGIN(sc_chardisp);
291 }
292
293 <sc_chardisp>.* {
294   BEGIN(sc_gen_byte);
295 }
296
297 <INITIAL,sc_gen_byte>{WDD_DATE} {
298   BEGIN(sc_wdd_date_d);
299   return WDD_DATE;
300 }
301
302 <sc_wdd_date_d>{D}{2} {
303   BEGIN(sc_wdd_date_m);
304   yylval->d = (guint32) strtoul(yytext, NULL, 10);
305   return DECNUM;
306 }
307
308 <sc_wdd_date_m>{D}{2} {
309   BEGIN(sc_wdd_date_y);
310   yylval->d = (guint32) strtoul(yytext, NULL, 10);
311   return DECNUM;
312 }
313
314 <sc_wdd_date_y>{D}{4} {
315   BEGIN(sc_wdd_time);
316   yylval->d = (guint32) strtoul(yytext, NULL, 10);
317   return DECNUM;
318 }
319
320 <sc_wdd_time>{WDD_TIME} {
321   BEGIN(sc_wdd_time_h);
322   return KEYWORD;
323 }
324
325 <sc_wdd_time_h>{D}{2} {
326   BEGIN(sc_wdd_time_m);
327   yylval->d = (guint32) strtoul(yytext, NULL, 10);
328   return DECNUM;
329 }
330
331 <sc_wdd_time_m>{D}{2} {
332   BEGIN(sc_wdd_time_s);
333   yylval->d = (guint32) strtoul(yytext, NULL, 10);
334   return DECNUM;
335 }
336
337 <sc_wdd_time_s>{D}{2} {
338   BEGIN(sc_wdd_cause);
339   yylval->d = (guint32) strtoul(yytext, NULL, 10);
340   return DECNUM;
341 }
342
343 <sc_wdd_cause>{WDD_CAUSE} {
344   BEGIN(sc_wdd_callnum);
345   return KEYWORD;
346 }
347
348 <sc_wdd_callnum>{WDD_CALLNUM} {
349   BEGIN(sc_wdd_chunk);
350   if (yyextra->pseudo_header != NULL) {
351     g_strlcpy(yyextra->pseudo_header->call_num, yytext, ASCEND_MAX_STR_LEN);
352   }
353   return STRING;
354 }
355
356 <INITIAL,sc_wdd_chunk,sc_gen_byte>{WDD_CHUNK} {
357   BEGIN(sc_wdd_chunknum);
358   return WDD_CHUNK;
359 }
360
361 <sc_wdd_chunknum>{H}{1,8} {
362   BEGIN(sc_wdd_type);
363   yylval->d = (guint32) strtoul(yytext, NULL, 16);
364   return HEXNUM;
365 }
366
367 <sc_wdd_type>{WDD_TYPE} {
368   BEGIN(sc_gen_task);
369   return KEYWORD;
370 }
371
372 <sc_gen_task>\/{D}+ {
373   return SLASH_SUFFIX;
374 }
375
376 (0x|0X)?{H}+ { return HEXNUM; }
377
378 task:|task|at|time:|octets { return KEYWORD; }
379
380 <<EOF>> { yyterminate(); }
381
382 (.|\n) ;