20 expr(strdup(expression)),
34 while (body_last->next && body_last->next->next) {
35 body_last = body_last->next;
40 tail = body_last->next;
41 body_last->next =
NULp;
49 if (next) next->
append(tail);
64 case AND: tail->op =
OR;
break;
65 case OR: tail->op =
AND;
break;
87 char *dup = strdup(err);
106 void QueryExpr::detect_query_type() {
107 char first = expr[0];
108 string&
str = xquery.str;
114 else if (first ==
'/') {
122 if (err) freedup(error, err);
124 else if (first ==
'|') type =
AQT_ACI;
125 else if (first ==
'<' || first ==
'>') {
126 const char *rest = expr+1;
128 float f = strtof(rest, const_cast<char**>(&end));
136 freeset(error,
GBS_global_string_copy(
"Could not convert '%s' to number (unexpected content '%s')", rest, end));
144 size_t qlen = strlen(expr);
145 char last = expr[qlen-1];
149 str =
string(str, 1, str.length()-2);
159 str =
string(str, 0, str.length()-1);
177 bool QueryExpr::first_matches(
const QueryTarget& target,
char*& matched_data)
const {
182 qe_assert(contradicted(data, retrieveError));
183 if (!data && !error)
setError(retrieveError);
190 hit = (data[0] == 0);
194 hit = (data[0] != 0);
198 hit = strcasecmp(data, expr) == 0;
206 hit = strncasecmp(data, xquery.str.c_str(), xquery.str.length()) == 0;
210 int dlen = strlen(data);
211 hit = strcasecmp(data+dlen-xquery.str.length(), xquery.str.c_str()) == 0;
220 const char *
start = data;
221 while (start[0] ==
' ') ++
start;
224 float f = strtof(start, const_cast<char**>(&end));
230 bool is_numeric = (end[0] == 0);
233 while (end[0] ==
' ') ++end;
234 is_numeric = (end[0] == 0);
260 hit = strcmp(aci_result,
"0") != 0;
262 freeset(lastACIresult, aci_result);
267 freedup(error,
"Invalid search expression");
274 return Not ? !hit : hit;
285 ++qindex, subexpr = subexpr ? subexpr->next :
NULp)
287 if ((subexpr->op ==
OR) == hit) {
291 string this_hit_reason;
293 const QueryKey& query_key = subexpr->get_key();
299 bool do_match =
true;
301 char *matched_data =
NULp;
302 bool matched = subexpr->first_matches(target, matched_data);
311 const char *reason_key = query_key.
get_name();
319 this_hit_reason =
string(reason_key)+
"="+matched_data;
320 const char *ACIresult = subexpr->get_last_ACI_result();
321 if (ACIresult) this_hit_reason =
string(
"[ACI=")+ACIresult+
"] "+this_hit_reason;
326 do_match = do_match && query_key.
next();
333 this_hit_reason = subexpr->shallMatch() ?
"<matched all>" :
"<matched none>";
339 const char *prefix =
GBS_global_string(
"%c%c",
'1'+qindex, subexpr->shallMatch() ?
' ' :
'!');
340 this_hit_reason =
string(prefix)+this_hit_reason;
345 switch (subexpr->op) {
349 hit_reason = hit_reason.empty() ? this_hit_reason : hit_reason+
" & "+this_hit_reason;
355 hit_reason = this_hit_reason;
virtual void reset() const =0
#define implicated(hypothesis, conclusion)
GBS_regex * GBS_compile_regexpr(const char *regexpr, GB_CASE case_flag, GB_ERROR *error)
return string(buffer, length)
const GBL_env & get_env() const
const char * GBS_unwrap_regexpr(const char *regexpr_in_slashes, GB_CASE *case_flag, GB_ERROR *error)
virtual const char * get_name() const =0
size_t GBS_shorten_repeated_data(char *data)
const char * GBS_global_string(const char *templat,...)
GB_CSTR GBS_find_string(GB_CSTR cont, GB_CSTR substr, int match_mode)
static HelixNrInfo * start
GB_ERROR GB_await_error()
static void error(const char *msg)
virtual char * get_target_data(const QueryTarget &target, GB_ERROR &error) const =0
#define MAX_SHOWN_DATA_SIZE
void append(QueryExpr *&tail)
const char * GBS_regmatch_compiled(const char *str, GBS_regex *comreg, size_t *matchlen)
bool matches(const QueryTarget &target, std::string &hit_reason) const
const char * GBS_static_string(const char *str)
GB_ERROR getError(int count=0) const
NOT4PERL char * GB_command_interpreter_in_env(const char *str, const char *commands, const GBL_call_env &callEnv)
bool containsWildcards(const char *str)
void setError(GB_ERROR error_) const
QueryExpr(query_operator aqo, QueryKeyPtr key, bool not_equal, const char *expression)
bool GBS_string_matches(const char *str, const char *expr, GB_CASE case_sens)
char * GBS_global_string_copy(const char *templat,...)
virtual GBDATA * get_ACI_item() const =0