From fa73948a1977da05788499807469e69d5a21bd98 Mon Sep 17 00:00:00 2001 From: hornik Date: Wed, 12 Feb 2025 07:31:01 +0000 Subject: [PATCH] Fix PR#18855 issue 2. By Duncan Murdoch. git-svn-id: https://svn.r-project.org/R/trunk@87714 00db46b3-68df-0310-9c12-caf00c1e9a41 --- doc/NEWS.Rd | 3 + src/library/tools/R/parseLatex.R | 4 +- src/library/tools/man/parseLatex.Rd | 4 +- src/library/tools/src/gramLatex.c | 116 +++++++++++----------------- src/library/tools/src/gramLatex.y | 110 ++++++++++---------------- 5 files changed, 92 insertions(+), 145 deletions(-) diff --git a/doc/NEWS.Rd b/doc/NEWS.Rd index ae348c6d44b..01f13120855 100644 --- a/doc/NEWS.Rd +++ b/doc/NEWS.Rd @@ -565,6 +565,9 @@ \item The \code{tools::parseLatex()} parser made several parsing errors (\PR{18855}). + + \item Error messages produced by \code{tools::parseLatex()} are + now more readable (\PR{18855}). } } } diff --git a/src/library/tools/R/parseLatex.R b/src/library/tools/R/parseLatex.R index d8baaf332d7..09e5250d089 100644 --- a/src/library/tools/R/parseLatex.R +++ b/src/library/tools/R/parseLatex.R @@ -16,13 +16,13 @@ # A copy of the GNU General Public License is available at # https://www.R-project.org/Licenses/ -parseLatex <- function(text, filename = deparse1(substitute(text)), +parseLatex <- function(text, filename = "text", verbose = FALSE, verbatim = c("verbatim", "verbatim*", "Sinput", "Soutput"), verb = "\\Sexpr") { ## the internal function must get some sort of srcfile - srcfile <- srcfilecopy(filename, text, file.mtime(filename)) + srcfile <- srcfilecopy(filename, text) text <- paste(text, collapse="\n") .External2(C_parseLatex, text, srcfile, verbose, as.character(verbatim), as.character(verb)) } diff --git a/src/library/tools/man/parseLatex.Rd b/src/library/tools/man/parseLatex.Rd index d685e7b4442..108383bd375 100644 --- a/src/library/tools/man/parseLatex.Rd +++ b/src/library/tools/man/parseLatex.Rd @@ -16,7 +16,7 @@ characters. } \usage{ -parseLatex(text, filename = deparse1(substitute(text)), +parseLatex(text, filename = "text", verbose = FALSE, verbatim = c("verbatim", "verbatim*", "Sinput", "Soutput"), @@ -29,7 +29,7 @@ latexToUtf8(x) A character vector containing LaTeX source code. } \item{filename}{ -A filename to use in syntax error messages. +No longer used. } \item{verbose}{ If \code{TRUE}, print debug error messages. diff --git a/src/library/tools/src/gramLatex.c b/src/library/tools/src/gramLatex.c index 4a79bd7ecbb..e0280766c0e 100644 --- a/src/library/tools/src/gramLatex.c +++ b/src/library/tools/src/gramLatex.c @@ -201,6 +201,7 @@ struct ParseState { static Rboolean busy = FALSE; static ParseState parseState; +static char ParseErrorMsg[PARSE_ERROR_SIZE]; #define PRESERVE_SV(x) R_PreserveInMSet((x), parseState.mset) #define RELEASE_SV(x) R_ReleaseFromMSet((x), parseState.mset) @@ -224,7 +225,7 @@ static int mkVerb2(const char *, int); static int mkVerbEnv(void); static int mkDollar(int); -static SEXP R_LatexTagSymbol = NULL; +static SEXP LatexTagSymbol = NULL; #define YYSTYPE SEXP @@ -746,9 +747,9 @@ static const yytype_int8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 183, 183, 184, 185, 188, 189, 190, 191, 192, - 193, 195, 196, 198, 199, 200, 201, 202, 203, 204, - 205, 207, 211, 215, 219, 221, 223, 224 + 0, 184, 184, 185, 186, 189, 190, 191, 192, 193, + 194, 196, 197, 199, 200, 201, 202, 203, 204, 205, + 206, 208, 212, 216, 220, 222, 224, 225 }; #endif @@ -2153,7 +2154,7 @@ static SEXP xxenv(SEXP begin, SEXP body, SEXP end, YYLTYPE *lloc) RELEASE_SV(body); } setAttrib(ans, R_SrcrefSymbol, makeSrcref(lloc, parseState.SrcFile)); - setAttrib(ans, R_LatexTagSymbol, mkString("ENVIRONMENT")); + setAttrib(ans, LatexTagSymbol, mkString("ENVIRONMENT")); if (!isNull(end)) RELEASE_SV(end); #if DEBUGVALS @@ -2171,7 +2172,7 @@ static SEXP xxmath(SEXP body, YYLTYPE *lloc, Rboolean display) PRESERVE_SV(ans = PairToVectorList(CDR(body))); RELEASE_SV(body); setAttrib(ans, R_SrcrefSymbol, makeSrcref(lloc, parseState.SrcFile)); - setAttrib(ans, R_LatexTagSymbol, + setAttrib(ans, LatexTagSymbol, mkString(display ? "DISPLAYMATH" : "MATH")); #if DEBUGVALS Rprintf(" result: %p\n", ans); @@ -2192,7 +2193,7 @@ static SEXP xxblock(SEXP body, YYLTYPE *lloc) RELEASE_SV(body); } setAttrib(ans, R_SrcrefSymbol, makeSrcref(lloc, parseState.SrcFile)); - setAttrib(ans, R_LatexTagSymbol, mkString("BLOCK")); + setAttrib(ans, LatexTagSymbol, mkString("BLOCK")); #if DEBUGVALS Rprintf(" result: %p\n", ans); @@ -2227,7 +2228,7 @@ static void xxsavevalue(SEXP items, YYLTYPE *lloc) } else { PRESERVE_SV(parseState.Value = allocVector(VECSXP, 1)); SET_VECTOR_ELT(parseState.Value, 0, ScalarString(mkChar(""))); - setAttrib(VECTOR_ELT(parseState.Value, 0), R_LatexTagSymbol, mkString("TEXT")); + setAttrib(VECTOR_ELT(parseState.Value, 0), LatexTagSymbol, mkString("TEXT")); } if (!isNull(parseState.Value)) { setAttrib(parseState.Value, R_ClassSymbol, mkString("LaTeX")); @@ -2237,7 +2238,7 @@ static void xxsavevalue(SEXP items, YYLTYPE *lloc) static SEXP xxtag(SEXP item, int type, YYLTYPE *lloc) { - setAttrib(item, R_LatexTagSymbol, mkString(yytname[YYTRANSLATE(type)])); + setAttrib(item, LatexTagSymbol, mkString(yytname[YYTRANSLATE(type)])); setAttrib(item, R_SrcrefSymbol, makeSrcref(lloc, parseState.SrcFile)); return item; } @@ -2278,10 +2279,7 @@ static int xxgetc(void) prevcols[prevpos] = parseState.xxcolno; if (c == EOF) return R_EOF; - - R_ParseContextLast = (R_ParseContextLast + 1) % PARSE_CONTEXT_SIZE; - R_ParseContext[R_ParseContextLast] = (char) c; - + if (c == '\n') { parseState.xxlineno += 1; parseState.xxcolno = 1; @@ -2293,8 +2291,6 @@ static int xxgetc(void) if (c == '\t') parseState.xxcolno = ((parseState.xxcolno + 6) & ~7) + 1; - R_ParseContextLine = parseState.xxlineno; - return c; } @@ -2306,12 +2302,6 @@ static int xxungetc(int c) parseState.xxcolno = prevcols[prevpos]; prevpos = (prevpos + PUSHBACK_BUFSIZE - 1) % PUSHBACK_BUFSIZE; - R_ParseContextLine = parseState.xxlineno; - - R_ParseContext[R_ParseContextLast] = '\0'; - /* macOS requires us to keep this non-negative */ - R_ParseContextLast = (R_ParseContextLast + PARSE_CONTEXT_SIZE - 1) - % PARSE_CONTEXT_SIZE; if(npush >= PUSHBACK_BUFSIZE - 2) return R_EOF; pushback[npush++] = c; return c; @@ -2402,18 +2392,9 @@ static void UseState(ParseState *state) { parseState.prevState = state->prevState; } -static void InitSymbols(void) -{ - if (!R_LatexTagSymbol) - R_LatexTagSymbol = install("latex_tag"); -} - static SEXP ParseLatex(ParseStatus *status, SEXP srcfile) { - InitSymbols(); - - R_ParseContextLast = 0; - R_ParseContext[0] = '\0'; + LatexTagSymbol = install("latex_tag"); parseState.xxInVerbEnv = NULL; @@ -2440,6 +2421,9 @@ static SEXP ParseLatex(ParseStatus *status, SEXP srcfile) RELEASE_SV(parseState.Value); UNPROTECT(1); /* parseState.mset */ + + if (*status == PARSE_ERROR) + error("%s", ParseErrorMsg); return parseState.Value; } @@ -2459,14 +2443,6 @@ static int char_getc(void) return (c); } -static -SEXP R_ParseLatex(SEXP text, ParseStatus *status, SEXP srcfile) -{ - nextchar_parse = translateCharUTF8(STRING_ELT(text, 0)); - ptr_getc = char_getc; - return ParseLatex(status, srcfile); -} - /*---------------------------------------------------------------------------- * * The Lexical Analyzer: @@ -2537,10 +2513,7 @@ static void yyerror(const char *s) static char const yyshortunexpected[] = "unexpected %s"; static char const yylongunexpected[] = "unexpected %s '%s'"; char *expecting; - char ParseErrorMsg[PARSE_ERROR_SIZE]; - SEXP filename; - char ParseErrorFilename[PARSE_ERROR_SIZE]; - + char ErrorTranslation[PARSE_ERROR_SIZE]; if (!strncmp(s, yyunexpected, sizeof yyunexpected -1)) { int i, translated = FALSE; /* Edit the error message */ @@ -2548,13 +2521,13 @@ static void yyerror(const char *s) if (expecting) *expecting = '\0'; for (i = 0; yytname_translations[i]; i += 2) { if (!strcmp(s + sizeof yyunexpected - 1, yytname_translations[i])) { - if (yychar < 256) - snprintf(ParseErrorMsg, PARSE_ERROR_SIZE, + if (yychar < 256 || yychar == END_OF_INPUT) + snprintf(ErrorTranslation, sizeof(ErrorTranslation), _(yyshortunexpected), i/2 < YYENGLISH ? _(yytname_translations[i+1]) : yytname_translations[i+1]); else - snprintf(ParseErrorMsg, PARSE_ERROR_SIZE, + snprintf(ErrorTranslation, sizeof(ErrorTranslation), _(yylongunexpected), i/2 < YYENGLISH ? _(yytname_translations[i+1]) : yytname_translations[i+1], @@ -2564,12 +2537,12 @@ static void yyerror(const char *s) } } if (!translated) { - if (yychar < 256) - snprintf(ParseErrorMsg, PARSE_ERROR_SIZE, + if (yychar < 256 || yychar == END_OF_INPUT) + snprintf(ErrorTranslation, sizeof(ErrorTranslation), _(yyshortunexpected), s + sizeof yyunexpected - 1); else - snprintf(ParseErrorMsg, PARSE_ERROR_SIZE, + snprintf(ErrorTranslation, sizeof(ErrorTranslation), _(yylongunexpected), s + sizeof yyunexpected - 1, CHAR(STRING_ELT(yylval, 0))); } @@ -2577,35 +2550,32 @@ static void yyerror(const char *s) translated = FALSE; for (i = 0; yytname_translations[i]; i += 2) { if (!strcmp(expecting + sizeof yyexpecting - 1, yytname_translations[i])) { - strcat(ParseErrorMsg, _(yyexpecting)); - strcat(ParseErrorMsg, i/2 < YYENGLISH ? _(yytname_translations[i+1]) - : yytname_translations[i+1]); + strncat(ErrorTranslation, _(yyexpecting), + sizeof(ErrorTranslation) - strlen(ErrorTranslation) - 1); + strncat(ErrorTranslation, i/2 < YYENGLISH + ? _(yytname_translations[i+1]) + : yytname_translations[i+1], + sizeof(ErrorTranslation) - strlen(ErrorTranslation) - 1); translated = TRUE; break; } } if (!translated) { - strcat(ParseErrorMsg, _(yyexpecting)); - strcat(ParseErrorMsg, expecting + sizeof yyexpecting - 1); + strncat(ErrorTranslation, _(yyexpecting), + sizeof(ErrorTranslation) - strlen(ErrorTranslation) - 1); + strncat(ErrorTranslation, expecting + sizeof yyexpecting - 1, + sizeof(ErrorTranslation) - strlen(ErrorTranslation) - 1); } } } else if (!strncmp(s, yyunknown, sizeof yyunknown-1)) { - snprintf(ParseErrorMsg, PARSE_ERROR_SIZE, + snprintf(ErrorTranslation, sizeof(ErrorTranslation), "%s '%s'", s, CHAR(STRING_ELT(yylval, 0))); } else { - snprintf(ParseErrorMsg, PARSE_ERROR_SIZE,"%s", s); + snprintf(ErrorTranslation, sizeof(ErrorTranslation), "%s", s); } - filename = findVar(install("filename"), parseState.SrcFile); - if (isString(filename) && LENGTH(filename)) - strncpy(ParseErrorFilename, CHAR(STRING_ELT(filename, 0)), PARSE_ERROR_SIZE - 1); - else - ParseErrorFilename[0] = '\0'; - if (yylloc.first_line != yylloc.last_line) - warning("%s:%d-%d: %s", - ParseErrorFilename, yylloc.first_line, yylloc.last_line, ParseErrorMsg); - else - warning("%s:%d: %s", - ParseErrorFilename, yylloc.first_line, ParseErrorMsg); + snprintf(ParseErrorMsg, sizeof(ParseErrorMsg), + "Parse error at %d:%d: %s", yylloc.first_line, yylloc.first_column, + ErrorTranslation); } #define TEXT_PUSH(c) do { \ @@ -2877,7 +2847,7 @@ static void PopState(void) { busy = FALSE; } -/* "do_parseLatex" +/* "parseLatex" .External2("parseLatex", text, srcfile, verbose, verbatim, verb) 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) yydebug = 1; #endif - R_ParseError = 0; - R_ParseErrorMsg[0] = '\0'; + ParseErrorMsg[0] = '\0'; PushState(); @@ -2908,10 +2877,13 @@ SEXP parseLatex(SEXP call, SEXP op, SEXP args, SEXP env) parseState.xxVerbatimList = CAR(args); args = CDR(args); parseState.xxVerbList = CAR(args); - s = R_ParseLatex(text, &status, source); + nextchar_parse = translateCharUTF8(STRING_ELT(text, 0)); + ptr_getc = char_getc; + s = ParseLatex(&status, source); PopState(); - if (status != PARSE_OK) parseError(call, R_ParseError); + if (status != PARSE_OK) error("%s", ParseErrorMsg); + return s; } diff --git a/src/library/tools/src/gramLatex.y b/src/library/tools/src/gramLatex.y index ba02db268bc..c863c963cc4 100644 --- a/src/library/tools/src/gramLatex.y +++ b/src/library/tools/src/gramLatex.y @@ -133,6 +133,7 @@ struct ParseState { static Rboolean busy = FALSE; static ParseState parseState; +static char ParseErrorMsg[PARSE_ERROR_SIZE]; #define PRESERVE_SV(x) R_PreserveInMSet((x), parseState.mset) #define RELEASE_SV(x) R_ReleaseFromMSet((x), parseState.mset) @@ -156,7 +157,7 @@ static int mkVerb2(const char *, int); static int mkVerbEnv(void); static int mkDollar(int); -static SEXP R_LatexTagSymbol = NULL; +static SEXP LatexTagSymbol = NULL; #define YYSTYPE SEXP @@ -279,7 +280,7 @@ static SEXP xxenv(SEXP begin, SEXP body, SEXP end, YYLTYPE *lloc) RELEASE_SV(body); } setAttrib(ans, R_SrcrefSymbol, makeSrcref(lloc, parseState.SrcFile)); - setAttrib(ans, R_LatexTagSymbol, mkString("ENVIRONMENT")); + setAttrib(ans, LatexTagSymbol, mkString("ENVIRONMENT")); if (!isNull(end)) RELEASE_SV(end); #if DEBUGVALS @@ -297,7 +298,7 @@ static SEXP xxmath(SEXP body, YYLTYPE *lloc, Rboolean display) PRESERVE_SV(ans = PairToVectorList(CDR(body))); RELEASE_SV(body); setAttrib(ans, R_SrcrefSymbol, makeSrcref(lloc, parseState.SrcFile)); - setAttrib(ans, R_LatexTagSymbol, + setAttrib(ans, LatexTagSymbol, mkString(display ? "DISPLAYMATH" : "MATH")); #if DEBUGVALS Rprintf(" result: %p\n", ans); @@ -318,7 +319,7 @@ static SEXP xxblock(SEXP body, YYLTYPE *lloc) RELEASE_SV(body); } setAttrib(ans, R_SrcrefSymbol, makeSrcref(lloc, parseState.SrcFile)); - setAttrib(ans, R_LatexTagSymbol, mkString("BLOCK")); + setAttrib(ans, LatexTagSymbol, mkString("BLOCK")); #if DEBUGVALS Rprintf(" result: %p\n", ans); @@ -353,7 +354,7 @@ static void xxsavevalue(SEXP items, YYLTYPE *lloc) } else { PRESERVE_SV(parseState.Value = allocVector(VECSXP, 1)); SET_VECTOR_ELT(parseState.Value, 0, ScalarString(mkChar(""))); - setAttrib(VECTOR_ELT(parseState.Value, 0), R_LatexTagSymbol, mkString("TEXT")); + setAttrib(VECTOR_ELT(parseState.Value, 0), LatexTagSymbol, mkString("TEXT")); } if (!isNull(parseState.Value)) { setAttrib(parseState.Value, R_ClassSymbol, mkString("LaTeX")); @@ -363,7 +364,7 @@ static void xxsavevalue(SEXP items, YYLTYPE *lloc) static SEXP xxtag(SEXP item, int type, YYLTYPE *lloc) { - setAttrib(item, R_LatexTagSymbol, mkString(yytname[YYTRANSLATE(type)])); + setAttrib(item, LatexTagSymbol, mkString(yytname[YYTRANSLATE(type)])); setAttrib(item, R_SrcrefSymbol, makeSrcref(lloc, parseState.SrcFile)); return item; } @@ -404,10 +405,7 @@ static int xxgetc(void) prevcols[prevpos] = parseState.xxcolno; if (c == EOF) return R_EOF; - - R_ParseContextLast = (R_ParseContextLast + 1) % PARSE_CONTEXT_SIZE; - R_ParseContext[R_ParseContextLast] = (char) c; - + if (c == '\n') { parseState.xxlineno += 1; parseState.xxcolno = 1; @@ -419,8 +417,6 @@ static int xxgetc(void) if (c == '\t') parseState.xxcolno = ((parseState.xxcolno + 6) & ~7) + 1; - R_ParseContextLine = parseState.xxlineno; - return c; } @@ -432,12 +428,6 @@ static int xxungetc(int c) parseState.xxcolno = prevcols[prevpos]; prevpos = (prevpos + PUSHBACK_BUFSIZE - 1) % PUSHBACK_BUFSIZE; - R_ParseContextLine = parseState.xxlineno; - - R_ParseContext[R_ParseContextLast] = '\0'; - /* macOS requires us to keep this non-negative */ - R_ParseContextLast = (R_ParseContextLast + PARSE_CONTEXT_SIZE - 1) - % PARSE_CONTEXT_SIZE; if(npush >= PUSHBACK_BUFSIZE - 2) return R_EOF; pushback[npush++] = c; return c; @@ -528,18 +518,9 @@ static void UseState(ParseState *state) { parseState.prevState = state->prevState; } -static void InitSymbols(void) -{ - if (!R_LatexTagSymbol) - R_LatexTagSymbol = install("latex_tag"); -} - static SEXP ParseLatex(ParseStatus *status, SEXP srcfile) { - InitSymbols(); - - R_ParseContextLast = 0; - R_ParseContext[0] = '\0'; + LatexTagSymbol = install("latex_tag"); parseState.xxInVerbEnv = NULL; @@ -566,6 +547,9 @@ static SEXP ParseLatex(ParseStatus *status, SEXP srcfile) RELEASE_SV(parseState.Value); UNPROTECT(1); /* parseState.mset */ + + if (*status == PARSE_ERROR) + error("%s", ParseErrorMsg); return parseState.Value; } @@ -585,14 +569,6 @@ static int char_getc(void) return (c); } -static -SEXP R_ParseLatex(SEXP text, ParseStatus *status, SEXP srcfile) -{ - nextchar_parse = translateCharUTF8(STRING_ELT(text, 0)); - ptr_getc = char_getc; - return ParseLatex(status, srcfile); -} - /*---------------------------------------------------------------------------- * * The Lexical Analyzer: @@ -663,10 +639,7 @@ static void yyerror(const char *s) static char const yyshortunexpected[] = "unexpected %s"; static char const yylongunexpected[] = "unexpected %s '%s'"; char *expecting; - char ParseErrorMsg[PARSE_ERROR_SIZE]; - SEXP filename; - char ParseErrorFilename[PARSE_ERROR_SIZE]; - + char ErrorTranslation[PARSE_ERROR_SIZE]; if (!strncmp(s, yyunexpected, sizeof yyunexpected -1)) { int i, translated = FALSE; /* Edit the error message */ @@ -674,13 +647,13 @@ static void yyerror(const char *s) if (expecting) *expecting = '\0'; for (i = 0; yytname_translations[i]; i += 2) { if (!strcmp(s + sizeof yyunexpected - 1, yytname_translations[i])) { - if (yychar < 256) - snprintf(ParseErrorMsg, PARSE_ERROR_SIZE, + if (yychar < 256 || yychar == END_OF_INPUT) + snprintf(ErrorTranslation, sizeof(ErrorTranslation), _(yyshortunexpected), i/2 < YYENGLISH ? _(yytname_translations[i+1]) : yytname_translations[i+1]); else - snprintf(ParseErrorMsg, PARSE_ERROR_SIZE, + snprintf(ErrorTranslation, sizeof(ErrorTranslation), _(yylongunexpected), i/2 < YYENGLISH ? _(yytname_translations[i+1]) : yytname_translations[i+1], @@ -690,12 +663,12 @@ static void yyerror(const char *s) } } if (!translated) { - if (yychar < 256) - snprintf(ParseErrorMsg, PARSE_ERROR_SIZE, + if (yychar < 256 || yychar == END_OF_INPUT) + snprintf(ErrorTranslation, sizeof(ErrorTranslation), _(yyshortunexpected), s + sizeof yyunexpected - 1); else - snprintf(ParseErrorMsg, PARSE_ERROR_SIZE, + snprintf(ErrorTranslation, sizeof(ErrorTranslation), _(yylongunexpected), s + sizeof yyunexpected - 1, CHAR(STRING_ELT(yylval, 0))); } @@ -703,35 +676,32 @@ static void yyerror(const char *s) translated = FALSE; for (i = 0; yytname_translations[i]; i += 2) { if (!strcmp(expecting + sizeof yyexpecting - 1, yytname_translations[i])) { - strcat(ParseErrorMsg, _(yyexpecting)); - strcat(ParseErrorMsg, i/2 < YYENGLISH ? _(yytname_translations[i+1]) - : yytname_translations[i+1]); + strncat(ErrorTranslation, _(yyexpecting), + sizeof(ErrorTranslation) - strlen(ErrorTranslation) - 1); + strncat(ErrorTranslation, i/2 < YYENGLISH + ? _(yytname_translations[i+1]) + : yytname_translations[i+1], + sizeof(ErrorTranslation) - strlen(ErrorTranslation) - 1); translated = TRUE; break; } } if (!translated) { - strcat(ParseErrorMsg, _(yyexpecting)); - strcat(ParseErrorMsg, expecting + sizeof yyexpecting - 1); + strncat(ErrorTranslation, _(yyexpecting), + sizeof(ErrorTranslation) - strlen(ErrorTranslation) - 1); + strncat(ErrorTranslation, expecting + sizeof yyexpecting - 1, + sizeof(ErrorTranslation) - strlen(ErrorTranslation) - 1); } } } else if (!strncmp(s, yyunknown, sizeof yyunknown-1)) { - snprintf(ParseErrorMsg, PARSE_ERROR_SIZE, + snprintf(ErrorTranslation, sizeof(ErrorTranslation), "%s '%s'", s, CHAR(STRING_ELT(yylval, 0))); } else { - snprintf(ParseErrorMsg, PARSE_ERROR_SIZE,"%s", s); + snprintf(ErrorTranslation, sizeof(ErrorTranslation), "%s", s); } - filename = findVar(install("filename"), parseState.SrcFile); - if (isString(filename) && LENGTH(filename)) - strncpy(ParseErrorFilename, CHAR(STRING_ELT(filename, 0)), PARSE_ERROR_SIZE - 1); - else - ParseErrorFilename[0] = '\0'; - if (yylloc.first_line != yylloc.last_line) - warning("%s:%d-%d: %s", - ParseErrorFilename, yylloc.first_line, yylloc.last_line, ParseErrorMsg); - else - warning("%s:%d: %s", - ParseErrorFilename, yylloc.first_line, ParseErrorMsg); + snprintf(ParseErrorMsg, sizeof(ParseErrorMsg), + "Parse error at %d:%d: %s", yylloc.first_line, yylloc.first_column, + ErrorTranslation); } #define TEXT_PUSH(c) do { \ @@ -1003,7 +973,7 @@ static void PopState(void) { busy = FALSE; } -/* "do_parseLatex" +/* "parseLatex" .External2("parseLatex", text, srcfile, verbose, verbatim, verb) If there is text then that is read and the other arguments are ignored. @@ -1020,8 +990,7 @@ SEXP parseLatex(SEXP call, SEXP op, SEXP args, SEXP env) yydebug = 1; #endif - R_ParseError = 0; - R_ParseErrorMsg[0] = '\0'; + ParseErrorMsg[0] = '\0'; PushState(); @@ -1034,10 +1003,13 @@ SEXP parseLatex(SEXP call, SEXP op, SEXP args, SEXP env) parseState.xxVerbatimList = CAR(args); args = CDR(args); parseState.xxVerbList = CAR(args); - s = R_ParseLatex(text, &status, source); + nextchar_parse = translateCharUTF8(STRING_ELT(text, 0)); + ptr_getc = char_getc; + s = ParseLatex(&status, source); PopState(); - if (status != PARSE_OK) parseError(call, R_ParseError); + if (status != PARSE_OK) error("%s", ParseErrorMsg); + return s; }