diff --git a/src/common/rclconfig.cpp b/src/common/rclconfig.cpp index 50d59ab7..4859fd65 100644 --- a/src/common/rclconfig.cpp +++ b/src/common/rclconfig.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: rclconfig.cpp,v 1.19 2006-01-19 17:11:46 dockes Exp $ (C) 2004 J.F.Dockes"; +static char rcsid[] = "@(#$Id: rclconfig.cpp,v 1.20 2006-01-20 10:01:59 dockes Exp $ (C) 2004 J.F.Dockes"; #endif #include #include @@ -20,43 +20,9 @@ static char rcsid[] = "@(#$Id: rclconfig.cpp,v 1.19 2006-01-19 17:11:46 dockes E using namespace std; #endif /* NO_NAMESPACES */ -static const char *configfiles[] = {"recoll.conf", "mimemap", "mimeconf"}; -static int ncffiles = sizeof(configfiles) / sizeof(char *); - -static bool createConfig(const string &datadir, string &reason) -{ - // Samples directory - string exdir = path_cat(datadir, "examples"); - // User's - string recolldir = path_tildexpand("~/.recoll"); - if (mkdir(recolldir.c_str(), 0755) < 0) { - reason += string("mkdir(") + recolldir + ") failed: " + - strerror(errno); - return false; - } - for (int i = 0; i < ncffiles; i++) { - string src = path_cat((const string&)exdir, string(configfiles[i])); - string dst = path_cat((const string&)recolldir, string(configfiles[i])); - if (!copyfile(src.c_str(), dst.c_str(), reason)) { - LOGERR(("Copyfile failed: %s\n", reason.c_str())); - return false; - } - } - return true; -} - - RclConfig::RclConfig() - : m_ok(false), m_conf(0), mimemap(0), mimeconf(0), mimemap_local(0), - stopsuffixes(0) { - static int loginit = 0; - if (!loginit) { - DebugLog::setfilename("stderr"); - DebugLog::getdbl()->setloglevel(10); - loginit = 1; - } - + zeroMe(); // Compute our data dir name, typically /usr/local/share/recoll const char *cdatadir = getenv("RECOLL_DATADIR"); if (cdatadir == 0) { @@ -77,7 +43,7 @@ RclConfig::RclConfig() if (access(m_confdir.c_str(), 0) != 0 || access(cfilename.c_str(), 0) != 0) { - if (!createConfig(m_datadir, reason)) + if (!initUserConfig()) return; } @@ -86,7 +52,7 @@ RclConfig::RclConfig() if (m_conf == 0 || (m_conf->getStatus() != ConfSimple::STATUS_RO && m_conf->getStatus() != ConfSimple::STATUS_RW)) { - reason = string("No main configuration file: ") + cfilename + + m_reason = string("No main configuration file: ") + cfilename + " does not exist or cannot be parsed"; return; } @@ -100,7 +66,7 @@ RclConfig::RclConfig() if (mimemap == 0 || (mimemap->getStatus() != ConfSimple::STATUS_RO && mimemap->getStatus() != ConfSimple::STATUS_RW)) { - reason = string("No mime map configuration file: ") + mpath + + m_reason = string("No mime map configuration file: ") + mpath + " does not exist or cannot be parsed"; return; } @@ -115,13 +81,13 @@ RclConfig::RclConfig() if (mimeconf == 0 || (mimeconf->getStatus() != ConfSimple::STATUS_RO && mimeconf->getStatus() != ConfSimple::STATUS_RW)) { - reason = string("No mime configuration file: ") + mpath + + m_reason = string("No mime configuration file: ") + mpath + " does not exist or cannot be parsed"; return; } // mimeconf->list(); - setKeyDir(string("")); + setKeyDir(""); m_ok = true; return; @@ -173,7 +139,7 @@ bool RclConfig::getStopSuffixes(list& sufflist) { if (stopsuffixes == 0 && (stopsuffixes = new list) != 0) { string stp; - if (mimemap->get("recoll_noindex", stp, keydir)) { + if (mimemap && mimemap->get("recoll_noindex", stp, m_keydir)) { stringToStrings(stp, *stopsuffixes); } } @@ -188,7 +154,7 @@ bool RclConfig::getStopSuffixes(list& sufflist) string RclConfig::getMimeTypeFromSuffix(const string &suff) { string mtype; - mimemap->get(suff, mtype, keydir); + mimemap->get(suff, mtype, m_keydir); return mtype; } @@ -281,3 +247,53 @@ bool RclConfig::getUncompressor(const string &mtype, list& cmd) cmd.assign(++it, tokens.end()); return true; } + + +// Create initial user config by copying sample files +static const char *configfiles[] = {"recoll.conf", "mimemap", "mimeconf"}; +static int ncffiles = sizeof(configfiles) / sizeof(char *); +bool RclConfig::initUserConfig() +{ + // Samples directory + string exdir = path_cat(m_datadir, "examples"); + // User's + string recolldir = path_tildexpand("~/.recoll"); + if (mkdir(recolldir.c_str(), 0755) < 0) { + m_reason += string("mkdir(") + recolldir + ") failed: " + + strerror(errno); + return false; + } + for (int i = 0; i < ncffiles; i++) { + string src = path_cat((const string&)exdir, string(configfiles[i])); + string dst = path_cat((const string&)recolldir, string(configfiles[i])); + if (!copyfile(src.c_str(), dst.c_str(), m_reason)) { + LOGERR(("Copyfile failed: %s\n", m_reason.c_str())); + return false; + } + } + return true; +} + +void RclConfig::initFrom(const RclConfig& r) +{ + zeroMe(); + if (!(m_ok = r.m_ok)) + return; + m_reason = r.m_reason; + m_confdir = r.m_confdir; + m_datadir = r.m_datadir; + m_keydir = r.m_datadir; + // We should use reference-counted objects instead! + if (r.m_conf) + m_conf = new ConfTree(*(r.m_conf)); + if (r.mimemap) + mimemap = new ConfTree(*(r.mimemap)); + if (r.mimeconf) + mimeconf = new ConfTree(*(r.mimeconf)); + if (r.mimemap_local) + mimemap_local = new ConfTree(*(r.mimemap_local)); + if (r.stopsuffixes) + stopsuffixes = new std::list(*(r.stopsuffixes)); + defcharset = r.defcharset; + guesscharset = r.guesscharset; +} diff --git a/src/common/rclconfig.h b/src/common/rclconfig.h index 1f5634b8..e5ff0f7b 100644 --- a/src/common/rclconfig.h +++ b/src/common/rclconfig.h @@ -1,6 +1,6 @@ #ifndef _RCLCONFIG_H_INCLUDED_ #define _RCLCONFIG_H_INCLUDED_ -/* @(#$Id: rclconfig.h,v 1.12 2006-01-19 17:11:46 dockes Exp $ (C) 2004 J.F.Dockes */ +/* @(#$Id: rclconfig.h,v 1.13 2006-01-20 10:01:59 dockes Exp $ (C) 2004 J.F.Dockes */ #include @@ -11,76 +11,97 @@ class RclConfig { public: RclConfig(); - ~RclConfig() { - delete m_conf; - delete mimemap; - delete mimeconf; - delete mimemap_local; - delete stopsuffixes; + bool ok() {return m_ok;} + const string &getReason() {return m_reason;} + /** Return the directory where this config is stored */ + string getConfDir() {return m_confdir;} + + /** Set current directory reference, and fetch automatic parameters. */ + void setKeyDir(const string &dir) + { + m_keydir = dir; + m_conf->get("defaultcharset", defcharset, m_keydir); + string str; + m_conf->get("guesscharset", str, m_keydir); + guesscharset = stringToBool(str); } - bool ok() {return m_ok;} - const string &getReason() {return reason;} - string getConfDir() {return m_confdir;} - //ConfTree *getConfig() {return m_ok ? conf : 0;} - - /// Get generic configuration parameter according to current keydir + /** Get generic configuration parameter according to current keydir */ bool getConfParam(const string &name, string &value) { if (m_conf == 0) return false; - return m_conf->get(name, value, keydir); + return m_conf->get(name, value, m_keydir); } - - /* - * Variants with autoconversion - */ + /** Variant with autoconversion to int */ bool getConfParam(const std::string &name, int *value); + /** Variant with autoconversion to bool */ bool getConfParam(const std::string &name, bool *value); + /** Get default charset for current keydir (was set during setKeydir) */ + const string &getDefCharset() {return defcharset;} + /** Get guessCharset for current keydir (was set during setKeydir) */ + bool getGuessCharset() {return guesscharset;} - /// Set current directory reference, and fetch automatic parameters. - void setKeyDir(const string &dir) - { - keydir = dir; - m_conf->get("defaultcharset", defcharset, keydir); - string str; - m_conf->get("guesscharset", str, keydir); - guesscharset = stringToBool(str); - } /** - * Check if input mime type is a compressed one, and return command to - * uncompress if it is + * Get list of ignored suffixes from mimemap + * + * The list is initialized on first call, and not changed for subsequent + * setKeydirs. + */ + bool getStopSuffixes(std::list& sufflist); + + /** + * Check in mimeconf if input mime type is a compressed one, and + * return command to uncompress if it is. + * * The returned command has substitutable places for input file name * and temp dir name, and will return output name */ bool getUncompressor(const std::string &mtpe, std::list& cmd); - bool getStopSuffixes(std::list& sufflist); + + /** Use mimemap to compute mimetype */ std::string getMimeTypeFromSuffix(const std::string &suffix); - std::string getMimeHandlerDef(const std::string &mtype); - /** - * Return external viewer exec string for given mime type - */ - std::string getMimeViewerDef(const std::string &mtype); - /** - * Return icon name for mime type - */ + + /** Get input filter from mimeconf for mimetype */ + std::string getMimeHandlerDef(const std::string &mimetype); + + /** Get external viewer exec string from mimeconf for mimetype */ + std::string getMimeViewerDef(const std::string &mimetype); + + /** Get icon name from mimeconf for mimetype */ string getMimeIconName(const string &mtype); - const string &getDefCharset() {return defcharset;} - bool getGuessCharset() {return guesscharset;} + /** Get a list of all indexable mime types defined in mimemap */ std::list getAllMimeTypes(); + /** Find exec file for external filter. cmd is the command name from the + * command string returned by getMimeHandlerDef */ std::string findFilter(const std::string& cmd); + ~RclConfig() { + freeAll(); + } + + RclConfig(const RclConfig &r) { + initFrom(r); + } + RclConfig& operator=(const RclConfig &r) { + if (this != &r) { + freeAll(); + initFrom(r); + } + return *this; + } + private: int m_ok; - string reason; // Explanation for bad state + string m_reason; // Explanation for bad state string m_confdir; // Directory where the files are stored string m_datadir; // Example: /usr/local/share/recoll + string m_keydir; // Current directory used for parameter fetches. + ConfTree *m_conf; // Parsed main configuration - string keydir; // Current directory used for parameter fetches. - ConfTree *mimemap; // These are independant of current keydir. ConfTree *mimeconf; ConfTree *mimemap_local; // @@ -89,6 +110,31 @@ class RclConfig { // Parameters auto-fetched on setkeydir string defcharset; // These are stored locally to avoid bool guesscharset; // They are fetched initially or on setKeydir() + + /** Create initial user configuration */ + bool initUserConfig(); + + /** Copy from other */ + void initFrom(const RclConfig& r); + /** Init pointers to 0 */ + void zeroMe() { + m_ok = false; + m_conf = 0; + mimemap = 0; + mimeconf = 0; + mimemap_local = 0; + stopsuffixes = 0; + } + /** Free data then zero pointers */ + void freeAll() { + delete m_conf; + delete mimemap; + delete mimeconf; + delete mimemap_local; + delete stopsuffixes; + // just in case + zeroMe(); + } }; diff --git a/src/kde/kioslave/recoll/00README.txt b/src/kde/kioslave/recoll/00README.txt index 169fe86c..ab8794a3 100644 --- a/src/kde/kioslave/recoll/00README.txt +++ b/src/kde/kioslave/recoll/00README.txt @@ -32,3 +32,6 @@ Implementation notes: - If you want to try, compile, then install kio_recoll.la kio_recoll.so wherever kde keeps its plugins (ie: lib/kde3), and recoll.protocol in the services directory (share/services ? look for other .protocol file). + +- I saw after doing the build/config mockup that kdevelop can generate a kio_slave project. This would certainly be the next thing to do. + diff --git a/src/mk/commondefs b/src/mk/commondefs index 7f97c0a2..c34dc5c3 100644 --- a/src/mk/commondefs +++ b/src/mk/commondefs @@ -1,7 +1,7 @@ -# Definitions mostly common to all systems, can be overridden by -# sys-specific include -COMMONCXXFLAGS = -Wall -Wno-unused -I. -I$(depth)/index \ +# Common/default for all systems, can be overridden by sys-specific include + +COMMONCXXFLAGS = -I. -I$(depth)/index \ -I$(depth)/utils -I$(depth)/common \ -I$(depth)/unac -I$(depth)/bincimapmime \ -I/usr/local/include diff --git a/src/mk/localdefs.in b/src/mk/localdefs.in index ec8133b9..aa9aa925 100644 --- a/src/mk/localdefs.in +++ b/src/mk/localdefs.in @@ -12,4 +12,4 @@ RECOLL_DATADIR = ${datadir}/recoll LOCALCXXFLAGS = $(INCICONV) $(XAPIANCXXFLAGS) \ -DRECOLL_DATADIR=\"$(RECOLL_DATADIR)\" -CXXFLAGS = -g +CXXFLAGS = -g -Wall -Wno-unused diff --git a/src/qtgui/idxthread.cpp b/src/qtgui/idxthread.cpp index 116ecd25..debfe561 100644 --- a/src/qtgui/idxthread.cpp +++ b/src/qtgui/idxthread.cpp @@ -41,9 +41,12 @@ void IdxThread::run() static IdxThread idxthread; -void start_idxthread(RclConfig *cnf) +void start_idxthread(const RclConfig& cnf) { - ConfIndexer *ix = new ConfIndexer(cnf); + // We have to make a copy of the config (setKeydir changes it during + // indexation) + RclConfig *myconf = new RclConfig(cnf); + ConfIndexer *ix = new ConfIndexer(myconf); idxthread.indexer = ix; idxthread.start(); } @@ -53,5 +56,3 @@ void stop_idxthread() stopidxthread = 1; idxthread.wait(); } - - diff --git a/src/qtgui/idxthread.h b/src/qtgui/idxthread.h index 1ccb3d91..285b8808 100644 --- a/src/qtgui/idxthread.h +++ b/src/qtgui/idxthread.h @@ -1,12 +1,12 @@ #ifndef _IDXTHREAD_H_INCLUDED_ #define _IDXTHREAD_H_INCLUDED_ -/* @(#$Id: idxthread.h,v 1.1 2005-02-01 17:20:05 dockes Exp $ (C) 2004 J.F.Dockes */ +/* @(#$Id: idxthread.h,v 1.2 2006-01-20 10:01:59 dockes Exp $ (C) 2004 J.F.Dockes */ class RclConfig; // These two deal with starting / stopping the thread itself, not indexing // sessions. -extern void start_idxthread(RclConfig *cnf); +extern void start_idxthread(const RclConfig& cnf); extern void stop_idxthread(); extern int startindexing; diff --git a/src/qtgui/main.cpp b/src/qtgui/main.cpp index 576b4937..ec91eddc 100644 --- a/src/qtgui/main.cpp +++ b/src/qtgui/main.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: main.cpp,v 1.29 2006-01-19 17:11:46 dockes Exp $ (C) 2005 J.F.Dockes"; +static char rcsid[] = "@(#$Id: main.cpp,v 1.30 2006-01-20 10:01:59 dockes Exp $ (C) 2005 J.F.Dockes"; #endif #include @@ -149,9 +149,9 @@ int main( int argc, char ** argv ) // Create main window and set its size to previous session's RecollMain w; mainWindow = &w; - QSize s(prefs_mainwidth, prefs_mainheight); w.resize(s); + w.allTermsCB->setChecked(prefs_ssall); string reason; rclconfig = recollinit(recollCleanup, sigcleanup, reason); @@ -198,7 +198,7 @@ int main( int argc, char ** argv ) w.connect(timer, SIGNAL(timeout()), &w, SLOT(periodic100())); timer->start(100); - if (!rcldb || !rcldb->open(dbdir, Rcl::Db::DbRO)) { + if (!rcldb->open(dbdir, Rcl::Db::DbRO)) { startindexing = 1; switch (QMessageBox:: question(0, "Recoll", @@ -216,7 +216,7 @@ int main( int argc, char ** argv ) } } - start_idxthread(rclconfig); + start_idxthread(*rclconfig); // Let's go w.show(); diff --git a/src/utils/conftree.h b/src/utils/conftree.h index dd12e115..cd4a3c2d 100755 --- a/src/utils/conftree.h +++ b/src/utils/conftree.h @@ -108,13 +108,43 @@ class ConfSimple { virtual std::string getFilename() {return filename;} + /** + * Copy constructor. Expensive but less so than a full rebuild + */ + ConfSimple(const ConfSimple &rhs) : data(0) { + if ((status = rhs.status) == STATUS_ERROR) + return; + filename = rhs.filename; + if (rhs.data) { + data = new string(*(rhs.data)); + } + submaps = rhs.submaps; + } + + /** + * Assignement. This is expensive + */ + ConfSimple& operator=(const ConfSimple &rhs) { + if (this != &rhs && (status = rhs.status) != STATUS_ERROR) { + delete data; + data = 0; + filename = rhs.filename; + if (rhs.data) { + data = new string(*(rhs.data)); + } + submaps = rhs.submaps; + } + return *this; + } + protected: bool dotildexpand; private: + StatusCode status; string filename; // set if we're working with a file string *data; // set if we're working with an in-memory string map > submaps; - StatusCode status; + void parseinput(std::istream &input); }; @@ -141,9 +171,14 @@ class ConfTree : public ConfSimple { /** * Build the object by reading content from file. */ - ConfTree(const char *fname, int readonly = 0) + ConfTree(const char *fname, int readonly = 0) : ConfSimple(fname, readonly, true) {} virtual ~ConfTree() {}; + ConfTree(const ConfTree& r) : ConfSimple(r) {}; + ConfTree& operator=(const ConfTree& r) { + ConfSimple::operator=(r); + return *this; + } /** * Get value for named parameter, from specified subsection, or its diff --git a/src/utils/debuglog.h b/src/utils/debuglog.h index 0eac11be..93b72b7c 100755 --- a/src/utils/debuglog.h +++ b/src/utils/debuglog.h @@ -33,7 +33,7 @@ class DebugLog { int dodate; DebugLogWriter *writer; public: - DebugLog() : debuglevel(-1), dodate(0), writer(0) {} + DebugLog() : debuglevel(10), dodate(0), writer(0) {} DebugLog(DebugLogWriter *w) : debuglevel(-1), dodate(0), writer(w) {} virtual ~DebugLog() {} virtual void setwriter(DebugLogWriter *w) {writer = w;}