summaryrefslogtreecommitdiff
path: root/wiretap/k12text.l
diff options
context:
space:
mode:
Diffstat (limited to 'wiretap/k12text.l')
-rw-r--r--wiretap/k12text.l268
1 files changed, 176 insertions, 92 deletions
diff --git a/wiretap/k12text.l b/wiretap/k12text.l
index 3ff7ca8610..4cdea9c951 100644
--- a/wiretap/k12text.l
+++ b/wiretap/k12text.l
@@ -1,4 +1,9 @@
/*
+ * We want a reentrant scanner.
+ */
+%option reentrant
+
+/*
* We don't use input, so don't generate code for it.
*/
%option noinput
@@ -19,10 +24,15 @@
%option noyywrap
/*
- * Prefix scanner routines with "K12Text_" rather than "yy", so this scanner
+ * The type for the state we keep for a scanner.
+ */
+%option extra-type="k12text_state_t *"
+
+/*
+ * Prefix scanner routines with "k12text_" rather than "yy", so this scanner
* can coexist with other scanners.
*/
-%option prefix="K12Text_"
+%option prefix="k12text_"
%option outfile="k12text.c"
@@ -45,6 +55,19 @@
/* %option noline */
/* %option debug */
+/*
+ * 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
+
%{
/* k12text.l
*
@@ -82,41 +105,64 @@
#include "file_wrappers.h"
#include <wsutil/buffer.h>
#include "k12.h"
-#include "k12text_lex.h"
#ifndef HAVE_UNISTD_H
#define YY_NO_UNISTD_H
#endif
-static guint g_h;
-static guint g_m;
-static guint g_s;
-static guint g_ms;
-static guint g_ns;
-static gint g_encap;
-static guint8 bb[WTAP_MAX_PACKET_SIZE];
-static guint ii;
-static gboolean is_k12text;
-static gboolean at_eof;
-static guint junk_chars;
-static void finalize_frame(void);
-static gchar* error_str;
-static guint64 file_bytes_read;
-static gboolean ok_frame;
-static FILE_T yy_fh;
-
-#define KERROR(text) do { error_str = g_strdup(text); yyterminate(); } while(0)
-#define SET_HOURS(text) g_h = (guint) strtoul(text,NULL,10)
-#define SET_MINUTES(text) g_m = (guint) strtoul(text,NULL,10)
-#define SET_SECONDS(text) g_s = (guint) strtoul(text,NULL,10)
-#define SET_MS(text) g_ms = (guint) strtoul(text,NULL,10)
-#define SET_NS(text) g_ns = (guint) strtoul(text,NULL,10)
-#define ADD_BYTE(text) do {if (ii >= WTAP_MAX_PACKET_SIZE) {KERROR("frame too large");} bb[ii++] = (guint8)strtoul(text,NULL,16); } while(0)
-#define FINALIZE_FRAME() finalize_frame()
+/*
+ * State kept by the scanner.
+ */
+typedef struct {
+ FILE_T fh;
+ int *err;
+ gchar **err_info;
+ int start_state;
+
+ guint g_h;
+ guint g_m;
+ guint g_s;
+ guint g_ms;
+ guint g_ns;
+ gint g_encap;
+ guint8 bb[WTAP_MAX_PACKET_SIZE];
+ guint ii;
+ gboolean is_k12text;
+ gboolean at_eof;
+ guint junk_chars;
+ gchar* error_str;
+ guint64 file_bytes_read;
+ gboolean ok_frame;
+} k12text_state_t;
+
+#define KERROR(text) do { yyextra->error_str = g_strdup(text); yyterminate(); } while(0)
+#define SET_HOURS(text) yyextra->g_h = (guint) strtoul(text,NULL,10)
+#define SET_MINUTES(text) yyextra->g_m = (guint) strtoul(text,NULL,10)
+#define SET_SECONDS(text) yyextra->g_s = (guint) strtoul(text,NULL,10)
+#define SET_MS(text) yyextra->g_ms = (guint) strtoul(text,NULL,10)
+#define SET_NS(text) yyextra->g_ns = (guint) strtoul(text,NULL,10)
+#define ADD_BYTE(text) do {if (yyextra->ii >= WTAP_MAX_PACKET_SIZE) {KERROR("frame too large");} yyextra->bb[yyextra->ii++] = (guint8)strtoul(text,NULL,16); } while(0)
+#define FINALIZE_FRAME() do { yyextra->ok_frame = TRUE; } while (0)
/*~ #define ECHO*/
-#define YY_USER_ACTION file_bytes_read += yyleng;
-#define YY_INPUT(buf,result,max_size) { int c = file_getc(yy_fh); result = (c==EOF) ? YY_NULL : (buf[0] = c, 1); }
-
+#define YY_USER_ACTION yyextra->file_bytes_read += yyleng;
+#define YY_USER_INIT { \
+ k12text_state_t *scanner_state = k12text_get_extra(yyscanner); \
+ BEGIN(scanner_state->start_state); \
+}
+#define YY_INPUT(buf,result,max_size) { \
+ k12text_state_t *scanner_state = k12text_get_extra(yyscanner); \
+ int c = file_getc(scanner_state->fh); \
+ if (c == EOF) { \
+ *(scanner_state->err) = file_error(scanner_state->fh, \
+ scanner_state->err_info); \
+ if (*(scanner_state->err) == 0) \
+ *(scanner_state->err) = WTAP_ERR_SHORT_READ; \
+ result = YY_NULL; \
+ } else { \
+ buf[0] = c; \
+ result = 1; \
+ } \
+}
#define MAX_JUNK 400000
#define ECHO
@@ -134,6 +180,19 @@ typedef struct {
*/
gint64 next_frame_offset;
} k12text_t;
+
+/*
+ * 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 k12text_alloc(size, yyscanner) (void *)malloc(size)
+#define k12text_realloc(ptr, size, yyscanner) (void *)realloc((char *)(ptr), (size))
+#define k12text_free(ptr, yyscanner) free((char *)ptr)
+
%}
start_timestamp \053[\055]{9}\053[\055]{15,100}\053[\055]{10,100}\053
oneormoredigits [0-9]+:
@@ -153,9 +212,9 @@ hdlc HDLC
%START MAGIC NEXT_FRAME HOURS MINUTES M2S SECONDS S2M MS M2N NS ENCAP STARTBYTES BYTE
%%
-<MAGIC>{start_timestamp} { is_k12text = TRUE; yyterminate(); }
+<MAGIC>{start_timestamp} { yyextra->is_k12text = TRUE; yyterminate(); }
-<MAGIC>. { if (++ junk_chars > MAX_JUNK) { is_k12text = FALSE; yyterminate(); } }
+<MAGIC>. { if (++ yyextra->junk_chars > MAX_JUNK) { yyextra->is_k12text = FALSE; yyterminate(); } }
<NEXT_FRAME>{start_timestamp} {BEGIN(HOURS); }
<HOURS>{oneormoredigits} { SET_HOURS(yytext); BEGIN(MINUTES); }
@@ -166,42 +225,39 @@ hdlc HDLC
<MS>{threedigits} { SET_MS(yytext); BEGIN(M2N); }
<M2N>{comma} { BEGIN(NS); }
<NS>{threedigits} { SET_NS(yytext); BEGIN(ENCAP);}
-<ENCAP>{eth} {g_encap = WTAP_ENCAP_ETHERNET; BEGIN(STARTBYTES); }
-<ENCAP>{mtp2} {g_encap = WTAP_ENCAP_MTP2; BEGIN(STARTBYTES); }
-<ENCAP>{sscop} {g_encap = WTAP_ENCAP_ATM_PDUS; BEGIN(STARTBYTES); }
-<ENCAP>{sscfnni} {g_encap = WTAP_ENCAP_MTP3; BEGIN(STARTBYTES); }
-<ENCAP>{hdlc} {g_encap = WTAP_ENCAP_CHDLC; BEGIN(STARTBYTES); }
+<ENCAP>{eth} {yyextra->g_encap = WTAP_ENCAP_ETHERNET; BEGIN(STARTBYTES); }
+<ENCAP>{mtp2} {yyextra->g_encap = WTAP_ENCAP_MTP2; BEGIN(STARTBYTES); }
+<ENCAP>{sscop} {yyextra->g_encap = WTAP_ENCAP_ATM_PDUS; BEGIN(STARTBYTES); }
+<ENCAP>{sscfnni} {yyextra->g_encap = WTAP_ENCAP_MTP3; BEGIN(STARTBYTES); }
+<ENCAP>{hdlc} {yyextra->g_encap = WTAP_ENCAP_CHDLC; BEGIN(STARTBYTES); }
<ENCAP,STARTBYTES>{start_bytes} { BEGIN(BYTE); }
<BYTE>{byte} { ADD_BYTE(yytext); }
<BYTE>{bytes_junk} ;
<BYTE>{end_bytes} { FINALIZE_FRAME(); yyterminate(); }
-. { if (++junk_chars > MAX_JUNK) { KERROR("too much junk"); } }
-<<EOF>> { at_eof = TRUE; yyterminate(); }
+. { if (++yyextra->junk_chars > MAX_JUNK) { KERROR("too much junk"); } }
+<<EOF>> { yyextra->at_eof = TRUE; yyterminate(); }
%%
-static void finalize_frame(void) {
- ok_frame = TRUE;
-}
-
/* Fill in pkthdr */
static gboolean
-k12text_set_headers(struct wtap_pkthdr *phdr, int *err, gchar **err_info)
+k12text_set_headers(struct wtap_pkthdr *phdr, k12text_state_t *state,
+ int *err, gchar **err_info)
{
phdr->rec_type = REC_TYPE_PACKET;
phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
- phdr->ts.secs = 946681200 + (3600*g_h) + (60*g_m) + g_s;
- phdr->ts.nsecs = 1000000*g_ms + 1000*g_ns;
+ phdr->ts.secs = 946681200 + (3600*state->g_h) + (60*state->g_m) + state->g_s;
+ phdr->ts.nsecs = 1000000*state->g_ms + 1000*state->g_ns;
- phdr->caplen = phdr->len = ii;
+ phdr->caplen = phdr->len = state->ii;
- phdr->pkt_encap = g_encap;
+ phdr->pkt_encap = state->g_encap;
/* The file-encap is WTAP_ENCAP_PER_PACKET */
- switch(g_encap) {
+ switch(state->g_encap) {
case WTAP_ENCAP_ETHERNET:
phdr->pseudo_header.eth.fcs_len = 0;
break;
@@ -236,30 +292,54 @@ k12text_set_headers(struct wtap_pkthdr *phdr, int *err, gchar **err_info)
/* used even when multiple files are open simultaneously (as for */
/* a file merge). */
-static void
-k12text_reset(FILE_T fh)
+static gboolean
+k12text_run_scanner(k12text_state_t *state, FILE_T fh, int start_state,
+ int *err, gchar **err_info)
{
- yy_fh = fh;
- yyrestart(0);
- g_encap = WTAP_ENCAP_UNKNOWN;
- ok_frame = FALSE;
- is_k12text = FALSE;
- at_eof = FALSE;
- junk_chars = 0;
- error_str = NULL;
- file_bytes_read=0;
- g_h=0;
- g_m=0;
- g_s=0;
- g_ns=0;
- g_ms=0;
- ii=0;
+ yyscan_t scanner = NULL;
+
+ if (yylex_init(&scanner) != 0) {
+ /* errno is set if this fails */
+ *err = errno;
+ *err_info = NULL;
+ return FALSE;
+ }
+ state->fh = fh;
+ state->err = err;
+ state->err_info = err_info;
+ state->start_state = start_state;
+
+ state->g_encap = WTAP_ENCAP_UNKNOWN;
+ state->ok_frame = FALSE;
+ state->is_k12text = FALSE;
+ state->at_eof = FALSE;
+ state->junk_chars = 0;
+ state->error_str = NULL;
+ state->file_bytes_read=0;
+ state->g_h=0;
+ state->g_m=0;
+ state->g_s=0;
+ state->g_ns=0;
+ state->g_ms=0;
+ state->ii=0;
+
+ /* Associate the state with the scanner */
+ k12text_set_extra(state, scanner);
+
+ yylex(scanner);
+ yylex_destroy(scanner);
+ if (*err != 0 && *err != WTAP_ERR_SHORT_READ) {
+ /* I/O error. */
+ return FALSE;
+ }
+ return TRUE;
}
static gboolean
k12text_read(wtap *wth, int *err, char ** err_info, gint64 *data_offset)
{
k12text_t *k12text = (k12text_t *)wth->priv;
+ k12text_state_t state;
/*
* We seek to the file position after the end of the previous frame
@@ -273,30 +353,29 @@ k12text_read(wtap *wth, int *err, char ** err_info, gint64 *data_offset)
if ( file_seek(wth->fh, k12text->next_frame_offset, SEEK_SET, err) == -1) {
return FALSE;
}
- k12text_reset(wth->fh); /* init lexer buffer and vars set by lexer */
-
- BEGIN(NEXT_FRAME);
- yylex();
+ if (!k12text_run_scanner(&state, wth->fh, NEXT_FRAME, err, err_info)) {
+ return FALSE;
+ }
- if (ok_frame == FALSE) {
- if (at_eof) {
+ if (state.ok_frame == FALSE) {
+ if (state.at_eof) {
*err = 0;
*err_info = NULL;
} else {
*err = WTAP_ERR_BAD_FILE;
- *err_info = error_str;
+ *err_info = state.error_str;
}
return FALSE;
}
- *data_offset = k12text->next_frame_offset; /* file position for beginning of this frame */
- k12text->next_frame_offset += file_bytes_read; /* file position after end of this frame */
+ *data_offset = k12text->next_frame_offset; /* file position for beginning of this frame */
+ k12text->next_frame_offset += state.file_bytes_read; /* file position after end of this frame */
- if (!k12text_set_headers(&wth->phdr, err, err_info))
+ if (!k12text_set_headers(&wth->phdr, &state, err, err_info))
return FALSE;
ws_buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);
- memcpy(ws_buffer_start_ptr(wth->frame_buffer), bb, wth->phdr.caplen);
+ memcpy(ws_buffer_start_ptr(wth->frame_buffer), state.bb, wth->phdr.caplen);
return TRUE;
}
@@ -304,30 +383,31 @@ k12text_read(wtap *wth, int *err, char ** err_info, gint64 *data_offset)
static gboolean
k12text_seek_read(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr, Buffer *buf, int *err, char **err_info)
{
+ k12text_state_t state;
+
if ( file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) {
return FALSE;
}
- k12text_reset(wth->random_fh); /* init lexer buffer and vars set by lexer */
-
- BEGIN(NEXT_FRAME);
- yylex();
+ if (!k12text_run_scanner(&state, wth->random_fh, NEXT_FRAME, err, err_info)) {
+ return FALSE;
+ }
- if (ok_frame == FALSE) {
+ if (state.ok_frame == FALSE) {
*err = WTAP_ERR_BAD_FILE;
- if (at_eof) {
+ if (state.at_eof) {
/* What happened ? The desired frame was previously read without a problem */
*err_info = g_strdup("Unexpected EOF (program error ?)");
} else {
- *err_info = error_str;
+ *err_info = state.error_str;
}
return FALSE;
}
- if (!k12text_set_headers(phdr, err, err_info))
+ if (!k12text_set_headers(phdr, &state, err, err_info))
return FALSE;
ws_buffer_assure_space(buf, phdr->caplen);
- memcpy(ws_buffer_start_ptr(buf), bb, phdr->caplen);
+ memcpy(ws_buffer_start_ptr(buf), state.bb, phdr->caplen);
return TRUE;
}
@@ -336,13 +416,17 @@ wtap_open_return_val
k12text_open(wtap *wth, int *err, gchar **err_info _U_)
{
k12text_t *k12text;
+ k12text_state_t state;
- k12text_reset(wth->fh); /* init lexer buffer and vars set by lexer */
-
- BEGIN(MAGIC);
- yylex();
+ if (!k12text_run_scanner(&state, wth->fh, MAGIC, err, err_info)) {
+ return WTAP_OPEN_ERROR;
+ }
- if (! is_k12text) return WTAP_OPEN_NOT_MINE;
+ if (!state.is_k12text) {
+ /* *err might have been set to WTAP_ERR_SHORT_READ */
+ *err = 0;
+ return WTAP_OPEN_NOT_MINE;
+ }
if ( file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
return WTAP_OPEN_ERROR;