--- formats.c.~1.52.~ 2002-09-04 22:29:33.000000000 +0200 +++ formats.c 2002-09-23 21:21:34.000000000 +0200 @@ -450,141 +450,101 @@ return NULL; } +/* Returns the index in currency_symbols of the symbol in ptr */ +int find_currency(char const *ptr, int len) { + int i; + + /* remove the trailing "\ " */ + if (ptr[0] == '[') + len -= 2; + + 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; + + /* This is the regexp for FMT_NUMBER and FMT_CURRENCY */ + char const *pattern_number_currency = "^\\(\\(\\$\\|£\\|Â¥\\|€\\|\\[\\$[A-Z][A-Z][A-Z]\\]\\\\ \\)\\?\\(#,##\\)\\?0\\(\\.0\\{1,30\\}\\)\\?\\)\\(\\(;\\(\\[Red\\]\\)\\?\\1\\)\\?\\|_)\\(;\\(\\[Red\\]\\)\\?(\\1)\\)\\?\\)$"; + regex_t re_number_currency; + + /* This one is for FMT_PERCENT and FMT_SCIENCE */ + char const *pattern_percent_science = "^0\\(.0\\{1,30\\}\\)\\?\\(%\\|E+00\\)$"; + regex_t re_percent_science; + + +#define MATCH_SIZE 10 + regmatch_t match[MATCH_SIZE]; + + // FMT_CURRENCY or FMT_NUMBER ? + + if ((regcomp(&re_number_currency, pattern_number_currency, 0)) != 0) + return FMT_UNKNOWN; + + if (regexec(&re_number_currency, fmt, MATCH_SIZE, match, 0) == 0) { + + /* match[2] contains the Currency symbol */ + if (match[2].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; - } - 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; + cur = find_currency(ptr + match[2].rm_so, + match[2].rm_eo - match[2].rm_so); + if (cur == -1) + return FMT_UNKNOWN; + info->currency_symbol_index = cur; } - 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 */ + + /* match[3] contains the #,## string */ + if (match[3].rm_eo != -1) + info->thousands_sep = TRUE; + + /* match[4] contains the .0000... string */ + info->num_decimals = 0; + if (match[4].rm_eo != -1) + info->num_decimals = match[4].rm_eo - + match[4].rm_so - 1; + + info->negative_fmt = 0; + // match[7] and match[9] contain the [Red] string */ + if ((match[7].rm_eo != -1) || (match[9].rm_eo != -1)) + info->negative_fmt++; + // match[8] contains _);(...) + if (match[8].rm_eo != -1) + info->negative_fmt += 2; - /* No special negative handling */ - if (ptr[0] == '\0') 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 ((regcomp(&re_percent_science, pattern_percent_science, 0)) != 0) + return FMT_UNKNOWN; + + 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