]> git.lyx.org Git - lyx.git/blob - src/LaTeX.C
Remove the XOpenIM test as lyxlookup.C has been buried.
[lyx.git] / src / LaTeX.C
1 /* This file is part of
2  * ======================================================
3  *
4  *           LyX, The Document Processor
5  *           Copyright 1995 Matthias Ettrich
6  *           Copyright 1995-2001 The LyX Team.
7  *
8  *           This file is Copyright 1996-2001
9  *           Lars Gullik Bjønnes
10  *
11  * ======================================================
12  */
13
14 #include <config.h>
15
16 #ifdef __GNUG__
17 #pragma implementation
18 #endif
19
20 #include "LaTeX.h"
21 #include "bufferlist.h"
22 #include "gettext.h"
23 #include "lyxfunc.h"
24 #include "debug.h"
25 #include "funcrequest.h"
26 #include "support/filetools.h"
27 #include "support/FileInfo.h"
28 #include "support/lstrings.h"
29 #include "support/lyxlib.h"
30 #include "support/systemcall.h"
31 #include "support/os.h"
32 #include "support/path.h"
33
34 #include <boost/regex.hpp>
35 #include "BoostFormat.h"
36
37 #include <fstream>
38 #include <cstdio>  // sscanf
39
40 #ifndef CXX_GLOBAL_CSTD
41 using std::sscanf;
42 #endif
43
44 using std::ifstream;
45 using std::getline;
46 using std::endl;
47 using std::vector;
48 using std::set;
49 using boost::regex;
50 using boost::regex_match;
51
52 #ifndef USE_INCLUDED_STRING
53 using boost::smatch;
54 #else
55 using boost::cmatch;
56 #endif
57
58 // TODO: in no particular order
59 // - get rid of the extern BufferList and the call to
60 //   BufferList::updateIncludedTeXfiles, this should either
61 //   be done before calling LaTeX::funcs or in a completely
62 //   different way.
63 // - the bibtex command options should be supported.
64 // - the makeindex style files should be taken care of with
65 //   the dependency mechanism.
66 // - makeindex commandline options should be supported
67 // - somewhere support viewing of bibtex and makeindex log files.
68 // - we should perhaps also scan the bibtex log file
69 // - we should perhaps also scan the bibtex log file
70
71 extern BufferList bufferlist;
72
73 /*
74  * CLASS TEXERRORS
75  */
76
77 void TeXErrors::insertError(int line, string const & error_desc,
78                             string const & error_text)
79 {
80         Error newerr(line, error_desc, error_text);
81         errors.push_back(newerr);
82 }
83
84 /*
85  * CLASS LaTeX
86  */
87
88 LaTeX::LaTeX(string const & latex, string const & f, string const & p)
89                 : cmd(latex), file(f), path(p)
90 {
91         num_errors = 0;
92         depfile = file + ".dep";
93         if (prefixIs(cmd, "pdf")) { // Do we use pdflatex ?
94                 depfile += "-pdf";
95                 output_file = ChangeExtension(file,".pdf");
96         } else {
97                 output_file = ChangeExtension(file,".dvi");
98         }
99 }
100
101
102 void LaTeX::deleteFilesOnError() const
103 {
104         // currently just a dummy function.
105
106         // What files do we have to delete?
107
108         // This will at least make latex do all the runs
109         lyx::unlink(depfile);
110
111         // but the reason for the error might be in a generated file...
112
113         string const ofname = OnlyFilename(file);
114
115         // bibtex file
116         string const bbl = ChangeExtension(ofname, ".bbl");
117         lyx::unlink(bbl);
118
119         // makeindex file
120         string const ind = ChangeExtension(ofname, ".ind");
121         lyx::unlink(ind);
122
123         // Also remove the aux file
124         string const aux = ChangeExtension(ofname, ".aux");
125         lyx::unlink(aux);
126 }
127
128
129 int LaTeX::run(TeXErrors & terr, LyXFunc * lfun)
130         // We know that this function will only be run if the lyx buffer
131         // has been changed. We also know that a newly written .tex file
132         // is always different from the previous one because of the date
133         // in it. However it seems safe to run latex (at least) on time each
134         // time the .tex file changes.
135 {
136         int scanres = NO_ERRORS;
137         unsigned int count = 0; // number of times run
138         num_errors = 0; // just to make sure.
139         unsigned int const MAX_RUN = 6;
140         DepTable head; // empty head
141         bool rerun = false; // rerun requested
142
143         // The class LaTeX does not know the temp path.
144         bufferlist.updateIncludedTeXfiles(lyx::getcwd()); //GetCWD());
145
146         // Never write the depfile if an error was encountered.
147
148         // 0
149         // first check if the file dependencies exist:
150         //     ->If it does exist
151         //             check if any of the files mentioned in it have
152         //             changed (done using a checksum).
153         //                 -> if changed:
154         //                        run latex once and
155         //                        remake the dependency file
156         //                 -> if not changed:
157         //                        just return there is nothing to do for us.
158         //     ->if it doesn't exist
159         //             make it and
160         //             run latex once (we need to run latex once anyway) and
161         //             remake the dependency file.
162         //
163
164         FileInfo fi(depfile);
165         bool had_depfile = fi.exist();
166         bool run_bibtex = false;
167         string aux_file = OnlyFilename(ChangeExtension(file, "aux"));
168
169         if (had_depfile) {
170                 lyxerr[Debug::DEPEND] << "Dependency file exists" << endl;
171                 // Read the dep file:
172                 head.read(depfile);
173                 // Update the checksums
174                 head.update();
175                 // Can't just check if anything has changed because it might have aborted
176                 // on error last time... in which cas we need to re-run latex
177                 // and collect the error messages (even if they are the same).
178                 if (!FileInfo(output_file).exist()) {
179                         lyxerr[Debug::DEPEND]
180                                 << "re-running LaTeX because output file doesn't exist." << endl;
181                 } else if (!head.sumchange()) {
182                         lyxerr[Debug::DEPEND] << "return no_change" << endl;
183                         return NO_CHANGE;
184                 } else {
185                         lyxerr[Debug::DEPEND]
186                                 << "Dependency file has changed" << endl;
187                 }
188
189                 if (head.extchanged(".bib") || head.extchanged(".bst"))
190                         run_bibtex = true;
191         } else
192                 lyxerr[Debug::DEPEND]
193                         << "Dependency file does not exist" << endl;
194
195         /// We scan the aux file even when had_depfile = false,
196         /// because we can run pdflatex on the file after running latex on it,
197         /// in which case we will not need to run bibtex again.
198         vector<Aux_Info> bibtex_info_old;
199         if (!run_bibtex)
200                 bibtex_info_old = scanAuxFiles(aux_file);
201
202         ++count;
203         lyxerr[Debug::LATEX] << "Run #" << count << endl;
204         if (lfun) {
205                 ostringstream str;
206 #if USE_BOOST_FORMAT
207                 str << boost::format(_("LaTeX run number %1$d")) % count;
208 #else
209                 str << _("LaTeX run number ") << count;
210 #endif
211                 lfun->dispatch(FuncRequest(LFUN_MESSAGE, STRCONV(str.str())));
212         }
213
214         this->operator()();
215         scanres = scanLogFile(terr);
216         if (scanres & ERROR_RERUN) {
217                 lyxerr[Debug::LATEX] << "Rerunning LaTeX" << endl;
218                 this->operator()();
219                 scanres = scanLogFile(terr);
220         }
221
222         if (scanres & ERRORS) {
223                 deleteFilesOnError();
224                 return scanres; // return on error
225         }
226
227         vector<Aux_Info> const bibtex_info = scanAuxFiles(aux_file);
228         if (!run_bibtex && bibtex_info_old != bibtex_info)
229                 run_bibtex = true;
230
231         // update the dependencies.
232         deplog(head); // reads the latex log
233         head.update();
234
235         // 0.5
236         // At this point we must run external programs if needed.
237         // makeindex will be run if a .idx file changed or was generated.
238         // And if there were undefined citations or changes in references
239         // the .aux file is checked for signs of bibtex. Bibtex is then run
240         // if needed.
241
242         // run makeindex
243         if (head.haschanged(OnlyFilename(ChangeExtension(file, ".idx")))) {
244                 // no checks for now
245                 lyxerr[Debug::LATEX] << "Running MakeIndex." << endl;
246                 if (lfun) {
247                         lfun->dispatch(FuncRequest(LFUN_MESSAGE, _("Running MakeIndex.")));
248                 }
249
250                 rerun = runMakeIndex(OnlyFilename(ChangeExtension(file, ".idx")));
251         }
252
253         // run bibtex
254         // if (scanres & UNDEF_CIT || scanres & RERUN || run_bibtex)
255         if (scanres & UNDEF_CIT || run_bibtex) {
256                 // Here we must scan the .aux file and look for
257                 // "\bibdata" and/or "\bibstyle". If one of those
258                 // tags is found -> run bibtex and set rerun = true;
259                 // no checks for now
260                 lyxerr[Debug::LATEX] << "Running BibTeX." << endl;
261                 if (lfun) {
262                         lfun->dispatch(FuncRequest(LFUN_MESSAGE, _("Running BibTeX.")));
263                 }
264
265                 updateBibtexDependencies(head, bibtex_info);
266                 rerun |= runBibTeX(bibtex_info);
267         } else if (!had_depfile) {
268                 /// If we run pdflatex on the file after running latex on it,
269                 /// then we do not need to run bibtex, but we do need to
270                 /// insert the .bib and .bst files into the .dep-pdf file.
271                 updateBibtexDependencies(head, bibtex_info);
272         }
273
274         // 1
275         // we know on this point that latex has been run once (or we just
276         // returned) and the question now is to decide if we need to run
277         // it any more. This is done by asking if any of the files in the
278         // dependency file has changed. (remember that the checksum for
279         // a given file is reported to have changed if it just was created)
280         //     -> if changed or rerun == true:
281         //             run latex once more and
282         //             update the dependency structure
283         //     -> if not changed:
284         //             we does nothing at this point
285         //
286         if (rerun || head.sumchange()) {
287                 rerun = false;
288                 ++count;
289                 lyxerr[Debug::DEPEND]
290                         << "Dep. file has changed or rerun requested" << endl;
291                 lyxerr[Debug::LATEX]
292                         << "Run #" << count << endl;
293                 if (lfun) {
294                         ostringstream str;
295 #if USE_BOOST_FORMAT
296                         str << boost::format(_("LaTeX run number %1$d")) % count;
297 #else
298                         str << _("LaTeX run number ") << count;
299 #endif
300                         // check lyxstring string stream and gcc 3.1 before fixing
301                         lfun->dispatch(FuncRequest(LFUN_MESSAGE, STRCONV(str.str())));
302                 }
303
304                 this->operator()();
305                 scanres = scanLogFile(terr);
306                 if (scanres & ERRORS) {
307                         deleteFilesOnError();
308                         return scanres; // return on error
309                 }
310
311                 // update the depedencies
312                 deplog(head); // reads the latex log
313                 head.update();
314         } else {
315                 lyxerr[Debug::DEPEND] << "Dep. file has NOT changed" << endl;
316         }
317
318         // 1.5
319         // The inclusion of files generated by external programs like
320         // makeindex or bibtex might have done changes to pagenumbereing,
321         // etc. And because of this we must run the external programs
322         // again to make sure everything is redone correctly.
323         // Also there should be no need to run the external programs any
324         // more after this.
325
326         // run makeindex if the <file>.idx has changed or was generated.
327         if (head.haschanged(OnlyFilename(ChangeExtension(file, ".idx")))) {
328                 // no checks for now
329                 lyxerr[Debug::LATEX] << "Running MakeIndex." << endl;
330                 if (lfun) {
331                         lfun->dispatch(FuncRequest(LFUN_MESSAGE, _("Running MakeIndex.")));
332                 }
333
334                 rerun = runMakeIndex(OnlyFilename(ChangeExtension(file, ".idx")));
335         }
336
337         // 2
338         // we will only run latex more if the log file asks for it.
339         // or if the sumchange() is true.
340         //     -> rerun asked for:
341         //             run latex and
342         //             remake the dependency file
343         //             goto 2 or return if max runs are reached.
344         //     -> rerun not asked for:
345         //             just return (fall out of bottom of func)
346         //
347         while ((head.sumchange() || rerun || (scanres & RERUN))
348                && count < MAX_RUN) {
349                 // Yes rerun until message goes away, or until
350                 // MAX_RUNS are reached.
351                 rerun = false;
352                 ++count;
353                 lyxerr[Debug::LATEX] << "Run #" << count << endl;
354                 if (lfun) {
355                         ostringstream str;
356 #if USE_BOOST_FORMAT
357                         str << boost::format(_("LaTeX run number %1$d")) % count;
358 #else
359                         str << _("LaTeX run number ") << count;
360 #endif
361                         lfun->dispatch(FuncRequest(LFUN_MESSAGE, STRCONV(str.str())));
362                 }
363
364                 this->operator()();
365                 scanres = scanLogFile(terr);
366                 if (scanres & ERRORS) {
367                         deleteFilesOnError();
368                         return scanres; // return on error
369                 }
370
371                 // keep this updated
372                 head.update();
373         }
374
375         // Write the dependencies to file.
376         head.write(depfile);
377         lyxerr[Debug::LATEX] << "Done." << endl;
378         return scanres;
379 }
380
381
382 int LaTeX::operator()()
383 {
384 #ifndef __EMX__
385         string tmp = cmd + ' ' + QuoteName(file) + " > /dev/null";
386 #else // cmd.exe (OS/2) causes SYS0003 error at "/dev/null"
387         string tmp = cmd + ' ' + file + " > nul";
388 #endif
389         Systemcall one;
390         return one.startscript(Systemcall::Wait, tmp);
391 }
392
393
394 bool LaTeX::runMakeIndex(string const & f)
395 {
396         lyxerr[Debug::LATEX] << "idx file has been made,"
397                 " running makeindex on file "
398                              <<  f << endl;
399
400         // It should be possible to set the switches for makeindex
401         // sorting style and such. It would also be very convenient
402         // to be able to make style files from within LyX. This has
403         // to come for a later time.
404         string tmp = "makeindex -c -q ";
405         tmp += f;
406         Systemcall one;
407         one.startscript(Systemcall::Wait, tmp);
408         return true;
409 }
410
411
412 vector<Aux_Info> const
413 LaTeX::scanAuxFiles(string const & file)
414 {
415         vector<Aux_Info> result;
416
417         result.push_back(scanAuxFile(file));
418
419         for (int i = 1; i < 1000; ++i) {
420                 string file2 = ChangeExtension(file, "") + '.' + tostr(i)
421                         + ".aux";
422                 FileInfo fi(file2);
423                 if (!fi.exist())
424                         break;
425                 result.push_back(scanAuxFile(file2));
426         }
427         return result;
428 }
429
430
431 Aux_Info const LaTeX::scanAuxFile(string const & file)
432 {
433         Aux_Info result;
434         result.aux_file = file;
435         scanAuxFile(file, result);
436         return result;
437 }
438
439
440 void LaTeX::scanAuxFile(string const & file, Aux_Info & aux_info)
441 {
442         lyxerr[Debug::LATEX] << "Scanning aux file: " << file << endl;
443
444         ifstream ifs(file.c_str());
445         string token;
446         regex reg1("\\\\citation\\{([^}]+)\\}");
447         regex reg2("\\\\bibdata\\{([^}]+)\\}");
448         regex reg3("\\\\bibstyle\\{([^}]+)\\}");
449         regex reg4("\\\\@input\\{([^}]+)\\}");
450
451         while (getline(ifs, token)) {
452                 token = rtrim(token, "\r");
453 #ifndef USE_INCLUDED_STRING
454                 smatch sub;
455 #else
456                 cmatch sub;
457 #endif
458                 if (regex_match(STRCONV(token), sub, reg1)) {
459                         string data = STRCONV(sub.str(1));
460                         while (!data.empty()) {
461                                 string citation;
462                                 data = split(data, citation, ',');
463                                 lyxerr[Debug::LATEX] << "Citation: "
464                                                      << citation << endl;
465                                 aux_info.citations.insert(citation);
466                         }
467                 } else if (regex_match(STRCONV(token), sub, reg2)) {
468                         string data = sub.STRCONV(str(1));
469                         // data is now all the bib files separated by ','
470                         // get them one by one and pass them to the helper
471                         while (!data.empty()) {
472                                 string database;
473                                 data = split(data, database, ',');
474                                 database = ChangeExtension(database, "bib");
475                                 lyxerr[Debug::LATEX] << "Bibtex database: `"
476                                                      << database << '\'' << endl;
477                                 aux_info.databases.insert(database);
478                         }
479                 } else if (regex_match(STRCONV(token), sub, reg3)) {
480                         string style = STRCONV(sub.str(1));
481                         // token is now the style file
482                         // pass it to the helper
483                         style = ChangeExtension(style, "bst");
484                         lyxerr[Debug::LATEX] << "Bibtex style: `"
485                                              << style << '\'' << endl;
486                         aux_info.styles.insert(style);
487                 } else if (regex_match(STRCONV(token), sub, reg4)) {
488                         string const file2 = STRCONV(sub.str(1));
489                         scanAuxFile(file2, aux_info);
490                 }
491         }
492 }
493
494
495 void LaTeX::updateBibtexDependencies(DepTable & dep,
496                                      vector<Aux_Info> const & bibtex_info)
497 {
498         // Since a run of Bibtex mandates more latex runs it is ok to
499         // remove all ".bib" and ".bst" files.
500         dep.remove_files_with_extension(".bib");
501         dep.remove_files_with_extension(".bst");
502         //string aux = OnlyFilename(ChangeExtension(file, ".aux"));
503
504         for (vector<Aux_Info>::const_iterator it = bibtex_info.begin();
505              it != bibtex_info.end(); ++it) {
506                 for (set<string>::const_iterator it2 = it->databases.begin();
507                      it2 != it->databases.end(); ++it2) {
508                         string file = findtexfile(*it2, "bib");
509                         if (!file.empty())
510                                 dep.insert(file, true);
511                 }
512
513                 for (set<string>::const_iterator it2 = it->styles.begin();
514                      it2 != it->styles.end(); ++it2) {
515                         string file = findtexfile(*it2, "bst");
516                         if (!file.empty())
517                                 dep.insert(file, true);
518                 }
519         }
520 }
521
522
523 bool LaTeX::runBibTeX(vector<Aux_Info> const & bibtex_info)
524 {
525         bool result = false;
526         for (vector<Aux_Info>::const_iterator it = bibtex_info.begin();
527              it != bibtex_info.end(); ++it) {
528                 if (it->databases.empty())
529                         continue;
530                 result = true;
531
532                 string tmp = "bibtex ";
533                 tmp += OnlyFilename(ChangeExtension(it->aux_file, string()));
534                 Systemcall one;
535                 one.startscript(Systemcall::Wait, tmp);
536         }
537         // Return whether bibtex was run
538         return result;
539 }
540
541
542 int LaTeX::scanLogFile(TeXErrors & terr)
543 {
544         int last_line = -1;
545         int line_count = 1;
546         int retval = NO_ERRORS;
547         string tmp = OnlyFilename(ChangeExtension(file, ".log"));
548         lyxerr[Debug::LATEX] << "Log file: " << tmp << endl;
549         ifstream ifs(tmp.c_str());
550
551         string token;
552         while (getline(ifs, token)) {
553                 lyxerr[Debug::LATEX] << "Log line: " << token << endl;
554
555                 if (token.empty())
556                         continue;
557
558                 if (prefixIs(token, "LaTeX Warning:")) {
559                         // Here shall we handle different
560                         // types of warnings
561                         retval |= LATEX_WARNING;
562                         lyxerr[Debug::LATEX] << "LaTeX Warning." << endl;
563                         if (contains(token, "Rerun to get cross-references")) {
564                                 retval |= RERUN;
565                                 lyxerr[Debug::LATEX]
566                                         << "We should rerun." << endl;
567                         } else if (contains(token, "Citation")
568                                    && contains(token, "on page")
569                                    && contains(token, "undefined")) {
570                                 retval |= UNDEF_CIT;
571                         }
572                 } else if (prefixIs(token, "Package")) {
573                         // Package warnings
574                         retval |= PACKAGE_WARNING;
575                         if (contains(token, "natbib Warning:")) {
576                                 // Natbib warnings
577                                 if (contains(token, "Citation")
578                                     && contains(token, "on page")
579                                     && contains(token, "undefined")) {
580                                         retval |= UNDEF_CIT;
581                                 }
582                         } else if (contains(token, "run BibTeX")) {
583                                 retval |= UNDEF_CIT;
584                         } else if (contains(token, "Rerun LaTeX") ||
585                                    contains(token, "Rerun to get")) {
586                                 // at least longtable.sty and bibtopic.sty
587                                 // might use this.
588                                 lyxerr[Debug::LATEX]
589                                         << "We should rerun." << endl;
590                                 retval |= RERUN;
591                         }
592                 } else if (token[0] == '(') {
593                         if (contains(token, "Rerun LaTeX") ||
594                             contains(token, "Rerun to get")) {
595                                 // Used by natbib
596                                 lyxerr[Debug::LATEX]
597                                         << "We should rerun." << endl;
598                                 retval |= RERUN;
599                         }
600                 } else if (prefixIs(token, "! ")) {
601                         // Ok, we have something that looks like a TeX Error
602                         // but what do we really have.
603
604                         // Just get the error description:
605                         string desc(token, 2);
606                         if (contains(token, "LaTeX Error:"))
607                                 retval |= LATEX_ERROR;
608                         // get the next line
609                         string tmp;
610                         int count = 0;
611                         do {
612                                 if (!getline(ifs, tmp))
613                                         break;
614                                 if (++count > 10)
615                                         break;
616                         } while (!prefixIs(tmp, "l."));
617                         if (prefixIs(tmp, "l.")) {
618                                 // we have a latex error
619                                 retval |=  TEX_ERROR;
620                                 if (contains(desc, "Package babel Error: You haven't defined the language"))
621                                         retval |= ERROR_RERUN;
622                                 // get the line number:
623                                 int line = 0;
624                                 sscanf(tmp.c_str(), "l.%d", &line);
625                                 // get the rest of the message:
626                                 string errstr(tmp, tmp.find(' '));
627                                 errstr += '\n';
628                                 getline(ifs, tmp);
629                                 while (!contains(errstr, "l.")
630                                        && !tmp.empty()
631                                        && !prefixIs(tmp, "! ")
632                                        && !contains(tmp, "(job aborted")) {
633                                         errstr += tmp;
634                                         errstr += "\n";
635                                         getline(ifs, tmp);
636                                 }
637                                 lyxerr[Debug::LATEX]
638                                         << "line: " << line << '\n'
639                                         << "Desc: " << desc << '\n'
640                                         << "Text: " << errstr << endl;
641                                 if (line == last_line)
642                                         ++line_count;
643                                 else {
644                                         line_count = 1;
645                                         last_line = line;
646                                 }
647                                 if (line_count <= 5) {
648                                         terr.insertError(line, desc, errstr);
649                                         ++num_errors;
650                                 }
651                         }
652                 } else {
653                         // information messages, TeX warnings and other
654                         // warnings we have not caught earlier.
655                         if (prefixIs(token, "Overfull ")) {
656                                 retval |= TEX_WARNING;
657                         } else if (prefixIs(token, "Underfull ")) {
658                                 retval |= TEX_WARNING;
659                         } else if (contains(token, "Rerun to get citations")) {
660                                 // Natbib seems to use this.
661                                 retval |= UNDEF_CIT;
662                         } else if (contains(token, "No pages of output")) {
663                                 // A dvi file was not created
664                                 retval |= NO_OUTPUT;
665                         } else if (contains(token, "That makes 100 errors")) {
666                                 // More than 100 errors were reprted
667                                 retval |= TOO_MANY_ERRORS;
668                         }
669                 }
670         }
671         lyxerr[Debug::LATEX] << "Log line: " << token << endl;
672         return retval;
673 }
674
675
676 void LaTeX::deplog(DepTable & head)
677 {
678         // This function reads the LaTeX log file end extracts all the external
679         // files used by the LaTeX run. The files are then entered into the
680         // dependency file.
681
682         string const logfile = OnlyFilename(ChangeExtension(file, ".log"));
683
684         regex reg1("\\)* *\\(([^ )]+).*");
685         regex reg2("File: ([^ ]+).*");
686         regex reg3("No file ([^ ]+)\\..*");
687         regex reg4("\\\\openout[0-9]+.*=.*`([^ ]+)'\\..*");
688         // If an index should be created, MikTex does not write a line like
689         //    \openout# = 'sample,idx'.
690         // but intstead only a line like this into the log:
691         //   Writing index file sample.idx
692         regex reg5("Writing index file ([^ ]+).*");
693         regex unwanted("^.*\\.(aux|log|dvi|bbl|ind|glo)$");
694
695         ifstream ifs(logfile.c_str());
696         while (ifs) {
697                 // Ok, the scanning of files here is not sufficient.
698                 // Sometimes files are named by "File: xxx" only
699                 // So I think we should use some regexps to find files instead.
700                 // "(\([^ ]+\)"   should match the "(file " variant
701                 // "File: \([^ ]+\)" should match the "File: file" variant
702                 string foundfile;
703                 string token;
704                 getline(ifs, token);
705                 token = rtrim(token, "\r");
706                 if (token.empty()) continue;
707
708 #ifndef USE_INCLUDED_STRING
709                 smatch sub;
710 #else
711                 cmatch sub;
712 #endif
713                 if (regex_match(STRCONV(token), sub, reg1)) {
714                         foundfile = STRCONV(sub.str(1));
715                 } else if (regex_match(STRCONV(token), sub, reg2)) {
716                         foundfile = STRCONV(sub.str(1));
717                 } else if (regex_match(STRCONV(token), sub, reg3)) {
718                         foundfile = STRCONV(sub.str(1));
719                 } else if (regex_match(STRCONV(token), sub, reg4)) {
720                         foundfile = STRCONV(sub.str(1));
721                 } else if (regex_match(STRCONV(token), sub, reg5)) {
722                         foundfile = STRCONV(sub.str(1));
723                 } else {
724                         continue;
725                 }
726
727                 // convert from native os path to unix path
728                 foundfile = os::internal_path(foundfile);
729
730                 lyxerr[Debug::DEPEND] << "Found file: "
731                                       << foundfile << endl;
732
733                 // Ok now we found a file.
734                 // Now we should make sure that this is a file that we can
735                 // access through the normal paths.
736                 // We will not try any fancy search methods to
737                 // find the file.
738
739                 // (1) foundfile is an
740                 //     absolute path and should
741                 //     be inserted.
742                 if (AbsolutePath(foundfile)) {
743                         lyxerr[Debug::DEPEND] << "AbsolutePath file: "
744                                               << foundfile << endl;
745                         // On initial insert we want to do the update at once
746                         // since this file can not be a file generated by
747                         // the latex run.
748                         if (FileInfo(foundfile).exist())
749                                 head.insert(foundfile, true);
750                 }
751
752                 // (2) foundfile is in the tmpdir
753                 //     insert it into head
754                 else if (FileInfo(OnlyFilename(foundfile)).exist()) {
755                         if (regex_match(STRCONV(foundfile), unwanted)) {
756                                 lyxerr[Debug::DEPEND]
757                                         << "We don't want "
758                                         << OnlyFilename(foundfile)
759                                         << " in the dep file"
760                                         << endl;
761                         } else if (suffixIs(foundfile, ".tex")) {
762                                 // This is a tex file generated by LyX
763                                 // and latex is not likely to change this
764                                 // during its runs.
765                                 lyxerr[Debug::DEPEND]
766                                         << "Tmpdir TeX file: "
767                                         << OnlyFilename(foundfile)
768                                         << endl;
769                                 head.insert(foundfile, true);
770                         } else {
771                                 lyxerr[Debug::DEPEND]
772                                         << "In tmpdir file:"
773                                         << OnlyFilename(foundfile)
774                                         << endl;
775                                 head.insert(OnlyFilename(foundfile));
776                         }
777                 } else
778                         lyxerr[Debug::DEPEND]
779                                 << "Not a file or we are unable to find it."
780                                 << endl;
781         }
782
783         // Make sure that the main .tex file is in the dependancy file.
784         head.insert(OnlyFilename(file), true);
785 }