|
a/src/rcldb/synfamily.cpp |
|
b/src/rcldb/synfamily.cpp |
|
... |
|
... |
26 |
#include "debuglog.h"
|
26 |
#include "debuglog.h"
|
27 |
#include "cstr.h"
|
27 |
#include "cstr.h"
|
28 |
#include "xmacros.h"
|
28 |
#include "xmacros.h"
|
29 |
#include "synfamily.h"
|
29 |
#include "synfamily.h"
|
30 |
#include "smallut.h"
|
30 |
#include "smallut.h"
|
|
|
31 |
#include "refcntr.h"
|
31 |
|
32 |
|
32 |
using namespace std;
|
33 |
using namespace std;
|
33 |
|
34 |
|
34 |
namespace Rcl {
|
35 |
namespace Rcl {
|
35 |
|
36 |
|
|
... |
|
... |
180 |
LOGDEB(("XapCompSynFamMbr::synExpand([%s]): term [%s] -> [%s]\n",
|
181 |
LOGDEB(("XapCompSynFamMbr::synExpand([%s]): term [%s] -> [%s]\n",
|
181 |
m_prefix.c_str(), term.c_str(), stringsToString(result).c_str()));
|
182 |
m_prefix.c_str(), term.c_str(), stringsToString(result).c_str()));
|
182 |
return true;
|
183 |
return true;
|
183 |
}
|
184 |
}
|
184 |
|
185 |
|
185 |
bool XapComputableSynFamMember::keyWildExpand(const string& inexp,
|
186 |
bool XapComputableSynFamMember::synKeyExpand(StrMatcher* inexp,
|
186 |
vector<string>& result,
|
187 |
vector<string>& result,
|
187 |
SynTermTrans *filtertrans)
|
188 |
SynTermTrans *filtertrans)
|
188 |
{
|
189 |
{
|
189 |
LOGDEB(("XapCompSynFam::keyWildExpand: [%s]\n", inexp.c_str()));
|
190 |
LOGDEB(("XapCompSynFam::synKeyExpand: [%s]\n", inexp->exp().c_str()));
|
190 |
|
191 |
|
191 |
// Transform input into our key format (e.g.: case-folded + diac-stripped)
|
|
|
192 |
string stripped_exp = (*m_trans)(inexp);
|
|
|
193 |
|
|
|
194 |
// If set, compute filtering term (e.g.: only case-folded)
|
192 |
// If set, compute filtering term (e.g.: only case-folded)
|
195 |
string filter_exp;
|
193 |
RefCntr<StrMatcher> filter_exp;
|
196 |
if (filtertrans)
|
194 |
if (filtertrans) {
|
|
|
195 |
filter_exp = RefCntr<StrMatcher>(inexp->clone());
|
197 |
filter_exp = (*filtertrans)(inexp);
|
196 |
filter_exp->setExp((*filtertrans)(inexp->exp()));
|
|
|
197 |
}
|
198 |
|
198 |
|
|
|
199 |
// Transform input into our key format (e.g.: case-folded + diac-stripped),
|
|
|
200 |
// and prepend prefix
|
|
|
201 |
inexp->setExp(m_prefix + (*m_trans)(inexp->exp()));
|
199 |
// Find the initial section before any special chars
|
202 |
// Find the initial section before any special chars for skipping the keys
|
200 |
string::size_type es = stripped_exp.find_first_of(cstr_wildSpecStChars);
|
203 |
string::size_type es = inexp->baseprefixlen();
|
201 |
string is; // Initial section
|
204 |
string is = inexp->exp().substr(0, es);
|
202 |
switch (es) {
|
|
|
203 |
case string::npos:
|
|
|
204 |
// No special chars, no expansion.
|
|
|
205 |
result.push_back(inexp);
|
|
|
206 |
return true;
|
|
|
207 |
break;
|
|
|
208 |
case 0:
|
|
|
209 |
// Input starts with special char: start at bottom
|
|
|
210 |
is = m_prefix;
|
|
|
211 |
break;
|
|
|
212 |
default:
|
|
|
213 |
// Compute initial section
|
|
|
214 |
is = m_prefix + stripped_exp.substr(0, es);
|
|
|
215 |
break;
|
|
|
216 |
}
|
|
|
217 |
|
|
|
218 |
// Input to matching: prefix + transformed input
|
|
|
219 |
string matchin = m_prefix + stripped_exp;
|
|
|
220 |
string::size_type preflen = m_prefix.size();
|
205 |
string::size_type preflen = m_prefix.size();
|
|
|
206 |
LOGDEB2(("XapCompSynFam::is: [%s]\n", is.c_str()));
|
221 |
|
207 |
|
222 |
string ermsg;
|
208 |
string ermsg;
|
223 |
try {
|
209 |
try {
|
224 |
for (Xapian::TermIterator xit = m_family.getdb().synonym_keys_begin(is);
|
210 |
for (Xapian::TermIterator xit = m_family.getdb().synonym_keys_begin(is);
|
225 |
xit != m_family.getdb().synonym_keys_end(is); xit++) {
|
211 |
xit != m_family.getdb().synonym_keys_end(is); xit++) {
|
226 |
LOGDEB2((" Checking1 [%s] against [%s]\n", (*xit).c_str(),
|
212 |
LOGDEB2((" Checking1 [%s] against [%s]\n", (*xit).c_str(),
|
227 |
matchin.c_str()));
|
213 |
inexp->exp().c_str()));
|
228 |
if (fnmatch(matchin.c_str(), (*xit).c_str(), 0) == FNM_NOMATCH)
|
214 |
if (!inexp->match(*xit))
|
229 |
continue;
|
215 |
continue;
|
230 |
|
216 |
|
231 |
// Push all the synonyms if they match the secondary filter
|
217 |
// Push all the synonyms if they match the secondary filter
|
232 |
for (Xapian::TermIterator xit1 =
|
218 |
for (Xapian::TermIterator xit1 =
|
233 |
m_family.getdb().synonyms_begin(*xit);
|
219 |
m_family.getdb().synonyms_begin(*xit);
|
234 |
xit1 != m_family.getdb().synonyms_end(*xit); xit1++) {
|
220 |
xit1 != m_family.getdb().synonyms_end(*xit); xit1++) {
|
235 |
string term = *xit1;
|
221 |
string term = *xit1;
|
236 |
if (filtertrans) {
|
222 |
if (filter_exp.isNotNull()) {
|
237 |
string term1 = (*filtertrans)(term);
|
223 |
string term1 = (*filtertrans)(term);
|
238 |
LOGDEB2((" Testing [%s] against [%s]\n",
|
224 |
LOGDEB2((" Testing [%s] against [%s]\n",
|
239 |
term1.c_str(), filter_exp.c_str()));
|
225 |
term1.c_str(), filter_exp.c_str()));
|
240 |
if (fnmatch(filter_exp.c_str(),
|
226 |
if (!filter_exp->match(term1)) {
|
241 |
term1.c_str(), 0) == FNM_NOMATCH) {
|
|
|
242 |
continue;
|
227 |
continue;
|
243 |
}
|
228 |
}
|
244 |
}
|
229 |
}
|
245 |
LOGDEB(("XapCompSynFam::keyWildExpand: Pushing %s\n",
|
230 |
LOGDEB2(("XapCompSynFam::keyWildExpand: [%s]\n",
|
246 |
(*xit1).c_str()));
|
231 |
(*xit1).c_str()));
|
247 |
result.push_back(*xit1);
|
232 |
result.push_back(*xit1);
|
248 |
}
|
233 |
}
|
249 |
// Same with key itself
|
234 |
// Same with key itself
|
250 |
string term = (*xit).substr(preflen);
|
235 |
string term = (*xit).substr(preflen);
|
251 |
if (filtertrans) {
|
236 |
if (filter_exp.isNotNull()) {
|
252 |
string term1 = (*filtertrans)(term);
|
237 |
string term1 = (*filtertrans)(term);
|
253 |
LOGDEB((" Testing [%s] against [%s]\n",
|
238 |
LOGDEB2((" Testing [%s] against [%s]\n",
|
254 |
term1.c_str(), filter_exp.c_str()));
|
239 |
term1.c_str(), filter_exp->exp().c_str()));
|
255 |
if (fnmatch(filter_exp.c_str(),
|
240 |
if (!filter_exp->match(term1)) {
|
256 |
term1.c_str(), 0) == FNM_NOMATCH) {
|
|
|
257 |
continue;
|
241 |
continue;
|
258 |
}
|
242 |
}
|
259 |
}
|
243 |
}
|
260 |
LOGDEB(("XapCompSynFam::keyWildExpand: Pushing [%s]\n",
|
244 |
LOGDEB2(("XapCompSynFam::keyWildExpand: [%s]\n", term.c_str()));
|
261 |
term.c_str()));
|
|
|
262 |
result.push_back(term);
|
245 |
result.push_back(term);
|
263 |
}
|
246 |
}
|
264 |
} XCATCHERROR(ermsg);
|
247 |
} XCATCHERROR(ermsg);
|
265 |
if (!ermsg.empty()) {
|
248 |
if (!ermsg.empty()) {
|
266 |
LOGERR(("XapCompSynFam::keyWildExpand: error: term [%s]\n",
|
249 |
LOGERR(("XapCompSynFam::keyWildExpand: xapian: [%s]\n", ermsg.c_str()));
|
267 |
inexp.c_str()));
|
|
|
268 |
result.push_back(inexp);
|
|
|
269 |
return false;
|
250 |
return false;
|
270 |
}
|
251 |
}
|
271 |
return true;
|
252 |
return true;
|
272 |
}
|
253 |
}
|
273 |
|
254 |
|
|
... |
|
... |
302 |
#define OPT_u 0x8
|
283 |
#define OPT_u 0x8
|
303 |
#define OPT_d 0x10
|
284 |
#define OPT_d 0x10
|
304 |
#define OPT_l 0x20
|
285 |
#define OPT_l 0x20
|
305 |
#define OPT_s 0x40
|
286 |
#define OPT_s 0x40
|
306 |
#define OPT_e 0x80
|
287 |
#define OPT_e 0x80
|
|
|
288 |
|
307 |
static string usage =
|
289 |
static string usage =
|
308 |
" -d <dbdir> {-s|-a|-u} database dir and synfamily: stem accents/case ustem\n"
|
290 |
" -d <dbdir> {-s|-a|-u} database dir and synfamily: stem accents/case ustem\n"
|
309 |
" -l : list members\n"
|
291 |
" -l : list members\n"
|
310 |
" -L <member>: list entries for given member\n"
|
292 |
" -L <member>: list entries for given member\n"
|
311 |
" -e <member> <key> : list expansion for given member and key\n"
|
293 |
" -e <member> <key> : list expansion for given member and key\n"
|