Commit 090f4187 authored by Morten Welinder's avatar Morten Welinder Committed by Morten Welinder

Take new argument "full" for indicating that the match must be for the

2009-02-02  Morten Welinder  <terra@gnome.org>

	* src/gutils.c (gnm_regcomp_XL): Take new argument "full" for
	indicating that the match must be for the full string.  All
	callers changed.

2009-02-02  Morten Welinder  <terra@gnome.org>

	* functions.c (wildcard_string_match): New function.
	(find_index_bisection): Call wildcard_string_match for the type=0
	case.
	(gnumeric_match): For the type=0 string case, use
	find_index_bisection if there are any wildcards.


svn path=/trunk/; revision=17122
parent 690f615a
2009-02-02 Morten Welinder <terra@gnome.org>
* src/gutils.c (gnm_regcomp_XL): Take new argument "full" for
indicating that the match must be for the full string. All
callers changed.
2009-01-31 Morten Welinder <terra@gnome.org>
* src/parser.y (build_range_ctor): Use gnm_expr_new_range_ctor,
......
......@@ -95,6 +95,7 @@ Morten:
* Fix plugin menu merging. [#569724]
* Improve handling of 3D ranges. [#569372]
* For VLOOKUP and friends, do not turn empties into zeroes. [#567389]
* Implement MATCH for wildcards. [#570139]
--------------------------------------------------------------------------
Gnumeric 1.9.3
......
2009-02-02 Morten Welinder <terra@gnome.org>
* functions.c (wildcard_string_match): New function.
(find_index_bisection): Call wildcard_string_match for the type=0
case.
(gnumeric_match): For the type=0 string case, use
find_index_bisection if there are any wildcards.
2009-02-01 Morten Welinder <terra@gnome.org>
* functions.c (get_elem): Don't turn empties into 0.
......
......@@ -39,6 +39,7 @@
#include <application.h>
#include <expr-name.h>
#include <mathfunc.h>
#include <gutils.h>
#include <parse-util.h>
#include <gnm-i18n.h>
......@@ -450,6 +451,30 @@ find_index_linear (GnmFuncEvalInfo *ei,
return LOOKUP_DATA_ERROR;
}
static int
wildcard_string_match (const char *key, LookupBisectionCacheItem *bc)
{
GORegexp rx;
GORegmatch rm;
int i, res = LOOKUP_NOT_THERE;
if (gnm_regcomp_XL (&rx, key, REG_ICASE, TRUE) != REG_OK) {
g_warning ("Unexpected regcomp result");
return LOOKUP_DATA_ERROR;
}
for (i = 0; i < bc->n; i++) {
if (go_regexec (&rx, bc->data[i].u.str, 1, &rm, 0) == REG_OK) {
res = i;
break;
}
}
go_regfree (&rx);
return res;
}
#undef DEBUG_BISECTION
static int
......@@ -501,6 +526,9 @@ find_index_bisection (GnmFuncEvalInfo *ei,
g_printerr ("find=%s\n", value_peek_string (find));
#endif
if (type == 0)
return wildcard_string_match (value_peek_string (find), bc);
if (stringp) {
char *vc = g_utf8_casefold (value_peek_string (find), -1);
key.u.str = g_string_chunk_insert (lookup_string_pool, vc);
......@@ -1071,8 +1099,10 @@ gnumeric_match (GnmFuncEvalInfo *ei, GnmValue const * const *args)
int width = value_area_get_width (args[1], ei->pos);
int height = value_area_get_height (args[1], ei->pos);
gboolean vertical;
GnmValue const *find = args[0];
gboolean is_string_match = FALSE;
if (!find_type_valid (args[0]))
if (!find_type_valid (find))
return value_new_error_NA (ei->pos);
if (width > 1 && height > 1)
......@@ -1081,15 +1111,21 @@ gnumeric_match (GnmFuncEvalInfo *ei, GnmValue const * const *args)
type = VALUE_IS_EMPTY (args[2]) ? 1 : value_get_as_int (args[2]);
/*
* FIXME: if type==0 and type is string, we ought to do some kind
* of match with "*" and "?".
*/
if (type == 0)
index = find_index_linear (ei, args[0], args[1],
vertical);
if (type == 0 && VALUE_IS_STRING (find)) {
const char *s = value_peek_string (find);
while (*s) {
if (*s == '*' || *s == '?' || *s == '~') {
is_string_match = TRUE;
break;
}
s++;
}
}
if (type == 0 && !is_string_match)
index = find_index_linear (ei, find, args[1], vertical);
else
index = find_index_bisection (ei, args[0], args[1], type,
index = find_index_bisection (ei, find, args[1], type,
vertical);
switch (index) {
......
......@@ -1192,7 +1192,7 @@ gnumeric_search (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
hay2 = g_utf8_next_char (hay2);
}
if (gnm_regcomp_XL (&r, needle, REG_ICASE) == REG_OK) {
if (gnm_regcomp_XL (&r, needle, REG_ICASE, FALSE) == REG_OK) {
GORegmatch rm;
switch (go_regexec (&r, hay2, 1, &rm, 0)) {
......
......@@ -156,11 +156,15 @@ gnm_usr_dir (void)
}
int
gnm_regcomp_XL (GORegexp *preg, char const *pattern, int cflags)
gnm_regcomp_XL (GORegexp *preg, char const *pattern, int cflags,
gboolean full)
{
GString *res = g_string_new (NULL);
int retval;
if (full)
g_string_append_c (res, '^');
while (*pattern) {
switch (*pattern) {
case '*':
......@@ -181,6 +185,9 @@ gnm_regcomp_XL (GORegexp *preg, char const *pattern, int cflags)
}
}
if (full)
g_string_append_c (res, '$');
retval = go_regcomp (preg, res->str, cflags);
g_string_free (res, TRUE);
return retval;
......
......@@ -19,7 +19,8 @@ char const *gnm_usr_dir (void);
#define PLUGIN_SUBDIR "plugins"
int gnm_regcomp_XL (GORegexp *preg, char const *pattern, int cflags);
int gnm_regcomp_XL (GORegexp *preg, char const *pattern,
int cflags, gboolean full);
/* Locale utilities */
typedef struct _GnmLocale GnmLocale;
......
......@@ -149,7 +149,7 @@ filter_expr_init (FilterExpr *fexpr, unsigned i,
workbook_date_conv (filter->sheet->workbook);
if ((op == GNM_FILTER_OP_EQUAL || op == GNM_FILTER_OP_NOT_EQUAL) &&
gnm_regcomp_XL (fexpr->regexp + i, str, REG_ICASE) == REG_OK) {
gnm_regcomp_XL (fexpr->regexp + i, str, REG_ICASE, TRUE) == REG_OK) {
fexpr->val[i] = NULL;
return;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment