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

Re: 1st patch for src/formats.c



Hello everyone, hello Jody,

Here is the new patch.

Jody Goldberg <jody gnome org> a écrit :

> 3) the curreny formats are not quite ready.  you need to check for
>     - currency placement (see currency_date_format_init)
>     - and optional single spaces between currency and value.

OK, now the regexp accepts different currency placement and the optional
single space. However I don't know if it's always OK to accept any
placement or if we should add some checking.

Points 1 and 2 are fixed...


Index: formats.c
===================================================================
RCS file: /cvs/gnome/gnumeric/src/formats.c,v
retrieving revision 1.52
diff -u -r1.52 formats.c
--- formats.c	4 Sep 2002 20:29:33 -0000	1.52
+++ formats.c	4 Oct 2002 20:43:06 -0000
@@ -15,6 +15,7 @@
 
 #include "format.h"
 #include <string.h>
+#include <stdio.h>
 
 /* The various formats */
 static char const * const
@@ -161,6 +162,10 @@
 	NULL
 };
 
+/* The compiled regexp for cell_format_classify */
+static regex_t re_number_currency;
+static regex_t re_percent_science;
+
 void
 currency_date_format_init (void)
 {
@@ -234,6 +239,40 @@
 
 		cell_format_time [4]  = "d/m/yy h:mm";
 	}
+
+	/* Compile the regexps for format classification */
+
+	/* This is the regexp for FMT_NUMBER and FMT_CURRENCY */
+	
+	/*
+	 *  1.  "$ #,##0.000"
+	 *   (currency symbol before number)
+	 *  2.  "$ "
+	 *  3.  "$"
+	 *  4.  " " (space after currency)
+	 *  5.  "#,##"
+	 *  6.  ".000"
+	 *   (currency symbol after number)
+	 *  7.  " $"
+	 *  8.  " " (space before currency)
+	 *  9.  "$"
+	 * 10.  11 or 13
+	 * 11.  ";[Red]\1"   (\1 means same string as 1)
+	 * 12.  "[Red]"
+	 * 13.  "_);[Red](\1)"
+	 * 14.  "[Red]"
+	 */
+
+	char const *pattern_number_currency = "^\\(\\(\\(\\$\\|£\\|¥\\|€\\|\\[\\$[A-Z][A-Z][A-Z]\\]\\)\\(\\\\\\? \\)\\?\\)\\?\\(#,##\\)\\?0\\(\\.0\\{1,30\\}\\)\\?\\(\\(\\\\\\? \\)\\?\\(\\$\\|£\\|¥\\|€\\|\\[\\$[A-Z][A-Z][A-Z]\\]\\)\\)\\?\\)\\(\\(;\\(\\[Red\\]\\)\\?\\1\\)\\|\\(_);\\(\\[Red\\]\\)\\?(\\1)\\)\\)\\?$";
+	
+	/* This one is for FMT_PERCENT and FMT_SCIENCE */
+	char const *pattern_percent_science = "^0\\(.0\\{1,30\\}\\)\\?\\(%\\|E+00\\)$";
+
+	if ((regcomp(&re_number_currency, pattern_number_currency, 0)) != 0)
+		fprintf(stderr, "Error in regcomp()\n");
+	
+	if ((regcomp(&re_percent_science, pattern_percent_science, 0)) != 0)
+		fprintf(stderr, "Error in regcomp()\n");
 }
 
 void
@@ -450,141 +489,93 @@
 	return NULL;
 }
 
+/* Returns the index in currency_symbols of the symbol in ptr */
+static int 
+find_currency(char const *ptr, int len)
+{
+	int i;
+	
+	for (i = 0; currency_symbols[i].symbol; i++) {
+		if (strncmp(currency_symbols[i].symbol, ptr, len) == 0)
+			return i;
+	}
+	
+	return -1;
+}
+
 static FormatFamily
 cell_format_is_number (char const * const fmt, FormatCharacteristics *info)
 {
 	FormatFamily result = FMT_NUMBER;
-	gboolean has_sep = FALSE;
-	int use_paren = 0;
-	int use_red = 0;
-	int num_decimals = 0;
-	char const *ptr = fmt, *end, *tmp;
-	int const fmt_len = strlen (fmt);
+	char const *ptr = fmt;
 	int cur = -1;
-
-	if (fmt_len < 1)
-		return FMT_UNKNOWN;
-
-	/* Check for prepended currency */
-	switch (ptr[0]) {
-	case '$' : cur = 1; break;
-	case '£' : cur = 2; break;
-	case '¥' : cur = 3; break;
-	case '¤' : cur = 4; break;
-	default :
-	if (ptr[0] == '[' && ptr[1] == '$') {
-		char const * const end = strchr (ptr, ']');
-
-		if (end != NULL && end[1] == ' ') {
-			/* FIXME : Look up the correct index */
-			info->currency_symbol_index = 1;
+	
+#define MATCH_SIZE 15	
+	regmatch_t match[MATCH_SIZE];	
+
+	// FMT_CURRENCY or FMT_NUMBER ?
+
+	if (regexec(&re_number_currency, fmt, MATCH_SIZE, match, 0) == 0) {
+		
+		/* match[3] and match[9] contain the Currency symbol */
+		if (match[3].rm_eo == -1 && match[9].rm_eo == -1)
+			result = FMT_NUMBER;
+		else {
 			result = FMT_CURRENCY;
-			ptr = end + 1;
-		} else
-			return FMT_UNKNOWN;
-	}
-	};
-
-	if (cur > 0) {
-		info->currency_symbol_index = cur;
-		result = FMT_CURRENCY;
-		++ptr;
-	}
-
-	/* Check for thousands separator */
-	if (ptr[0] == '#') {
-		if (ptr[1] == ',')
-			++ptr;
-		else
-			return FMT_UNKNOWN;
-		ptr = strncmp_inc (ptr, "##", 2);
-		if (ptr == NULL)
-			return FMT_UNKNOWN;
-		has_sep = TRUE;
-	}
-
-	if (ptr[0] != '0')
-		return FMT_UNKNOWN;
-	++ptr;
-
-	/* Check for decimals */
-	if (ptr [0] == '.') {
-		num_decimals = 0;
-		ptr++;
-		while (ptr[num_decimals] == '0')
-			++num_decimals;
-		ptr += num_decimals;
-	}
-
-	if (ptr[0] == '%') {
-		if (!has_sep && info->currency_symbol_index == 0) {
-			info->num_decimals = num_decimals;
-			return FMT_PERCENT;
+			if (match[9].rm_eo == -1)
+				cur = find_currency(ptr + match[3].rm_so,
+						    match[3].rm_eo
+						    - match[3].rm_so);
+			else if (match[3].rm_eo == -1)
+				cur = find_currency(ptr + match[9].rm_so,
+						    match[9].rm_eo
+						    - match[9].rm_so);
+			else
+				return FMT_UNKNOWN;
+			
+			if (cur == -1)
+				return FMT_UNKNOWN;
+			info->currency_symbol_index = cur;
 		}
-		return FMT_UNKNOWN;
-	}
-	if (NULL != (tmp = strcmp_inc (ptr, "E+00"))) {
-		if (!has_sep && info->currency_symbol_index == 0 && *tmp == '\0') {
-			info->num_decimals = num_decimals;
-			return FMT_SCIENCE;
-		}
-		return FMT_UNKNOWN;
-	}
-
-	if (ptr[0] != ';' && ptr[0] != '_' && ptr[0])
-		return FMT_UNKNOWN;
-
-	/* We have now handled decimals, and thousands separators */
-	info->thousands_sep = has_sep;
-	info->num_decimals = num_decimals;
-	info->negative_fmt = 0; /* Temporary, we may change this below */
-
-	/* No special negative handling */
-	if (ptr[0] == '\0')
+		
+		/* match[5] contains the #,## string */
+		if (match[5].rm_eo != -1)
+			info->thousands_sep = TRUE;
+		
+		/* match[6] contains the .0000... string */
+		info->num_decimals = 0;
+		if (match[6].rm_eo != -1)
+			info->num_decimals = match[6].rm_eo -
+				match[6].rm_so - 1;
+		
+		info->negative_fmt = 0;
+		// match[12] and match[14] contain the [Red] string */
+		if ((match[12].rm_eo != -1) || (match[14].rm_eo != -1))
+			info->negative_fmt++;
+		// match[13] contains _);(...)
+		if (match[13].rm_eo != -1)
+			info->negative_fmt += 2;
+		
 		return result;
-
-	/* Save this position */
-	end = ptr;
-
-	/* Handle Trailing '_)' */
-	if (ptr[0] == '_') {
-		if (ptr[1] != ')')
-			return FMT_UNKNOWN;
-		ptr += 2;
-		use_paren = 2;
 	}
 
-	if (ptr[0] != ';')
-		return FMT_UNKNOWN;
-	++ptr;
-
-	if (ptr[0] == '[') {
-		if (g_ascii_strncasecmp (_("[Red]"), ptr, 5) != 0)
-			return FMT_UNKNOWN;
-		ptr += 5;
-		use_red = 1;
-	}
-
-	if (use_paren) {
-		if (ptr[0] != '(')
-			return FMT_UNKNOWN;
-		++ptr;
-	}
-
-	/* The next segment should match the original */
-	ptr = strncmp_inc (ptr, fmt, end-fmt);
-	if (ptr == NULL)
-		return FMT_UNKNOWN;
-
-	if (use_paren) {
-		if (ptr[0] != ')')
-			return FMT_UNKNOWN;
-		++ptr;
+	// FMT_PERCENT or FMT_SCIENCE ?
+	
+	if (regexec(&re_percent_science, fmt, MATCH_SIZE, match, 0) == 0) {
+		
+		info->num_decimals = 0;
+		if (match[1].rm_eo != -1)
+			info->num_decimals = match[1].rm_eo -
+				match[1].rm_so - 1;
+		
+		if (ptr[match[2].rm_so] == '%')
+			return FMT_PERCENT;
+		else
+			return FMT_SCIENCE;
 	}
-
-	info->negative_fmt = use_paren + use_red;
-
-	return result;
+	
+	return FMT_UNKNOWN;
+	
 }
 
 FormatFamily


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