35 #include <sys/types.h> 41 #include "import-parse.h" 43 static QofLogModule log_module = GNC_MOD_IMPORT;
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;
57 #define import_set_flag(i,f) (i = static_cast<GncImportFormat>(static_cast<int>(i) | static_cast<int>(f))) 58 #define import_clear_flag(i,f) (i = static_cast<GncImportFormat>(static_cast<int>(i) & static_cast<int>(~f))) 63 int flags = REG_EXTENDED;
66 regcomp(&decimal_radix_regex,
67 "^ *\\$?[+-]?\\$?[0-9]+ *$|^ *\\$?[+-]?\\$?[0-9]?[0-9]?[0-9]?(,[0-9][0-9][0-9])*(\\.[0-9]*)? *$|^ *\\$?[+-]?\\$?[0-9]+\\.[0-9]* *$", flags);
68 regcomp(&comma_radix_regex,
69 "^ *\\$?[+-]?\\$?[0-9]+ *$|^ *\\$?[+-]?\\$?[0-9]?[0-9]?[0-9]?(\\.[0-9][0-9][0-9])*(,[0-9]*)? *$|^ *\\$?[+-]?\\$?[0-9]+,[0-9]* *$", flags);
73 "^ *([0-9]+) *[-/.'] *([0-9]+) *[-/.'] *([0-9]+).*$|^ *([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]).*$", flags);
74 regcomp(&date_mdy_regex,
"([0-9][0-9])([0-9][0-9])([0-9][0-9][0-9][0-9])", flags);
75 regcomp(&date_ymd_regex,
"([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])", flags);
77 regex_compiled = TRUE;
81 my_strntol(
const char *str,
int len)
85 g_return_val_if_fail(str, 0);
86 g_return_val_if_fail(len, 0);
91 if (*str < '0' || *str >
'9')
98 res += *(str++) -
'0';
108 static GncImportFormat
109 check_date_format(
const char * str, regmatch_t *match, GncImportFormat fmts)
111 GncImportFormat res = GNCIF_NONE;
112 int len0 = 0, len1 = 0, len2 = 0;
113 int val0 = 0, val1 = 0, val2 = 0;
115 g_return_val_if_fail(match, res);
116 g_return_val_if_fail(fmts, res);
119 len0 = match[1].rm_eo - match[1].rm_so;
120 len1 = match[2].rm_eo - match[2].rm_so;
121 len2 = match[3].rm_eo - match[3].rm_so;
124 val0 = my_strntol(str + match[1].rm_so, len0);
125 val1 = my_strntol(str + match[2].rm_so, len1);
126 val2 = my_strntol(str + match[3].rm_so, len2);
130 if (val0 > 12) import_clear_flag(fmts, GNCIF_DATE_MDY);
131 if (val0 > 31) import_clear_flag(fmts, GNCIF_DATE_DMY);
134 import_clear_flag(fmts, GNCIF_DATE_DMY);
135 import_clear_flag(fmts, GNCIF_DATE_MDY);
140 import_clear_flag(fmts, GNCIF_DATE_DMY);
141 import_clear_flag(fmts, GNCIF_DATE_YMD);
145 import_clear_flag(fmts, GNCIF_DATE_MDY);
146 import_clear_flag(fmts, GNCIF_DATE_YDM);
149 if (val2 > 12) import_clear_flag(fmts, GNCIF_DATE_YDM);
150 if (val2 > 31) import_clear_flag(fmts, GNCIF_DATE_YMD);
153 import_clear_flag(fmts, GNCIF_DATE_YMD);
154 import_clear_flag(fmts, GNCIF_DATE_YDM);
160 if (len0 == 4 && (val0 < 1930 || val0 > 2100))
162 import_clear_flag(fmts, GNCIF_DATE_YMD);
163 import_clear_flag(fmts, GNCIF_DATE_YDM);
165 if (len2 == 4 && (val2 < 1930 || val2 > 2100))
167 import_clear_flag(fmts, GNCIF_DATE_MDY);
168 import_clear_flag(fmts, GNCIF_DATE_DMY);
176 import_clear_flag(fmts, GNCIF_DATE_YMD);
177 import_clear_flag(fmts, GNCIF_DATE_YDM);
184 gnc_import_test_numeric(
const char* str, GncImportFormat fmts)
186 GncImportFormat res = GNCIF_NONE;
188 g_return_val_if_fail(str, fmts);
193 if ((fmts & GNCIF_NUM_PERIOD) && !regexec(&decimal_radix_regex, str, 0, NULL, 0))
194 import_set_flag (res, GNCIF_NUM_PERIOD);
196 if ((fmts & GNCIF_NUM_COMMA) && !regexec(&comma_radix_regex, str, 0, NULL, 0))
197 import_set_flag (res, GNCIF_NUM_COMMA);
204 gnc_import_test_date(
const char* str, GncImportFormat fmts)
207 GncImportFormat res = GNCIF_NONE;
209 g_return_val_if_fail(str, fmts);
210 g_return_val_if_fail(strlen(str) > 1, fmts);
215 if (!regexec(&date_regex, str, 5, match, 0))
217 if (match[1].rm_so != -1)
218 res = check_date_format(str, match, fmts);
226 char temp[DATE_LEN + 1];
228 g_return_val_if_fail(match[4].rm_so != -1, fmts);
229 g_return_val_if_fail(match[4].rm_eo - match[4].rm_so == DATE_LEN, fmts);
232 strncpy(temp, str + match[4].rm_so, DATE_LEN);
233 temp[DATE_LEN] =
'\0';
236 if (((fmts & GNCIF_DATE_YDM) || (fmts & GNCIF_DATE_YMD)) &&
237 !regexec(&date_ymd_regex, temp, 4, match, 0))
238 import_set_flag (res, check_date_format (temp, match, fmts));
240 if (((fmts & GNCIF_DATE_DMY) || (fmts & GNCIF_DATE_MDY)) &&
241 !regexec(&date_mdy_regex, temp, 4, match, 0))
242 import_set_flag (res, check_date_format (temp, match, fmts));
250 gnc_import_parse_numeric(
const char* str, GncImportFormat fmt, gnc_numeric *val)
252 g_return_val_if_fail(str, FALSE);
253 g_return_val_if_fail(val, FALSE);
254 g_return_val_if_fail(fmt, FALSE);
255 g_return_val_if_fail(!(fmt & (fmt - 1)), FALSE);
259 case GNCIF_NUM_PERIOD:
262 case GNCIF_NUM_COMMA:
266 PERR(
"invalid format: %d", fmt);
284 return (1900 + (y - 19000));
300 gnc_import_parse_date(
const char *str, GncImportFormat fmt,
time64 *val)
306 int v0 = 0, v1 = 0, v2 = 0;
307 int m = 0, d = 0, y = 0;
309 g_return_val_if_fail(str, FALSE);
310 g_return_val_if_fail(val, FALSE);
311 g_return_val_if_fail(fmt, FALSE);
312 g_return_val_if_fail(!(fmt & (fmt - 1)), FALSE);
314 if (!regexec(&date_regex, str, 5, match, 0))
316 if (match[1].rm_so != -1)
323 g_return_val_if_fail(match[4].rm_so != -1, FALSE);
324 g_return_val_if_fail(match[4].rm_eo - match[4].rm_so == 8, FALSE);
326 strncpy(temp, str + match[4].rm_so, 8);
333 g_return_val_if_fail(!regexec(&date_mdy_regex, temp, 4, match, 0), FALSE);
337 g_return_val_if_fail(!regexec(&date_ymd_regex, temp, 4, match, 0), FALSE);
340 PERR(
"Invalid date format provided: %d", fmt);
348 if (match[1].rm_so == -1 || match[2].rm_so == -1 || match[3].rm_so == -1)
350 PERR(
"can't interpret date %s", str);
355 v0 = my_strntol(datestr + match[1].rm_so, match[1].rm_eo - match[1].rm_so);
356 v1 = my_strntol(datestr + match[2].rm_so, match[2].rm_eo - match[2].rm_so);
357 v2 = my_strntol(datestr + match[3].rm_so, match[3].rm_eo - match[3].rm_so);
362 if (v0 > 0 && v0 <= 31 && v1 > 0 && v1 <= 12 && v2 > 0)
369 PERR(
"format is d/m/y but date is %s", str);
373 if (v0 > 0 && v0 <= 12 && v1 > 0 && v1 <= 31 && v2 > 0)
380 PERR(
"format is m/d/y but date is %s", str);
384 if (v0 > 0 && v1 > 0 && v1 <= 12 && v2 > 0 && v2 <= 31)
391 PERR(
"format is y/m/d but date is %s", str);
395 if (v0 > 0 && v1 > 0 && v1 <= 31 && v2 > 0 && v2 <= 12)
402 PERR(
"format is y/d/m but date is %s", str);
406 PERR(
"invalid date format: %d", fmt);
utility functions for the GnuCash UI
time64 gnc_dmy2time64(gint day, gint month, gint year)
Convert a day, month, and year to a time64, returning the first second of the day.
#define PERR(format, args...)
Log a serious error.
gboolean xaccParseAmountExtended(const char *in_str, gboolean monetary, gunichar negative_sign, gunichar decimal_point, gunichar group_separator, const char *ignore_list, gnc_numeric *result, char **endstr)
Converts a string to a gnc_numeric.
All type declarations for the whole Gnucash engine.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...