24 #define __EXTENSIONS__
35 #include "sixtp-utils.h"
39 #ifdef GNUCASH_MAJOR_VERSION
49 isspace_str(
const gchar *str,
int nomorethan)
51 const gchar *cursor = str;
52 while (*cursor && (nomorethan != 0))
54 if (!isspace(*cursor))
65 allow_and_ignore_only_whitespace(GSList *sibling_data,
72 return(isspace_str(text, length));
76 generic_accumulate_chars(GSList *sibling_data,
84 gchar *copytxt = g_strndup(text, length);
85 g_return_val_if_fail(result, FALSE);
93 generic_free_data_for_children(gpointer data_for_children,
94 GSList* data_from_children,
101 if (data_for_children) g_free(data_for_children);
105 concatenate_child_result_chars(GSList *data_from_children)
108 gchar *name = g_strdup(
"");
110 g_return_val_if_fail(name, NULL);
113 data_from_children = g_slist_reverse(g_slist_copy(data_from_children));
115 for (lp = data_from_children; lp; lp = lp->next)
118 if (cr->type != SIXTP_CHILD_RESULT_CHARS)
120 PERR (
"result type is not chars");
121 g_slist_free (data_from_children);
128 temp = g_strconcat(name, (gchar *) cr->data, NULL);
133 g_slist_free (data_from_children);
147 string_to_double(
const char *str,
double *result)
151 g_return_val_if_fail(str, FALSE);
152 g_return_val_if_fail(result, FALSE);
154 *result = strtod (str, &endptr);
155 if (endptr == str)
return (FALSE);
166 string_to_gint64(
const gchar *str, gint64 *v)
172 g_return_val_if_fail(str, FALSE);
175 if (sscanf(str,
" " QOF_SCANF_LLD
"%n", &v_in, &num_read) < 1)
185 while ( (*((gchar*)str + num_read) !=
'\0') &&
186 isspace(*((
unsigned char*)str + num_read)))
192 if (!isspace_str(str + num_read, -1))
return(FALSE);
201 string_to_gint32(
const gchar *str, gint32 *v)
208 if (sscanf(str,
" %d%n", &v_in, &num_read) < 1)
212 while ( (*((gchar*)str + num_read) !=
'\0') &&
213 isspace(*((
unsigned char*)str + num_read)))
219 if (!isspace_str(str + num_read, -1))
return(FALSE);
228 hex_string_to_binary(
const gchar *str,
void **v, guint64 *data_len)
231 const gchar *cursor = str;
233 gboolean error = FALSE;
235 g_return_val_if_fail(str, FALSE);
236 g_return_val_if_fail(v, FALSE);
237 g_return_val_if_fail(data_len, FALSE);
239 str_len = strlen(str);
243 if ((str_len % 2) != 0)
return(FALSE);
245 *v = g_new0(
char, str_len / 2);
247 g_return_val_if_fail(*v, FALSE);
249 while (*cursor && *(cursor + 1))
254 if (isspace(*cursor) || isspace(*(cursor + 1)))
262 tmpstr[0] = *(cursor + 1);
264 if ((sscanf(tmpstr,
"%x%n", &tmpint, &num_read) < 1)
271 *((gchar *) (v + *data_len)) = tmpint;
278 if (error || (*data_len != (str_len / 2)))
311 generic_return_chars_end_handler(gpointer data_for_children,
312 GSList* data_from_children,
313 GSList* sibling_data,
314 gpointer parent_data,
315 gpointer global_data,
321 txt = concatenate_child_result_chars(data_from_children);
322 g_return_val_if_fail(txt, FALSE);
329 simple_chars_only_parser_new(sixtp_end_handler end_handler)
331 return sixtp_set_any(
333 SIXTP_END_HANDLER_ID, (end_handler
335 : generic_return_chars_end_handler),
336 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
337 SIXTP_CLEANUP_RESULT_ID, sixtp_child_free_data,
338 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
339 SIXTP_RESULT_FAIL_ID, sixtp_child_free_data,
340 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
341 SIXTP_NO_MORE_HANDLERS);
362 string_to_timespec_secs(
const gchar *str,
Timespec *ts)
365 struct tm parsed_time;
370 if (!str || !ts)
return FALSE;
372 memset(&parsed_time, 0,
sizeof(
struct tm));
377 strpos = strptime(str, TIMESPEC_PARSE_TIME_FORMAT, &parsed_time);
379 g_return_val_if_fail(strpos, FALSE);
390 if (sscanf(strpos,
" %c%1d%1d%1d%1d%n",
401 if ((sign !=
'+') && (sign !=
'-'))
return(FALSE);
402 if (!isspace_str(strpos + num_read, -1))
return(FALSE);
404 gmtoff = (h1 * 10 + h2) * 60 * 60;
405 gmtoff += (m1 * 10 + m2) * 60;
406 if (sign ==
'-') gmtoff = - gmtoff;
408 parsed_time.tm_isdst = -1;
413 parsed_secs -= gmtoff;
415 ts->tv_sec = parsed_secs;
421 string_to_timespec_nsecs(
const gchar *str,
Timespec *ts)
424 unsigned int charcount;
426 if (!str || !ts)
return FALSE;
429 if (1 != sscanf(str,
" %ld%n", &nanosecs, &charcount))
432 while ( (*((gchar*)str + charcount) !=
'\0') &&
433 isspace(*((
unsigned char*)str + charcount)))
436 if (charcount != strlen(str))
return(FALSE);
438 ts->tv_nsec = nanosecs;
461 generic_timespec_start_handler(GSList* sibling_data, gpointer parent_data,
462 gpointer global_data,
463 gpointer *data_for_children, gpointer *result,
464 const gchar *tag, gchar **attrs)
467 g_return_val_if_fail(tsp, FALSE);
468 *data_for_children = tsp;
480 if ((info->s_block_count > 1) || (info->ns_block_count > 1) ||
481 ((info->s_block_count == 0) && (info->ns_block_count == 0)))
512 generic_timespec_secs_end_handler(gpointer data_for_children,
513 GSList *data_from_children, GSList *sibling_data,
514 gpointer parent_data, gpointer global_data,
515 gpointer *result,
const gchar *tag)
521 g_return_val_if_fail(parent_data, FALSE);
523 txt = concatenate_child_result_chars(data_from_children);
524 g_return_val_if_fail(txt, FALSE);
526 ok = string_to_timespec_secs(txt, &(info->ts));
529 g_return_val_if_fail(ok, FALSE);
531 info->s_block_count++;
553 generic_timespec_nsecs_end_handler(gpointer data_for_children,
554 GSList *data_from_children, GSList *sibling_data,
555 gpointer parent_data, gpointer global_data,
556 gpointer *result,
const gchar *tag)
562 g_return_val_if_fail(parent_data, FALSE);
564 txt = concatenate_child_result_chars(data_from_children);
565 g_return_val_if_fail(txt, FALSE);
567 ok = string_to_timespec_nsecs(txt, &(info->ts));
570 g_return_val_if_fail(ok, FALSE);
572 info->ns_block_count++;
577 timespec_sixtp_new(sixtp_end_handler ender)
579 return sixtp_set_any(
581 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
582 SIXTP_END_HANDLER_ID, ender,
583 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
584 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
585 SIXTP_NO_MORE_HANDLERS);
589 generic_timespec_parser_new(sixtp_end_handler end_handler)
592 sixtp_set_any(sixtp_new(), FALSE,
593 SIXTP_START_HANDLER_ID, generic_timespec_start_handler,
594 SIXTP_CHARACTERS_HANDLER_ID, allow_and_ignore_only_whitespace,
595 SIXTP_END_HANDLER_ID, end_handler,
596 SIXTP_CLEANUP_RESULT_ID, sixtp_child_free_data,
597 SIXTP_FAIL_HANDLER_ID, generic_free_data_for_children,
598 SIXTP_RESULT_FAIL_ID, sixtp_child_free_data,
599 SIXTP_NO_MORE_HANDLERS);
600 g_return_val_if_fail(top_level, NULL);
602 if (!sixtp_add_some_sub_parsers(
604 "s", timespec_sixtp_new(generic_timespec_secs_end_handler),
605 "ns", timespec_sixtp_new(generic_timespec_nsecs_end_handler),
636 generic_guid_end_handler(gpointer data_for_children,
637 GSList *data_from_children, GSList *sibling_data,
638 gpointer parent_data, gpointer global_data,
639 gpointer *result,
const gchar *tag)
645 txt = concatenate_child_result_chars(data_from_children);
646 g_return_val_if_fail(txt, FALSE);
660 PERR (
"couldn't parse GncGUID");
670 generic_guid_parser_new(
void)
672 return sixtp_set_any(
674 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
675 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
676 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
677 SIXTP_END_HANDLER_ID, generic_guid_end_handler,
678 SIXTP_RESULT_FAIL_ID, sixtp_child_free_data,
679 SIXTP_CLEANUP_RESULT_ID, sixtp_child_free_data,
680 SIXTP_NO_MORE_HANDLERS);
705 generic_gnc_numeric_end_handler(gpointer data_for_children,
706 GSList *data_from_children, GSList *sibling_data,
707 gpointer parent_data, gpointer global_data,
708 gpointer *result,
const gchar *tag)
714 txt = concatenate_child_result_chars(data_from_children);
732 PERR (
"couldn't parse numeric quantity");
740 generic_gnc_numeric_parser_new(
void)
742 return sixtp_set_any(
744 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
745 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
746 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
747 SIXTP_END_HANDLER_ID, generic_gnc_numeric_end_handler,
748 SIXTP_RESULT_FAIL_ID, sixtp_child_free_data,
749 SIXTP_CLEANUP_RESULT_ID, sixtp_child_free_data,
750 SIXTP_NO_MORE_HANDLERS);
756 restore_char_generator(sixtp_end_handler ender)
758 return sixtp_set_any(
760 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
761 SIXTP_END_HANDLER_ID, ender,
762 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
763 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
764 SIXTP_NO_MORE_HANDLERS);
Date and Time handling routines.
gboolean string_to_guid(const gchar *string, GncGUID *guid)
Use a 64-bit unsigned int timespec.
#define PERR(format, args...)
gboolean string_to_gnc_numeric(const gchar *str, gnc_numeric *n)
time64 gnc_timegm(struct tm *time)
calculate seconds from the epoch given a time struct
const gchar * QofLogModule