%top { /* Include this before everything else, for various large-file definitions */ #include "config.h" } /* * We want a reentrant scanner. */ %option reentrant /* * We don't use input, so don't generate code for it. */ %option noinput /* * We don't use unput, so don't generate code for it. */ %option nounput /* * 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 a scanner. */ %option extra-type="WimaxasncpDict_scanner_state_t *" /* * 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 /* * The language we're scanning is case-insensitive. */ %option caseless /* * We use start condition stacks. */ %option stack /* * Prefix scanner routines with "WimaxasncpDict_" rather than "yy", so this * scanner can coexist with other scanners. */ %option prefix="WimaxasncpDict_" %option outfile="wimaxasncp_dict.c" %{ /* ** wimaxasncp_dict.h ** WIMAXASNCP Dictionary Import Routines ** ** (c) 2007, Luis E. Garcia Ontanon ** (c) 2007, Stephen Croll ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library 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 ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the Free Software ** Foundation, Inc., 51 Franklin Street, Fifth Floor, ** Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include /* array_length */ #include #include "wimaxasncp_dict.h" typedef struct entity_t { gchar *name; gchar *file; struct entity_t *next; } entity_t; #define ATTR_UINT(cont) do { D(("attr_uint " #cont "\t" )); yyextra->attr_uint = &(cont); yy_push_state(GET_UINT_ATTR, yyscanner); } while(0) #define ATTR_UINT16(cont) do { D(("attr_uint16 " #cont "\t" )); yyextra->attr_uint16 = &(cont); yy_push_state(GET_UINT16_ATTR, yyscanner); } while(0) #define ATTR_STR(cont) do { D(("attr_str " #cont "\t" )); yyextra->attr_str = &(cont); yy_push_state(GET_ATTR, yyscanner); } while(0) #define ATTR_DECODER(cont) do { D(("attr_decoder " #cont "\t" )); yyextra->attr_uint = &(cont); yy_push_state(GET_DECODER_ATTR, yyscanner); } while(0) #define WIMAXASNCP_IGNORE() do { D(("ignore: %s\t",yytext)); yy_push_state(IGNORE_ATTR, yyscanner); } while(0) #define D(args) wimaxasncp_dict_debug args #define MAX_INCLUDE_DEPTH 10 #define YY_INPUT(buf,result,max_size) { result = yyextra->current_yyinput(buf,max_size,yyscanner); } #define YY_USER_INIT { \ WimaxasncpDict_scanner_state_t *scanner_state = WimaxasncpDict_get_extra(yyscanner); \ BEGIN(scanner_state->start_state); \ } #define ECHO #define APPEND(txt,len) append_to_buffer(txt,(int)len,yyextra) typedef struct { GString *dict_error; const gchar *sys_dir; gchar *strbuf; guint size_strbuf; guint len_strbuf; gchar *write_ptr; gchar *read_ptr; wimaxasncp_dict_t *dict; wimaxasncp_dict_tlv_t *tlv; wimaxasncp_dict_enum_t *enumitem; wimaxasncp_dict_xmlpi_t *xmlpi; wimaxasncp_dict_tlv_t *last_tlv; wimaxasncp_dict_enum_t *last_enumitem; wimaxasncp_dict_xmlpi_t *last_xmlpi; entity_t *ents; YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; int include_stack_ptr; size_t (*current_yyinput)(gchar*,size_t,yyscan_t); gchar **attr_str; guint *attr_uint; gint16 *attr_uint16; int start_state; } WimaxasncpDict_scanner_state_t; static guint wimaxasncp_bits(guint bits, char *n); static gint wimaxasncp_decode_type(const gchar *name); static void wimaxasncp_dict_debug(const gchar *fmt, ...) G_GNUC_PRINTF(1, 2); static void append_to_buffer(const gchar *txt, int len, WimaxasncpDict_scanner_state_t *state); static FILE *wimaxasncp_dict_open(const gchar*, const gchar*); /* * 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 WimaxasncpDict_alloc(size, yyscanner) (void *)malloc(size) #define WimaxasncpDict_realloc(ptr, size, yyscanner) (void *)realloc((char *)(ptr), (size)) #define WimaxasncpDict_free(ptr, yyscanner) free((char *)ptr) %} xmlpi_start [[:blank:] \r\n]*<\?[[:blank:] \r\n]* xmlpi_end [[:blank:] \r\n]*\?>[[:blank:] \r\n]* xmlpi_key_attr [[:blank:] \r\n]*key[[:blank:] \r\n]*=[[:blank:] \r\n]*\042 xmlpi_value_attr [[:blank:] \r\n]*value[[:blank:] \r\n]*=[[:blank:] \r\n]*\042 comment_start [[:blank:] \r\n]*[[:blank:] \r\n]* open_tag [[:blank:] \r\n]*<[[:blank:] \r\n]* end_tag [[:blank:] \r\n]*\/>[[:blank:] \r\n]* close_tag [[:blank:] \r\n]*>[[:blank:] \r\n]* open_closetag [[:blank:] \r\n]*<\/[[:blank:] \r\n]* equals [[:blank:] \r\n]*=[[:blank:] \r\n]* whitespace [[:blank:] \r\n]* dquoted \042[^\042]*\042 doctype [[:blank:] \r\n]*[[:blank:] \r\n]* start_entity [[:blank:] \r\n]*<\!ENTITY[[:blank:] \r\n]* system [[:blank:] \r\n]*SYSTEM[[:blank:] \r\n]*\042 entityname [a-z0-9-]+ ndquot [^\042]+ end_entity \042[[:blank:] \r\n]*>[[:blank:] \r\n]* entity \&[a-z0-9-]+; any . stop > stop_end \/> dquot \042 number [-]?[0-9]*|(0x)?[0-9a-fA-F]* dictionary_start dictionary_end <\/dictionary> tlv_start type_start {doctype} ; {doctype_end} ; {comment_start} BEGIN LOADING_COMMENT; . ; {comment_end} BEGIN LOADING; {xmlpi_start} BEGIN LOADING_XMLPI; {whitespace} ; {entityname} { yyextra->xmlpi = g_new(wimaxasncp_dict_xmlpi_t,1); yyextra->xmlpi->name = g_strdup(yytext); yyextra->xmlpi->key = NULL; yyextra->xmlpi->value = NULL; yyextra->xmlpi->next = NULL; if (!yyextra->dict->xmlpis) yyextra->last_xmlpi = yyextra->dict->xmlpis = yyextra->xmlpi; else yyextra->last_xmlpi = yyextra->last_xmlpi->next = yyextra->xmlpi; BEGIN XMLPI_ATTRS; } {xmlpi_key_attr} BEGIN XMLPI_GETKEY; {ndquot} { yyextra->xmlpi->key = g_strdup(yytext); BEGIN XMLPI_ATTRS; } {xmlpi_value_attr} BEGIN XMLPI_GETVAL; {ndquot} { yyextra->xmlpi->value = g_strdup(yytext); BEGIN XMLPI_ATTRS; } . {xmlpi_end} BEGIN LOADING; {start_entity} BEGIN ENTITY; {entityname} { entity_t *e = g_new(entity_t,1); D(("ENTITY: %s\n",yytext)); e->name = g_strdup(yytext); e->next = yyextra->ents; yyextra->ents = e; BEGIN GET_SYSTEM; }; {system} BEGIN GET_FILE; {ndquot} { D(("GET_FILE: %s\n",yytext)); yyextra->ents->file = g_strdup(yytext); BEGIN END_ENTITY; } {end_entity} BEGIN LOADING; {open_tag} APPEND("<",1); {close_tag} APPEND(">",1); {end_tag} APPEND("/>",2); {open_closetag} APPEND("{whitespace} APPEND(" ",1); {dquoted} APPEND(yytext,yyleng); {equals} APPEND("=",1); {any} APPEND(yytext,yyleng); {entity} { gchar *p = ++yytext, *temp_str; entity_t* e; while(*p != ';') p++; *p = '\0'; D(("looking for entity: %s\n",yytext)); if ( yyextra->include_stack_ptr >= MAX_INCLUDE_DEPTH ) { yyextra->dict_error = g_string_append( yyextra->dict_error, "included files nested too deeply\n"); yyterminate(); } yyextra->include_stack[yyextra->include_stack_ptr++] = YY_CURRENT_BUFFER; for (e = yyextra->ents; e; e = e->next) { if (strcmp(e->name,yytext) == 0) { yyin = wimaxasncp_dict_open(yyextra->sys_dir,e->file); D(("entity: %s filename: %s yyin: %p\n",e->name,e->file,(void*)yyin)); if (!yyin) { yyterminate(); } else { WimaxasncpDict__switch_to_buffer(WimaxasncpDict__create_buffer(yyin, YY_BUF_SIZE, yyscanner), yyscanner); } break; } } if (!e) { temp_str = g_strdup_printf( "cannot find entity: '%s'\n", yytext); yyextra->dict_error = g_string_append(yyextra->dict_error, temp_str); g_free(temp_str); yyterminate(); } } <> { if (!yyin) yyterminate(); fclose(yyin); D(("closing: %p %i\n",(void*)yyin,yyextra->include_stack_ptr)); if ( --yyextra->include_stack_ptr < 0 ) { D(("DONE READING\n")); yyin = NULL; yyterminate(); } else { WimaxasncpDict__delete_buffer(YY_CURRENT_BUFFER, yyscanner); WimaxasncpDict__switch_to_buffer(yyextra->include_stack[yyextra->include_stack_ptr], yyscanner); BEGIN LOADING; } } {ndquot} { *yyextra->attr_str = g_strdup(yytext); D(("%s\n",yytext)); yyextra->attr_str = NULL; BEGIN END_ATTR; } {number} { *yyextra->attr_uint = (guint)strtoul(yytext,NULL,0); D(("%s\n",yytext);); yyextra->attr_uint = NULL; BEGIN END_ATTR; } {number} { *yyextra->attr_uint16 = (gint16) strtol(yytext,NULL,0); D(("%s\n",yytext);); yyextra->attr_uint16 = NULL; BEGIN END_ATTR; } "WIMAXASNCP_BIT32"[ \t]*"(" { BEGIN BIT32; } [0-9]+ { *yyextra->attr_uint = wimaxasncp_bits(32, yytext); D(("WIMAXASNCP_BIT32(%s)\n",yytext);); yyextra->attr_uint = NULL; } "WIMAXASNCP_BIT16"[ \t]*"(" { BEGIN BIT16; } [0-9]+ { *yyextra->attr_uint = wimaxasncp_bits(16, yytext); D(("WIMAXASNCP_BIT16(%s)\n",yytext);); yyextra->attr_uint = NULL; } "WIMAXASNCP_BIT8"[ \t]*"(" { BEGIN BIT8; } [0-9]+ { *yyextra->attr_uint = wimaxasncp_bits(8, yytext); D(("WIMAXASNCP_BIT8(%s)\n",yytext);); yyextra->attr_uint = NULL; } [ \t]*")" { BEGIN END_ATTR; } {ndquot} { *yyextra->attr_uint = wimaxasncp_decode_type(yytext); D(("%s\n",yytext)); yyextra->attr_uint = NULL; BEGIN END_ATTR; } {dquot} { yy_pop_state(yyscanner); } . { /* XXX: should go?*/ D(("{%s}",yytext)); } {ignored_quoted} { D(("=>%s<=\n",yytext)); yy_pop_state(yyscanner); } {dictionary_start} { D(("dictionary_start\n")); BEGIN IN_DICT; } {tlv_start} { D(("tlv_start\n")); yyextra->tlv = g_new(wimaxasncp_dict_tlv_t,1); yyextra->tlv->type = 0; yyextra->tlv->name = NULL; yyextra->tlv->description = NULL; yyextra->tlv->decoder = 0; yyextra->tlv->since = 0; yyextra->tlv->hf_root = -1; yyextra->tlv->hf_value = -1; yyextra->tlv->hf_ipv4 = -1; yyextra->tlv->hf_ipv6 = -1; yyextra->tlv->hf_bsid = -1; yyextra->tlv->hf_protocol = -1; yyextra->tlv->hf_port_low = -1; yyextra->tlv->hf_port_high = -1; yyextra->tlv->hf_ipv4_mask = -1; yyextra->tlv->hf_ipv6_mask = -1; yyextra->tlv->hf_vendor_id = -1; yyextra->tlv->hf_vendor_rest_of_info = -1; yyextra->tlv->enum_vs = NULL; yyextra->tlv->enums = NULL; yyextra->tlv->next = NULL; if (! yyextra->dict->tlvs ) yyextra->last_tlv = yyextra->dict->tlvs = yyextra->tlv; else yyextra->last_tlv = yyextra->last_tlv->next = yyextra->tlv; BEGIN TLV_ATTRS; } {name_attr} { ATTR_STR(yyextra->tlv->name); } {description_attr} { ATTR_STR(yyextra->tlv->description); } {type_attr} { ATTR_UINT16(yyextra->tlv->type); } {decoder_attr} { ATTR_DECODER(yyextra->tlv->decoder); } {since_attr} { ATTR_UINT(yyextra->tlv->since); } {stop} { BEGIN IN_TLV; } {stop_end} { BEGIN IN_DICT; } {enum_start} { D(("enum_start\n")); yyextra->enumitem = g_new(wimaxasncp_dict_enum_t,1); yyextra->enumitem->name = NULL; yyextra->enumitem->code = 0; yyextra->enumitem->next = NULL; if (!yyextra->tlv->enums) yyextra->last_enumitem = yyextra->tlv->enums = yyextra->enumitem; else yyextra->last_enumitem = yyextra->last_enumitem->next = yyextra->enumitem; BEGIN ENUM_ATTRS; } {name_attr} { ATTR_STR(yyextra->enumitem->name); } {code_attr} { ATTR_UINT(yyextra->enumitem->code); } {stop} { BEGIN IN_TLV; } {stop_end} { BEGIN IN_TLV; } {tlv_end} { D(("tlv_end")); BEGIN IN_DICT; } {dictionary_end} { yyterminate(); } {ignored_attr} WIMAXASNCP_IGNORE(); . ; %% static int debugging = 0; static void wimaxasncp_dict_debug(const gchar *fmt, ...) { va_list ap; va_start(ap, fmt); if (debugging) vfprintf(stderr, fmt, ap); va_end(ap); fflush(stderr); } static guint wimaxasncp_bits(guint bits, char *n) { return 1u << ((bits - 1) - (strtoul(n, NULL, 10))); } static const value_string wimaxasncp_decode_type_vals[] = { { WIMAXASNCP_TLV_TBD, "WIMAXASNCP_TLV_TBD"}, { WIMAXASNCP_TLV_COMPOUND, "WIMAXASNCP_TLV_COMPOUND"}, { WIMAXASNCP_TLV_BYTES, "WIMAXASNCP_TLV_BYTES"}, { WIMAXASNCP_TLV_ENUM8, "WIMAXASNCP_TLV_ENUM8"}, { WIMAXASNCP_TLV_ENUM16, "WIMAXASNCP_TLV_ENUM16"}, { WIMAXASNCP_TLV_ENUM32, "WIMAXASNCP_TLV_ENUM32"}, { WIMAXASNCP_TLV_ETHER, "WIMAXASNCP_TLV_ETHER"}, { WIMAXASNCP_TLV_ASCII_STRING, "WIMAXASNCP_TLV_ASCII_STRING"}, { WIMAXASNCP_TLV_FLAG0, "WIMAXASNCP_TLV_FLAG0"}, { WIMAXASNCP_TLV_BITFLAGS8, "WIMAXASNCP_TLV_BITFLAGS8"}, { WIMAXASNCP_TLV_BITFLAGS16, "WIMAXASNCP_TLV_BITFLAGS16"}, { WIMAXASNCP_TLV_BITFLAGS32, "WIMAXASNCP_TLV_BITFLAGS32"}, { WIMAXASNCP_TLV_ID, "WIMAXASNCP_TLV_ID"}, { WIMAXASNCP_TLV_HEX8, "WIMAXASNCP_TLV_HEX8"}, { WIMAXASNCP_TLV_HEX16, "WIMAXASNCP_TLV_HEX16"}, { WIMAXASNCP_TLV_HEX32, "WIMAXASNCP_TLV_HEX32"}, { WIMAXASNCP_TLV_DEC8, "WIMAXASNCP_TLV_DEC8"}, { WIMAXASNCP_TLV_DEC16, "WIMAXASNCP_TLV_DEC16"}, { WIMAXASNCP_TLV_DEC32, "WIMAXASNCP_TLV_DEC32"}, { WIMAXASNCP_TLV_IP_ADDRESS, "WIMAXASNCP_TLV_IP_ADDRESS"}, { WIMAXASNCP_TLV_IPV4_ADDRESS, "WIMAXASNCP_TLV_IPV4_ADDRESS"}, { WIMAXASNCP_TLV_PROTOCOL_LIST, "WIMAXASNCP_TLV_PROTOCOL_LIST"}, { WIMAXASNCP_TLV_PORT_RANGE_LIST, "WIMAXASNCP_TLV_PORT_RANGE_LIST"}, { WIMAXASNCP_TLV_IP_ADDRESS_MASK_LIST,"WIMAXASNCP_TLV_IP_ADDRESS_MASK_LIST"}, { WIMAXASNCP_TLV_EAP, "WIMAXASNCP_TLV_EAP"}, { WIMAXASNCP_TLV_VENDOR_SPECIFIC, "WIMAXASNCP_TLV_VENDOR_SPECIFIC"}, { 0, NULL} }; static gint wimaxasncp_decode_type(const gchar *name) { gsize i; for (i = 0; i < array_length(wimaxasncp_decode_type_vals) - 1; ++i) { if (strcmp(name, wimaxasncp_decode_type_vals[i].strptr) == 0) { return wimaxasncp_decode_type_vals[i].value; } } /* not found, emit some sort of error here? */ return WIMAXASNCP_TLV_TBD; } extern void wimaxasncp_dict_unused(yyscan_t yyscanner); void wimaxasncp_dict_unused(yyscan_t yyscanner) { yy_top_state(yyscanner); } static void append_to_buffer(const gchar *txt, int len, WimaxasncpDict_scanner_state_t *state) { if (state->strbuf == NULL) { state->read_ptr = state->write_ptr = state->strbuf = (gchar *)g_malloc(state->size_strbuf); } if ( (state->len_strbuf + len + 1) >= state->size_strbuf ) { state->read_ptr = state->strbuf = (gchar *)g_realloc(state->strbuf,state->size_strbuf *= 2); } state->write_ptr = state->strbuf + state->len_strbuf; strncpy(state->write_ptr,txt,len); state->len_strbuf += len; state->strbuf[state->len_strbuf] = '\0'; } static size_t file_input(gchar *buf, size_t max, yyscan_t scanner) { FILE *in = yyget_in(scanner); size_t read_cnt; read_cnt = fread(buf,1,max,in); if ( read_cnt == max ) { return max; } else if (read_cnt > 0) { return read_cnt; } else { return YY_NULL; } } static size_t string_input(gchar *buf, size_t max, yyscan_t scanner) { WimaxasncpDict_scanner_state_t *statep = yyget_extra(scanner); if (statep->read_ptr >= statep->write_ptr ) { return YY_NULL; } else if ( statep->read_ptr + max > statep->write_ptr ) { max = statep->write_ptr - statep->read_ptr; } memcpy(buf,statep->read_ptr,max); statep->read_ptr += max; return max; } static FILE *wimaxasncp_dict_open( const gchar *system_directory, const gchar *filename) { FILE *fh; gchar *fname; if (system_directory) { fname = g_strdup_printf("%s%s%s", system_directory, G_DIR_SEPARATOR_S,filename); } else { fname = g_strdup(filename); } fh = ws_fopen(fname,"r"); D(("fname: %s fh: %p\n",fname,(void*)fh)); g_free(fname); return fh; } wimaxasncp_dict_t *wimaxasncp_dict_scan( const gchar *system_directory, const gchar *filename, int dbg, gchar **error) { WimaxasncpDict_scanner_state_t state; FILE *in; yyscan_t scanner; entity_t *e; debugging = dbg; state.dict_error = g_string_new(""); state.sys_dir = system_directory; state.dict = g_new(wimaxasncp_dict_t,1); state.dict->tlvs = NULL; state.dict->xmlpis = NULL; state.strbuf = NULL; state.size_strbuf = 8192; state.len_strbuf = 0; state.write_ptr = NULL; state.read_ptr = NULL; state.tlv = NULL; state.enumitem = NULL; state.xmlpi = NULL; state.last_tlv = NULL; state.last_enumitem = NULL; state.last_xmlpi = NULL; state.ents = NULL; /* * Pass 1. * * Reads the file, does some work, and stores a modified version * of the file contents in memory. */ state.current_yyinput = file_input; state.include_stack_ptr = 0; in = wimaxasncp_dict_open(system_directory,filename); if (in == NULL) { /* * Couldn't open the dictionary. * * Treat all failures other then ENOENT as errors? */ *error = NULL; return state.dict; } if (WimaxasncpDict_lex_init(&scanner) != 0) { D(("Can't initialize scanner: %s\n", strerror(errno))); fclose(in); g_free(state.dict); return NULL; } WimaxasncpDict_set_in(in, scanner); /* Associate the state with the scanner */ WimaxasncpDict_set_extra(&state, scanner); state.start_state = LOADING; WimaxasncpDict_lex(scanner); WimaxasncpDict_lex_destroy(scanner); /* * XXX - can the lexical analyzer terminate without closing * all open input files? */ D(("\n---------------\n%s\n------- %d -------\n", state.strbuf, state.len_strbuf)); /* * Pass 2. * * Reads the modified version of the file contents and does the * rest of the work. */ state.current_yyinput = string_input; if (WimaxasncpDict_lex_init(&scanner) != 0) { D(("Can't initialize scanner: %s\n", strerror(errno))); fclose(in); g_free(state.dict); g_free(state.strbuf); return NULL; } /* Associate the state with the scanner */ WimaxasncpDict_set_extra(&state, scanner); state.start_state = OUTSIDE; WimaxasncpDict_lex(scanner); WimaxasncpDict_lex_destroy(scanner); g_free(state.strbuf); e = state.ents; while (e) { entity_t *next = e->next; g_free(e->name); g_free(e->file); g_free(e); e = next; } if (state.dict_error->len > 0) { *error = g_string_free(state.dict_error, FALSE); } else { *error = NULL; g_string_free(state.dict_error, TRUE); } return state.dict; } void wimaxasncp_dict_free(wimaxasncp_dict_t *d) { wimaxasncp_dict_tlv_t *t, *tn; #define FREE_NAMEANDOBJ(n) do { g_free(n->name); g_free(n); } while(0) for (t = d->tlvs; t; t = tn) { wimaxasncp_dict_enum_t *e, *en; tn = t->next; for (e = t->enums; e; e = en) { en = e->next; FREE_NAMEANDOBJ(e); } g_free(t->description); FREE_NAMEANDOBJ(t); } g_free(d); } void wimaxasncp_dict_print(FILE *fh, wimaxasncp_dict_t *d) { wimaxasncp_dict_tlv_t *tlvp; fprintf(fh,"\n"); for (tlvp = d->tlvs; tlvp; tlvp = tlvp->next) { wimaxasncp_dict_enum_t *e; fprintf(fh,"TLV: %s[%u] %s[%d] %s (since %u)\n", tlvp->name ? tlvp->name : "-", tlvp->type, val_to_str(tlvp->decoder, wimaxasncp_decode_type_vals, "Unknown"), tlvp->decoder, tlvp->description ? tlvp->description : "", tlvp->since); for (e = tlvp->enums; e; e = e->next) { fprintf(fh,"\tEnum: %s[%u]\n", e->name ? e->name : "-", e->code); } } } #ifdef TEST_WIMAXASNCP_DICT_STANDALONE int main(int argc, char **argv) { wimaxasncp_dict_t *d; gchar *dname = NULL; gchar *fname; int i = 1; switch (argc) { case 3: dname = argv[i++]; case 2: fname = argv[i]; break; default: fprintf(stderr,"%s: usage [dictionary_dir] dictionary_filename\n",argv[0]); return 1; } d = wimaxasncp_dict_scan(dname,fname,1,&dict_error); if (dict_error) { printf("wimaxasncp - %s", dict_error); g_free(dict_error); } wimaxasncp_dict_print(stdout, d); return 0; } #endif