42 #include "sixtp-utils.h" 47 static QofLogModule log_module = GNC_MOD_IO;
50 isspace_str (
const gchar* str,
int nomorethan)
52 const gchar* cursor = str;
53 while (*cursor && (nomorethan != 0))
55 if (!isspace (*cursor))
66 allow_and_ignore_only_whitespace (GSList* sibling_data,
73 return (isspace_str (text, length));
77 generic_accumulate_chars (GSList* sibling_data,
85 gchar* copytxt = g_strndup (text, length);
86 g_return_val_if_fail (result, FALSE);
94 generic_free_data_for_children (gpointer data_for_children,
95 GSList* data_from_children,
102 if (data_for_children) g_free (data_for_children);
106 concatenate_child_result_chars (GSList* data_from_children)
109 gchar* name = g_strdup (
"");
111 g_return_val_if_fail (name, NULL);
114 data_from_children = g_slist_reverse (g_slist_copy (data_from_children));
116 for (lp = data_from_children; lp; lp = lp->next)
118 sixtp_child_result* cr = (sixtp_child_result*) lp->data;
119 if (cr->type != SIXTP_CHILD_RESULT_CHARS)
121 PERR (
"result type is not chars");
122 g_slist_free (data_from_children);
129 temp = g_strconcat (name, (gchar*) cr->data,
nullptr);
134 g_slist_free (data_from_children);
143 template <
typename T>
144 static bool parse_chars_into_num (
const char* str, T* num_ptr)
146 if (!str || !num_ptr)
149 while (std::isspace (*str))
152 const char* end_ptr = str + std::strlen (str);
154 auto res = std::from_chars (str, end_ptr, *num_ptr);
155 if (res.ec != std::errc{})
158 while (std::isspace (*res.ptr))
161 return (res.ptr == end_ptr);
169 string_to_double (
const char* str,
double* result)
171 #if __cpp_lib_to_chars >= 201611L 172 return parse_chars_into_num<double>(str, result);
175 char* endptr =
nullptr;
176 g_return_val_if_fail (str && result,
false);
177 *result = std::strtod (str, &endptr);
178 return (endptr != str);
186 string_to_gint64 (
const gchar* str, gint64* v)
188 return parse_chars_into_num<gint64>(str, v);
195 string_to_guint16 (
const gchar* str, guint16* v)
197 return parse_chars_into_num<guint16>(str, v);
204 string_to_guint (
const gchar* str, guint* v)
206 return parse_chars_into_num<guint>(str, v);
214 hex_string_to_binary (
const gchar* str,
void** v, guint64* data_len)
217 const gchar* cursor = str;
219 gboolean error = FALSE;
221 g_return_val_if_fail (str, FALSE);
222 g_return_val_if_fail (v, FALSE);
223 g_return_val_if_fail (data_len, FALSE);
225 str_len = strlen (str);
229 if ((str_len % 2) != 0)
return (FALSE);
231 *v = g_new0 (
char, str_len / 2);
233 g_return_val_if_fail (*v, FALSE);
235 while (*cursor && * (cursor + 1))
240 if (isspace (*cursor) || isspace (* (cursor + 1)))
248 tmpstr[0] = * (cursor + 1);
250 if ((sscanf (tmpstr,
"%x%n", &tmpint, &num_read) < 1)
257 * ((gchar*) (v + *data_len)) = tmpint;
264 if (error || (*data_len != (str_len / 2)))
297 generic_return_chars_end_handler (gpointer data_for_children,
298 GSList* data_from_children,
299 GSList* sibling_data,
300 gpointer parent_data,
301 gpointer global_data,
307 txt = concatenate_child_result_chars (data_from_children);
308 g_return_val_if_fail (txt, FALSE);
315 simple_chars_only_parser_new (sixtp_end_handler end_handler)
317 return sixtp_set_any (
319 SIXTP_END_HANDLER_ID, (end_handler
321 : generic_return_chars_end_handler),
322 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
323 SIXTP_CLEANUP_RESULT_ID, sixtp_child_free_data,
324 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
325 SIXTP_RESULT_FAIL_ID, sixtp_child_free_data,
326 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
327 SIXTP_NO_MORE_HANDLERS);
365 generic_timespec_start_handler (GSList* sibling_data, gpointer parent_data,
366 gpointer global_data,
367 gpointer* data_for_children, gpointer* result,
368 const gchar* tag, gchar** attrs)
371 g_return_val_if_fail (tsp, FALSE);
372 *data_for_children = tsp;
383 return info->s_block_count != 1;
407 generic_timespec_secs_end_handler (gpointer data_for_children,
408 GSList* data_from_children, GSList* sibling_data,
409 gpointer parent_data, gpointer global_data,
410 gpointer* result,
const gchar* tag)
415 g_return_val_if_fail (parent_data, FALSE);
417 txt = concatenate_child_result_chars (data_from_children);
418 g_return_val_if_fail (txt, FALSE);
424 g_return_val_if_fail (info->time < INT64_MAX, FALSE);
426 info->s_block_count++;
448 generic_timespec_nsecs_end_handler (gpointer data_for_children,
449 GSList* data_from_children, GSList* sibling_data,
450 gpointer parent_data, gpointer global_data,
451 gpointer* result,
const gchar* tag)
457 timespec_sixtp_new (sixtp_end_handler ender)
459 return sixtp_set_any (
461 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
462 SIXTP_END_HANDLER_ID, ender,
463 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
464 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
465 SIXTP_NO_MORE_HANDLERS);
469 generic_timespec_parser_new (sixtp_end_handler end_handler)
472 sixtp_set_any (sixtp_new (), FALSE,
473 SIXTP_START_HANDLER_ID, generic_timespec_start_handler,
474 SIXTP_CHARACTERS_HANDLER_ID, allow_and_ignore_only_whitespace,
475 SIXTP_END_HANDLER_ID, end_handler,
476 SIXTP_CLEANUP_RESULT_ID, sixtp_child_free_data,
477 SIXTP_FAIL_HANDLER_ID, generic_free_data_for_children,
478 SIXTP_RESULT_FAIL_ID, sixtp_child_free_data,
479 SIXTP_NO_MORE_HANDLERS);
480 g_return_val_if_fail (top_level, NULL);
482 if (!sixtp_add_some_sub_parsers (
484 "s", timespec_sixtp_new (generic_timespec_secs_end_handler),
485 "ns", timespec_sixtp_new (generic_timespec_nsecs_end_handler),
516 generic_guid_end_handler (gpointer data_for_children,
517 GSList* data_from_children, GSList* sibling_data,
518 gpointer parent_data, gpointer global_data,
519 gpointer* result,
const gchar* tag)
525 txt = concatenate_child_result_chars (data_from_children);
526 g_return_val_if_fail (txt, FALSE);
540 PERR (
"couldn't parse GncGUID");
550 generic_guid_parser_new (
void)
552 return sixtp_set_any (
554 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
555 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
556 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
557 SIXTP_END_HANDLER_ID, generic_guid_end_handler,
558 SIXTP_RESULT_FAIL_ID, sixtp_child_free_data,
559 SIXTP_CLEANUP_RESULT_ID, sixtp_child_free_data,
560 SIXTP_NO_MORE_HANDLERS);
585 generic_gnc_numeric_end_handler (gpointer data_for_children,
586 GSList* data_from_children, GSList* sibling_data,
587 gpointer parent_data, gpointer global_data,
588 gpointer* result,
const gchar* tag)
590 gnc_numeric* num = NULL;
594 txt = concatenate_child_result_chars (data_from_children);
598 num = g_new (gnc_numeric, 1);
613 PERR (
"couldn't parse numeric quantity");
621 generic_gnc_numeric_parser_new (
void)
623 return sixtp_set_any (
625 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
626 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
627 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
628 SIXTP_END_HANDLER_ID, generic_gnc_numeric_end_handler,
629 SIXTP_RESULT_FAIL_ID, sixtp_child_free_data,
630 SIXTP_CLEANUP_RESULT_ID, sixtp_child_free_data,
631 SIXTP_NO_MORE_HANDLERS);
637 restore_char_generator (sixtp_end_handler ender)
639 return sixtp_set_any (
641 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
642 SIXTP_END_HANDLER_ID, ender,
643 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
644 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
645 SIXTP_NO_MORE_HANDLERS);
time64 gnc_iso8601_to_time64_gmt(const gchar *)
The gnc_iso8601_to_time64_gmt() routine converts an ISO-8601 style date/time string to time64...
Date and Time handling routines.
gboolean string_to_guid(const gchar *string, GncGUID *guid)
Given a string, replace the given guid with the parsed one unless the given value is null...
#define PERR(format, args...)
Log a serious error.
gnc_numeric gnc_numeric_from_string(const gchar *str)
Read a gnc_numeric from str, skipping any leading whitespace.
GNCNumericErrorCode gnc_numeric_check(gnc_numeric a)
Check for error signal in value.
The type used to store guids in C.