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