diff --git a/jtag/src/svf/svf.c b/jtag/src/svf/svf.c index 0bb76a57..c21c36c6 100644 --- a/jtag/src/svf/svf.c +++ b/jtag/src/svf/svf.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -448,7 +449,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) +svf_compare_tdo(char *tdo, char *mask, tap_register *reg, YYLTYPE *loc) { char *tdo_bit, *mask_bit; int pos, mismatch, result = 1; @@ -469,10 +470,14 @@ svf_compare_tdo(char *tdo, char *mask, tap_register *reg) mismatch = pos; if (mismatch >= 0) { - printf( _("Error %s: mismatch for TDO\n"), "svf"); - printf( " TDO: %s\n", tdo_bit); - printf( " MASK: %s\n", mask_bit); - printf( " Read: %s\n", reg->string); + printf( _("Error %s: mismatch at position %d for TDO\n"), "svf", mismatch); + if (loc != NULL) { + printf( " in input file between line %d col %d and line %d col %d\n", + loc->first_line+1, + loc->first_column+1, + loc->last_line+1, + loc->last_column+1 ); + } if (svf_stop_on_mismatch) result = 0; } @@ -769,7 +774,7 @@ svf_state(struct path_states *path_states, int stable_state) * 0 : error occured * ***************************************************************************/ int -svf_sxr(enum generic_irdr_coding ir_dr, struct ths_params *params) +svf_sxr(enum generic_irdr_coding ir_dr, struct ths_params *params, YYLTYPE *loc) { struct sxr *sxr_params; int len, result = 1; @@ -831,6 +836,13 @@ svf_sxr(enum generic_irdr_coding ir_dr, struct ths_params *params) if (ir->value->len != len) { printf( _("Error %s: SIR command length inconsistent.\n"), "svf"); + if (loc != NULL) { + printf( " in input file between line %d col %d and line %d col %d\n", + loc->first_line+1, + loc->first_column+1, + loc->last_line+1, + loc->last_column+1 ); + } return(0); } break; @@ -885,7 +897,7 @@ svf_sxr(enum generic_irdr_coding ir_dr, struct ths_params *params) svf_goto_state(enddr); if (sxr_params->params.tdo) - result = svf_compare_tdo(sxr_params->params.tdo, sxr_params->params.mask, dr->out); + result = svf_compare_tdo(sxr_params->params.tdo, sxr_params->params.mask, dr->out, loc); break; } diff --git a/jtag/src/svf/svf.h b/jtag/src/svf/svf.h index de2b5216..1538079b 100644 --- a/jtag/src/svf/svf.h +++ b/jtag/src/svf/svf.h @@ -23,6 +23,9 @@ */ +#include + + #define MAX_PATH_STATES 64 /* Coding for commands referring either to IR or DR */ @@ -55,19 +58,20 @@ struct path_states { struct runtest { int run_state; - double run_count; + uint32_t run_count; int run_clk; double min_time; double max_time; int end_state; }; +struct YYLTYPE; void svf_endxr(enum generic_irdr_coding, int); void svf_frequency(double); int svf_hxr(enum generic_irdr_coding, struct ths_params *); int svf_runtest(struct runtest *); int svf_state(struct path_states *, int); -int svf_sxr(enum generic_irdr_coding, struct ths_params *); +int svf_sxr(enum generic_irdr_coding, struct ths_params *, struct YYLTYPE *); int svf_trst(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 7e268f1d..b1dec535 100644 --- a/jtag/src/svf/svf_bison.y +++ b/jtag/src/svf/svf_bison.y @@ -24,6 +24,8 @@ * */ +%pure-parser +%locations %{ #include @@ -47,7 +49,6 @@ static struct svf_parser_params parser_params = { }; void yyerror(const char *); -int yylex(void); static void svf_free_ths_params(struct ths_params *); %} @@ -79,8 +80,8 @@ static void svf_free_ths_params(struct ths_params *); %type NUMBER %type runtest_clk_count -%type runtest_run_state -%type runtest_end_state +%type runtest_run_state_opt +%type runtest_end_state_opt %% @@ -152,7 +153,7 @@ svf_statement YYERROR; } - | RUNTEST runtest_run_state runtest_clk_count runtest_min_time1 runtest_end_state ';' + | RUNTEST runtest_run_state_opt runtest_clk_count runtest_time_opt runtest_end_state_opt ';' { struct runtest *rt = &parser_params.runtest; @@ -167,14 +168,14 @@ svf_statement } } - | RUNTEST runtest_run_state runtest_min_time2 runtest_max_time runtest_end_state ';' + | RUNTEST runtest_run_state_opt runtest_time runtest_end_state_opt ';' { struct runtest *rt = &parser_params.runtest; rt->run_state = $2; rt->run_count = 0; rt->run_clk = 0; - rt->end_state = $5; + rt->end_state = $4; if (!svf_runtest(rt)) { yyerror("RUNTEST"); @@ -188,7 +189,7 @@ svf_statement int result; p->number = $2; - result = svf_sxr(generic_dr, p); + result = svf_sxr(generic_dr, p, &@$); svf_free_ths_params(p); if (!result) { @@ -203,7 +204,7 @@ svf_statement int result; p->number = $2; - result = svf_sxr(generic_ir, p); + result = svf_sxr(generic_ir, p, &@$); svf_free_ths_params(p); if (!result) { @@ -294,7 +295,7 @@ stable_state | IRPAUSE ; -runtest_run_state +runtest_run_state_opt : { $$ = 0; } /* specify value for 'not existing' */ | stable_state { @@ -316,27 +317,24 @@ runtest_clk_count } ; -runtest_min_time1 +runtest_time_opt : { parser_params.runtest.min_time = 0.0; parser_params.runtest.max_time = 0.0; } - | NUMBER SEC runtest_max_time - { - parser_params.runtest.min_time = $1; - } + | runtest_time ; -runtest_min_time2 - : NUMBER SEC +runtest_time + : NUMBER SEC runtest_max_time_opt { parser_params.runtest.min_time = $1; } ; -runtest_max_time +runtest_max_time_opt : | MAXIMUM NUMBER SEC { @@ -344,7 +342,7 @@ runtest_max_time } ; -runtest_end_state +runtest_end_state_opt : { $$ = 0; } /* specify value for 'not existing' */ | ENDSTATE stable_state { diff --git a/jtag/src/svf/svf_flex.l b/jtag/src/svf/svf_flex.l index 2672bf91..aa6b59b3 100644 --- a/jtag/src/svf/svf_flex.l +++ b/jtag/src/svf/svf_flex.l @@ -24,6 +24,8 @@ */ +%option bison-locations + %{ #include #include @@ -31,14 +33,18 @@ #include "svf.h" #include "svf_bison.h" -static int map_keyw_ident(void); +static int map_keyw_ident(YYSTYPE *, char *); static void align_string(char *); +static void fix_yylloc(YYLTYPE *, char *); +static void fix_yylloc_nl(YYLTYPE *, char *); int yywrap(void) { return(1); } +#define YY_USER_INIT do { yylloc->first_line = yylloc->last_line = yylloc->first_column = yylloc->last_column = 0; } while (0) + %} %pointer @@ -58,7 +64,8 @@ COMMENT (!.*)|("//".*)[^\n] /* token is a keyword or identifier */ int keyw; - keyw = map_keyw_ident(); + fix_yylloc(yylloc, yytext); + keyw = map_keyw_ident(yylval, yytext); /* enable detection of VECTOR_STRING when this is a PIO command */ if (keyw == PIO) { @@ -72,7 +79,9 @@ COMMENT (!.*)|("//".*)[^\n] {DIGIT}+(\.{DIGIT}+)?([eE][-+]?{DIGIT}+)? { /* token is a real number */ - yylval.dvalue = strtod(yytext, (char **) NULL); + yylval->dvalue = strtod(yytext, (char **) NULL); + fix_yylloc(yylloc, yytext); + return(NUMBER); } /* end of real number */ @@ -86,11 +95,12 @@ COMMENT (!.*)|("//".*)[^\n] /* token is a vector string */ char *cstring; + fix_yylloc_nl(yylloc, yytext); align_string(yytext); cstring = calloc(strlen(yytext) + 1, sizeof(char)); strcpy(cstring, yytext); - yylval.cvalue = cstring; + yylval->cvalue = cstring; return(VECTOR_STRING); } /* end of vector string */ @@ -99,6 +109,7 @@ COMMENT (!.*)|("//".*)[^\n] /* token is a hexadecimal value (2) */ char *cstring; + fix_yylloc_nl(yylloc, yytext); align_string(yytext); cstring = calloc(strlen(yytext) + 1, sizeof(char)); @@ -110,26 +121,29 @@ COMMENT (!.*)|("//".*)[^\n] {WSPACE}+ { /* token is a white space character */ - + fix_yylloc(yylloc, yytext); } /* end of white space */ {COMMENT} { /* token is a comment */ - + fix_yylloc(yylloc, yytext); } /* end of comment */ [()] { /* left or right parenthes */ - + fix_yylloc(yylloc, yytext); return(yytext[0]); } /* end of left or right parenthesis */ \n { /* token is a new line character */ - + yylloc->first_line = yylloc->last_line; + yylloc->first_column = yylloc->last_column; + ++yylloc->last_line; + yylloc->last_column = 0; } /* end of new line */ @@ -139,6 +153,7 @@ COMMENT (!.*)|("//".*)[^\n] /* release expect_vector */ BEGIN(INITIAL); + fix_yylloc(yylloc, yytext); return(yytext[0]); } /* end of statement character */ @@ -225,18 +240,18 @@ static struct rwtable #define END(v) (sizeof(v) / sizeof(v[0]) - 1) static int -map_keyw_ident(void) +map_keyw_ident(YYSTYPE * yylval, char *str) { int idx; int rw = IDENTIFIER; - yylval.cvalue = yytext; + yylval->cvalue = str; for (idx = 0; idx <= END(rwtable); idx++) { - if (strcasecmp(rwtable[idx].rw_name, yytext) == 0) { + if (strcasecmp(rwtable[idx].rw_name, str) == 0) { /* always return terminal value as semantic value */ rw = rwtable[idx].rw_yylex; - yylval.token = rw; + yylval->token = rw; } } @@ -258,3 +273,30 @@ align_string(char *str) } str[dst] = '\0'; } + + +static void +fix_yylloc(YYLTYPE * yylloc, char *str) +{ + yylloc->first_line = yylloc->last_line; + yylloc->first_column = yylloc->last_column; + yylloc->last_column += strlen(str); +} + + +static void +fix_yylloc_nl(YYLTYPE * yylloc, char *str) +{ + char *p; + + yylloc->first_line = yylloc->last_line; + yylloc->first_column = yylloc->last_column; + for (p = str; *p; ++p) { + if (*p == '\n') { + yylloc->last_column = 0; + ++yylloc->last_line; + } else { + ++yylloc->last_column; + } + } +}