@@ -201,6 +201,7 @@ struct ParseState {
201201
202202static Rboolean busy = FALSE;
203203static ParseState parseState ;
204+ static char ParseErrorMsg [PARSE_ERROR_SIZE ];
204205
205206#define PRESERVE_SV (x ) R_PreserveInMSet((x), parseState.mset)
206207#define RELEASE_SV (x ) R_ReleaseFromMSet((x), parseState.mset)
@@ -224,7 +225,7 @@ static int mkVerb2(const char *, int);
224225static int mkVerbEnv (void );
225226static int mkDollar (int );
226227
227- static SEXP R_LatexTagSymbol = NULL ;
228+ static SEXP LatexTagSymbol = NULL ;
228229
229230#define YYSTYPE SEXP
230231
@@ -746,9 +747,9 @@ static const yytype_int8 yytranslate[] =
746747/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
747748static const yytype_uint8 yyrline [] =
748749{
749- 0 , 183 , 183 , 184 , 185 , 188 , 189 , 190 , 191 , 192 ,
750- 193 , 195 , 196 , 198 , 199 , 200 , 201 , 202 , 203 , 204 ,
751- 205 , 207 , 211 , 215 , 219 , 221 , 223 , 224
750+ 0 , 184 , 184 , 185 , 186 , 189 , 190 , 191 , 192 , 193 ,
751+ 194 , 196 , 197 , 199 , 200 , 201 , 202 , 203 , 204 , 205 ,
752+ 206 , 208 , 212 , 216 , 220 , 222 , 224 , 225
752753};
753754#endif
754755
@@ -2153,7 +2154,7 @@ static SEXP xxenv(SEXP begin, SEXP body, SEXP end, YYLTYPE *lloc)
21532154 RELEASE_SV (body );
21542155 }
21552156 setAttrib (ans , R_SrcrefSymbol , makeSrcref (lloc , parseState .SrcFile ));
2156- setAttrib (ans , R_LatexTagSymbol , mkString ("ENVIRONMENT" ));
2157+ setAttrib (ans , LatexTagSymbol , mkString ("ENVIRONMENT" ));
21572158 if (!isNull (end ))
21582159 RELEASE_SV (end );
21592160#if DEBUGVALS
@@ -2171,7 +2172,7 @@ static SEXP xxmath(SEXP body, YYLTYPE *lloc, Rboolean display)
21712172 PRESERVE_SV (ans = PairToVectorList (CDR (body )));
21722173 RELEASE_SV (body );
21732174 setAttrib (ans , R_SrcrefSymbol , makeSrcref (lloc , parseState .SrcFile ));
2174- setAttrib (ans , R_LatexTagSymbol ,
2175+ setAttrib (ans , LatexTagSymbol ,
21752176 mkString (display ? "DISPLAYMATH" : "MATH" ));
21762177#if DEBUGVALS
21772178 Rprintf (" result: %p\n" , ans );
@@ -2192,7 +2193,7 @@ static SEXP xxblock(SEXP body, YYLTYPE *lloc)
21922193 RELEASE_SV (body );
21932194 }
21942195 setAttrib (ans , R_SrcrefSymbol , makeSrcref (lloc , parseState .SrcFile ));
2195- setAttrib (ans , R_LatexTagSymbol , mkString ("BLOCK" ));
2196+ setAttrib (ans , LatexTagSymbol , mkString ("BLOCK" ));
21962197
21972198#if DEBUGVALS
21982199 Rprintf (" result: %p\n" , ans );
@@ -2227,7 +2228,7 @@ static void xxsavevalue(SEXP items, YYLTYPE *lloc)
22272228 } else {
22282229 PRESERVE_SV (parseState .Value = allocVector (VECSXP , 1 ));
22292230 SET_VECTOR_ELT (parseState .Value , 0 , ScalarString (mkChar ("" )));
2230- setAttrib (VECTOR_ELT (parseState .Value , 0 ), R_LatexTagSymbol , mkString ("TEXT" ));
2231+ setAttrib (VECTOR_ELT (parseState .Value , 0 ), LatexTagSymbol , mkString ("TEXT" ));
22312232 }
22322233 if (!isNull (parseState .Value )) {
22332234 setAttrib (parseState .Value , R_ClassSymbol , mkString ("LaTeX" ));
@@ -2237,7 +2238,7 @@ static void xxsavevalue(SEXP items, YYLTYPE *lloc)
22372238
22382239static SEXP xxtag (SEXP item , int type , YYLTYPE * lloc )
22392240{
2240- setAttrib (item , R_LatexTagSymbol , mkString (yytname [YYTRANSLATE (type )]));
2241+ setAttrib (item , LatexTagSymbol , mkString (yytname [YYTRANSLATE (type )]));
22412242 setAttrib (item , R_SrcrefSymbol , makeSrcref (lloc , parseState .SrcFile ));
22422243 return item ;
22432244}
@@ -2278,10 +2279,7 @@ static int xxgetc(void)
22782279 prevcols [prevpos ] = parseState .xxcolno ;
22792280
22802281 if (c == EOF ) return R_EOF ;
2281-
2282- R_ParseContextLast = (R_ParseContextLast + 1 ) % PARSE_CONTEXT_SIZE ;
2283- R_ParseContext [R_ParseContextLast ] = (char ) c ;
2284-
2282+
22852283 if (c == '\n' ) {
22862284 parseState .xxlineno += 1 ;
22872285 parseState .xxcolno = 1 ;
@@ -2293,8 +2291,6 @@ static int xxgetc(void)
22932291
22942292 if (c == '\t' ) parseState .xxcolno = ((parseState .xxcolno + 6 ) & ~7 ) + 1 ;
22952293
2296- R_ParseContextLine = parseState .xxlineno ;
2297-
22982294 return c ;
22992295}
23002296
@@ -2306,12 +2302,6 @@ static int xxungetc(int c)
23062302 parseState .xxcolno = prevcols [prevpos ];
23072303 prevpos = (prevpos + PUSHBACK_BUFSIZE - 1 ) % PUSHBACK_BUFSIZE ;
23082304
2309- R_ParseContextLine = parseState .xxlineno ;
2310-
2311- R_ParseContext [R_ParseContextLast ] = '\0' ;
2312- /* macOS requires us to keep this non-negative */
2313- R_ParseContextLast = (R_ParseContextLast + PARSE_CONTEXT_SIZE - 1 )
2314- % PARSE_CONTEXT_SIZE ;
23152305 if (npush >= PUSHBACK_BUFSIZE - 2 ) return R_EOF ;
23162306 pushback [npush ++ ] = c ;
23172307 return c ;
@@ -2402,18 +2392,9 @@ static void UseState(ParseState *state) {
24022392 parseState .prevState = state -> prevState ;
24032393}
24042394
2405- static void InitSymbols (void )
2406- {
2407- if (!R_LatexTagSymbol )
2408- R_LatexTagSymbol = install ("latex_tag" );
2409- }
2410-
24112395static SEXP ParseLatex (ParseStatus * status , SEXP srcfile )
24122396{
2413- InitSymbols ();
2414-
2415- R_ParseContextLast = 0 ;
2416- R_ParseContext [0 ] = '\0' ;
2397+ LatexTagSymbol = install ("latex_tag" );
24172398
24182399 parseState .xxInVerbEnv = NULL ;
24192400
@@ -2440,6 +2421,9 @@ static SEXP ParseLatex(ParseStatus *status, SEXP srcfile)
24402421
24412422 RELEASE_SV (parseState .Value );
24422423 UNPROTECT (1 ); /* parseState.mset */
2424+
2425+ if (* status == PARSE_ERROR )
2426+ error ("%s" , ParseErrorMsg );
24432427
24442428 return parseState .Value ;
24452429}
@@ -2459,14 +2443,6 @@ static int char_getc(void)
24592443 return (c );
24602444}
24612445
2462- static
2463- SEXP R_ParseLatex (SEXP text , ParseStatus * status , SEXP srcfile )
2464- {
2465- nextchar_parse = translateCharUTF8 (STRING_ELT (text , 0 ));
2466- ptr_getc = char_getc ;
2467- return ParseLatex (status , srcfile );
2468- }
2469-
24702446/*----------------------------------------------------------------------------
24712447 *
24722448 * The Lexical Analyzer:
@@ -2537,24 +2513,21 @@ static void yyerror(const char *s)
25372513 static char const yyshortunexpected [] = "unexpected %s" ;
25382514 static char const yylongunexpected [] = "unexpected %s '%s'" ;
25392515 char * expecting ;
2540- char ParseErrorMsg [PARSE_ERROR_SIZE ];
2541- SEXP filename ;
2542- char ParseErrorFilename [PARSE_ERROR_SIZE ];
2543-
2516+ char ErrorTranslation [PARSE_ERROR_SIZE ];
25442517 if (!strncmp (s , yyunexpected , sizeof yyunexpected - 1 )) {
25452518 int i , translated = FALSE;
25462519 /* Edit the error message */
25472520 expecting = strstr (s + sizeof yyunexpected - 1 , yyexpecting );
25482521 if (expecting ) * expecting = '\0' ;
25492522 for (i = 0 ; yytname_translations [i ]; i += 2 ) {
25502523 if (!strcmp (s + sizeof yyunexpected - 1 , yytname_translations [i ])) {
2551- if (yychar < 256 )
2552- snprintf (ParseErrorMsg , PARSE_ERROR_SIZE ,
2524+ if (yychar < 256 || yychar == END_OF_INPUT )
2525+ snprintf (ErrorTranslation , sizeof ( ErrorTranslation ) ,
25532526 _ (yyshortunexpected ),
25542527 i /2 < YYENGLISH ? _ (yytname_translations [i + 1 ])
25552528 : yytname_translations [i + 1 ]);
25562529 else
2557- snprintf (ParseErrorMsg , PARSE_ERROR_SIZE ,
2530+ snprintf (ErrorTranslation , sizeof ( ErrorTranslation ) ,
25582531 _ (yylongunexpected ),
25592532 i /2 < YYENGLISH ? _ (yytname_translations [i + 1 ])
25602533 : yytname_translations [i + 1 ],
@@ -2564,48 +2537,45 @@ static void yyerror(const char *s)
25642537 }
25652538 }
25662539 if (!translated ) {
2567- if (yychar < 256 )
2568- snprintf (ParseErrorMsg , PARSE_ERROR_SIZE ,
2540+ if (yychar < 256 || yychar == END_OF_INPUT )
2541+ snprintf (ErrorTranslation , sizeof ( ErrorTranslation ) ,
25692542 _ (yyshortunexpected ),
25702543 s + sizeof yyunexpected - 1 );
25712544 else
2572- snprintf (ParseErrorMsg , PARSE_ERROR_SIZE ,
2545+ snprintf (ErrorTranslation , sizeof ( ErrorTranslation ) ,
25732546 _ (yylongunexpected ),
25742547 s + sizeof yyunexpected - 1 , CHAR (STRING_ELT (yylval , 0 )));
25752548 }
25762549 if (expecting ) {
25772550 translated = FALSE;
25782551 for (i = 0 ; yytname_translations [i ]; i += 2 ) {
25792552 if (!strcmp (expecting + sizeof yyexpecting - 1 , yytname_translations [i ])) {
2580- strcat (ParseErrorMsg , _ (yyexpecting ));
2581- strcat (ParseErrorMsg , i /2 < YYENGLISH ? _ (yytname_translations [i + 1 ])
2582- : yytname_translations [i + 1 ]);
2553+ strncat (ErrorTranslation , _ (yyexpecting ),
2554+ sizeof (ErrorTranslation ) - strlen (ErrorTranslation ) - 1 );
2555+ strncat (ErrorTranslation , i /2 < YYENGLISH
2556+ ? _ (yytname_translations [i + 1 ])
2557+ : yytname_translations [i + 1 ],
2558+ sizeof (ErrorTranslation ) - strlen (ErrorTranslation ) - 1 );
25832559 translated = TRUE;
25842560 break ;
25852561 }
25862562 }
25872563 if (!translated ) {
2588- strcat (ParseErrorMsg , _ (yyexpecting ));
2589- strcat (ParseErrorMsg , expecting + sizeof yyexpecting - 1 );
2564+ strncat (ErrorTranslation , _ (yyexpecting ),
2565+ sizeof (ErrorTranslation ) - strlen (ErrorTranslation ) - 1 );
2566+ strncat (ErrorTranslation , expecting + sizeof yyexpecting - 1 ,
2567+ sizeof (ErrorTranslation ) - strlen (ErrorTranslation ) - 1 );
25902568 }
25912569 }
25922570 } else if (!strncmp (s , yyunknown , sizeof yyunknown - 1 )) {
2593- snprintf (ParseErrorMsg , PARSE_ERROR_SIZE ,
2571+ snprintf (ErrorTranslation , sizeof ( ErrorTranslation ) ,
25942572 "%s '%s'" , s , CHAR (STRING_ELT (yylval , 0 )));
25952573 } else {
2596- snprintf (ParseErrorMsg , PARSE_ERROR_SIZE , "%s" , s );
2574+ snprintf (ErrorTranslation , sizeof ( ErrorTranslation ), "%s" , s );
25972575 }
2598- filename = findVar (install ("filename" ), parseState .SrcFile );
2599- if (isString (filename ) && LENGTH (filename ))
2600- strncpy (ParseErrorFilename , CHAR (STRING_ELT (filename , 0 )), PARSE_ERROR_SIZE - 1 );
2601- else
2602- ParseErrorFilename [0 ] = '\0' ;
2603- if (yylloc .first_line != yylloc .last_line )
2604- warning ("%s:%d-%d: %s" ,
2605- ParseErrorFilename , yylloc .first_line , yylloc .last_line , ParseErrorMsg );
2606- else
2607- warning ("%s:%d: %s" ,
2608- ParseErrorFilename , yylloc .first_line , ParseErrorMsg );
2576+ snprintf (ParseErrorMsg , sizeof (ParseErrorMsg ),
2577+ "Parse error at %d:%d: %s" , yylloc .first_line , yylloc .first_column ,
2578+ ErrorTranslation );
26092579}
26102580
26112581#define TEXT_PUSH (c ) do { \
@@ -2877,7 +2847,7 @@ static void PopState(void) {
28772847 busy = FALSE;
28782848}
28792849
2880- /* "do_parseLatex "
2850+ /* "parseLatex "
28812851
28822852 .External2("parseLatex", text, srcfile, verbose, verbatim, verb)
28832853 If there is text then that is read and the other arguments are ignored.
@@ -2894,8 +2864,7 @@ SEXP parseLatex(SEXP call, SEXP op, SEXP args, SEXP env)
28942864 yydebug = 1 ;
28952865#endif
28962866
2897- R_ParseError = 0 ;
2898- R_ParseErrorMsg [0 ] = '\0' ;
2867+ ParseErrorMsg [0 ] = '\0' ;
28992868
29002869 PushState ();
29012870
@@ -2908,10 +2877,13 @@ SEXP parseLatex(SEXP call, SEXP op, SEXP args, SEXP env)
29082877 parseState .xxVerbatimList = CAR (args ); args = CDR (args );
29092878 parseState .xxVerbList = CAR (args );
29102879
2911- s = R_ParseLatex (text , & status , source );
2880+ nextchar_parse = translateCharUTF8 (STRING_ELT (text , 0 ));
2881+ ptr_getc = char_getc ;
2882+ s = ParseLatex (& status , source );
29122883
29132884 PopState ();
29142885
2915- if (status != PARSE_OK ) parseError (call , R_ParseError );
2886+ if (status != PARSE_OK ) error ("%s" , ParseErrorMsg );
2887+
29162888 return s ;
29172889}
0 commit comments