Make it possible to add/remove values from skippedNames, noContentSuffixes and xallexcepts by using +- suffixed var names

This commit is contained in:
Jean-Francois Dockes 2017-02-22 17:03:08 +01:00
parent fff59f7814
commit b328215c9a
3 changed files with 266 additions and 151 deletions

View File

@ -65,55 +65,93 @@ bool o_uptodate_test_use_mtime = false;
string RclConfig::o_localecharset; string RclConfig::o_localecharset;
string RclConfig::o_origcwd; string RclConfig::o_origcwd;
bool ParamStale::needrecompute() // Compute the difference of 1st to 2nd set<string> and return as
// plus/minus strings
static void setPlusMinus(const set<string>& base, const set<string>& upd,
string& plus, string& minus)
{ {
LOGDEB2("ParamStale:: needrecompute. parent gen " << (parent->m_keydirgen) << " mine " << (savedkeydirgen) << "\n" ); vector<string> diff;
if (active && parent->m_keydirgen != savedkeydirgen) { auto it =
LOGDEB2("ParamState:: needrecompute. conffile " << (conffile) << "\n" ); set_difference(base.begin(), base.end(), upd.begin(), upd.end(),
std::inserter(diff, diff.begin()));
minus = stringsToString(diff);
savedkeydirgen = parent->m_keydirgen; diff.clear();
string newvalue; it = set_difference(upd.begin(), upd.end(), base.begin(), base.end(),
if (!conffile) std::inserter(diff, diff.begin()));
return false; plus = stringsToString(diff);
conffile->get(paramname, newvalue, parent->m_keydir); }
if (newvalue.compare(savedvalue)) {
savedvalue = newvalue; static void computeBasePlusMinus(set<string>& res, const string& strbase,
LOGDEB2("ParamState:: needrecompute. return true newvalue [" << (newvalue) << "]\n" ); const string& strplus, const string& strminus)
return true; {
set<string> plus, minus;
stringToStrings(strbase, res);
stringToStrings(strplus, plus);
stringToStrings(strminus, minus);
for (auto& it : minus) {
auto it1 = res.find(it);
if (it1 != res.end()) {
res.erase(it1);
} }
} }
return false; for (auto& it : plus) {
res.insert(it);
}
}
bool ParamStale::needrecompute()
{
LOGDEB1("ParamStale:: needrecompute. parent gen " << parent->m_keydirgen <<
" mine " << savedkeydirgen << "\n");
if (!conffile) {
LOGDEB("ParamStale::needrecompute: conffile not set\n");
return false;
}
bool needrecomp = false;
if (active && parent->m_keydirgen != savedkeydirgen) {
savedkeydirgen = parent->m_keydirgen;
for (unsigned int i = 0; i < paramnames.size(); i++) {
string newvalue;
conffile->get(paramnames[i], newvalue, parent->m_keydir);
LOGDEB1("ParamStale::needrecompute: " << paramnames[i] << " -> " <<
newvalue << " keydir " << parent->m_keydir << endl);
if (newvalue.compare(savedvalues[i])) {
savedvalues[i] = newvalue;
needrecomp = true;
}
}
}
return needrecomp;
}
const string& ParamStale::getvalue(unsigned int i) const
{
if (i < savedvalues.size()) {
return savedvalues[i];
} else {
static string nll;
return nll;
}
} }
void ParamStale::init(ConfNull *cnf) void ParamStale::init(ConfNull *cnf)
{ {
conffile = cnf; conffile = cnf;
active = false; active = false;
if (conffile) if (conffile) {
active = conffile->hasNameAnywhere(paramname); for (auto& nm : paramnames) {
if (conffile->hasNameAnywhere(nm)) {
active = true;
break;
}
}
}
savedkeydirgen = -1; savedkeydirgen = -1;
} }
ParamStale::ParamStale(RclConfig *rconf, const string& nm)
: parent(rconf), conffile(0), paramname(nm),
active(false), savedkeydirgen(-1)
{
}
void RclConfig::zeroMe() {
m_ok = false;
m_keydirgen = 0;
m_conf = 0;
mimemap = 0;
mimeconf = 0;
mimeview = 0;
m_fields = 0;
m_ptrans = 0;
m_stopsuffixes = 0;
m_maxsufflen = 0;
initParamStale(0, 0);
}
bool RclConfig::isDefaultConfig() const bool RclConfig::isDefaultConfig() const
{ {
string defaultconf = path_cat(path_homedata(), string defaultconf = path_cat(path_homedata(),
@ -124,10 +162,24 @@ bool RclConfig::isDefaultConfig() const
return !defaultconf.compare(specifiedconf); return !defaultconf.compare(specifiedconf);
} }
RclConfig::RclConfig(const RclConfig &r)
: m_oldstpsuffstate(this, "recoll_noindex"),
m_stpsuffstate(this, {"noContentSuffixes", "noContentSuffixes+",
"noContentSuffixes-"}),
m_skpnstate(this, {"skippedNames", "skippedNames+", "skippedNames-"}),
m_rmtstate(this, "indexedmimetypes"),
m_xmtstate(this, "excludedmimetypes"),
m_mdrstate(this, "metadatacmds")
{
initFrom(r);
}
RclConfig::RclConfig(const string *argcnf) RclConfig::RclConfig(const string *argcnf)
: m_oldstpsuffstate(this, "recoll_noindex"), : m_oldstpsuffstate(this, "recoll_noindex"),
m_stpsuffstate(this, "noContentSuffixes"), m_stpsuffstate(this, {"noContentSuffixes", "noContentSuffixes+",
m_skpnstate(this, "skippedNames"), "noContentSuffixes-"}),
m_skpnstate(this, {"skippedNames", "skippedNames+", "skippedNames-"}),
m_rmtstate(this, "indexedmimetypes"), m_rmtstate(this, "indexedmimetypes"),
m_xmtstate(this, "excludedmimetypes"), m_xmtstate(this, "excludedmimetypes"),
m_mdrstate(this, "metadatacmds") m_mdrstate(this, "metadatacmds")
@ -139,7 +191,8 @@ RclConfig::RclConfig(const string *argcnf)
if (getcwd(buf, MAXPATHLEN)) { if (getcwd(buf, MAXPATHLEN)) {
o_origcwd = string(buf); o_origcwd = string(buf);
} else { } else {
fprintf(stderr, "recollxx: can't retrieve current working directory: relative path translations will fail\n"); fprintf(stderr, "recollxx: can't retrieve current working "
"directory: relative path translations will fail\n");
} }
} }
@ -163,7 +216,7 @@ RclConfig::RclConfig(const string *argcnf)
m_confdir = path_canon(cp); m_confdir = path_canon(cp);
} else { } else {
autoconfdir = true; autoconfdir = true;
m_confdir = path_cat(path_homedata(), path_defaultrecollconfsubdir()); m_confdir=path_cat(path_homedata(), path_defaultrecollconfsubdir());
} }
} }
@ -448,7 +501,7 @@ void RclConfig::initThrConf()
vector<int> vq; vector<int> vq;
vector<int> vt; vector<int> vt;
if (!getConfParam("thrQSizes", &vq)) { if (!getConfParam("thrQSizes", &vq)) {
LOGINFO("RclConfig::initThrConf: no thread info (queues)\n" ); LOGINFO("RclConfig::initThrConf: no thread info (queues)\n");
goto out; goto out;
} }
@ -456,7 +509,7 @@ void RclConfig::initThrConf()
if (vq.size() > 0 && vq[0] == 0) { if (vq.size() > 0 && vq[0] == 0) {
CpuConf cpus; CpuConf cpus;
if (!getCpuConf(cpus) || cpus.ncpus < 1) { if (!getCpuConf(cpus) || cpus.ncpus < 1) {
LOGERR("RclConfig::initThrConf: could not retrieve cpu conf\n" ); LOGERR("RclConfig::initThrConf: could not retrieve cpu conf\n");
cpus.ncpus = 1; cpus.ncpus = 1;
} }
if (cpus.ncpus != 1) { if (cpus.ncpus != 1) {
@ -484,12 +537,12 @@ void RclConfig::initThrConf()
} }
if (!getConfParam("thrTCounts", &vt) ) { if (!getConfParam("thrTCounts", &vt) ) {
LOGINFO("RclConfig::initThrConf: no thread info (threads)\n" ); LOGINFO("RclConfig::initThrConf: no thread info (threads)\n");
goto out; goto out;
} }
if (vq.size() != 3 || vt.size() != 3) { if (vq.size() != 3 || vt.size() != 3) {
LOGINFO("RclConfig::initThrConf: bad thread info vector sizes\n" ); LOGINFO("RclConfig::initThrConf: bad thread info vector sizes\n");
goto out; goto out;
} }
@ -506,13 +559,14 @@ out:
") "; ") ";
} }
LOGDEB("RclConfig::initThrConf: chosen config (ql,nt): " << (sconf.str()) << "\n" ); LOGDEB("RclConfig::initThrConf: chosen config (ql,nt): " << sconf.str() <<
"\n");
} }
pair<int,int> RclConfig::getThrConf(ThrStage who) const pair<int,int> RclConfig::getThrConf(ThrStage who) const
{ {
if (m_thrConf.size() != 3) { if (m_thrConf.size() != 3) {
LOGERR("RclConfig::getThrConf: bad data in rclconfig\n" ); LOGERR("RclConfig::getThrConf: bad data in rclconfig\n");
return pair<int,int>(-1,-1); return pair<int,int>(-1,-1);
} }
return m_thrConf[who]; return m_thrConf[who];
@ -522,7 +576,8 @@ vector<string> RclConfig::getTopdirs() const
{ {
vector<string> tdl; vector<string> tdl;
if (!getConfParam("topdirs", &tdl)) { if (!getConfParam("topdirs", &tdl)) {
LOGERR("RclConfig::getTopdirs: no top directories in config or bad list format\n" ); LOGERR("RclConfig::getTopdirs: no top directories in config or "
"bad list format\n");
return tdl; return tdl;
} }
@ -611,7 +666,7 @@ typedef multiset<SfString, SuffCmp> SuffixStore;
bool RclConfig::inStopSuffixes(const string& fni) bool RclConfig::inStopSuffixes(const string& fni)
{ {
LOGDEB2("RclConfig::inStopSuffixes(" << (fni) << ")\n" ); LOGDEB2("RclConfig::inStopSuffixes(" << fni << ")\n");
// Beware: both needrecompute() need to be called always hence the // Beware: both needrecompute() need to be called always hence the
// bizarre way we do things // bizarre way we do things
bool needrecompute = m_stpsuffstate.needrecompute(); bool needrecompute = m_stpsuffstate.needrecompute();
@ -620,23 +675,24 @@ bool RclConfig::inStopSuffixes(const string& fni)
// Need to initialize the suffixes // Need to initialize the suffixes
delete STOPSUFFIXES; delete STOPSUFFIXES;
if ((m_stopsuffixes = new SuffixStore) == 0) { if ((m_stopsuffixes = new SuffixStore) == 0) {
LOGERR("RclConfig::inStopSuffixes: out of memory\n" ); LOGERR("RclConfig::inStopSuffixes: out of memory\n");
return false; return false;
} }
// Let the old customisation have priority: if recoll_noindex // Let the old customisation have priority: if recoll_noindex
// from mimemap is set, it the user's (the default value is // from mimemap is set, it the user's (the default value is
// gone). Else use the new variable // gone). Else use the new variable
vector<string> stoplist; set<string> stoplist;
if (!m_oldstpsuffstate.savedvalue.empty()) { if (!m_oldstpsuffstate.getvalue(0).empty()) {
stringToStrings(m_oldstpsuffstate.savedvalue, stoplist); stringToStrings(m_oldstpsuffstate.getvalue(0), stoplist);
} else { } else {
stringToStrings(m_stpsuffstate.savedvalue, stoplist); computeBasePlusMinus(stoplist, m_stpsuffstate.getvalue(0),
m_stpsuffstate.getvalue(1),
m_stpsuffstate.getvalue(2));
} }
for (vector<string>::const_iterator it = stoplist.begin(); for (auto& it : stoplist) {
it != stoplist.end(); it++) { STOPSUFFIXES->insert(SfString(stringtolower(it)));
STOPSUFFIXES->insert(SfString(stringtolower(*it))); if (m_maxsufflen < it.length())
if (m_maxsufflen < it->length()) m_maxsufflen = int(it.length());
m_maxsufflen = int(it->length());
} }
} }
@ -647,10 +703,11 @@ bool RclConfig::inStopSuffixes(const string& fni)
stringtolower(fn); stringtolower(fn);
SuffixStore::const_iterator it = STOPSUFFIXES->find(fn); SuffixStore::const_iterator it = STOPSUFFIXES->find(fn);
if (it != STOPSUFFIXES->end()) { if (it != STOPSUFFIXES->end()) {
LOGDEB2("RclConfig::inStopSuffixes: Found (" << (fni) << ") [" << ((*it).m_str) << "]\n" ); LOGDEB2("RclConfig::inStopSuffixes: Found (" << fni << ") [" <<
((*it).m_str) << "]\n");
return true; return true;
} else { } else {
LOGDEB2("RclConfig::inStopSuffixes: not found [" << (fni) << "]\n" ); LOGDEB2("RclConfig::inStopSuffixes: not found [" << fni << "]\n");
return false; return false;
} }
} }
@ -717,28 +774,28 @@ string RclConfig::getMimeHandlerDef(const string &mtype, bool filtertypes)
if (filtertypes) { if (filtertypes) {
if(m_rmtstate.needrecompute()) { if(m_rmtstate.needrecompute()) {
m_restrictMTypes.clear(); m_restrictMTypes.clear();
stringToStrings(stringtolower((const string&)m_rmtstate.savedvalue), stringToStrings(stringtolower((const string&)m_rmtstate.getvalue()),
m_restrictMTypes); m_restrictMTypes);
} }
if (m_xmtstate.needrecompute()) { if (m_xmtstate.needrecompute()) {
m_excludeMTypes.clear(); m_excludeMTypes.clear();
stringToStrings(stringtolower((const string&)m_xmtstate.savedvalue), stringToStrings(stringtolower((const string&)m_xmtstate.getvalue()),
m_excludeMTypes); m_excludeMTypes);
} }
if (!m_restrictMTypes.empty() && if (!m_restrictMTypes.empty() &&
!m_restrictMTypes.count(stringtolower(mtype))) { !m_restrictMTypes.count(stringtolower(mtype))) {
LOGDEB2("RclConfig::getMimeHandlerDef: not in mime type list\n" ); LOGDEB2("RclConfig::getMimeHandlerDef: not in mime type list\n");
return hs; return hs;
} }
if (!m_excludeMTypes.empty() && if (!m_excludeMTypes.empty() &&
m_excludeMTypes.count(stringtolower(mtype))) { m_excludeMTypes.count(stringtolower(mtype))) {
LOGDEB2("RclConfig::getMimeHandlerDef: in excluded mime list\n" ); LOGDEB2("RclConfig::getMimeHandlerDef: in excluded mime list\n");
return hs; return hs;
} }
} }
if (!mimeconf->get(mtype, hs, "index")) { if (!mimeconf->get(mtype, hs, "index")) {
LOGDEB1("getMimeHandler: no handler for '" << (mtype) << "'\n" ); LOGDEB1("getMimeHandlerDef: no handler for '" << mtype << "'\n");
} }
return hs; return hs;
} }
@ -748,8 +805,8 @@ const vector<MDReaper>& RclConfig::getMDReapers()
string hs; string hs;
if (m_mdrstate.needrecompute()) { if (m_mdrstate.needrecompute()) {
m_mdreapers.clear(); m_mdreapers.clear();
// New value now stored in m_mdrstate.savedvalue // New value now stored in m_mdrstate.getvalue(0)
string& sreapers = m_mdrstate.savedvalue; const string& sreapers = m_mdrstate.getvalue(0);
if (sreapers.empty()) if (sreapers.empty())
return m_mdreapers; return m_mdreapers;
string value; string value;
@ -829,7 +886,7 @@ void RclConfig::storeMissingHelperDesc(const string &s)
FILE *fp = fopen(fmiss.c_str(), "w"); FILE *fp = fopen(fmiss.c_str(), "w");
if (fp) { if (fp) {
if (s.size() > 0 && fwrite(s.c_str(), s.size(), 1, fp) != 1) { if (s.size() > 0 && fwrite(s.c_str(), s.size(), 1, fp) != 1) {
LOGERR("storeMissingHelperDesc: fwrite failed\n" ); LOGERR("storeMissingHelperDesc: fwrite failed\n");
} }
fclose(fp); fclose(fp);
} }
@ -839,7 +896,7 @@ void RclConfig::storeMissingHelperDesc(const string &s)
// things for speed (theses are used a lot during indexing) // things for speed (theses are used a lot during indexing)
bool RclConfig::readFieldsConfig(const string& cnferrloc) bool RclConfig::readFieldsConfig(const string& cnferrloc)
{ {
LOGDEB2("RclConfig::readFieldsConfig\n" ); LOGDEB2("RclConfig::readFieldsConfig\n");
m_fields = new ConfStack<ConfSimple>("fields", m_cdirs, true); m_fields = new ConfStack<ConfSimple>("fields", m_cdirs, true);
if (m_fields == 0 || !m_fields->ok()) { if (m_fields == 0 || !m_fields->ok()) {
m_reason = string("No/bad fields file in: ") + cnferrloc; m_reason = string("No/bad fields file in: ") + cnferrloc;
@ -919,7 +976,7 @@ bool RclConfig::readFieldsConfig(const string& cnferrloc)
for (map<string, FieldTraits>::const_iterator it = m_fldtotraits.begin(); for (map<string, FieldTraits>::const_iterator it = m_fldtotraits.begin();
it != m_fldtotraits.end(); it++) { it != m_fldtotraits.end(); it++) {
LOGDEB("readFieldsConfig: [" << *it << "] -> [" << it->second.pfx << LOGDEB("readFieldsConfig: [" << *it << "] -> [" << it->second.pfx <<
"] " << it->second.wdfinc << " " << it->second.boost << "\n"); "] " << it->second.wdfinc << " " << it->second.boost << "\n");
} }
#endif #endif
@ -952,10 +1009,12 @@ bool RclConfig::getFieldTraits(const string& _fld, const FieldTraits **ftpp,
map<string, FieldTraits>::const_iterator pit = m_fldtotraits.find(fld); map<string, FieldTraits>::const_iterator pit = m_fldtotraits.find(fld);
if (pit != m_fldtotraits.end()) { if (pit != m_fldtotraits.end()) {
*ftpp = &pit->second; *ftpp = &pit->second;
LOGDEB1("RclConfig::getFieldTraits: [" << (_fld) << "]->[" << (pit->second.pfx) << "]\n" ); LOGDEB1("RclConfig::getFieldTraits: [" << _fld << "]->[" <<
pit->second.pfx << "]\n");
return true; return true;
} else { } else {
LOGDEB1("RclConfig::getFieldTraits: no prefix for field [" << (fld) << "]\n" ); LOGDEB1("RclConfig::getFieldTraits: no prefix for field [" << fld <<
"]\n");
*ftpp = 0; *ftpp = 0;
return false; return false;
} }
@ -977,10 +1036,11 @@ string RclConfig::fieldCanon(const string& f) const
string fld = stringtolower(f); string fld = stringtolower(f);
map<string, string>::const_iterator it = m_aliastocanon.find(fld); map<string, string>::const_iterator it = m_aliastocanon.find(fld);
if (it != m_aliastocanon.end()) { if (it != m_aliastocanon.end()) {
LOGDEB1("RclConfig::fieldCanon: [" << (f) << "] -> [" << (it->second) << "]\n" ); LOGDEB1("RclConfig::fieldCanon: [" << f << "] -> [" << it->second <<
"]\n");
return it->second; return it->second;
} }
LOGDEB1("RclConfig::fieldCanon: [" << (f) << "] -> [" << (fld) << "]\n" ); LOGDEB1("RclConfig::fieldCanon: [" << (f) << "] -> [" << (fld) << "]\n");
return fld; return fld;
} }
@ -989,7 +1049,8 @@ string RclConfig::fieldQCanon(const string& f) const
string fld = stringtolower(f); string fld = stringtolower(f);
map<string, string>::const_iterator it = m_aliastoqcanon.find(fld); map<string, string>::const_iterator it = m_aliastoqcanon.find(fld);
if (it != m_aliastoqcanon.end()) { if (it != m_aliastoqcanon.end()) {
LOGDEB1("RclConfig::fieldQCanon: [" << (f) << "] -> [" << (it->second) << "]\n" ); LOGDEB1("RclConfig::fieldQCanon: [" << f << "] -> [" << it->second <<
"]\n");
return it->second; return it->second;
} }
return fieldCanon(f); return fieldCanon(f);
@ -1011,20 +1072,44 @@ bool RclConfig::getFieldConfParam(const string &name, const string &sk,
return m_fields->get(name, value, sk); return m_fields->get(name, value, sk);
} }
string RclConfig::getMimeViewerAllEx() const set<string> RclConfig::getMimeViewerAllEx() const
{ {
string hs; set<string> res;
if (mimeview == 0) if (mimeview == 0)
return hs; return res;
mimeview->get("xallexcepts", hs, "");
return hs; string base, plus, minus;
mimeview->get("xallexcepts", base, "");
LOGDEB1("RclConfig::getMimeViewerAllEx(): base: " << s << endl);
mimeview->get("xallexcepts+", plus, "");
LOGDEB1("RclConfig::getMimeViewerAllEx(): plus: " << plus << endl);
mimeview->get("xallexcepts-", minus, "");
LOGDEB1("RclConfig::getMimeViewerAllEx(): minus: " << minus << endl);
computeBasePlusMinus(res, base, plus, minus);
LOGDEB1("RclConfig::getMimeViewerAllEx(): res: " << stringsToString(res)
<< endl);
return res;
} }
bool RclConfig::setMimeViewerAllEx(const string& allex) bool RclConfig::setMimeViewerAllEx(const set<string>& allex)
{ {
if (mimeview == 0) if (mimeview == 0)
return false; return false;
if (!mimeview->set("xallexcepts", allex, "")) {
string s;
mimeview->get("xallexcepts", s, "");
set<string> base;
stringToStrings(s, base);
string splus, sminus;
setPlusMinus(base, allex, splus, sminus);
if (!mimeview->set("xallexcepts-", sminus, "")) {
m_reason = string("RclConfig:: cant set value. Readonly?");
return false;
}
if (!mimeview->set("xallexcepts+", splus, "")) {
m_reason = string("RclConfig:: cant set value. Readonly?"); m_reason = string("RclConfig:: cant set value. Readonly?");
return false; return false;
} }
@ -1035,21 +1120,19 @@ bool RclConfig::setMimeViewerAllEx(const string& allex)
string RclConfig::getMimeViewerDef(const string &mtype, const string& apptag, string RclConfig::getMimeViewerDef(const string &mtype, const string& apptag,
bool useall) const bool useall) const
{ {
LOGDEB2("RclConfig::getMimeViewerDef: mtype [" << (mtype) << "] apptag [" << (apptag) << "]\n" ); LOGDEB2("RclConfig::getMimeViewerDef: mtype [" << mtype << "] apptag ["
<< apptag << "]\n");
string hs; string hs;
if (mimeview == 0) if (mimeview == 0)
return hs; return hs;
if (useall) { if (useall) {
// Check for exception // Check for exception
string excepts = getMimeViewerAllEx(); set<string> allex = getMimeViewerAllEx();
vector<string> vex;
stringToTokens(excepts, vex);
bool isexcept = false; bool isexcept = false;
for (vector<string>::iterator it = vex.begin(); for (auto& it : allex) {
it != vex.end(); it++) {
vector<string> mita; vector<string> mita;
stringToTokens(*it, mita, "|"); stringToTokens(it, mita, "|");
if ((mita.size() == 1 && apptag.empty() && mita[0] == mtype) || if ((mita.size() == 1 && apptag.empty() && mita[0] == mtype) ||
(mita.size() == 2 && mita[1] == apptag && mita[0] == mtype)) { (mita.size() == 2 && mita[1] == apptag && mita[0] == mtype)) {
// Exception to x-all // Exception to x-all
@ -1219,17 +1302,19 @@ string RclConfig::getPidfile() const
void RclConfig::urlrewrite(const string& dbdir, string& url) const void RclConfig::urlrewrite(const string& dbdir, string& url) const
{ {
LOGDEB2("RclConfig::urlrewrite: dbdir [" << (dbdir) << "] url [" << (url) << "]\n" ); LOGDEB2("RclConfig::urlrewrite: dbdir [" << dbdir << "] url [" << url <<
"]\n");
// Do path translations exist for this index ? // Do path translations exist for this index ?
if (m_ptrans == 0 || !m_ptrans->hasSubKey(dbdir)) { if (m_ptrans == 0 || !m_ptrans->hasSubKey(dbdir)) {
LOGDEB2("RclConfig::urlrewrite: no paths translations (m_ptrans " << (m_ptrans) << ")\n" ); LOGDEB2("RclConfig::urlrewrite: no paths translations (m_ptrans " <<
m_ptrans << ")\n");
return; return;
} }
string path = fileurltolocalpath(url); string path = fileurltolocalpath(url);
if (path.empty()) { if (path.empty()) {
LOGDEB2("RclConfig::urlrewrite: not file url\n" ); LOGDEB2("RclConfig::urlrewrite: not file url\n");
return; return;
} }
@ -1279,7 +1364,10 @@ string RclConfig::getWebQueueDir() const
vector<string>& RclConfig::getSkippedNames() vector<string>& RclConfig::getSkippedNames()
{ {
if (m_skpnstate.needrecompute()) { if (m_skpnstate.needrecompute()) {
stringToStrings(m_skpnstate.savedvalue, m_skpnlist); set<string> ss;
computeBasePlusMinus(ss, m_skpnstate.getvalue(0),
m_skpnstate.getvalue(1), m_skpnstate.getvalue(2));
m_skpnlist = vector<string>(ss.begin(), ss.end());
} }
return m_skpnlist; return m_skpnlist;
} }
@ -1388,7 +1476,7 @@ bool RclConfig::getUncompressor(const string &mtype, vector<string>& cmd) const
vector<string> tokens; vector<string> tokens;
stringToStrings(hs, tokens); stringToStrings(hs, tokens);
if (tokens.empty()) { if (tokens.empty()) {
LOGERR("getUncompressor: empty spec for mtype " << (mtype) << "\n" ); LOGERR("getUncompressor: empty spec for mtype " << mtype << "\n");
return false; return false;
} }
vector<string>::iterator it = tokens.begin(); vector<string>::iterator it = tokens.begin();
@ -1406,7 +1494,8 @@ bool RclConfig::getUncompressor(const string &mtype, vector<string>& cmd) const
if (!stringlowercmp("python", *it) || !stringlowercmp("perl", *it)) { if (!stringlowercmp("python", *it) || !stringlowercmp("perl", *it)) {
it++; it++;
if (tokens.size() < 3) { if (tokens.size() < 3) {
LOGERR("getUncpressor: python/perl cmd: no script?. [" << (mtype) << "]\n" ); LOGERR("getUncpressor: python/perl cmd: no script?. [" <<
mtype << "]\n");
} else { } else {
*it = findFilter(*it); *it = findFilter(*it);
} }
@ -1481,6 +1570,20 @@ bool RclConfig::initUserConfig()
return true; return true;
} }
void RclConfig::zeroMe() {
m_ok = false;
m_keydirgen = 0;
m_conf = 0;
mimemap = 0;
mimeconf = 0;
mimeview = 0;
m_fields = 0;
m_ptrans = 0;
m_stopsuffixes = 0;
m_maxsufflen = 0;
initParamStale(0, 0);
}
void RclConfig::freeAll() void RclConfig::freeAll()
{ {
delete m_conf; delete m_conf;
@ -1499,12 +1602,30 @@ void RclConfig::initFrom(const RclConfig& r)
zeroMe(); zeroMe();
if (!(m_ok = r.m_ok)) if (!(m_ok = r.m_ok))
return; return;
// Copyable fields
m_ok = r.m_ok;
m_reason = r.m_reason; m_reason = r.m_reason;
m_confdir = r.m_confdir; m_confdir = r.m_confdir;
m_cachedir = r.m_cachedir; m_cachedir = r.m_cachedir;
m_datadir = r.m_datadir; m_datadir = r.m_datadir;
m_keydir = r.m_keydir; m_keydir = r.m_keydir;
m_keydirgen = r.m_keydirgen;
m_cdirs = r.m_cdirs; m_cdirs = r.m_cdirs;
m_fldtotraits = r.m_fldtotraits;
m_aliastocanon = r.m_aliastocanon;
m_aliastoqcanon = r.m_aliastoqcanon;
m_storedFields = r.m_storedFields;
m_xattrtofld = r.m_xattrtofld;
m_maxsufflen = r.m_maxsufflen;
m_skpnlist = r.m_skpnlist;
m_defcharset = r.m_defcharset;
m_restrictMTypes = r.m_restrictMTypes;
m_excludeMTypes = r.m_excludeMTypes;
m_thrConf = r.m_thrConf;
m_mdreapers = r.m_mdreapers;
// Special treatment
if (r.m_conf) if (r.m_conf)
m_conf = new ConfStack<ConfTree>(*(r.m_conf)); m_conf = new ConfStack<ConfTree>(*(r.m_conf));
if (r.mimemap) if (r.mimemap)
@ -1517,19 +1638,9 @@ void RclConfig::initFrom(const RclConfig& r)
m_fields = new ConfStack<ConfSimple>(*(r.m_fields)); m_fields = new ConfStack<ConfSimple>(*(r.m_fields));
if (r.m_ptrans) if (r.m_ptrans)
m_ptrans = new ConfSimple(*(r.m_ptrans)); m_ptrans = new ConfSimple(*(r.m_ptrans));
m_fldtotraits = r.m_fldtotraits;
m_aliastocanon = r.m_aliastocanon;
m_aliastoqcanon = r.m_aliastoqcanon;
m_storedFields = r.m_storedFields;
m_xattrtofld = r.m_xattrtofld;
if (r.m_stopsuffixes) if (r.m_stopsuffixes)
m_stopsuffixes = new SuffixStore(*((SuffixStore*)r.m_stopsuffixes)); m_stopsuffixes = new SuffixStore(*((SuffixStore*)r.m_stopsuffixes));
m_maxsufflen = r.m_maxsufflen;
m_defcharset = r.m_defcharset;
initParamStale(m_conf, mimemap); initParamStale(m_conf, mimemap);
m_thrConf = r.m_thrConf;
} }
void RclConfig::initParamStale(ConfNull *cnf, ConfNull *mimemap) void RclConfig::initParamStale(ConfNull *cnf, ConfNull *mimemap)

View File

@ -36,22 +36,38 @@ using std::map;
class RclConfig; class RclConfig;
// A small class used for parameters that need to be computed from the // Cache parameter string values for params which need computation and
// config string, and which can change with the keydir. Minimize work // which can change with the keydir. Minimize work by using the
// by using the keydirgen and a saved string to avoid unneeded // keydirgen and a saved string to avoid unneeded recomputations:
// recomputations // keydirgen is incremented in RclConfig with each setKeyDir(). We
// compare our saved value with the current one. If it did not change
// no get() is needed. If it did change, but the resulting param get()
// string value is identical, no recomputation is needed.
class ParamStale { class ParamStale {
public: public:
RclConfig *parent; ParamStale() {}
ConfNull *conffile; ParamStale(RclConfig *rconf, const string& nm)
string paramname; : parent(rconf), paramnames(vector<string>(1, nm)), savedvalues(1) {
bool active; // Check at init if config defines name at all }
int savedkeydirgen; ParamStale(RclConfig *rconf, const vector<string>& nms)
string savedvalue; : parent(rconf), paramnames(nms), savedvalues(nms.size()) {
}
ParamStale(RclConfig *rconf, const string& nm);
void init(ConfNull *cnf); void init(ConfNull *cnf);
bool needrecompute(); bool needrecompute();
const string& getvalue(unsigned int i = 0) const;
private:
// The config we belong to.
RclConfig *parent{0};
// The configuration file we search for values. This is a borrowed
// pointer belonging to the parent, we do not manage it.
ConfNull *conffile{0};
vector<string> paramnames;
vector<string> savedvalues;
// Check at init if the configuration defines our vars at all. No
// further processing is needed if it does not.
bool active{false};
int savedkeydirgen{-1};
}; };
// Hold the description for an external metadata-gathering command // Hold the description for an external metadata-gathering command
@ -63,13 +79,10 @@ struct MDReaper {
// Data associated to a indexed field name: // Data associated to a indexed field name:
struct FieldTraits { struct FieldTraits {
string pfx; // indexing prefix, string pfx; // indexing prefix,
int wdfinc; // Index time term frequency increment (default 1) int wdfinc{1}; // Index time term frequency increment (default 1)
double boost; // Query time boost (default 1.0) double boost{1.0}; // Query time boost (default 1.0)
bool pfxonly; // Suppress prefix-less indexing bool pfxonly{false}; // Suppress prefix-less indexing
bool noterms; // Don't add term to highlight data (e.g.: rclbes) bool noterms{false}; // Don't add term to highlight data (e.g.: rclbes)
FieldTraits()
: wdfinc(1), boost(1.0), pfxonly(false), noterms(false)
{}
}; };
class RclConfig { class RclConfig {
@ -80,15 +93,7 @@ class RclConfig {
// argcnf // argcnf
RclConfig(const string *argcnf = 0); RclConfig(const string *argcnf = 0);
RclConfig(const RclConfig &r) RclConfig(const RclConfig &r);
: m_oldstpsuffstate(this, "recoll_noindex"),
m_stpsuffstate(this, "noContentSuffixes"),
m_skpnstate(this, "skippedNames"),
m_rmtstate(this, "indexedmimetypes"),
m_xmtstate(this, "excludedmimetypes"),
m_mdrstate(this, "metadatacmds") {
initFrom(r);
}
~RclConfig() { ~RclConfig() {
freeAll(); freeAll();
@ -289,8 +294,8 @@ class RclConfig {
/** mimeview: get/set external viewer exec string(s) for mimetype(s) */ /** mimeview: get/set external viewer exec string(s) for mimetype(s) */
string getMimeViewerDef(const string &mimetype, const string& apptag, string getMimeViewerDef(const string &mimetype, const string& apptag,
bool useall) const; bool useall) const;
string getMimeViewerAllEx() const; set<string> getMimeViewerAllEx() const;
bool setMimeViewerAllEx(const string& allex); bool setMimeViewerAllEx(const set<string>& allex);
bool getMimeViewerDefs(vector<pair<string, string> >&) const; bool getMimeViewerDefs(vector<pair<string, string> >&) const;
bool setMimeViewerDef(const string& mimetype, const string& cmd); bool setMimeViewerDef(const string& mimetype, const string& cmd);
/** Check if mime type is designated as needing no uncompress before view /** Check if mime type is designated as needing no uncompress before view
@ -355,19 +360,12 @@ class RclConfig {
vector<string> m_cdirs; // directory stack for the confstacks vector<string> m_cdirs; // directory stack for the confstacks
ConfStack<ConfTree> *m_conf; // Parsed configuration files
ConfStack<ConfTree> *mimemap; // The files don't change with keydir,
ConfStack<ConfSimple> *mimeconf; // but their content may depend on it.
ConfStack<ConfSimple> *mimeview; //
ConfStack<ConfSimple> *m_fields;
ConfSimple *m_ptrans; // Paths translations
map<string, FieldTraits> m_fldtotraits; // Field to field params map<string, FieldTraits> m_fldtotraits; // Field to field params
map<string, string> m_aliastocanon; map<string, string> m_aliastocanon;
map<string, string> m_aliastoqcanon; map<string, string> m_aliastoqcanon;
set<string> m_storedFields; set<string> m_storedFields;
map<string, string> m_xattrtofld; map<string, string> m_xattrtofld;
void *m_stopsuffixes;
unsigned int m_maxsufflen; unsigned int m_maxsufflen;
ParamStale m_oldstpsuffstate; // Values from user mimemap, now obsolete ParamStale m_oldstpsuffstate; // Values from user mimemap, now obsolete
ParamStale m_stpsuffstate; ParamStale m_stpsuffstate;
@ -396,7 +394,18 @@ class RclConfig {
ParamStale m_mdrstate; ParamStale m_mdrstate;
vector<MDReaper> m_mdreapers; vector<MDReaper> m_mdreapers;
/** Create initial user configuration */ //////////////////
// Members needing explicit processing when copying
void *m_stopsuffixes;
ConfStack<ConfTree> *m_conf; // Parsed configuration files
ConfStack<ConfTree> *mimemap; // The files don't change with keydir,
ConfStack<ConfSimple> *mimeconf; // but their content may depend on it.
ConfStack<ConfSimple> *mimeview; //
ConfStack<ConfSimple> *m_fields;
ConfSimple *m_ptrans; // Paths translations
///////////////////
/** Create initial user configuration */
bool initUserConfig(); bool initUserConfig();
/** Init all ParamStale members */ /** Init all ParamStale members */
void initParamStale(ConfNull *cnf, ConfNull *mimemap); void initParamStale(ConfNull *cnf, ConfNull *mimemap);

View File

@ -83,8 +83,7 @@ void ViewAction::fillLists()
set<string> viewerXs; set<string> viewerXs;
if (prefs.useDesktopOpen) { if (prefs.useDesktopOpen) {
string s = theconfig->getMimeViewerAllEx(); viewerXs = theconfig->getMimeViewerAllEx();
stringToStrings(s, viewerXs);
} }
for (vector<pair<string, string> >::const_iterator it = defs.begin(); for (vector<pair<string, string> >::const_iterator it = defs.begin();
it != defs.end(); it++) { it != defs.end(); it++) {
@ -176,9 +175,7 @@ void ViewAction::editActions()
QString action0; QString action0;
int except0 = -1; int except0 = -1;
set<string> viewerXs; set<string> viewerXs = theconfig->getMimeViewerAllEx();
string s = theconfig->getMimeViewerAllEx();
stringToStrings(s, viewerXs);
list<string> mtypes; list<string> mtypes;
bool dowarnmultiple = true; bool dowarnmultiple = true;
@ -233,8 +230,6 @@ void ViewAction::editActions()
theconfig->setMimeViewerDef(*mit, sact); theconfig->setMimeViewerDef(*mit, sact);
} }
s = stringsToString(viewerXs); theconfig->setMimeViewerAllEx(viewerXs);
theconfig->setMimeViewerAllEx(s);
fillLists(); fillLists();
} }