diff --git a/jtag/ChangeLog b/jtag/ChangeLog index 681f01cf..f2ecf08f 100644 --- a/jtag/ChangeLog +++ b/jtag/ChangeLog @@ -1,3 +1,14 @@ +2008-04-03 Arnim Laeuger + + [ 1929235 ] Use less global and static variables: + * src/svf/svf.c, src/svf/svf.h: support reentrant parser and scanner + * src/svf/svf_bison.y: provisions for reentrant parser + * src/svf/svf_flex.l: made scanner reentrant + * src/svf/Makefile.am: removed command line options for + bison and flex + * configure.ac: require flex 2.5.33 also for SVF scanner + * doc/UrJTAG.txt: document flex version for SVF scanner + 2008-04-02 Arnim Laeuger [ 1929235 ] Use less global and static variables: diff --git a/jtag/configure.ac b/jtag/configure.ac index a2736de4..246d4a33 100644 --- a/jtag/configure.ac +++ b/jtag/configure.ac @@ -237,23 +237,6 @@ CFLAGS="$CFLAGS -Wall" CPPFLAGS="$CPPFLAGS -I\$(top_srcdir) -I\$(top_srcdir)/include" -dnl Enable SVF player? -AC_ARG_ENABLE(svf, -[AS_HELP_STRING([--enable-svf], [Enable SVF player (default is enabled)])], -[case "${enableval}" in - yes) svf=true ;; - no) svf=false ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-svf) ;; - esac], -[svf=true]) -AS_IF([test "x$svf" = xtrue], [ - AM_CONDITIONAL(ENABLE_SVF, true) - AC_DEFINE(ENABLE_SVF, 1, [define if SVF player is enabled]) -],[ - AM_CONDITIONAL(ENABLE_SVF, false) -]) - - # check for lex/flex AC_PROG_LEX # check for modern version of flex @@ -295,52 +278,53 @@ AS_IF([test "$LEX" == flex], [ flex_v2=`echo $flex_version | $AWK -F . '{print $2}' | $SED -e 's/[a-zA-Z]//g'` flex_v3=`echo $flex_version | $AWK -F . '{print $3}' | $SED -e 's/[a-zA-Z]//g'` - # bison error locations require flex >= 2.5.31 - flex_ref_v1=2 - flex_ref_v2=5 - flex_ref_v3=31 - flex_ref_version="$flex_ref_v1.$flex_ref_v2.$flex_ref_v3" - AC_MSG_CHECKING([for flex >= $flex_ref_version, required for SVF error locations]) - # - AS_IF([ver_ge_ver $flex_v1 $flex_v2 $flex_v3 $flex_ref_v1 $flex_ref_v2 $flex_ref_v3], [ - AC_MSG_RESULT([yes - flex $flex_version]) - AM_CONDITIONAL([BISON_LOCATIONS], true) - bison_locations=yes - ], [ - AS_IF([test -r src/svf/svf_flex.c], [ - # If the transformed svf_flex.c is already existing, it shouldn't matter - # that flex is too old for building a lexer with bison locations - AC_MSG_RESULT([using pre-generated src/svf/svf_flex.c]) - AM_CONDITIONAL([BISON_LOCATIONS], false) - bison_locations="as is" - ], [ - AC_MSG_RESULT([no - flex $flex_version]) - AM_CONDITIONAL([BISON_LOCATIONS], false) - bison_locations=no - ]) - ]) - - # bsdl lexer requires flex >= 2.5.33 + # svf and bsdl lexer require flex >= 2.5.33 flex_ref_v1=2 flex_ref_v2=5 flex_ref_v3=33 flex_ref_version="$flex_ref_v1.$flex_ref_v2.$flex_ref_v3" - AC_MSG_CHECKING([for flex >= $flex_ref_version, required for BSDL lexer]) + AC_MSG_CHECKING([for flex >= $flex_ref_version, required for SVF and BSDL lexer]) # AS_IF([ver_ge_ver $flex_v1 $flex_v2 $flex_v3 $flex_ref_v1 $flex_ref_v2 $flex_ref_v3], [ AC_MSG_RESULT([yes - flex $flex_version]) + svf_lexer=true bsdl_lexer=true ], [ AC_MSG_RESULT([no - flex $flex_version]) + svf_lexer=false bsdl_lexer=false ]) ], [ - bison_locations=no - AM_CONDITIONAL([BISON_LOCATIONS], false) + svf_lexer=false bsdl_lexer=false ]) +dnl If the transformed svf_flex.c is already existing, it doesn't matter +dnl that flex is too old for building the lexer. +AS_IF([test "x$svf_lexer" == xfalse], [ + AS_IF([test -r src/svf/svf_flex.c], [ + svf_lexer=true + ]) +]) + +dnl Enable SVF player? +AC_ARG_ENABLE(svf, +[AS_HELP_STRING([--enable-svf], [Enable SVF player (default is enabled)])], +[case "${enableval}" in + yes) svf=true ;; + no) svf=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-svf) ;; + esac], +[svf=$svf_lexer]) +AS_IF([test "x$svf" = xtrue], [ + AM_CONDITIONAL(ENABLE_SVF, true) + AC_DEFINE(ENABLE_SVF, 1, [define if SVF player is enabled]) +],[ + AM_CONDITIONAL(ENABLE_SVF, false) +]) + + dnl If the transformed bsdl_flex.c is already existing, it doesn't matter dnl that flex is too old for building the lexer. AS_IF([test "x$bsdl_lexer" == xfalse], [ @@ -349,7 +333,6 @@ AS_IF([test "x$bsdl_lexer" == xfalse], [ ]) ]) - dnl Enable BSDL subsystem? AC_ARG_ENABLE(bsdl, [AS_HELP_STRING([--enable-bsdl], [Enable BSDL subsystem (default is enabled)])], @@ -571,7 +554,6 @@ jtag is now configured for Detected libusb : $FLAG_HAVELIBUSB Detected libftdi : $FLAG_HAVELIBFTDI Detected libftd2xx : $FLAG_HAVELIBFTD2XX - SVF error locations : $bison_locations Build SVF player : $FLAG_SVF Build BSDL subsystem : $FLAG_BSDL Bus drivers : $enabled_bus_drivers diff --git a/jtag/doc/UrJTAG.txt b/jtag/doc/UrJTAG.txt index 6acce2ff..c5aba738 100644 --- a/jtag/doc/UrJTAG.txt +++ b/jtag/doc/UrJTAG.txt @@ -285,13 +285,13 @@ be untested combinations of chip type, bus width, ... To run autogen.sh, you need autoconf and automake, bison, and a recent flex. -The distributed source tarball contains source pregenerated with a current flex -version; flex therefore is only needed if you want to compile code checked -out from our Subversion repository. Flex 2.5.4a as it comes with Cygwin will -work but some parts of UrJTAG (namely the SVF player) become more verbose if -Flex 2.5.31 or newer is used. Building the BSDL subsystem files requires Flex -2.5.33 or newer. The configure script will compare the available Flex version -against these preconditions and enables or disables the related features. , +The distributed source tarball contains source pregenerated with a current +flex version; flex therefore is only needed if you want to compile code +checked out from our Subversion repository. Flex 2.5.4a as it comes with +Cygwin cannot build the scanners for BSDL and SVF. Building these files +requires Flex 2.5.33 or newer. The configure script will compare the available +Flex version against these preconditions and enables or disables the related +features. Furthermore, libtool should be available, and "devel" versions of the following packages: diff --git a/jtag/src/svf/Makefile.am b/jtag/src/svf/Makefile.am index f80ea67c..7386d826 100644 --- a/jtag/src/svf/Makefile.am +++ b/jtag/src/svf/Makefile.am @@ -23,11 +23,6 @@ include $(top_srcdir)/Makefile.rules AM_YFLAGS = -d -if BISON_LOCATIONS -AM_LFLAGS = --bison-locations -AM_YFLAGS += --locations -endif - noinst_LIBRARIES = libsvf.a libsvf_a_SOURCES = \ diff --git a/jtag/src/svf/svf.c b/jtag/src/svf/svf.c index 48b5e8e3..074e26a7 100644 --- a/jtag/src/svf/svf.c +++ b/jtag/src/svf/svf.c @@ -51,39 +51,7 @@ #include "svf.h" #include "svf_bison.h" -int yyparse(chain_t *chain); - - -struct sxr { - struct ths_params params; - int no_tdi; - int no_tdo; -}; - - -FILE *yyin, *yyout; - -int svf_stop_on_mismatch; - -static part_t *part; -static instruction *ir; -static data_register *dr; - - -static struct sxr sir_params, - sdr_params; - -static int endir, - enddr; - -static int runtest_run_state, - runtest_end_state; - -static int svf_trst_absent; -static int svf_state_executed; - -/* protocol issued warnings */ -static int issued_runtest_maxtime; +int svfparse(parser_priv_t *priv_data, chain_t *chain); /* @@ -449,7 +417,7 @@ svf_copy_hex_to_register(char *hex_string, tap_register *reg) * 0 : tdo and reg do not match or error occured */ static int -svf_compare_tdo(char *tdo, char *mask, tap_register *reg, YYLTYPE *loc) +svf_compare_tdo(parser_priv_t *priv, char *tdo, char *mask, tap_register *reg, YYLTYPE *loc) { char *tdo_bit, *mask_bit; int pos, mismatch, result = 1; @@ -478,7 +446,7 @@ svf_compare_tdo(char *tdo, char *mask, tap_register *reg, YYLTYPE *loc) loc->last_line+1, loc->last_column+1 ); } - if (svf_stop_on_mismatch) + if (priv->svf_stop_on_mismatch) result = 0; } @@ -567,14 +535,14 @@ svf_all_care(char **string, double number) * state : required end state (SVF parser encoding) * ***************************************************************************/ void -svf_endxr(enum generic_irdr_coding ir_dr, int state) +svf_endxr(parser_priv_t *priv, enum generic_irdr_coding ir_dr, int state) { switch (ir_dr) { case generic_ir: - endir = svf_map_state(state); + priv->endir = svf_map_state(state); break; case generic_dr: - enddr = svf_map_state(state); + priv->enddr = svf_map_state(state); break; } } @@ -642,7 +610,7 @@ static void sigalrm_handler(int signal) * 0 : error occured * ***************************************************************************/ int -svf_runtest(chain_t *chain, struct runtest *params) +svf_runtest(chain_t *chain, parser_priv_t *priv, struct runtest *params) { uint32_t run_count, frequency; @@ -657,21 +625,21 @@ svf_runtest(chain_t *chain, struct runtest *params) return(0); } if (params->max_time > 0.0) - if (!issued_runtest_maxtime) { + if (!priv->issued_runtest_maxtime) { printf( _("Warning %s: maximum time for RUNTEST not guaranteed.\n"), "svf"); printf( _(" This message is only displayed once.\n")); - issued_runtest_maxtime = 1; + priv->issued_runtest_maxtime = 1; } /* update default values for run_state and end_state */ if (params->run_state != 0) { - runtest_run_state = svf_map_state(params->run_state); + priv->runtest_run_state = svf_map_state(params->run_state); if (params->end_state == 0) - runtest_end_state = svf_map_state(params->run_state); + priv->runtest_end_state = svf_map_state(params->run_state); } if (params->end_state != 0) - runtest_end_state = svf_map_state(params->end_state); + priv->runtest_end_state = svf_map_state(params->end_state); /* compute run_count */ run_count = params->run_count; @@ -684,7 +652,7 @@ svf_runtest(chain_t *chain, struct runtest *params) } assert(run_count > 0); - svf_goto_state(chain, runtest_run_state); + svf_goto_state(chain, priv->runtest_run_state); /* set up the timer for max_time */ if (params->max_time > 0.0) { @@ -713,7 +681,7 @@ svf_runtest(chain_t *chain, struct runtest *params) else chain_clock(chain, 0, 0, run_count); - svf_goto_state(chain, runtest_end_state); + svf_goto_state(chain, priv->runtest_end_state); /* stop the timer */ if (params->max_time > 0.0) { @@ -747,11 +715,12 @@ svf_runtest(chain_t *chain, struct runtest *params) * 0 : error occured * ***************************************************************************/ int -svf_state(chain_t *chain, struct path_states *path_states, int stable_state) +svf_state(chain_t *chain, parser_priv_t *priv, struct path_states *path_states, + int stable_state) { int i; - svf_state_executed = 1; + priv->svf_state_executed = 1; for (i = 0; i < path_states->num_states; i++) svf_goto_state(chain, svf_map_state(path_states->states[i])); @@ -777,12 +746,13 @@ svf_state(chain_t *chain, struct path_states *path_states, int stable_state) * 0 : error occured * ***************************************************************************/ int -svf_sxr(chain_t *chain, enum generic_irdr_coding ir_dr, struct ths_params *params, YYLTYPE *loc) +svf_sxr(chain_t *chain, parser_priv_t *priv, enum generic_irdr_coding ir_dr, + struct ths_params *params, YYLTYPE *loc) { - struct sxr *sxr_params; + sxr_t *sxr_params; int len, result = 1; - sxr_params = ir_dr == generic_ir ? &sir_params : &sdr_params; + sxr_params = ir_dr == generic_ir ? &(priv->sir_params) : &(priv->sdr_params); /* remember parameters */ svf_remember_param(&sxr_params->params.tdi, params->tdi); @@ -836,7 +806,7 @@ svf_sxr(chain_t *chain, enum generic_irdr_coding ir_dr, struct ths_params *param switch (ir_dr) { case generic_ir: /* is SIR large enough? */ - if (ir->value->len != len) { + if (priv->ir->value->len != len) { printf( _("Error %s: SIR command length inconsistent.\n"), "svf"); if (loc != NULL) { @@ -852,18 +822,18 @@ svf_sxr(chain_t *chain, enum generic_irdr_coding ir_dr, struct ths_params *param case generic_dr: /* check data register SDR */ - if (dr->in->len != len) { + if (priv->dr->in->len != len) { /* length does not match, so install proper registers */ - register_free(dr->in); - dr->in = NULL; - register_free(dr->out); - dr->out = NULL; + register_free(priv->dr->in); + priv->dr->in = NULL; + register_free(priv->dr->out); + priv->dr->out = NULL; - if (!(dr->in = register_alloc(len))) { + if (!(priv->dr->in = register_alloc(len))) { printf( _("out of memory") ); return(0); } - if (!(dr->out = register_alloc(len))) { + if (!(priv->dr->out = register_alloc(len))) { printf( _("out of memory") ); return(0); } @@ -874,8 +844,8 @@ svf_sxr(chain_t *chain, enum generic_irdr_coding ir_dr, struct ths_params *param /* fill register with value of TDI parameter */ if (!svf_copy_hex_to_register(sxr_params->params.tdi, - ir_dr == generic_ir ? ir->value : - dr->in)) + ir_dr == generic_ir ? priv->ir->value : + priv->dr->in)) return(0); @@ -887,10 +857,10 @@ svf_sxr(chain_t *chain, enum generic_irdr_coding ir_dr, struct ths_params *param sxr_params->params.tdo ? 1 : 0, 0, EXITMODE_EXIT1); - svf_goto_state(chain, endir); + svf_goto_state(chain, priv->endir); if (sxr_params->params.tdo) - result = svf_compare_tdo(sxr_params->params.tdo, sxr_params->params.mask, ir->out, loc); + result = svf_compare_tdo(priv, sxr_params->params.tdo, sxr_params->params.mask, priv->ir->out, loc); break; case generic_dr: @@ -899,10 +869,10 @@ svf_sxr(chain_t *chain, enum generic_irdr_coding ir_dr, struct ths_params *param sxr_params->params.tdo ? 1 : 0, 0, EXITMODE_EXIT1); - svf_goto_state(chain, enddr); + svf_goto_state(chain, priv->enddr); if (sxr_params->params.tdo) - result = svf_compare_tdo(sxr_params->params.tdo, sxr_params->params.mask, dr->out, loc); + result = svf_compare_tdo(priv, sxr_params->params.tdo, sxr_params->params.mask, priv->dr->out, loc); break; } @@ -928,12 +898,12 @@ svf_sxr(chain_t *chain, enum generic_irdr_coding ir_dr, struct ths_params *param * 0 : error occured * ***************************************************************************/ int -svf_trst(chain_t *chain, int trst_mode) +svf_trst(chain_t *chain, parser_priv_t *priv, int trst_mode) { int trst_cable = -1; char *unimplemented_mode; - if (svf_trst_absent) { + if (priv->svf_trst_absent) { printf( _("Error %s: no further TRST command allowed after mode ABSENT\n"), "svf"); return(0); @@ -951,15 +921,15 @@ svf_trst(chain_t *chain, int trst_mode) break; case ABSENT: unimplemented_mode = "ABSENT"; - svf_trst_absent = 1; + priv->svf_trst_absent = 1; - if (svf_state_executed) { + if (priv->svf_state_executed) { printf( _("Error %s: TRST ABSENT must not be issued after a STATE command\n"), "svf"); return(0); } - if (sir_params.params.number > 0.0 || - sdr_params.params.number > 0.0) { + if (priv->sir_params.params.number > 0.0 || + priv->sdr_params.params.number > 0.0) { printf( _("Error %s: TRST ABSENT must not be issued after an SIR or SDR command\n"), "svf"); } @@ -1027,8 +997,9 @@ svf_txr(enum generic_irdr_coding ir_dr, struct ths_params *params) void svf_run(chain_t *chain, FILE *SVF_FILE, int stop_on_mismatch) { - const struct sxr sxr_default = { {0.0, NULL, NULL, NULL, NULL}, - 1, 1}; + const sxr_t sxr_default = { {0.0, NULL, NULL, NULL, NULL}, + 1, 1}; + parser_priv_t priv; /* initialize - part @@ -1042,10 +1013,10 @@ svf_run(chain_t *chain, FILE *SVF_FILE, int stop_on_mismatch) printf( _("Error %s: chain without any parts\n"), "svf"); return; } - part = chain->parts->parts[chain->active_part]; + priv.part = chain->parts->parts[chain->active_part]; /* setup register SDR if not already existing */ - if (!(dr = part_find_data_register(part, "SDR"))) { + if (!(priv.dr = part_find_data_register(priv.part, "SDR"))) { char *register_cmd[] = {"register", "SDR", "32", @@ -1054,14 +1025,14 @@ svf_run(chain_t *chain, FILE *SVF_FILE, int stop_on_mismatch) if (cmd_run(chain, register_cmd) < 1) return; - if (!(dr = part_find_data_register(part, "SDR"))) { + if (!(priv.dr = part_find_data_register(priv.part, "SDR"))) { printf( _("Error %s: could not establish SDR register\n"), "svf"); return; } } /* setup instruction SIR if not already existing */ - if (!(ir = part_find_instruction(part, "SIR"))) { + if (!(priv.ir = part_find_instruction(priv.part, "SIR"))) { char *instruction_cmd[] = {"instruction", "SIR", "", @@ -1070,7 +1041,7 @@ svf_run(chain_t *chain, FILE *SVF_FILE, int stop_on_mismatch) char *instruction_string; int len, result; - len = part->instruction_length; + len = priv.part->instruction_length; if (len > 0) { if ((instruction_string = (char *)calloc(len+1, sizeof(char))) != NULL) { memset(instruction_string, '1', len); @@ -1086,47 +1057,49 @@ svf_run(chain_t *chain, FILE *SVF_FILE, int stop_on_mismatch) } } - if (!(ir = part_find_instruction(part, "SIR"))) { + if (!(priv.ir = part_find_instruction(priv.part, "SIR"))) { printf( _("Error %s: could not establish SIR instruction\n"), "svf"); return; } } /* initialize variables for new parser run */ - svf_stop_on_mismatch = stop_on_mismatch; + priv.svf_stop_on_mismatch = stop_on_mismatch; - sir_params = sdr_params = sxr_default; + priv.sir_params = priv.sdr_params = sxr_default; - endir = enddr = Run_Test_Idle; + priv.endir = priv.enddr = Run_Test_Idle; - runtest_run_state = runtest_end_state = Run_Test_Idle; + priv.runtest_run_state = priv.runtest_end_state = Run_Test_Idle; - svf_trst_absent = 0; - svf_state_executed = 0; + priv.svf_trst_absent = 0; + priv.svf_state_executed = 0; /* set back flags for issued warnings */ - issued_runtest_maxtime = 0; + priv.issued_runtest_maxtime = 0; /* select SIR instruction */ - part_set_instruction(part, "SIR"); + part_set_instruction(priv.part, "SIR"); - yyin = SVF_FILE; - yyparse(chain); + if (svf_bison_init(&priv, SVF_FILE)) { + svfparse(&priv, chain); + svf_bison_deinit(&priv); + } /* clean up */ /* SIR */ - if (sir_params.params.tdi) - free(sir_params.params.tdi); - if (sir_params.params.mask) - free(sir_params.params.mask); - if (sir_params.params.smask) - free(sir_params.params.smask); + if (priv.sir_params.params.tdi) + free(priv.sir_params.params.tdi); + if (priv.sir_params.params.mask) + free(priv.sir_params.params.mask); + if (priv.sir_params.params.smask) + free(priv.sir_params.params.smask); /* SDR */ - if (sdr_params.params.tdi) - free(sdr_params.params.tdi); - if (sdr_params.params.mask) - free(sdr_params.params.mask); - if (sdr_params.params.smask) - free(sdr_params.params.smask); + if (priv.sdr_params.params.tdi) + free(priv.sdr_params.params.tdi); + if (priv.sdr_params.params.mask) + free(priv.sdr_params.params.mask); + if (priv.sdr_params.params.smask) + free(priv.sdr_params.params.smask); } diff --git a/jtag/src/svf/svf.h b/jtag/src/svf/svf.h index d31c9cbb..e429e215 100644 --- a/jtag/src/svf/svf.h +++ b/jtag/src/svf/svf.h @@ -66,13 +66,55 @@ struct runtest { int end_state; }; +typedef struct { + struct ths_params params; + int no_tdi; + int no_tdo; +} sxr_t; + + +struct svf_parser_params { + struct ths_params ths_params; + struct path_states path_states; + struct runtest runtest; +}; + + +/* private data of the bison parser + used to store variables the would end up as globals otherwise */ +struct parser_priv { + struct svf_parser_params parser_params; + void *scanner; + part_t *part; + instruction *ir; + data_register *dr; + sxr_t sir_params; + sxr_t sdr_params; + int endir; + int enddr; + int runtest_run_state; + int runtest_end_state; + int svf_stop_on_mismatch; + int svf_trst_absent; + int svf_state_executed; + /* protocol issued warnings */ + int issued_runtest_maxtime; +}; +typedef struct parser_priv parser_priv_t; + struct YYLTYPE; -void svf_endxr(enum generic_irdr_coding, int); +void *svf_flex_init(FILE *); +void svf_flex_deinit(void *); + +int svf_bison_init(parser_priv_t *, FILE *); +void svf_bison_deinit(parser_priv_t *); + +void svf_endxr(parser_priv_t *, enum generic_irdr_coding, int); void svf_frequency(chain_t *, double); int svf_hxr(enum generic_irdr_coding, struct ths_params *); -int svf_runtest(chain_t *, struct runtest *); -int svf_state(chain_t *, struct path_states *, int); -int svf_sxr(chain_t *, enum generic_irdr_coding, struct ths_params *, struct YYLTYPE *); -int svf_trst(chain_t *, int); +int svf_runtest(chain_t *, parser_priv_t *, struct runtest *); +int svf_state(chain_t *, parser_priv_t *, struct path_states *, int); +int svf_sxr(chain_t *, parser_priv_t *, enum generic_irdr_coding, struct ths_params *, struct YYLTYPE *); +int svf_trst(chain_t *, parser_priv_t *, int); int svf_txr(enum generic_irdr_coding, struct ths_params *); diff --git a/jtag/src/svf/svf_bison.y b/jtag/src/svf/svf_bison.y index cde0ec7f..b27cb994 100644 --- a/jtag/src/svf/svf_bison.y +++ b/jtag/src/svf/svf_bison.y @@ -25,6 +25,10 @@ */ %pure-parser +%parse-param {parser_priv_t *priv_data} +%parse-param {chain_t *chain} +%name-prefix="svf" +%locations %{ #include @@ -34,30 +38,17 @@ /* interface to flex */ #include "svf_bison.h" -int yylex (YYSTYPE *, YYLTYPE *); +#define YYLEX_PARAM priv_data->scanner +int yylex (YYSTYPE *, YYLTYPE *, void *); #define YYERROR_VERBOSE -struct svf_parser_params { - struct ths_params ths_params; - struct path_states path_states; - struct runtest runtest; -}; - -static struct svf_parser_params parser_params = { - {0.0, NULL, NULL, NULL, NULL}, - {{}, 0}, - {0, 0.0, 0, 0, 0, 0} -}; - -void yyerror(YYLTYPE *, chain_t *, const char *); +void yyerror(YYLTYPE *, parser_priv_t *priv_data, chain_t *, const char *); static void svf_free_ths_params(struct ths_params *); %} -%parse-param {chain_t *chain} - %union { int token; double dvalue; @@ -107,12 +98,12 @@ line svf_statement : ENDIR stable_state ';' { - svf_endxr(generic_ir, $2); + svf_endxr(priv_data, generic_ir, $2); } | ENDDR stable_state ';' { - svf_endxr(generic_dr, $2); + svf_endxr(priv_data, generic_dr, $2); } | FREQUENCY ';' @@ -127,7 +118,7 @@ svf_statement | HDR NUMBER ths_param_list ';' { - struct ths_params *p = &parser_params.ths_params; + struct ths_params *p = &(priv_data->parser_params.ths_params); p->number = $2; svf_hxr(generic_dr, p); @@ -136,7 +127,7 @@ svf_statement | HIR NUMBER ths_param_list ';' { - struct ths_params *p = &parser_params.ths_params; + struct ths_params *p = &(priv_data->parser_params.ths_params); p->number = $2; svf_hxr(generic_ir, p); @@ -146,7 +137,7 @@ svf_statement | PIOMAP '(' direction IDENTIFIER piomap_rec ')' ';' { printf("PIOMAP not implemented\n"); - yyerror(&@$, chain, "PIOMAP"); + yyerror(&@$, priv_data, chain, "PIOMAP"); YYERROR; } @@ -154,81 +145,81 @@ svf_statement { free($2); printf("PIO not implemented\n"); - yyerror(&@$, chain, "PIO"); + yyerror(&@$, priv_data, chain, "PIO"); YYERROR; } | RUNTEST runtest_run_state_opt runtest_clk_count runtest_time_opt runtest_end_state_opt ';' { - struct runtest *rt = &parser_params.runtest; + struct runtest *rt = &(priv_data->parser_params.runtest); rt->run_state = $2; rt->run_count = $3.dvalue; rt->run_clk = $3.token; rt->end_state = $5; - if (!svf_runtest(chain, rt)) { - yyerror(&@$, chain, "RUNTEST"); + if (!svf_runtest(chain, priv_data, rt)) { + yyerror(&@$, priv_data, chain, "RUNTEST"); YYERROR; } } | RUNTEST runtest_run_state_opt runtest_time runtest_end_state_opt ';' { - struct runtest *rt = &parser_params.runtest; + struct runtest *rt = &(priv_data->parser_params.runtest); rt->run_state = $2; rt->run_count = 0; rt->run_clk = 0; rt->end_state = $4; - if (!svf_runtest(chain, rt)) { - yyerror(&@$, chain, "RUNTEST"); + if (!svf_runtest(chain, priv_data, rt)) { + yyerror(&@$, priv_data, chain, "RUNTEST"); YYERROR; } } | SDR NUMBER ths_param_list ';' { - struct ths_params *p = &parser_params.ths_params; + struct ths_params *p = &(priv_data->parser_params.ths_params); int result; p->number = $2; - result = svf_sxr(chain, generic_dr, p, &@$); + result = svf_sxr(chain, priv_data, generic_dr, p, &@$); svf_free_ths_params(p); if (!result) { - yyerror(&@$, chain, "SDR"); + yyerror(&@$, priv_data, chain, "SDR"); YYERROR; } } | SIR NUMBER ths_param_list ';' { - struct ths_params *p = &parser_params.ths_params; + struct ths_params *p = &(priv_data->parser_params.ths_params); int result; p->number = $2; - result = svf_sxr(chain, generic_ir, p, &@$); + result = svf_sxr(chain, priv_data, generic_ir, p, &@$); svf_free_ths_params(p); if (!result) { - yyerror(&@$, chain, "SIR"); + yyerror(&@$, priv_data, chain, "SIR"); YYERROR; } } | STATE path_states stable_state ';' { - if (!svf_state(chain, &parser_params.path_states, $3)) { - yyerror(&@$, chain, "STATE"); + if (!svf_state(chain, priv_data, &(priv_data->parser_params.path_states), $3)) { + yyerror(&@$, priv_data, chain, "STATE"); YYERROR; } } | TDR NUMBER ths_param_list ';' { - struct ths_params *p = &parser_params.ths_params; + struct ths_params *p = &(priv_data->parser_params.ths_params); int result; p->number = $2; @@ -236,14 +227,14 @@ svf_statement svf_free_ths_params(p); if (!result) { - yyerror(&@$, chain, "TDR"); + yyerror(&@$, priv_data, chain, "TDR"); YYERROR; } } | TIR NUMBER ths_param_list ';' { - struct ths_params *p = &parser_params.ths_params; + struct ths_params *p = &(priv_data->parser_params.ths_params); int result; p->number = $2; @@ -251,15 +242,15 @@ svf_statement svf_free_ths_params(p); if (!result) { - yyerror(&@$, chain, "TIR"); + yyerror(&@$, priv_data, chain, "TIR"); YYERROR; } } | TRST trst_mode ';' { - if (!svf_trst(chain, $2)) { - yyerror(&@$, chain, "TRST"); + if (!svf_trst(chain, priv_data, $2)) { + yyerror(&@$, priv_data, chain, "TRST"); YYERROR; } } @@ -274,22 +265,22 @@ ths_param_list ths_opt_param : TDI HEXA_NUM { - parser_params.ths_params.tdi = $2; + priv_data->parser_params.ths_params.tdi = $2; } | TDO HEXA_NUM { - parser_params.ths_params.tdo = $2; + priv_data->parser_params.ths_params.tdo = $2; } | MASK HEXA_NUM { - parser_params.ths_params.mask = $2; + priv_data->parser_params.ths_params.mask = $2; } | SMASK HEXA_NUM { - parser_params.ths_params.smask = $2; + priv_data->parser_params.ths_params.smask = $2; } ; @@ -325,8 +316,8 @@ runtest_clk_count runtest_time_opt : { - parser_params.runtest.min_time = 0.0; - parser_params.runtest.max_time = 0.0; + priv_data->parser_params.runtest.min_time = 0.0; + priv_data->parser_params.runtest.max_time = 0.0; } | runtest_time @@ -335,7 +326,7 @@ runtest_time_opt runtest_time : NUMBER SEC runtest_max_time_opt { - parser_params.runtest.min_time = $1; + priv_data->parser_params.runtest.min_time = $1; } ; @@ -343,7 +334,7 @@ runtest_max_time_opt : | MAXIMUM NUMBER SEC { - parser_params.runtest.max_time = $2; + priv_data->parser_params.runtest.max_time = $2; } ; @@ -377,12 +368,12 @@ all_states path_states : /* empty element, returns index 0 */ { - parser_params.path_states.num_states = 0; + priv_data->parser_params.path_states.num_states = 0; } | path_states all_states { - struct path_states *ps = &parser_params.path_states; + struct path_states *ps = &(priv_data->parser_params.path_states); if (ps->num_states < MAX_PATH_STATES) { ps->states[ps->num_states] = $2; @@ -415,7 +406,7 @@ direction void -yyerror(YYLTYPE *locp, chain_t *chain, const char *error_string) +yyerror(YYLTYPE *locp, parser_priv_t *priv_data, chain_t *chain, const char *error_string) { printf("Error occured for SVF command %s.\n", error_string); } @@ -443,3 +434,28 @@ svf_free_ths_params(struct ths_params *params) params->smask = NULL; } } + + +int +svf_bison_init(parser_priv_t *priv_data, FILE *f) +{ + const struct svf_parser_params params = { + {0.0, NULL, NULL, NULL, NULL}, + {{}, 0}, + {0, 0.0, 0, 0, 0, 0} + }; + + priv_data->parser_params = params; + + if ((priv_data->scanner = svf_flex_init(f)) == NULL) + return 0; + else + return 1; +} + + +void +svf_bison_deinit(parser_priv_t *priv_data) +{ + svf_flex_deinit(priv_data->scanner); +} diff --git a/jtag/src/svf/svf_flex.l b/jtag/src/svf/svf_flex.l index e17e376d..1954393e 100644 --- a/jtag/src/svf/svf_flex.l +++ b/jtag/src/svf/svf_flex.l @@ -24,16 +24,11 @@ */ -/* - * Note: This lexer supports bison_locations if HAVE_MODERN_FLEX is - defined. Apart from this, the option --bison-locations has - to be specified on the command line. - The command line option is controlled by the configure - script that enables this feature based on the available - version of flex. The #define is derived below from the version - information that flex itself embeds in the *.c output. - */ - +%option bison-bridge +%option reentrant +%option prefix="svf" +%option outfile="lex.yy.c" +%option bison-locations %{ #include @@ -46,41 +41,17 @@ static int map_keyw_ident(YYSTYPE *, char *); static void align_string(char *); -#ifdef YY_FLEX_MAJOR_VERSION - #if (YY_FLEX_MAJOR_VERSION > 2) ||\ - ((YY_FLEX_MAJOR_VERSION == 2) && ((YY_FLEX_MINOR_VERSION > 5) \ - || ((YY_FLEX_MINOR_VERSION == 5) && (YY_FLEX_SUBMINOR_VERSION >= 31)))) - #undef HAVE_MODERN_FLEX - #define HAVE_MODERN_FLEX 1 - #else - #undef HAVE_MODERN_FLEX - #endif -#endif - -#ifdef HAVE_MODERN_FLEX static void fix_yylloc(YYLTYPE *, char *); static void fix_yylloc_nl(YYLTYPE *, char *); #define FIX_YYLLOC(lloc, text) fix_yylloc(lloc, text); #define FIX_YYLLOC_NL(lloc, text) fix_yylloc_nl(lloc, text); -#else - -#define MAP_KEYW_IDENT(LVAL, TEXT) map_keyw_ident(LVAL, TEXT) -#define FIX_YYLLOC(lloc, text) -#define FIX_YYLLOC_NL(lloc, text) - -#define YY_DECL int yylex (YYSTYPE *yylval) - -#endif /* HAVE_MODERN_FLEX */ - -int yywrap(void) +int yywrap(yyscan_t scanner) { return(1); } -#ifdef HAVE_MODERN_FLEX #define YY_USER_INIT do { yylloc->first_line = yylloc->last_line = yylloc->first_column = yylloc->last_column = 0; } while (0) -#endif /* HAVE_MODERN_FLEX */ %} @@ -177,12 +148,10 @@ COMMENT (!.*)|("//".*)[^\n] \n { /* token is a new line character */ -#ifdef HAVE_MODERN_FLEX yylloc->first_line = yylloc->last_line; yylloc->first_column = yylloc->last_column; ++yylloc->last_line; yylloc->last_column = 0; -#endif /* HAVE_MODERN_FLEX */ } /* end of new line */ @@ -279,18 +248,18 @@ static struct rwtable #define END(v) (sizeof(v) / sizeof(v[0]) - 1) static int -map_keyw_ident(YYSTYPE * yylval, char *str) +map_keyw_ident(YYSTYPE * mylval, char *str) { int idx; int rw = IDENTIFIER; - yylval->cvalue = str; + mylval->cvalue = str; for (idx = 0; idx <= END(rwtable); idx++) { if (strcasecmp(rwtable[idx].rw_name, str) == 0) { /* always return terminal value as semantic value */ rw = rwtable[idx].rw_yylex; - yylval->token = rw; + mylval->token = rw; } } @@ -314,30 +283,48 @@ align_string(char *str) } -#ifdef HAVE_MODERN_FLEX static void -fix_yylloc(YYLTYPE * yylloc, char *str) +fix_yylloc(YYLTYPE * mylloc, char *str) { - yylloc->first_line = yylloc->last_line; - yylloc->first_column = yylloc->last_column; - yylloc->last_column += strlen(str); + mylloc->first_line = mylloc->last_line; + mylloc->first_column = mylloc->last_column; + mylloc->last_column += strlen(str); } static void -fix_yylloc_nl(YYLTYPE * yylloc, char *str) +fix_yylloc_nl(YYLTYPE * mylloc, char *str) { char *p; - yylloc->first_line = yylloc->last_line; - yylloc->first_column = yylloc->last_column; + mylloc->first_line = mylloc->last_line; + mylloc->first_column = mylloc->last_column; for (p = str; *p; ++p) { if (*p == '\n') { - yylloc->last_column = 0; - ++yylloc->last_line; + mylloc->last_column = 0; + ++mylloc->last_line; } else { - ++yylloc->last_column; + ++mylloc->last_column; } } } -#endif /* HAVE_MODERN_FLEX */ + + +void *svf_flex_init(FILE *f) +{ + yyscan_t scanner; + + /* get our scanner structure */ + if (yylex_init(&scanner) != 0) + return NULL; + + yyset_in(f, scanner); + + return scanner; +} + + +void svf_flex_deinit(void *scanner) +{ + yylex_destroy(scanner); +}