diff --git a/src/common/rclconfig.cpp b/src/common/rclconfig.cpp index 54924f57..f4cfe133 100644 --- a/src/common/rclconfig.cpp +++ b/src/common/rclconfig.cpp @@ -98,7 +98,7 @@ void RclConfig::zeroMe() { m_rmtstate.init(this, 0, "indexedmimetypes"); } -bool RclConfig::isDefaultConfig() +bool RclConfig::isDefaultConfig() const { string defaultconf = path_cat(path_canon(path_home()), ".recoll/"); string specifiedconf = path_canon(m_confdir); @@ -106,6 +106,8 @@ bool RclConfig::isDefaultConfig() return !defaultconf.compare(specifiedconf); } +string RclConfig::o_localecharset; + RclConfig::RclConfig(const string *argcnf) { zeroMe(); @@ -157,6 +159,34 @@ RclConfig::RclConfig(const string *argcnf) return; } + // This can't change once computed inside a process. It would be + // nicer to move this to a static class initializer to avoid + // possible threading issues but this doesn't work (tried) as + // things would not be ready. In practise we make sure that this + // is called from the main thread at once, by constructing a config + // from recollinit + if (o_localecharset.empty()) { + const char *cp; + cp = nl_langinfo(CODESET); + // We don't keep US-ASCII. It's better to use a superset + // Ie: me have a C locale and some french file names, and I + // can't imagine a version of iconv that couldn't translate + // from iso8859? + // The 646 thing is for solaris. + if (cp && *cp && strcmp(cp, "US-ASCII") +#ifdef sun + && strcmp(cp, "646") +#endif + ) { + o_localecharset = string(cp); + } else { + // Use cp1252 instead of iso-8859-1, it's a superset. + o_localecharset = string(cstr_cp1252); + } + LOGDEB1(("RclConfig::getDefCharset: localecharset [%s]\n", + o_localecharset.c_str())); + } + m_cdirs.push_back(m_confdir); m_cdirs.push_back(path_cat(m_datadir, "examples")); string cnferrloc = m_confdir + " or " + path_cat(m_datadir, "examples"); @@ -272,11 +302,11 @@ void RclConfig::setKeyDir(const string &dir) if (m_conf == 0) return; - if (!m_conf->get("defaultcharset", defcharset, m_keydir)) - defcharset.erase(); + if (!m_conf->get("defaultcharset", m_defcharset, m_keydir)) + m_defcharset.erase(); } -bool RclConfig::getConfParam(const string &name, int *ivp) +bool RclConfig::getConfParam(const string &name, int *ivp) const { string value; if (!getConfParam(name, value)) @@ -290,7 +320,7 @@ bool RclConfig::getConfParam(const string &name, int *ivp) return true; } -bool RclConfig::getConfParam(const string &name, bool *bvp) +bool RclConfig::getConfParam(const string &name, bool *bvp) const { if (!bvp) return false; @@ -303,7 +333,7 @@ bool RclConfig::getConfParam(const string &name, bool *bvp) return true; } -bool RclConfig::getConfParam(const string &name, vector *svvp) +bool RclConfig::getConfParam(const string &name, vector *svvp) const { if (!svvp) return false; @@ -313,7 +343,7 @@ bool RclConfig::getConfParam(const string &name, vector *svvp) return false; return stringToStrings(s, *svvp); } -bool RclConfig::getConfParam(const string &name, list *svvp) +bool RclConfig::getConfParam(const string &name, list *svvp) const { if (!svvp) return false; @@ -324,7 +354,7 @@ bool RclConfig::getConfParam(const string &name, list *svvp) return stringToStrings(s, *svvp); } -list RclConfig::getTopdirs() +list RclConfig::getTopdirs() const { list tdl; if (!getConfParam("topdirs", &tdl)) { @@ -348,49 +378,16 @@ list RclConfig::getTopdirs() // // For filenames, same thing except that we do not use the config file value // (only the locale). -const string& RclConfig::getDefCharset(bool filename) +const string& RclConfig::getDefCharset(bool filename) const { - // This can't change once computed inside a process. It would be - // nicer to move this to a static class initializer to avoid - // possible threading issues but this doesn't work (tried) as - // things would not be ready. In practise we make sure that this - // is called from the main thread at once, by calling - // getDefCharset from recollinit - static string localecharset; - if (localecharset.empty()) { - const char *cp; - cp = nl_langinfo(CODESET); - // We don't keep US-ASCII. It's better to use a superset - // Ie: me have a C locale and some french file names, and I - // can't imagine a version of iconv that couldn't translate - // from iso8859? - // The 646 thing is for solaris. - if (cp && *cp && strcmp(cp, "US-ASCII") -#ifdef sun - && strcmp(cp, "646") -#endif - ) { - localecharset = string(cp); - } else { - // Use cp1252 instead of iso-8859-1, it's a superset. - localecharset = string(cstr_cp1252); - } - LOGDEB1(("RclConfig::getDefCharset: localecharset [%s]\n", - localecharset.c_str())); - } - - if (defcharset.empty()) { - defcharset = localecharset; - } - if (filename) { - return localecharset; + return o_localecharset; } else { - return defcharset; + return m_defcharset.empty() ? o_localecharset : m_defcharset; } } -bool RclConfig::addLocalFields(map *tgt) +bool RclConfig::addLocalFields(map *tgt) const { LOGDEB0(("RclConfig::addLocalFields: keydir [%s]\n", m_keydir.c_str())); string sfields; @@ -421,7 +418,7 @@ bool RclConfig::addLocalFields(map *tgt) // // This unfortunately means that searches by file names and mime type // filtering don't work well together. -vector RclConfig::getAllMimeTypes() +vector RclConfig::getAllMimeTypes() const { vector lst; if (mimeconf == 0) @@ -506,14 +503,14 @@ bool RclConfig::inStopSuffixes(const string& fni) } } -string RclConfig::getMimeTypeFromSuffix(const string& suff) +string RclConfig::getMimeTypeFromSuffix(const string& suff) const { string mtype; mimemap->get(suff, mtype, m_keydir); return mtype; } -string RclConfig::getSuffixFromMimeType(const string &mt) +string RclConfig::getSuffixFromMimeType(const string &mt) const { string suffix; vectorsfs = mimemap->getNames(cstr_null); @@ -528,7 +525,7 @@ string RclConfig::getSuffixFromMimeType(const string &mt) } /** Get list of file categories from mimeconf */ -bool RclConfig::getMimeCategories(vector& cats) +bool RclConfig::getMimeCategories(vector& cats) const { if (!mimeconf) return false; @@ -536,7 +533,7 @@ bool RclConfig::getMimeCategories(vector& cats) return true; } -bool RclConfig::isMimeCategory(string& cat) +bool RclConfig::isMimeCategory(string& cat) const { vectorcats; getMimeCategories(cats); @@ -548,7 +545,7 @@ bool RclConfig::isMimeCategory(string& cat) } /** Get list of mime types for category from mimeconf */ -bool RclConfig::getMimeCatTypes(const string& cat, vector& tps) +bool RclConfig::getMimeCatTypes(const string& cat, vector& tps) const { tps.clear(); if (!mimeconf) @@ -581,7 +578,7 @@ string RclConfig::getMimeHandlerDef(const string &mtype, bool filtertypes) return hs; } -bool RclConfig::getGuiFilterNames(vector& cats) +bool RclConfig::getGuiFilterNames(vector& cats) const { if (!mimeconf) return false; @@ -589,7 +586,7 @@ bool RclConfig::getGuiFilterNames(vector& cats) return true; } -bool RclConfig::getGuiFilter(const string& catfiltername, string& frag) +bool RclConfig::getGuiFilter(const string& catfiltername, string& frag) const { frag.clear(); if (!mimeconf) @@ -623,7 +620,7 @@ bool RclConfig::valueSplitAttributes(const string& whole, string& value, } -string RclConfig::getMissingHelperDesc() +string RclConfig::getMissingHelperDesc() const { string fmiss = path_cat(getConfDir(), "missing"); string out; @@ -735,6 +732,7 @@ bool RclConfig::readFieldsConfig(const string& cnferrloc) // Return specifics for field name: bool RclConfig::getFieldTraits(const string& _fld, const FieldTraits **ftpp) + const { string fld = fieldCanon(_fld); map::const_iterator pit = m_fldtotraits.find(fld); @@ -751,7 +749,7 @@ bool RclConfig::getFieldTraits(const string& _fld, const FieldTraits **ftpp) } } -set RclConfig::getIndexedFields() +set RclConfig::getIndexedFields() const { set flds; if (m_fields == 0) @@ -762,7 +760,7 @@ set RclConfig::getIndexedFields() return flds; } -string RclConfig::fieldCanon(const string& f) +string RclConfig::fieldCanon(const string& f) const { string fld = stringtolower(f); map::const_iterator it = m_aliastocanon.find(fld); @@ -776,6 +774,7 @@ string RclConfig::fieldCanon(const string& f) } vector RclConfig::getFieldSectNames(const string &sk, const char* patrn) + const { if (m_fields == 0) return vector(); @@ -783,14 +782,14 @@ vector RclConfig::getFieldSectNames(const string &sk, const char* patrn) } bool RclConfig::getFieldConfParam(const string &name, const string &sk, - string &value) + string &value) const { if (m_fields == 0) return false; return m_fields->get(name, value, sk); } -string RclConfig::getMimeViewerAllEx() +string RclConfig::getMimeViewerAllEx() const { string hs; if (mimeview == 0) @@ -807,12 +806,12 @@ bool RclConfig::setMimeViewerAllEx(const string& allex) m_reason = string("RclConfig:: cant set value. Readonly?"); return false; } - + return true; } string RclConfig::getMimeViewerDef(const string &mtype, const string& apptag, - bool useall) + bool useall) const { LOGDEB2(("RclConfig::getMimeViewerDef: mtype [%s] apptag [%s]\n", mtype.c_str(), apptag.c_str())); @@ -851,7 +850,7 @@ string RclConfig::getMimeViewerDef(const string &mtype, const string& apptag, return hs; } -bool RclConfig::getMimeViewerDefs(vector >& defs) +bool RclConfig::getMimeViewerDefs(vector >& defs) const { if (mimeview == 0) return false; @@ -874,7 +873,7 @@ bool RclConfig::setMimeViewerDef(const string& mt, const string& def) return true; } -bool RclConfig::mimeViewerNeedsUncomp(const string &mimetype) +bool RclConfig::mimeViewerNeedsUncomp(const string &mimetype) const { string s; vector v; @@ -886,6 +885,7 @@ bool RclConfig::mimeViewerNeedsUncomp(const string &mimetype) } string RclConfig::getMimeIconPath(const string &mtype, const string &apptag) + const { string iconname; if (!apptag.empty()) @@ -911,7 +911,7 @@ string RclConfig::getMimeIconPath(const string &mtype, const string &apptag) return path_cat(iconpath, iconname) + ".png"; } -string RclConfig::getDbDir() +string RclConfig::getDbDir() const { string dbdir; if (!getConfParam("dbdir", dbdir)) { @@ -928,7 +928,7 @@ string RclConfig::getDbDir() return path_canon(dbdir); } -bool RclConfig::sourceChanged() +bool RclConfig::sourceChanged() const { if (m_conf && m_conf->sourceChanged()) return true; @@ -943,18 +943,18 @@ bool RclConfig::sourceChanged() return false; } -string RclConfig::getStopfile() +string RclConfig::getStopfile() const { return path_cat(getConfDir(), "stoplist.txt"); } -string RclConfig::getPidfile() +string RclConfig::getPidfile() const { return path_cat(getConfDir(), "index.pid"); } // The index status file is fast changing, so it's possible to put it outside // of the config directory (for ssds, not sure this is really useful). -string RclConfig::getIdxStatusFile() +string RclConfig::getIdxStatusFile() const { string path; if (!getConfParam("idxstatusfile", path)) { @@ -977,7 +977,7 @@ vector& RclConfig::getSkippedNames() return m_skpnlist; } -vector RclConfig::getSkippedPaths() +vector RclConfig::getSkippedPaths() const { vector skpl; getConfParam("skippedPaths", &skpl); @@ -997,7 +997,7 @@ vector RclConfig::getSkippedPaths() return skpl; } -vector RclConfig::getDaemSkippedPaths() +vector RclConfig::getDaemSkippedPaths() const { vector dskpl; getConfParam("daemSkippedPaths", &dskpl); @@ -1024,7 +1024,7 @@ vector RclConfig::getDaemSkippedPaths() // Look up an executable filter. We look in $RECOLL_FILTERSDIR, // filtersdir in config file, then let the system use the PATH -string RclConfig::findFilter(const string &icmd) +string RclConfig::findFilter(const string &icmd) const { // If the path is absolute, this is it if (icmd[0] == '/') @@ -1066,7 +1066,7 @@ string RclConfig::findFilter(const string &icmd) /** * Return decompression command line for given mime type */ -bool RclConfig::getUncompressor(const string &mtype, vector& cmd) +bool RclConfig::getUncompressor(const string &mtype, vector& cmd) const { string hs; @@ -1177,7 +1177,7 @@ void RclConfig::initFrom(const RclConfig& r) if (r.m_stopsuffixes) m_stopsuffixes = new SuffixStore(*((SuffixStore*)r.m_stopsuffixes)); m_maxsufflen = r.m_maxsufflen; - defcharset = r.defcharset; + m_defcharset = r.m_defcharset; m_stpsuffstate.init(this, mimemap, r.m_stpsuffstate.paramname); m_skpnstate.init(this, m_conf, r.m_skpnstate.paramname); diff --git a/src/common/rclconfig.h b/src/common/rclconfig.h index be84dbac..fdb1ac84 100644 --- a/src/common/rclconfig.h +++ b/src/common/rclconfig.h @@ -80,53 +80,54 @@ class RclConfig { /** (re)Read recoll.conf */ bool updateMainConfig(); - bool ok() {return m_ok;} - const string &getReason() {return m_reason;} + bool ok() const {return m_ok;} + const string &getReason() const {return m_reason;} /** Return the directory where this configuration is stored. * This was possibly silently created by the rclconfig * constructor it it is the default one (~/.recoll) and it did * not exist yet. */ - string getConfDir() {return m_confdir;} + string getConfDir() const {return m_confdir;} /** Check if the config files were modified since we read them */ - bool sourceChanged(); + bool sourceChanged() const; /** Returns true if this is ~/.recoll */ - bool isDefaultConfig(); + bool isDefaultConfig() const; /** Get the local value for /usr/local/share/recoll/ */ - const string& getDatadir() {return m_datadir;} + const string& getDatadir() const {return m_datadir;} /** Set current directory reference, and fetch automatic parameters. */ void setKeyDir(const string &dir); string getKeyDir() const {return m_keydir;} /** Get generic configuration parameter according to current keydir */ - bool getConfParam(const string &name, string &value) + bool getConfParam(const string &name, string &value) const { if (m_conf == 0) return false; return m_conf->get(name, value, m_keydir); } /** Variant with autoconversion to int */ - bool getConfParam(const string &name, int *value); + bool getConfParam(const string &name, int *value) const; /** Variant with autoconversion to bool */ - bool getConfParam(const string &name, bool *value); + bool getConfParam(const string &name, bool *value) const; /** Variant with conversion to string list/vector * (stringToStrings). Can fail if the string is malformed. */ - bool getConfParam(const string &name, vector *value); - bool getConfParam(const string &name, list *value); + bool getConfParam(const string &name, vector *value) const; + bool getConfParam(const string &name, list *value) const; /** * Get list of config names under current sk, with possible * wildcard filtering */ - vector getConfNames(const char *pattern = 0) { + vector getConfNames(const char *pattern = 0) const + { return m_conf->getNames(m_keydir, pattern); } /** Check if name exists anywhere in config */ - bool hasNameAnywhere(const string& nm) + bool hasNameAnywhere(const string& nm) const { return m_conf? m_conf->hasNameAnywhere(nm) : false; } @@ -134,33 +135,33 @@ class RclConfig { /** Get default charset for current keydir (was set during setKeydir) * filenames are handled differently */ - const string &getDefCharset(bool filename = false); + const string &getDefCharset(bool filename = false) const; /** Get list of top directories. This is needed from a number of places * and needs some cleaning-up code. An empty list is always an error, no * need for other status */ - list getTopdirs(); + list getTopdirs() const; /** Get database directory */ - string getDbDir(); + string getDbDir() const; /** Get stoplist file name */ - string getStopfile(); + string getStopfile() const; /** Get indexing pid file name */ - string getPidfile(); + string getPidfile() const; /** Get indexing status file name */ - string getIdxStatusFile(); + string getIdxStatusFile() const; /** Get list of skipped file names for current keydir */ vector& getSkippedNames(); /** Get list of skipped paths patterns. Doesn't depend on the keydir */ - vector getSkippedPaths(); + vector getSkippedPaths() const; /** Get list of skipped paths patterns, daemon version (may add some) Doesn't depend on the keydir */ - vector getDaemSkippedPaths(); + vector getDaemSkippedPaths() const; /** conf: Add local fields to target dic */ - bool addLocalFields(map *tgt); + bool addLocalFields(map *tgt) const; /** * mimemap: Check if file name should be ignored because of suffix @@ -177,14 +178,14 @@ class RclConfig { * The returned command has substitutable places for input file name * and temp dir name, and will return output name */ - bool getUncompressor(const string &mtpe, vector& cmd); + bool getUncompressor(const string &mtpe, vector& cmd) const; /** mimemap: compute mimetype */ - string getMimeTypeFromSuffix(const string &suffix); + string getMimeTypeFromSuffix(const string &suffix) const; /** mimemap: get a list of all indexable mime types defined */ - vector getAllMimeTypes(); + vector getAllMimeTypes() const; /** mimemap: Get appropriate suffix for mime type. This is inefficient */ - string getSuffixFromMimeType(const string &mt); + string getSuffixFromMimeType(const string &mt) const; /** mimeconf: get input filter for mimetype */ string getMimeHandlerDef(const string &mimetype, bool filtertypes=false); @@ -193,57 +194,58 @@ class RclConfig { * Separate the value and store the attributes in a ConfSimple * @param whole the raw value. No way to escape a semi-colon in there. */ - bool valueSplitAttributes(const string& whole, string& value, - ConfSimple& attrs); + static bool valueSplitAttributes(const string& whole, string& value, + ConfSimple& attrs) ; /** Return icon path for mime type and tag */ - string getMimeIconPath(const string &mt, const string& apptag); + string getMimeIconPath(const string &mt, const string& apptag) const; /** mimeconf: get list of file categories */ - bool getMimeCategories(vector&); + bool getMimeCategories(vector&) const; /** mimeconf: is parameter one of the categories ? */ - bool isMimeCategory(string&); + bool isMimeCategory(string&) const; /** mimeconf: get list of mime types for category */ - bool getMimeCatTypes(const string& cat, vector&); + bool getMimeCatTypes(const string& cat, vector&) const; /** mimeconf: get list of gui filters (doc cats by default */ - bool getGuiFilterNames(vector&); + bool getGuiFilterNames(vector&) const; /** mimeconf: get query lang frag for named filter */ - bool getGuiFilter(const string& filtername, string& frag); + bool getGuiFilter(const string& filtername, string& frag) const; /** fields: get field prefix from field name */ - bool getFieldTraits(const string& fldname, const FieldTraits **); - const set& getStoredFields() {return m_storedFields;} - set getIndexedFields(); + bool getFieldTraits(const string& fldname, const FieldTraits **) const; + const set& getStoredFields() const {return m_storedFields;} + set getIndexedFields() const; /** Get canonic name for possible alias */ - string fieldCanon(const string& fld); + string fieldCanon(const string& fld) const; /** Get xattr name to field names translations */ - const map& getXattrToField() {return m_xattrtofld;} + const map& getXattrToField() const {return m_xattrtofld;} /** Get value of a parameter inside the "fields" file. Only some filters use this (ie: mh_mail). The information specific to a given filter is typically stored in a separate section(ie: [mail]) */ - vector getFieldSectNames(const string &sk, const char* = 0); - bool getFieldConfParam(const string &name, const string &sk, string &value); + vector getFieldSectNames(const string &sk, const char* = 0) const; + bool getFieldConfParam(const string &name, const string &sk, string &value) + const; /** mimeview: get/set external viewer exec string(s) for mimetype(s) */ string getMimeViewerDef(const string &mimetype, const string& apptag, - bool useall); - string getMimeViewerAllEx(); + bool useall) const; + string getMimeViewerAllEx() const; bool setMimeViewerAllEx(const string& allex); - bool getMimeViewerDefs(vector >&); + bool getMimeViewerDefs(vector >&) const; bool setMimeViewerDef(const string& mimetype, const string& cmd); /** Check if mime type is designated as needing no uncompress before view * (if a file of this type is found compressed). Default is true, * exceptions are found in the nouncompforviewmts mimeview list */ - bool mimeViewerNeedsUncomp(const string &mimetype); + bool mimeViewerNeedsUncomp(const string &mimetype) const; /** Store/retrieve missing helpers description string */ - string getMissingHelperDesc(); + string getMissingHelperDesc() const; void storeMissingHelperDesc(const string &s); /** Find exec file for external filter. cmd is the command name from the * command string returned by getMimeHandlerDef */ - string findFilter(const string& cmd); + string findFilter(const string& cmd) const; ~RclConfig() { freeAll(); @@ -290,7 +292,8 @@ class RclConfig { vector m_skpnlist; // Parameters auto-fetched on setkeydir - string defcharset; + string m_defcharset; + static string o_localecharset; // Limiting set of mime types to be processed. Normally empty. ParamStale m_rmtstate; set m_restrictMTypes;