2 * We don't use input, so don't generate code for it.
7 * We don't use unput, so don't generate code for it.
12 * We don't read from the terminal.
14 %option never-interactive
17 * Prefix scanner routines with "uat_load_" rather than "yy", so this scanner
18 * can coexist with other scanners.
20 %option prefix="uat_load_"
28 * User Accessible Tables
29 * Mantain an array of user accessible data strucures
30 * One parser to fit them all
32 * (c) 2007, Luis E. Garcia Ontanon <luis@ontanon.org>
34 * Wireshark - Network traffic analyzer
35 * By Gerald Combs <gerald@wireshark.org>
36 * Copyright 2001 Gerald Combs
38 * This program is free software; you can redistribute it and/or
39 * modify it under the terms of the GNU General Public License
40 * as published by the Free Software Foundation; either version 2
41 * of the License, or (at your option) any later version.
43 * This program is distributed in the hope that it will be useful,
44 * but WITHOUT ANY WARRANTY; without even the implied warranty of
45 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46 * GNU General Public License for more details.
48 * You should have received a copy of the GNU General Public License
49 * along with this program; if not, write to the Free Software
50 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
62 #include <epan/emem.h>
64 #include "uat_load_lex.h"
65 #include <wsutil/file_util.h>
68 /* disable Windows VC compiler warning "signed/unsigned mismatch" associated */
69 /* with YY_INPUT code generated by flex versions such as 2.5.35. */
70 #pragma warning (disable:4018)
74 static gboolean valid_record;
81 static gchar *parse_str;
82 static guint parse_str_pos;
84 #define ERROR(fmtd) do { \
85 error = ep_strdup_printf("%s:%d: %s",uat->filename,linenum,ep_strdup_printf fmtd); \
90 { const gchar* errx; \
91 if (uat->fields[colnum].cb.chk) { \
92 if ( ! uat->fields[colnum].cb.chk(record, ptrx, len, uat->fields[colnum].cbdata.chk, uat->fields[colnum].fld_data, &errx) ) { \
93 error = ep_strdup_printf("%s:%d: %s",uat->filename,linenum,ep_strdup_printf("%s",errx)); \
94 valid_record = FALSE; \
97 uat->fields[colnum].cb.set(record, ptrx, len, uat->fields[colnum].cbdata.chk, uat->fields[colnum].fld_data);\
102 #ifdef DEBUG_UAT_LOAD
103 #define DUMP_FIELD(str) \
104 { guint i; printf("%s: %s='",str,uat->fields[colnum].name); for(i=0;i<len;i++) if (uat->fields[colnum].mode == PT_TXTMOD_HEXBYTES) { printf("%.2x ",((guint8*)ptrx)[i]); } else putc(ptrx[i],stdout); printf("'[%d]\n",len); }
106 #define DUMP(str) printf("%s\n",str)
108 #define DUMP_FIELD(s)
112 /* Modified version of YY_INPUT generated by Flex 2.91 */
113 #define YY_INPUT(buf,result,max_size) \
117 guint pslen = strlen(parse_str); \
118 if (parse_str_pos < pslen) \
120 n = pslen - parse_str_pos; \
121 if (n > max_size) n = max_size; \
122 memcpy(buf, parse_str + parse_str_pos, n); \
123 parse_str_pos += n; \
130 while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
132 if( errno != EINTR) \
134 YY_FATAL_ERROR( "input in flex scanner failed" ); \
144 * quoted_string below fails badly on "...\\"
145 * workarround in uat_save(), using /x5c and /x22
149 quoted_string \042([^\042]|\134\042)*\042
150 binstring ([0-9a-zA-Z][0-9a-zA-Z])*
152 newline [ \t]*[\r]?\n
156 %x START_OF_LINE NEXT_FIELD SEPARATOR END_OF_RECORD ERRORED
158 <START_OF_LINE,NEXT_FIELD>{ws} ;
159 <START_OF_LINE>{newline} linenum++;
160 <START_OF_LINE>{comment} linenum++;
162 <START_OF_LINE,NEXT_FIELD>{separator} {
166 DUMP_FIELD("empty->next");
170 if ( colnum >= uat->ncols ) {
171 ERROR(("more fields than required"));
177 <START_OF_LINE,NEXT_FIELD>{newline} {
186 <START_OF_LINE,NEXT_FIELD>{quoted_string} {
187 ptrx = uat_undquote(yytext,yyleng,&len);
190 if (colnum < uat->ncols - 1) {
191 DUMP("quoted_str->s");
194 DUMP("quoted_str->eor");
199 <START_OF_LINE,NEXT_FIELD>{binstring} {
200 ptrx = uat_unbinstring(yytext,yyleng,&len);
203 ERROR(("uneven hexstring for field %s",uat->fields[colnum].name));
206 if ( colnum < uat->ncols - 1 ) {
207 DUMP("binstring->s");
210 DUMP("binstring->eor");
215 <SEPARATOR>{separator} {
217 DUMP_FIELD("separator->next");
221 if ( colnum >= uat->ncols ) {
222 ERROR(("more fields than required"));
228 <SEPARATOR>{newline} {
230 ERROR(("expecting field %s in previous line",uat->fields[colnum].name));
234 ERROR(("unexpected char '%s' while looking for field %s",yytext,uat->fields[colnum].name));
237 <END_OF_RECORD>{separator} {
238 ERROR(("more fields than required"));
241 <END_OF_RECORD>{newline} {
243 const char* err = NULL;
247 DUMP_FIELD("newline->start");
251 rec = uat_add_record(uat, record, valid_record);
253 if ((uat->update_cb) && (rec != NULL))
254 uat->update_cb(rec,&err);
257 char *tmp = ep_strdup(err);
258 /* XXX bit of a hack to remove emem from dissectors, this can
259 * be removed as proper use of glib memory is propogated
260 * through the rest of the UAT code */
270 /* XXX is this necessary since we free it before reusing anyway? */
271 memset(record,0,uat->record_size);
277 ERROR(("unexpected char while looking for end of line"));
280 <ERRORED>{newline} { linenum++; BEGIN START_OF_LINE; }
283 {newline} { linenum++; ERROR(("incomplete record")); BEGIN START_OF_LINE; }
284 . { ERROR(("unexpected input")); }
292 uat_load(uat_t *uat_in, const char **errx)
294 gchar *fname = uat_get_actual_filename(uat_in, FALSE);
302 if (uat->post_update_cb)
303 uat->post_update_cb();
309 if (!(yyin = ws_fopen(fname,"r"))) {
310 *errx = g_strerror(errno);
319 record = g_malloc0(uat->record_size);
324 g_free(fname); /* we're done with the file name now */
330 uat->changed = FALSE;
335 *errx = ep_strdup(error);
339 if (uat->post_update_cb)
340 uat->post_update_cb();
347 uat_load_str(uat_t *uat_in, char *entry, char **err)
350 parse_str = g_strdup_printf("%s\n", entry); /* Records must end with a newline */
358 record = g_malloc0(uat->record_size);
374 *err = ep_strdup(error);
378 if (uat->post_update_cb)
379 uat->post_update_cb();
386 * We want to stop processing when we get to the end of the input.
387 * (%option noyywrap is not used because if used then
388 * some flex versions (eg: 2.5.35) generate code which causes
389 * warnings by the Windows VC compiler).