return bformat(_("Waiting for LaTeX run number %1$d"), count);
}
-} // anon namespace
+} // namespace
/*
* CLASS TEXERRORS
*/
LaTeX::LaTeX(string const & latex, OutputParams const & rp,
- FileName const & f, string const & p, string const & lp,
- bool const clean_start)
- : cmd(latex), file(f), path(p), lpath(lp), runparams(rp), biber(false)
+ FileName const & f, string const & p, string const & lp,
+ bool allow_cancellation, bool const clean_start)
+ : cmd(latex), file(f), path(p), lpath(lp), runparams(rp), biber(false),
+ allow_cancel(allow_cancellation)
{
num_errors = 0;
// lualatex can still produce a DVI with --output-format=dvi. However,
message(runMessage(count));
int exit_code = startscript();
+ if (exit_code == Systemcall::KILLED)
+ return Systemcall::KILLED;
scanres = scanLogFile(terr);
if (scanres & ERROR_RERUN) {
LYXERR(Debug::LATEX, "Rerunning LaTeX");
terr.clearErrors();
exit_code = startscript();
+ if (exit_code == Systemcall::KILLED)
+ return Systemcall::KILLED;
scanres = scanLogFile(terr);
}
LYXERR(Debug::LATEX, "Running MakeIndex.");
message(_("Running Index Processor."));
// onlyFileName() is needed for cygwin
- rerun |= runMakeIndex(onlyFileName(idxfile.absFileName()),
- runparams);
+ int const ret =
+ runMakeIndex(onlyFileName(idxfile.absFileName()), runparams);
+ if (ret == Systemcall::KILLED)
+ return Systemcall::KILLED;
+ rerun = true;
}
+
FileName const nlofile(changeExtension(file.absFileName(), ".nlo"));
// 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");
+ if (head.haschanged(nlofile) || (nlofile.exists() && nlofile.isFileEmpty())) {
+ int const ret = runMakeIndexNomencl(file, ".nlo", ".nls");
+ if (ret == Systemcall::KILLED)
+ return Systemcall::KILLED;
+ rerun = true;
+ }
+
FileName const glofile(changeExtension(file.absFileName(), ".glo"));
- if (head.haschanged(glofile))
- rerun |= runMakeIndexNomencl(file, ".glo", ".gls");
+ if (head.haschanged(glofile)) {
+ int const ret = runMakeIndexNomencl(file, ".glo", ".gls");
+ if (ret)
+ return ret;
+ rerun = true;
+ }
+
// check if we're using biber instead of bibtex
// biber writes no info to the aux file, so we just check
LYXERR(Debug::LATEX, "Running BibTeX.");
message(_("Running BibTeX."));
updateBibtexDependencies(head, bibtex_info);
- rerun |= runBibTeX(bibtex_info, runparams);
+ int exit_code;
+ rerun |= runBibTeX(bibtex_info, runparams, exit_code);
+ if (exit_code == Systemcall::KILLED)
+ return Systemcall::KILLED;
FileName const blgfile(changeExtension(file.absFileName(), ".blg"));
if (blgfile.exists())
bscanres = scanBlgFile(head, terr);
LYXERR(Debug::DEPEND, "Dep. file has changed or rerun requested");
LYXERR(Debug::LATEX, "Run #" << count);
message(runMessage(count));
- startscript();
+ int exit_code = startscript();
+ if (exit_code == Systemcall::KILLED)
+ return Systemcall::KILLED;
scanres = scanLogFile(terr);
// update the depedencies
LYXERR(Debug::LATEX, "Running BibTeX.");
message(_("Running BibTeX."));
updateBibtexDependencies(head, bibtex_info);
- rerun |= runBibTeX(bibtex_info, runparams);
+ int exit_code;
+ rerun |= runBibTeX(bibtex_info, runparams, exit_code);
+ if (exit_code == Systemcall::KILLED)
+ return Systemcall::KILLED;
FileName const blgfile(changeExtension(file.absFileName(), ".blg"));
if (blgfile.exists())
bscanres = scanBlgFile(head, terr);
LYXERR(Debug::LATEX, "Running MakeIndex.");
message(_("Running Index Processor."));
// onlyFileName() is needed for cygwin
- rerun = runMakeIndex(onlyFileName(changeExtension(
+ int const ret = runMakeIndex(onlyFileName(changeExtension(
file.absFileName(), ".idx")), runparams);
+ if (ret == Systemcall::KILLED)
+ return Systemcall::KILLED;
+ rerun = true;
}
- // I am not pretty sure if need this twice.
+ // MSVC complains that bool |= int is unsafe. Not sure why.
if (head.haschanged(nlofile))
- rerun |= runMakeIndexNomencl(file, ".nlo", ".nls");
+ rerun |= (runMakeIndexNomencl(file, ".nlo", ".nls") != 0);
if (head.haschanged(glofile))
- rerun |= runMakeIndexNomencl(file, ".glo", ".gls");
+ rerun |= (runMakeIndexNomencl(file, ".glo", ".gls") != 0);
// 5
// we will only run latex more if the log file asks for it.
+ quoteName(onlyFileName(file.toFilesystemEncoding()))
+ " > " + os::nulldev();
Systemcall one;
- return one.startscript(Systemcall::Wait, tmp, path, lpath);
+ Systemcall::Starttype const starttype =
+ allow_cancel ? Systemcall::WaitLoop : Systemcall::Wait;
+ return one.startscript(starttype, tmp, path, lpath, true);
}
-bool LaTeX::runMakeIndex(string const & f, OutputParams const & runparams,
+int LaTeX::runMakeIndex(string const & f, OutputParams const & rp,
string const & params)
{
- string tmp = runparams.use_japanese ?
+ string tmp = rp.use_japanese ?
lyxrc.jindex_command : lyxrc.index_command;
- if (!runparams.index_command.empty())
- tmp = runparams.index_command;
+ if (!rp.index_command.empty())
+ tmp = rp.index_command;
LYXERR(Debug::LATEX,
"idx file has been made, running index processor ("
<< tmp << ") on file " << f);
- tmp = subst(tmp, "$$lang", runparams.document_language);
- if (runparams.use_indices) {
+ tmp = subst(tmp, "$$lang", rp.document_language);
+ if (rp.use_indices) {
tmp = lyxrc.splitindex_command + " -m " + quoteName(tmp);
LYXERR(Debug::LATEX,
"Multiple indices. Using splitindex command: " << tmp);
tmp += quoteName(f);
tmp += params;
Systemcall one;
- one.startscript(Systemcall::Wait, tmp, path, lpath);
- return true;
+ Systemcall::Starttype const starttype =
+ allow_cancel ? Systemcall::WaitLoop : Systemcall::Wait;
+ return one.startscript(starttype, tmp, path, lpath, true);
}
-bool LaTeX::runMakeIndexNomencl(FileName const & file,
+int LaTeX::runMakeIndexNomencl(FileName const & fname,
string const & nlo, string const & nls)
{
LYXERR(Debug::LATEX, "Running MakeIndex for nomencl.");
message(_("Running MakeIndex for nomencl."));
string tmp = lyxrc.nomencl_command + ' ';
// onlyFileName() is needed for cygwin
- tmp += quoteName(onlyFileName(changeExtension(file.absFileName(), nlo)));
+ tmp += quoteName(onlyFileName(changeExtension(fname.absFileName(), nlo)));
tmp += " -o "
- + onlyFileName(changeExtension(file.toFilesystemEncoding(), nls));
+ + onlyFileName(changeExtension(fname.toFilesystemEncoding(), nls));
Systemcall one;
- one.startscript(Systemcall::Wait, tmp, path, lpath);
- return true;
+ Systemcall::Starttype const starttype =
+ allow_cancel ? Systemcall::WaitLoop : Systemcall::Wait;
+ return one.startscript(starttype, tmp, path, lpath, true);
}
vector<AuxInfo> const
-LaTeX::scanAuxFiles(FileName const & file, bool const only_childbibs)
+LaTeX::scanAuxFiles(FileName const & fname, bool const only_childbibs)
{
vector<AuxInfo> result;
if (only_childbibs) {
for (string const &s: children) {
FileName fn =
- makeAbsPath(s, file.onlyPath().realPath());
+ makeAbsPath(s, fname.onlyPath().realPath());
fn.changeExtension("aux");
if (fn.exists())
result.push_back(scanAuxFile(fn));
return result;
}
- result.push_back(scanAuxFile(file));
+ result.push_back(scanAuxFile(fname));
// This is for bibtopic
- string const basename = removeExtension(file.absFileName());
+ string const basename = removeExtension(fname.absFileName());
for (int i = 1; i < 1000; ++i) {
FileName const file2(basename
+ '.' + convert<string>(i)
}
-AuxInfo const LaTeX::scanAuxFile(FileName const & file)
+AuxInfo const LaTeX::scanAuxFile(FileName const & fname)
{
AuxInfo result;
- result.aux_file = file;
- scanAuxFile(file, result);
+ result.aux_file = fname;
+ scanAuxFile(fname, result);
return result;
}
-void LaTeX::scanAuxFile(FileName const & file, AuxInfo & aux_info)
+void LaTeX::scanAuxFile(FileName const & fname, AuxInfo & aux_info)
{
- LYXERR(Debug::LATEX, "Scanning aux file: " << file);
+ LYXERR(Debug::LATEX, "Scanning aux file: " << fname);
- ifstream ifs(file.toFilesystemEncoding().c_str());
+ ifstream ifs(fname.toFilesystemEncoding().c_str());
string token;
static regex const reg1("\\\\citation\\{([^}]+)\\}");
static regex const reg2("\\\\bibdata\\{([^}]+)\\}");
bool LaTeX::runBibTeX(vector<AuxInfo> const & bibtex_info,
- OutputParams const & runparams)
+ OutputParams const & rp, int & exit_code)
{
bool result = false;
+ exit_code = 0;
for (vector<AuxInfo>::const_iterator it = bibtex_info.begin();
it != bibtex_info.end(); ++it) {
if (!biber && it->databases.empty())
continue;
result = true;
- string tmp = runparams.bibtex_command;
+ string tmp = rp.bibtex_command;
tmp += " ";
// onlyFileName() is needed for cygwin
tmp += quoteName(onlyFileName(removeExtension(
it->aux_file.absFileName())));
Systemcall one;
- one.startscript(Systemcall::Wait, tmp, path, lpath);
+ Systemcall::Starttype const starttype =
+ allow_cancel ? Systemcall::WaitLoop : Systemcall::Wait;
+ exit_code = one.startscript(starttype, tmp, path, lpath, true);
+ if (exit_code) {
+ return result;
+ }
}
// Return whether bibtex was run
return result;
onlyFileName(changeExtension(file.absFileName(), ".log"));
LYXERR(Debug::LATEX, "Log file: " << tmp);
FileName const fn = FileName(makeAbsPath(tmp));
+ // FIXME we should use an ifdocstream here and a docstring for token
+ // below. The encoding of the log file depends on the _output_ (font)
+ // encoding of the TeX file (T1, TU etc.). See #10728.
ifstream ifs(fn.toFilesystemEncoding().c_str());
bool fle_style = false;
static regex const file_line_error(".+\\.\\D+:[0-9]+: (.+)");
- static regex const child_file(".*([0-9]+[A-Za-z]*_.+\\.tex).*");
+ static regex const child_file("[^0-9]*([0-9]+[A-Za-z]*_.+\\.tex).*");
// Flag for 'File ended while scanning' message.
// We need to wait for subsequent processing.
string wait_for_error;
string const substr = token.substr(i + 1, len);
if (regex_match(substr, sub, child_file)) {
string const name = sub.str(1);
- child.push(make_pair(name, pnest));
- children.push_back(name);
+ // Sometimes also masters have a name that matches
+ // (if their name starts with a number and _)
+ if (name != file.onlyFileName()) {
+ child.push(make_pair(name, pnest));
+ children.push_back(name);
+ }
i += len;
}
} else if (token[i] == ')') {
} while (!contains(tmp, "(job aborted"));
terr.insertError(0,
- from_local8bit("Emergency stop"),
+ from_ascii("Emergency stop"),
from_local8bit(errstr),
child_name);
}
// get the next line
- string tmp;
int count = 0;
do {
if (!getline(ifs, tmp))
// !pdfTeX error: pdflatex (file feyn10): Font feyn10 at 600 not found
retval |= ERRORS;
terr.insertError(0,
- from_local8bit("pdfTeX Error"),
+ from_ascii("pdfTeX Error"),
from_local8bit(token),
child_name);
} else if (!ignore_missing_glyphs
// Warning about missing glyph in selected font
// may be dataloss (bug 9610)
// but can be ignored for 'nullfont' (bug 10394).
- retval |= LATEX_ERROR;
- terr.insertError(0,
- from_local8bit("Missing glyphs!"),
- from_local8bit(token),
- child_name);
+ // as well as for ZERO WIDTH NON-JOINER (0x200C) which is
+ // missing in many fonts and output for ligature break (bug 10727).
+ // Since this error only occurs with utf8 output, we can safely assume
+ // that the log file is utf8-encoded
+ docstring const utoken = from_utf8(token);
+ if (!contains(utoken, 0x200C)) {
+ retval |= LATEX_ERROR;
+ terr.insertError(0,
+ from_ascii("Missing glyphs!"),
+ utoken,
+ child_name);
+ }
} else if (!wait_for_error.empty()) {
// We collect information until we know we have an error.
wait_for_error += token + '\n';
}
-int iterateLine(string const & token, regex const & reg, string const & closing,
- int fragment_pos, DepTable & head)
+int iterateLine(string const & token, regex const & reg, string const & opening,
+ string const & closing, int fragment_pos, DepTable & head)
{
smatch what;
string::const_iterator first = token.begin();
// since we had a closing bracket,
// do not investigate further
fragment = false;
+ } else if (what.str(2) == opening) {
+ // if we have another opening bracket,
+ // we might have a nested file chain
+ // as is (file.ext (subfile.ext))
+ fragment = !handleFoundFile(rtrim(what.str(1)), head);
+ // decrease first position by one in order to
+ // consider the opening delimiter on next iteration
+ if (first > token.begin())
+ --first;
} else
// if we have no closing bracket,
// try to handle as file nevertheless
return result;
}
-} // anon namespace
+} // namespace
void LaTeX::deplog(DepTable & head)
if (regex_match(token, sub, reg5)) {
// search for strings in <...>
static regex const reg5_1("<([^>]+)(.)");
- fragment_pos = iterateLine(token, reg5_1, ">",
+ fragment_pos = iterateLine(token, reg5_1, "<", ">",
fragment_pos, head);
fragment = (fragment_pos != -1);
}
if (regex_match(token, sub, reg6)) {
// search for strings in (...)
static regex const reg6_1("\\(([^()]+)(.)");
- fragment_pos = iterateLine(token, reg6_1, ")",
+ fragment_pos = iterateLine(token, reg6_1, "(", ")",
fragment_pos, head);
fragment = (fragment_pos != -1);
}
|| regex_match(token, sub, bibtexError5)) {
retval |= BIBTEX_ERROR;
string errstr = N_("BibTeX error: ") + token;
- string message;
+ string msg;
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';
+ msg = prevtoken + '\n';
}
- message += token;
+ msg += token;
terr.insertError(0,
from_local8bit(errstr),
- from_local8bit(message));
+ from_local8bit(msg));
} else if (regex_match(prevtoken, sub, bibtexError3)) {
retval |= BIBTEX_ERROR;
string errstr = N_("BibTeX error: ") + prevtoken;
- string message = prevtoken + '\n' + token;
+ string msg = prevtoken + '\n' + token;
terr.insertError(0,
from_local8bit(errstr),
- from_local8bit(message));
+ from_local8bit(msg));
} else if (regex_match(token, sub, biberError)) {
retval |= BIBTEX_ERROR;
string errstr = N_("Biber error: ") + sub.str(2);
- string message = token;
+ string msg = token;
terr.insertError(0,
from_local8bit(errstr),
- from_local8bit(message));
+ from_local8bit(msg));
}
prevtoken = token;
}