35 #include <sys/types.h>
41 #include "import-parse.h"
46 static regex_t decimal_radix_regex;
47 static regex_t comma_radix_regex;
50 static regex_t date_regex;
51 static regex_t date_mdy_regex;
52 static regex_t date_ymd_regex;
54 static gboolean regex_compiled = FALSE;
59 int flags = REG_EXTENDED;
62 regcomp(&decimal_radix_regex,
63 "^ *\\$?[+-]?\\$?[0-9]+ *$|^ *\\$?[+-]?\\$?[0-9]?[0-9]?[0-9]?(,[0-9][0-9][0-9])*(\\.[0-9]*)? *$|^ *\\$?[+-]?\\$?[0-9]+\\.[0-9]* *$", flags);
64 regcomp(&comma_radix_regex,
65 "^ *\\$?[+-]?\\$?[0-9]+ *$|^ *\\$?[+-]?\\$?[0-9]?[0-9]?[0-9]?(\\.[0-9][0-9][0-9])*(,[0-9]*)? *$|^ *\\$?[+-]?\\$?[0-9]+,[0-9]* *$", flags);
69 "^ *([0-9]+) *[-/.'] *([0-9]+) *[-/.'] *([0-9]+).*$|^ *([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]).*$", flags);
70 regcomp(&date_mdy_regex,
"([0-9][0-9])([0-9][0-9])([0-9][0-9][0-9][0-9])", flags);
71 regcomp(&date_ymd_regex,
"([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])", flags);
73 regex_compiled = TRUE;
77 my_strntol(
const char *str,
int len)
81 g_return_val_if_fail(str, 0);
82 g_return_val_if_fail(len, 0);
87 if (*str < '0' || *str >
'9')
94 res += *(str++) -
'0';
104 static GncImportFormat
105 check_date_format(
const char * str, regmatch_t *match, GncImportFormat fmts)
107 GncImportFormat res = 0;
108 int len0 = 0, len1 = 0, len2 = 0;
109 int val0 = 0, val1 = 0, val2 = 0;
111 g_return_val_if_fail(match, res);
112 g_return_val_if_fail(fmts, res);
115 len0 = match[1].rm_eo - match[1].rm_so;
116 len1 = match[2].rm_eo - match[2].rm_so;
117 len2 = match[3].rm_eo - match[3].rm_so;
120 val0 = my_strntol(str + match[1].rm_so, len0);
121 val1 = my_strntol(str + match[2].rm_so, len1);
122 val2 = my_strntol(str + match[3].rm_so, len2);
126 if (val0 > 12) import_clear_flag(fmts, GNCIF_DATE_MDY);
127 if (val0 > 31) import_clear_flag(fmts, GNCIF_DATE_DMY);
130 import_clear_flag(fmts, GNCIF_DATE_DMY);
131 import_clear_flag(fmts, GNCIF_DATE_MDY);
136 import_clear_flag(fmts, GNCIF_DATE_DMY);
137 import_clear_flag(fmts, GNCIF_DATE_YMD);
141 import_clear_flag(fmts, GNCIF_DATE_MDY);
142 import_clear_flag(fmts, GNCIF_DATE_YDM);
145 if (val2 > 12) import_clear_flag(fmts, GNCIF_DATE_YDM);
146 if (val2 > 31) import_clear_flag(fmts, GNCIF_DATE_YMD);
149 import_clear_flag(fmts, GNCIF_DATE_YMD);
150 import_clear_flag(fmts, GNCIF_DATE_YDM);
156 if (len0 == 4 && (val0 < 1930 || val0 > 2100))
158 import_clear_flag(fmts, GNCIF_DATE_YMD);
159 import_clear_flag(fmts, GNCIF_DATE_YDM);
161 if (len2 == 4 && (val2 < 1930 || val2 > 2100))
163 import_clear_flag(fmts, GNCIF_DATE_MDY);
164 import_clear_flag(fmts, GNCIF_DATE_DMY);
172 import_clear_flag(fmts, GNCIF_DATE_YMD);
173 import_clear_flag(fmts, GNCIF_DATE_YDM);
180 gnc_import_test_numeric(
const char* str, GncImportFormat fmts)
182 GncImportFormat res = 0;
184 g_return_val_if_fail(str, fmts);
189 if ((fmts & GNCIF_NUM_PERIOD) && !regexec(&decimal_radix_regex, str, 0, NULL, 0))
190 res |= GNCIF_NUM_PERIOD;
192 if ((fmts & GNCIF_NUM_COMMA) && !regexec(&comma_radix_regex, str, 0, NULL, 0))
193 res |= GNCIF_NUM_COMMA;
200 gnc_import_test_date(
const char* str, GncImportFormat fmts)
203 GncImportFormat res = 0;
205 g_return_val_if_fail(str, fmts);
206 g_return_val_if_fail(strlen(str) > 1, fmts);
211 if (!regexec(&date_regex, str, 5, match, 0))
213 if (match[1].rm_so != -1)
214 res = check_date_format(str, match, fmts);
223 g_return_val_if_fail(match[4].rm_so != -1, fmts);
224 g_return_val_if_fail(match[4].rm_eo - match[4].rm_so == 8, fmts);
227 strncpy(temp, str + match[4].rm_so, 8);
231 if (((fmts & GNCIF_DATE_YDM) || (fmts & GNCIF_DATE_YMD)) &&
232 !regexec(&date_ymd_regex, temp, 4, match, 0))
233 res |= check_date_format(temp, match, fmts);
235 if (((fmts & GNCIF_DATE_DMY) || (fmts & GNCIF_DATE_MDY)) &&
236 !regexec(&date_mdy_regex, temp, 4, match, 0))
237 res |= check_date_format(temp, match, fmts);
245 gnc_import_parse_numeric(
const char* str, GncImportFormat fmt,
gnc_numeric *val)
247 g_return_val_if_fail(str, FALSE);
248 g_return_val_if_fail(val, FALSE);
249 g_return_val_if_fail(fmt, FALSE);
250 g_return_val_if_fail(!(fmt & (fmt - 1)), FALSE);
254 case GNCIF_NUM_PERIOD:
255 return xaccParseAmountExtended(str, TRUE,
'-',
'.',
',', NULL,
"$+",
257 case GNCIF_NUM_COMMA:
258 return xaccParseAmountExtended(str, TRUE,
'-',
',',
'.', NULL,
"$+",
261 PERR(
"invalid format: %d", fmt);
279 return (1900 + (y - 19000));
295 gnc_import_parse_date(
const char *str, GncImportFormat fmt,
Timespec *val)
301 int v0 = 0, v1 = 0, v2 = 0;
302 int m = 0, d = 0, y = 0;
304 g_return_val_if_fail(str, FALSE);
305 g_return_val_if_fail(val, FALSE);
306 g_return_val_if_fail(fmt, FALSE);
307 g_return_val_if_fail(!(fmt & (fmt - 1)), FALSE);
309 if (!regexec(&date_regex, str, 5, match, 0))
311 if (match[1].rm_so != -1)
318 g_return_val_if_fail(match[4].rm_so != -1, FALSE);
319 g_return_val_if_fail(match[4].rm_eo - match[4].rm_so == 8, FALSE);
321 strncpy(temp, str + match[4].rm_so, 8);
328 g_return_val_if_fail(!regexec(&date_mdy_regex, temp, 4, match, 0), FALSE);
332 g_return_val_if_fail(!regexec(&date_ymd_regex, temp, 4, match, 0), FALSE);
335 PERR(
"Invalid date format provided: %d", fmt);
343 if (match[1].rm_so == -1 || match[2].rm_so == -1 || match[3].rm_so == -1)
345 PERR(
"can't interpret date %s", str);
350 v0 = my_strntol(datestr + match[1].rm_so, match[1].rm_eo - match[1].rm_so);
351 v1 = my_strntol(datestr + match[2].rm_so, match[2].rm_eo - match[2].rm_so);
352 v2 = my_strntol(datestr + match[3].rm_so, match[3].rm_eo - match[3].rm_so);
357 if (v0 > 0 && v0 <= 31 && v1 > 0 && v1 <= 12 && v2 > 0)
364 PERR(
"format is d/m/y but date is %s", str);
368 if (v0 > 0 && v0 <= 12 && v1 > 0 && v1 <= 31 && v2 > 0)
375 PERR(
"format is m/d/y but date is %s", str);
379 if (v0 > 0 && v1 > 0 && v1 <= 12 && v2 > 0 && v2 <= 31)
386 PERR(
"format is y/m/d but date is %s", str);
390 if (v0 > 0 && v1 > 0 && v1 <= 31 && v2 > 0 && v2 <= 12)
397 PERR(
"format is y/d/m but date is %s", str);
401 PERR(
"invalid date format: %d", fmt);
utility functions for the GnuCash UI
Use a 64-bit unsigned int timespec.
Timespec gnc_dmy2timespec(gint day, gint month, gint year)
#define PERR(format, args...)
All type declarations for the whole Gnucash engine.
const gchar * QofLogModule