54 if (search_expr[0] ==
'/') {
55 const char *end = strchr(search_expr, 0)-1;
56 if (end>search_expr && end[0] ==
'/') {
58 const char *unwrapped_expr =
GBS_unwrap_regexpr(search_expr, &expr_attached_case, &error);
61 if (expr_attached_case !=
GB_MIND_CASE) error =
"format '/../i' not allowed here";
72 if (!matcher->
regexpr && !error) {
73 if (strcmp(search_expr,
"*") == 0) {
83 error =
GBS_global_string(
"Failed to create GBS_string_matcher from '%s'", search_expr);
113 switch (match_mode) {
116 for (p1 = cont, p2 = substr; *p1;) {
131 if (!*p2)
return (
char *)cont;
135 for (p1 = cont, p2 = substr; *p1;) {
140 if (toupper(*p1) == toupper(b)) {
150 if (!*p2)
return (
char *)cont;
153 for (p1 = cont, p2 = substr; *p1;) {
158 if (b == *p1 || (b==
'?')) {
168 if (!*p2)
return (
char *)cont;
172 for (p1 = cont, p2 = substr; *p1;) {
177 if (toupper(*p1) == toupper(b) || (b==
'?')) {
187 if (!*p2)
return (
char *)cont;
203 const char *ps =
str;
204 const char *pe = expr;
216 int len = nextStar-pe-1;
219 int psl = strlen(ps);
275 bool matches =
false;
277 switch (expr->
type) {
302 #define GBS_SET ((char)1)
303 #define GBS_SEP ((char)2)
304 #define GBS_MWILD ((char)3)
305 #define GBS_WILD ((char)4)
309 const char *sWildcards,
long sWildMax,
310 const char*
const *mWildcards,
long mWildMax,
335 char *psym = strpbrk(p,
"#|:");
364 gb_entry = gb_container;
367 if (psym) *psym = separator;
369 char *entry = (gb_entry && gb_entry != gb_container)
414 int wildcard_num = d -
'1';
415 bool followed_by_number = wildcard_num>=0 && wildcard_num<=9;
418 if (!followed_by_number) {
420 wildcard_num = sWildAuto++;
422 if (wildcard_num>=sWildMax) {
426 out.
put(sWildcards[wildcard_num]);
430 if (!followed_by_number) {
432 wildcard_num = mWildAuto++;
434 if (wildcard_num>=mWildMax) {
438 out.
cat(mWildcards[wildcard_num]);
468 while ((ch = *(s++))) {
470 case '=': *(d++) =
GBS_SET;
break;
471 case ':': *(d++) =
GBS_SEP;
break;
475 ch = *(s++);
if (!ch) { s--;
break; };
477 case 'n': *(d++) =
'\n';
break;
478 case 't': *(d++) =
'\t';
break;
479 case '0': *(d++) =
'\0';
break;
480 default: *(d++) = ch;
break;
484 default: *(d++) = ch;
break;
529 if (!icommand || !icommand[0]) {
541 size_t inlen = strlen(insource);
543 in.
ncat(insource, inlen);
549 for (
char *subcmd = command; subcmd; subcmd = next_subcmd) {
551 next_subcmd = strchr(subcmd,
GBS_SEP);
552 if (next_subcmd) *(next_subcmd++) = 0;
554 if (!subcmd[0])
continue;
557 char *replaceBy = strchr(subcmd+1,
GBS_SET);
559 error =
GBS_global_string(
"SRT ERROR: no '=' found in command '%s' (position > %zi)", icommand, subcmd-command+1);
569 const char *empty =
"";
578 bool match_failed =
false;
579 for (
GB_CSTR source = not_yet_copied; *source; ) {
582 char *search = subcmd;
586 while (!match_failed && (c = *(search++))) {
589 if (!start_match) start_match = source;
591 char *start_of_wildcard = search;
592 if (!(c = *(search++))) {
594 source = strchr(source, 0);
605 char what_wild_card = c;
608 if (!p) match_failed =
true;
611 source = p + strlen(start_of_wildcard);
612 *search = what_wild_card;
617 if (!source[0]) match_failed =
true;
619 if (!start_match) start_match = source;
620 sWildcard[sWildSeen++] = *(source++);
626 if (c != *(source++)) match_failed =
true;
629 char *buf1 = search-1;
636 char what_wild_card = c;
644 source = p + strlen(buf1);
645 *search = what_wild_card;
664 out.
ncat(not_yet_copied, start_match-not_yet_copied);
666 not_yet_copied = source;
669 for (
long i = 0; i < mWildSeen; i++) {
670 freenull(mWildcard[i]);
675 if (error || match_failed)
break;
683 out.
cat(not_yet_copied);
715 static char *tokenMatchResults(
const char *expr,
GB_CASE caseDef,
const char *tokenStr) {
720 for (
int t = 0; token[t]; ++t) {
722 token.
replace(t, matched ?
"1" :
"0");
729 #define TEST_MATCH_TOKENS(expr,caseDef,tokenStr,expected) do{ \
730 char *results = tokenMatchResults(expr, caseDef, tokenStr); \
731 TEST_EXPECT_EQUAL(results, expected); \
735 #define TEST_MATCH_TOKENS__BROKEN(expr,caseDef,tokenStr,expected,got) do{ \
736 char *results = tokenMatchResults(expr, caseDef, tokenStr); \
737 TEST_EXPECT_EQUAL__BROKEN(results, expected, got); \
741 void TEST_matcher() {
742 TEST_MATCH_TOKENS(
"???",
GB_MIND_CASE,
"ab;abc;abcd",
"010");
743 TEST_MATCH_TOKENS(
"???*",
GB_MIND_CASE,
"ab;abc;abcd",
"011");
744 TEST_MATCH_TOKENS(
"?*",
GB_MIND_CASE,
";a;ab;abc",
"0111");
746 TEST_MATCH_TOKENS(
"a*c",
GB_MIND_CASE,
"ca;ab;abc;abC;ABC;abcd",
"001000");
747 TEST_MATCH_TOKENS(
"a*c",
GB_IGNORE_CASE,
"ca;ab;abc;abC;ABC;abcd",
"001110");
749 TEST_MATCH_TOKENS(
"a*c*a",
GB_MIND_CASE,
"aca;aaacccaaa;a--c--a;acac;acaca;aba",
"111010");
750 TEST_MATCH_TOKENS(
"a*c?d*c",
GB_MIND_CASE,
"acxdc;a--cxd--c;acxdcxdcxdc;acdcdcdc",
"1110");
752 TEST_MATCH_TOKENS(
"???*.c",
GB_MIND_CASE,
"ab.c;abc.c;abcd.c",
"011");
753 TEST_MATCH_TOKENS(
"?b.*.c",
GB_MIND_CASE,
"ab.c;ab..c;ab.x.c",
"011");
754 TEST_MATCH_TOKENS(
"rere*erer",
GB_MIND_CASE,
"rerer;rererer;rerererer;rererererer",
"0011");
GBDATA * get_item_ref() const
void GBS_free_matcher(GBS_string_matcher *matcher)
GBS_regex * GBS_compile_regexpr(const char *regexpr, GB_CASE case_flag, GB_ERROR *error)
const char * GBS_unwrap_regexpr(const char *regexpr_in_slashes, GB_CASE *case_flag, GB_ERROR *error)
char * GBS_string_eval(const char *insource, const char *icommand)
bool GBS_string_matches(const char *str, const char *expr, GB_CASE case_sens)
char * ARB_strdup(const char *str)
char * GB_read_as_string(GBDATA *gbd)
const char * GBS_global_string(const char *templat,...)
void cat(const char *from)
GB_CSTR GBS_find_string(GB_CSTR cont, GB_CSTR substr, int match_mode)
char * ARB_strpartdup(const char *start, const char *end)
GBDATA * GB_get_father(GBDATA *gbd)
const char * track_field_access(const char *fieldname) const
#define TEST_PUBLISH(testfunction)
GB_ERROR GB_export_error(const char *error)
GB_ERROR GB_await_error()
void print_trace(const char *text)
bool GBS_string_matches_regexp(const char *str, const GBS_string_matcher *expr)
static void error(const char *msg)
bool GB_is_container(GBDATA *gbd)
void swap_content(GBS_strstruct &other)
const char * GBS_regmatch_compiled(const char *str, GBS_regex *comreg, size_t *matchlen)
char * GBT_join_strings(const CharPtrArray &strings, char separator)
void ncat(const char *from, size_t count)
#define __ATTR__USERESULT
char * GBS_string_eval_in_env(const char *insource, const char *icommand, const GBL_call_env &callEnv)
const char * search_matching_parenthesis(const char *source)
const char * ARB_strchrnul(const char *str, int chr)
void GBS_free_regexpr(GBS_regex *toFree)
GBS_string_matcher * GBS_compile_matcher(const char *search_expr, GB_CASE case_flag)
void GBT_split_string(ConstStrArray &dest, const char *namelist, const char *separator, SplitMode mode)
bool ARB_strBeginsWith(const char *str, const char *with)
const char * get_data() const
NOT4PERL char * GB_command_interpreter_in_env(const char *str, const char *commands, const GBL_call_env &callEnv)
static __ATTR__USERESULT GB_ERROR gbs_build_replace_string(GBS_strstruct &out, char *replaceBy, const char *sWildcards, long sWildMax, const char *const *mWildcards, long mWildMax, const GBL_call_env &callEnv)
GBDATA * GB_search(GBDATA *gbd, const char *fieldpath, GB_TYPES create)
static char * gbs_compress_command(const char *com)
const char * replace(int i, const char *elem)
GB_write_int const char s