gnumeric r17122 - in trunk: . plugins/fn-lookup plugins/fn-string src



Author: mortenw
Date: Mon Feb  2 18:32:34 2009
New Revision: 17122
URL: http://svn.gnome.org/viewvc/gnumeric?rev=17122&view=rev

Log:
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.



Modified:
   trunk/ChangeLog
   trunk/NEWS
   trunk/plugins/fn-lookup/ChangeLog
   trunk/plugins/fn-lookup/functions.c
   trunk/plugins/fn-string/functions.c
   trunk/src/gutils.c
   trunk/src/gutils.h
   trunk/src/sheet-filter.c

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS	(original)
+++ trunk/NEWS	Mon Feb  2 18:32:34 2009
@@ -95,6 +95,7 @@
 	* 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

Modified: trunk/plugins/fn-lookup/functions.c
==============================================================================
--- trunk/plugins/fn-lookup/functions.c	(original)
+++ trunk/plugins/fn-lookup/functions.c	Mon Feb  2 18:32:34 2009
@@ -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 @@
 	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 @@
 	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 @@
 	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 @@
 
 	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) {

Modified: trunk/plugins/fn-string/functions.c
==============================================================================
--- trunk/plugins/fn-string/functions.c	(original)
+++ trunk/plugins/fn-string/functions.c	Mon Feb  2 18:32:34 2009
@@ -1192,7 +1192,7 @@
 		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)) {

Modified: trunk/src/gutils.c
==============================================================================
--- trunk/src/gutils.c	(original)
+++ trunk/src/gutils.c	Mon Feb  2 18:32:34 2009
@@ -156,11 +156,15 @@
 }
 
 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 @@
 		}
 	}
 
+	if (full)
+		g_string_append_c (res, '$');
+
 	retval = go_regcomp (preg, res->str, cflags);
 	g_string_free (res, TRUE);
 	return retval;

Modified: trunk/src/gutils.h
==============================================================================
--- trunk/src/gutils.h	(original)
+++ trunk/src/gutils.h	Mon Feb  2 18:32:34 2009
@@ -19,7 +19,8 @@
 
 #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;

Modified: trunk/src/sheet-filter.c
==============================================================================
--- trunk/src/sheet-filter.c	(original)
+++ trunk/src/sheet-filter.c	Mon Feb  2 18:32:34 2009
@@ -149,7 +149,7 @@
 			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;
 		}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]