X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FLaTeX.cpp;h=3436645fec13db6e717d8772bd3b151498d13702;hb=ec84cbfb445413e51472845c3c1a2b5da930492f;hp=ecd255f4eaec8431c4278006217812407c733f37;hpb=e8a01d099a7ecbe5059cbdf0aa0aab16e9862cf6;p=lyx.git diff --git a/src/LaTeX.cpp b/src/LaTeX.cpp index ecd255f4ea..3436645fec 100644 --- a/src/LaTeX.cpp +++ b/src/LaTeX.cpp @@ -49,7 +49,6 @@ namespace os = support::os; // different way. // - the makeindex style files should be taken care of with // the dependency mechanism. -// - we should perhaps also scan the bibtex log file namespace { @@ -94,7 +93,7 @@ bool operator!=(AuxInfo const & a, AuxInfo const & o) LaTeX::LaTeX(string const & latex, OutputParams const & rp, FileName const & f, string const & p) - : cmd(latex), file(f), path(p), runparams(rp) + : cmd(latex), file(f), path(p), runparams(rp), biber(false) { num_errors = 0; if (prefixIs(cmd, "pdf")) { // Do we use pdflatex ? @@ -184,7 +183,7 @@ int LaTeX::run(TeXErrors & terr) bool had_depfile = depfile.exists(); bool run_bibtex = false; - FileName const aux_file(changeExtension(file.absFileName(), "aux")); + FileName const aux_file(changeExtension(file.absFileName(), ".aux")); if (had_depfile) { LYXERR(Debug::DEPEND, "Dependency file exists"); @@ -269,7 +268,12 @@ int LaTeX::run(TeXErrors & terr) runparams); } FileName const nlofile(changeExtension(file.absFileName(), ".nlo")); - if (head.haschanged(nlofile)) + // If all nomencl entries are removed, nomencl writes an empty nlo file. + // DepTable::hasChanged() returns false in this case, since it does not + // distinguish empty files from non-existing files. This is why we need + // the extra checks here (to trigger a rerun). Cf. discussions in #8905. + // FIXME: Sort out the real problem in DepTable. + if (head.haschanged(nlofile) || (nlofile.exists() && nlofile.isFileEmpty())) rerun |= runMakeIndexNomencl(file, ".nlo", ".nls"); FileName const glofile(changeExtension(file.absFileName(), ".glo")); if (head.haschanged(glofile)) @@ -292,13 +296,13 @@ int LaTeX::run(TeXErrors & terr) message(_("Running BibTeX.")); updateBibtexDependencies(head, bibtex_info); rerun |= runBibTeX(bibtex_info, runparams); - if (biber) { - // since biber writes no info to the aux file, we have - // to parse the blg file (which only exists after biber - // was first issued) - FileName const blgfile(changeExtension(file.absFileName(), ".blg")); - if (blgfile.exists()) - scanBlgFile(head); + FileName const blgfile(changeExtension(file.absFileName(), ".blg")); + if (blgfile.exists()) { + int bscanres = scanBlgFile(head, terr); + if (bscanres & ERRORS) { + deleteFilesOnError(); + return bscanres; // return on error + } } } else if (!had_depfile) { /// If we run pdflatex on the file after running latex on it, @@ -352,6 +356,14 @@ int LaTeX::run(TeXErrors & terr) message(_("Running BibTeX.")); updateBibtexDependencies(head, bibtex_info); rerun |= runBibTeX(bibtex_info, runparams); + FileName const blgfile(changeExtension(file.absFileName(), ".blg")); + if (blgfile.exists()) { + int bscanres = scanBlgFile(head, terr); + if (bscanres & ERRORS) { + deleteFilesOnError(); + return bscanres; // return on error + } + } } // 4 @@ -578,7 +590,8 @@ void LaTeX::updateBibtexDependencies(DepTable & dep, // biber writes nothing into the aux file. // Instead, we have to scan the blg file if (biber) { - scanBlgFile(dep); + TeXErrors terr; + scanBlgFile(dep, terr); } } @@ -621,8 +634,8 @@ int LaTeX::scanLogFile(TeXErrors & terr) FileName const fn = FileName(makeAbsPath(tmp)); ifstream ifs(fn.toFilesystemEncoding().c_str()); bool fle_style = false; - static regex file_line_error(".+\\.\\D+:[0-9]+: (.+)"); - static regex child_file(".*([0-9]+[A-Za-z]*_.+\\.tex).*"); + static regex const file_line_error(".+\\.\\D+:[0-9]+: (.+)"); + static regex const child_file(".*([0-9]+[A-Za-z]*_.+\\.tex).*"); // Flag for 'File ended while scanning' message. // We need to wait for subsequent processing. string wait_for_error; @@ -694,6 +707,10 @@ int LaTeX::scanLogFile(TeXErrors & terr) && contains(token, "on page") && contains(token, "undefined")) { retval |= UNDEF_CIT; + } else if (contains(token, "Citation") + && contains(token, "on input line") + && contains(token, "undefined")) { + retval |= UNDEF_CIT; } } else if (prefixIs(token, "Package")) { // Package warnings @@ -799,9 +816,11 @@ int LaTeX::scanLogFile(TeXErrors & terr) // we have a latex error retval |= TEX_ERROR; if (contains(desc, - "Package babel Error: You haven't defined the language") || - contains(desc, - "Package babel Error: You haven't loaded the option")) + "Package babel Error: You haven't defined the language") + || contains(desc, + "Package babel Error: You haven't loaded the option") + || contains(desc, + "Package babel Error: Unknown language")) retval |= ERROR_RERUN; // get the line number: int line = 0; @@ -996,7 +1015,7 @@ bool completeFilename(string const & ff, DepTable & head) } -int iterateLine(string const token, regex const reg, string const closing, +int iterateLine(string const & token, regex const & reg, string const & closing, int fragment_pos, DepTable & head) { smatch what; @@ -1044,7 +1063,7 @@ int iterateLine(string const token, regex const reg, string const closing, // result = -1 means we did not find a fragment! int result = -1; int last_match_pos = -1; - if (token.find(last_match) != string::npos) + if (!last_match.empty() && token.find(last_match) != string::npos) last_match_pos = int(token.find(last_match)); if (fragment) { if (last_match_pos > fragment_pos) @@ -1054,6 +1073,7 @@ int iterateLine(string const token, regex const reg, string const closing, } else if (last_match_pos < fragment_pos) result = fragment_pos; + return result; } @@ -1195,7 +1215,7 @@ void LaTeX::deplog(DepTable & head) // (and in addition to those above) if (regex_match(token, sub, reg5)) { // search for strings in <...> - static regex reg5_1("<([^>]+)(.)"); + static regex const reg5_1("<([^>]+)(.)"); fragment_pos = iterateLine(token, reg5_1, ">", fragment_pos, head); fragment = (fragment_pos != -1); @@ -1208,7 +1228,7 @@ void LaTeX::deplog(DepTable & head) // where "File: file.ext" would be skipped if (regex_match(token, sub, reg6)) { // search for strings in (...) - static regex reg6_1("\\(([^()]+)(.)"); + static regex const reg6_1("\\(([^()]+)(.)"); fragment_pos = iterateLine(token, reg6_1, ")", fragment_pos, head); fragment = (fragment_pos != -1); @@ -1228,7 +1248,7 @@ void LaTeX::deplog(DepTable & head) } -void LaTeX::scanBlgFile(DepTable & dep) +int LaTeX::scanBlgFile(DepTable & dep, TeXErrors & terr) { FileName const blg_file(changeExtension(file.absFileName(), "blg")); LYXERR(Debug::LATEX, "Scanning blg file: " << blg_file); @@ -1236,7 +1256,15 @@ void LaTeX::scanBlgFile(DepTable & dep) ifstream ifs(blg_file.toFilesystemEncoding().c_str()); string token; static regex const reg1(".*Found (bibtex|BibTeX) data (file|source) '([^']+).*"); + static regex const bibtexError("^(.*---line [0-9]+ of file).*$"); + static regex const bibtexError2("^(.*---while reading file).*$"); + static regex const bibtexError3("(A bad cross reference---).*"); + static regex const bibtexError4("(Sorry---you've exceeded BibTeX's).*"); + static regex const bibtexError5("\\*Please notify the BibTeX maintainer\\*"); + static regex const biberError("^.*> (FATAL|ERROR) - (.*)$"); + int retval = NO_ERRORS; + string prevtoken; while (getline(ifs, token)) { token = rtrim(token, "\r"); smatch sub; @@ -1250,7 +1278,42 @@ void LaTeX::scanBlgFile(DepTable & dep) handleFoundFile(data, dep); } } - } + else if (regex_match(token, sub, bibtexError) + || regex_match(token, sub, bibtexError2) + || regex_match(token, sub, bibtexError4) + || regex_match(token, sub, bibtexError5)) { + retval |= BIBTEX_ERROR; + string errstr = N_("BibTeX error: ") + token; + string message; + if ((prefixIs(token, "while executing---line") + || prefixIs(token, "---line ") + || prefixIs(token, "*Please notify the BibTeX")) + && !prevtoken.empty()) { + errstr = N_("BibTeX error: ") + prevtoken; + message = prevtoken + '\n'; + } + message += token; + terr.insertError(0, + from_local8bit(errstr), + from_local8bit(message)); + } else if (regex_match(prevtoken, sub, bibtexError3)) { + retval |= BIBTEX_ERROR; + string errstr = N_("BibTeX error: ") + prevtoken; + string message = prevtoken + '\n' + token; + terr.insertError(0, + from_local8bit(errstr), + from_local8bit(message)); + } else if (regex_match(token, sub, biberError)) { + retval |= BIBTEX_ERROR; + string errstr = N_("Biber error: ") + sub.str(2); + string message = token; + terr.insertError(0, + from_local8bit(errstr), + from_local8bit(message)); + } + prevtoken = token; + } + return retval; }