wireshark/wiretap/ascend_scanner.l
Guy Harris 6f37317539 Include config.h at the very beginning of all Flex scanners.
That way, if we #define anything for large file support, that's done
before we include any system header files that either depend on that
definition or that define it themselves if it's not already defined.

Change-Id: I9b07344151103be337899dead44d6960715d6813
Reviewed-on: https://code.wireshark.org/review/19035
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2016-12-02 21:02:10 +00:00

386 lines
8 KiB
Text

%top {
/* Include this before everything else, for various large-file definitions */
#include "config.h"
}
/*
* We want a reentrant scanner.
*/
%option reentrant
/*
* We want to generate code that can be used by a reentrant parser
* generated by Bison or Berkeley YACC.
*/
%option bison-bridge
/*
* We don't read interactively from the terminal.
*/
%option never-interactive
/*
* We want to stop processing when we get to the end of the input.
*/
%option noyywrap
/*
* The type for the state we keep for the scanner (and parser).
*/
%option extra-type="ascend_state_t *"
/*
* Prefix scanner routines with "ascend" rather than "yy", so this scanner
* can coexist with other scanners.
*/
%option prefix="ascend"
/*
* We have to override the memory allocators so that we don't get
* "unused argument" warnings from the yyscanner argument (which
* we don't use, as we have a global memory allocator).
*
* We provide, as macros, our own versions of the routines generated by Flex,
* which just call malloc()/realloc()/free() (as the Flex versions do),
* discarding the extra argument.
*/
%option noyyalloc
%option noyyrealloc
%option noyyfree
%{
/* ascend_scanner.l
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <stdlib.h>
#include <string.h>
#include "wtap-int.h"
#include "ascendtext.h"
#include "ascend-int.h"
#include "ascend.h"
#include "file_wrappers.h"
#define YY_INPUT(buf,result,max_size) { \
ascend_state_t *parser_state = ascendget_extra(yyscanner); \
int c = file_getc(parser_state->fh); \
if (c == EOF) { \
parser_state->err = file_error(parser_state->fh, \
&parser_state->err_info); \
if (parser_state->err == 0) \
parser_state->err = WTAP_ERR_SHORT_READ; \
result = YY_NULL; \
} else { \
buf[0] = c; \
result = 1; \
} \
}
#define NO_USER "<none>"
#ifndef HAVE_UNISTD_H
#define YY_NO_UNISTD_H
#endif
/*
* Sleazy hack to suppress compiler warnings in yy_fatal_error().
*/
#define YY_EXIT_FAILURE ((void)yyscanner, 2)
/*
* Macros for the allocators, to discard the extra argument.
*/
#define ascendalloc(size, yyscanner) (void *)malloc(size)
#define ascendrealloc(ptr, size, yyscanner) (void *)realloc((char *)(ptr), (size))
#define ascendfree(ptr, yyscanner) free((char *)ptr)
%}
D [0-9]
H [A-Fa-f0-9]
PPP_XPFX PPP-OUT
PPP_RPFX PPP-IN
ISDN_XPFX PRI-XMIT-
ISDN_RPFX PRI-RCV-
WAN_XPFX XMIT[\-:]*
WAN_RPFX RECV[\-:]*
ETHER_PFX ETHER
WDD_DATE "Date:"
WDD_TIME "Time:"
WDD_CAUSE "Cause an attempt to place call to "
WDD_CALLNUM [^\n\r\t ]+
WDD_CHUNK "WD_DIALOUT_DISP: chunk"
WDD_TYPE "type "[^\n\r\t ]+
%s sc_gen_task
%s sc_gen_time_s
%s sc_gen_time_u
%s sc_gen_octets
%s sc_gen_counter
%s sc_gen_byte
%s sc_wds_user
%s sc_wds_sess
%s sc_wdd_date_d
%s sc_wdd_date_m
%s sc_wdd_date_y
%s sc_wdd_time
%s sc_wdd_time_h
%s sc_wdd_time_m
%s sc_wdd_time_s
%s sc_wdd_cause
%s sc_wdd_callnum
%s sc_wdd_chunk
%s sc_wdd_chunknum
%s sc_wdd_type
%s sc_chardisp
%s sc_isdn_call
%s sc_ether_direction
%%
<INITIAL,sc_gen_byte>{ETHER_PFX} {
BEGIN(sc_ether_direction);
yylval->d = ASCEND_PFX_ETHER;
return ETHER_PREFIX;
}
<INITIAL,sc_gen_byte>{ISDN_XPFX} {
BEGIN(sc_isdn_call);
yylval->d = ASCEND_PFX_ISDN_X;
return ISDN_PREFIX;
}
<INITIAL,sc_gen_byte>{ISDN_RPFX} {
BEGIN(sc_isdn_call);
yylval->d = ASCEND_PFX_ISDN_R;
return ISDN_PREFIX;
}
<INITIAL,sc_gen_byte>{WAN_XPFX} {
BEGIN(sc_wds_user);
yylval->d = ASCEND_PFX_WDS_X;
return WDS_PREFIX;
}
<INITIAL,sc_gen_byte>{WAN_RPFX} {
BEGIN(sc_wds_user);
yylval->d = ASCEND_PFX_WDS_R;
return WDS_PREFIX;
}
<INITIAL,sc_gen_byte>{PPP_XPFX} {
BEGIN(sc_wds_user);
yylval->d = ASCEND_PFX_WDS_X;
return WDS_PREFIX;
}
<INITIAL,sc_gen_byte>{PPP_RPFX} {
BEGIN(sc_wds_user);
yylval->d = ASCEND_PFX_WDS_R;
return WDS_PREFIX;
}
<sc_ether_direction>[^\(]{2,20} {
BEGIN(sc_gen_task);
return STRING;
}
<sc_isdn_call>[^\/\(:]{2,20} {
BEGIN(sc_gen_task);
return DECNUM;
}
<sc_wds_user>[^:]{2,20} {
char *atcopy = g_strdup(yytext);
char colon = input(yyscanner);
char after = input(yyscanner);
int retval = STRING;
unput(after); unput(colon);
if (after != '(' && after != ' ') {
BEGIN(sc_wds_sess);
if (yyextra->pseudo_header != NULL) {
g_strlcpy(yyextra->pseudo_header->user, atcopy, ASCEND_MAX_STR_LEN);
}
} else { /* We have a version 7 file */
BEGIN(sc_gen_task);
if (yyextra->pseudo_header != NULL) {
g_strlcpy(yyextra->pseudo_header->user, NO_USER, ASCEND_MAX_STR_LEN);
}
/* Are valid values ever > 2^32? If so we need to adjust YYSTYPE and a lot of */
/* upstream code accordingly. */
yylval->d = (guint32) strtoul(yytext, NULL, 10);
retval = DECNUM;
}
g_free (atcopy);
return retval;
}
<sc_wds_sess>{D}* {
BEGIN(sc_gen_task);
yylval->d = (guint32) strtoul(yytext, NULL, 10);
return DECNUM;
}
<sc_gen_task>(0x|0X)?{H}{2,8} {
BEGIN(sc_gen_time_s);
yylval->d = (guint32) strtoul(yytext, NULL, 16);
return HEXNUM;
}
<sc_gen_task>\"[A-Za-z0-9_ ]+\" {
return STRING;
}
<sc_gen_time_s>{D}{1,10} {
BEGIN(sc_gen_time_u);
yylval->d = (guint32) strtoul(yytext, NULL, 10);
return DECNUM;
}
<sc_gen_time_u>{D}{1,6} {
char *atcopy = g_strdup(yytext);
BEGIN(sc_gen_octets);
/* only want the most significant 2 digits. convert to usecs */
if (strlen(atcopy) > 2)
atcopy[2] = '\0';
yylval->d = (guint32) strtoul(atcopy, NULL, 10) * 10000;
g_free(atcopy);
return DECNUM;
}
<sc_gen_octets>{D}{1,10} {
BEGIN(sc_gen_counter);
yylval->d = (guint32) strtoul(yytext, NULL, 10);
return DECNUM;
}
<sc_gen_counter,sc_gen_byte>"["{H}{4}"]:" {
BEGIN(sc_gen_byte);
return COUNTER;
}
<sc_gen_byte>{H}{2} {
yylval->b = (guint8)(guint32) strtoul(yytext, NULL, 16);
return HEXBYTE;
}
<sc_gen_byte>" "{4} {
BEGIN(sc_chardisp);
}
<sc_chardisp>.* {
BEGIN(sc_gen_byte);
}
<INITIAL,sc_gen_byte>{WDD_DATE} {
BEGIN(sc_wdd_date_d);
return WDD_DATE;
}
<sc_wdd_date_d>{D}{2} {
BEGIN(sc_wdd_date_m);
yylval->d = (guint32) strtoul(yytext, NULL, 10);
return DECNUM;
}
<sc_wdd_date_m>{D}{2} {
BEGIN(sc_wdd_date_y);
yylval->d = (guint32) strtoul(yytext, NULL, 10);
return DECNUM;
}
<sc_wdd_date_y>{D}{4} {
BEGIN(sc_wdd_time);
yylval->d = (guint32) strtoul(yytext, NULL, 10);
return DECNUM;
}
<sc_wdd_time>{WDD_TIME} {
BEGIN(sc_wdd_time_h);
return KEYWORD;
}
<sc_wdd_time_h>{D}{2} {
BEGIN(sc_wdd_time_m);
yylval->d = (guint32) strtoul(yytext, NULL, 10);
return DECNUM;
}
<sc_wdd_time_m>{D}{2} {
BEGIN(sc_wdd_time_s);
yylval->d = (guint32) strtoul(yytext, NULL, 10);
return DECNUM;
}
<sc_wdd_time_s>{D}{2} {
BEGIN(sc_wdd_cause);
yylval->d = (guint32) strtoul(yytext, NULL, 10);
return DECNUM;
}
<sc_wdd_cause>{WDD_CAUSE} {
BEGIN(sc_wdd_callnum);
return KEYWORD;
}
<sc_wdd_callnum>{WDD_CALLNUM} {
BEGIN(sc_wdd_chunk);
if (yyextra->pseudo_header != NULL) {
g_strlcpy(yyextra->pseudo_header->call_num, yytext, ASCEND_MAX_STR_LEN);
}
return STRING;
}
<INITIAL,sc_wdd_chunk,sc_gen_byte>{WDD_CHUNK} {
BEGIN(sc_wdd_chunknum);
return WDD_CHUNK;
}
<sc_wdd_chunknum>{H}{1,8} {
BEGIN(sc_wdd_type);
yylval->d = (guint32) strtoul(yytext, NULL, 16);
return HEXNUM;
}
<sc_wdd_type>{WDD_TYPE} {
BEGIN(sc_gen_task);
return KEYWORD;
}
<sc_gen_task>\/{D}+ {
return SLASH_SUFFIX;
}
(0x|0X)?{H}+ { return HEXNUM; }
task:|task|at|time:|octets { return KEYWORD; }
<<EOF>> { yyterminate(); }
(.|\n) ;