diff --git a/src/index/indexer.cpp b/src/index/indexer.cpp index 0c50a237..18cb6ab4 100644 --- a/src/index/indexer.cpp +++ b/src/index/indexer.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: indexer.cpp,v 1.52 2007-02-06 18:01:57 dockes Exp $ (C) 2004 J.F.Dockes"; +static char rcsid[] = "@(#$Id: indexer.cpp,v 1.53 2007-02-08 17:05:12 dockes Exp $ (C) 2004 J.F.Dockes"; #endif /* * This program is free software; you can redistribute it and/or modify @@ -131,6 +131,12 @@ bool DbIndexer::indexDb(bool resetbefore, list *topdirs) m_dbdir.c_str())); return false; } + if (!m_missingExternal.empty()) { + string missing; + stringsToString(m_missingExternal, missing); + LOGERR(("DbIndexer::index missing helper program(s): %s\n", + missing.c_str())); + } return true; } @@ -387,6 +393,9 @@ DbIndexer::processone(const std::string &fn, const struct stat *stp, string ipath; fis = interner.internfile(doc, ipath); if (fis == FileInterner::FIError) { + list ext = interner.getMissingExternal(); + m_missingExternal.merge(ext); + m_missingExternal.unique(); // We dont stop indexing for one bad doc return FsTreeWalker::FtwOk; } diff --git a/src/index/indexer.h b/src/index/indexer.h index 01f7eb80..c7c2e91c 100644 --- a/src/index/indexer.h +++ b/src/index/indexer.h @@ -16,7 +16,7 @@ */ #ifndef _INDEXER_H_INCLUDED_ #define _INDEXER_H_INCLUDED_ -/* @(#$Id: indexer.h,v 1.22 2006-11-30 13:38:44 dockes Exp $ (C) 2004 J.F.Dockes */ +/* @(#$Id: indexer.h,v 1.23 2007-02-08 17:05:12 dockes Exp $ (C) 2004 J.F.Dockes */ #include #include @@ -143,6 +143,7 @@ class DbIndexer : public FsTreeWalkerCB { Rcl::Db m_db; string m_tmpdir; DbIxStatusUpdater *m_updater; + list m_missingExternal; // Names of missing helper programs bool init(bool rst = false, bool rdonly = false); }; diff --git a/src/internfile/internfile.cpp b/src/internfile/internfile.cpp index 292c353a..cd23c559 100644 --- a/src/internfile/internfile.cpp +++ b/src/internfile/internfile.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: internfile.cpp,v 1.26 2007-02-06 18:01:58 dockes Exp $ (C) 2004 J.F.Dockes"; +static char rcsid[] = "@(#$Id: internfile.cpp,v 1.27 2007-02-08 17:05:12 dockes Exp $ (C) 2004 J.F.Dockes"; #endif /* * This program is free software; you can redistribute it and/or modify @@ -223,6 +223,37 @@ bool FileInterner::dataToTempFile(const string& dt, const string& mt, return true; } +// See if the error string is formatted as a missing helper message, +// accumulate helper name if it is +void FileInterner::maybeExternalMissing(const string& msg) +{ + if (msg.find("RECFILTERROR") == 0) { + list lerr; + stringToStrings(msg, lerr); + if (lerr.size() > 2) { + list::iterator it = lerr.begin(); + it++; + if (*it == "HELPERNOTFOUND") { + it++; + m_missingExternal.push_back(it->c_str()); + } + } + } +} + +const list& FileInterner::getMissingExternal() +{ + m_missingExternal.sort(); + m_missingExternal.unique(); + return m_missingExternal; +} +void FileInterner::getMissingExternal(string& out) +{ + m_missingExternal.sort(); + m_missingExternal.unique(); + stringsToString(m_missingExternal, out); +} + static inline bool getKeyValue(const map& docdata, const string& key, string& value) { @@ -368,6 +399,7 @@ FileInterner::Status FileInterner::internfile(Rcl::Doc& doc, string& ipath) Rcl::Doc doc; string ipath; collectIpathAndMT(doc, ipath); m_reason = m_handlers.back()->get_error(); + maybeExternalMissing(m_reason); LOGERR(("FileInterner::internfile: next_document error [%s%s%s] %s\n", m_fn.c_str(), ipath.empty()?"":"|", ipath.c_str(), m_reason.c_str())); diff --git a/src/internfile/internfile.h b/src/internfile/internfile.h index 3e6159e0..d72cd8df 100644 --- a/src/internfile/internfile.h +++ b/src/internfile/internfile.h @@ -16,7 +16,7 @@ */ #ifndef _INTERNFILE_H_INCLUDED_ #define _INTERNFILE_H_INCLUDED_ -/* @(#$Id: internfile.h,v 1.13 2007-02-08 12:25:49 dockes Exp $ (C) 2004 J.F.Dockes */ +/* @(#$Id: internfile.h,v 1.14 2007-02-08 17:05:12 dockes Exp $ (C) 2004 J.F.Dockes */ #include #include @@ -91,6 +91,8 @@ class FileInterner { const string& ipath, const string& mtype); const string& getReason() const {return m_reason;} + const list& getMissingExternal(); + void getMissingExternal(string& missing); private: static const unsigned int MAXHANDLERS = 20; @@ -110,12 +112,15 @@ class FileInterner { vector m_tempfiles; // Error data if any string m_reason; + // Missing external programs + list m_missingExternal; void tmpcleanup(); bool dijontorcl(Rcl::Doc&); void collectIpathAndMT(Rcl::Doc&, string& ipath) const; bool dataToTempFile(const string& data, const string& mt, string& fn); void popHandler(); + void maybeExternalMissing(const string& msg); }; diff --git a/src/qtgui/preview_w.cpp b/src/qtgui/preview_w.cpp index 830b958d..e6e86808 100644 --- a/src/qtgui/preview_w.cpp +++ b/src/qtgui/preview_w.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: preview_w.cpp,v 1.15 2007-02-06 18:01:58 dockes Exp $ (C) 2005 J.F.Dockes"; +static char rcsid[] = "@(#$Id: preview_w.cpp,v 1.16 2007-02-08 17:05:12 dockes Exp $ (C) 2005 J.F.Dockes"; #endif /* * This program is free software; you can redistribute it and/or modify @@ -443,7 +443,7 @@ class LoadThread : public QThread { string tmpdir; int loglevel; public: - string reason; + string missing; LoadThread(int *stp, Rcl::Doc *odoc, string fn, string ip, string *mt) : statusp(stp), out(odoc), filename(fn), ipath(ip), mtype(mt) { @@ -457,6 +457,7 @@ class LoadThread : public QThread { } virtual void run() { DebugLog::getdbl()->setloglevel(loglevel); + string reason; if (!maketmpdir(tmpdir, reason)) { QMessageBox::critical(0, "Recoll", Preview::tr("Cannot create temporary directory")); @@ -486,7 +487,7 @@ class LoadThread : public QThread { *statusp = 0; } else { out->mimetype = interner.getMimetype(); - reason = interner.getReason(); + interner.getMissingExternal(missing); *statusp = -1; } } catch (CancelExcept) { @@ -588,19 +589,10 @@ bool Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc, return false; if (status != 0) { QString explain; - if (lthr.reason.find("RECFILTERROR") == 0) { - list lerr; - stringToStrings(lthr.reason, lerr); - if (lerr.size() > 2) { - list::iterator it = lerr.begin(); - it++; - if (*it == "HELPERNOTFOUND") { - it++; - explain = QString::fromAscii("
") + - tr("Missing helper program: ") + - QString::fromLocal8Bit(it->c_str()); - } - } + if (!lthr.missing.empty()) { + explain = QString::fromAscii("
") + + tr("Missing helper program: ") + + QString::fromLocal8Bit(lthr.missing.c_str()); } QMessageBox::warning(0, "Recoll", tr("Can't turn doc into internal " diff --git a/src/utils/smallut.cpp b/src/utils/smallut.cpp index 84b7ecef..2965c88d 100644 --- a/src/utils/smallut.cpp +++ b/src/utils/smallut.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: smallut.cpp,v 1.25 2006-12-19 12:11:21 dockes Exp $ (C) 2004 J.F.Dockes"; +static char rcsid[] = "@(#$Id: smallut.cpp,v 1.26 2007-02-08 17:05:12 dockes Exp $ (C) 2004 J.F.Dockes"; #endif /* * This program is free software; you can redistribute it and/or modify @@ -258,6 +258,31 @@ bool stringToStrings(const string &s, std::list &tokens) return true; } +void stringsToString(const list &tokens, string &s) +{ + for (list::const_iterator it = tokens.begin(); + it != tokens.end(); it++) { + bool hasblanks = false; + if (it->find_first_of(" \t\n") != string::npos) + hasblanks = true; + if (it != tokens.begin()) + s.append(1, ' '); + if (hasblanks) + s.append(1, '"'); + for (unsigned int i = 0; i < it->length(); i++) { + char car = it->at(i); + if (car == '"') { + s.append(1, '\\'); + s.append(1, car); + } else { + s.append(1, car); + } + } + if (hasblanks) + s.append(1, '"'); + } +} + void stringToTokens(const string& str, list& tokens, const string& delims, bool skipinit) { diff --git a/src/utils/smallut.h b/src/utils/smallut.h index 3a405868..dff7d8e1 100644 --- a/src/utils/smallut.h +++ b/src/utils/smallut.h @@ -16,7 +16,7 @@ */ #ifndef _SMALLUT_H_INCLUDED_ #define _SMALLUT_H_INCLUDED_ -/* @(#$Id: smallut.h,v 1.25 2006-12-19 12:11:21 dockes Exp $ (C) 2004 J.F.Dockes */ +/* @(#$Id: smallut.h,v 1.26 2007-02-08 17:05:12 dockes Exp $ (C) 2004 J.F.Dockes */ #include #include #include @@ -45,6 +45,10 @@ extern bool samecharset(const string &cs1, const string &cs2); * dquotes can be escaped with \ etc... */ extern bool stringToStrings(const string &s, list &tokens); +/** + * Inverse operation: + */ +extern void stringsToString(const list &tokens, string &s); /** * Split input string. No handling of quoting