24 #define __EXTENSIONS__ 43 #include "sixtp-utils.h" 48 static QofLogModule log_module = GNC_MOD_IO;
51 isspace_str (
const gchar* str,
int nomorethan)
53 const gchar* cursor = str;
54 while (*cursor && (nomorethan != 0))
56 if (!isspace (*cursor))
67 allow_and_ignore_only_whitespace (GSList* sibling_data,
74 return (isspace_str (text, length));
78 generic_accumulate_chars (GSList* sibling_data,
86 gchar* copytxt = g_strndup (text, length);
87 g_return_val_if_fail (result, FALSE);
95 generic_free_data_for_children (gpointer data_for_children,
96 GSList* data_from_children,
103 if (data_for_children) g_free (data_for_children);
107 concatenate_child_result_chars (GSList* data_from_children)
110 gchar* name = g_strdup (
"");
112 g_return_val_if_fail (name, NULL);
115 data_from_children = g_slist_reverse (g_slist_copy (data_from_children));
117 for (lp = data_from_children; lp; lp = lp->next)
119 sixtp_child_result* cr = (sixtp_child_result*) lp->data;
120 if (cr->type != SIXTP_CHILD_RESULT_CHARS)
122 PERR (
"result type is not chars");
123 g_slist_free (data_from_children);
130 temp = g_strconcat (name, (gchar*) cr->data,
nullptr);
135 g_slist_free (data_from_children);
144 template <
typename T>
145 static bool parse_chars_into_num (
const char* str, T* num_ptr)
147 if (!str || !num_ptr)
150 while (std::isspace (*str))
153 const char* end_ptr = str + std::strlen (str);
155 auto res = std::from_chars (str, end_ptr, *num_ptr);
156 if (res.ec != std::errc{})
159 while (std::isspace (*res.ptr))
162 return (res.ptr == end_ptr);
170 string_to_double (
const char* str,
double* result)
172 #if __cpp_lib_to_chars >= 201611L 173 return parse_chars_into_num<double>(str, result);
176 char* endptr =
nullptr;
177 g_return_val_if_fail (str && result,
false);
178 *result = std::strtod (str, &endptr);
179 return (endptr != str);
187 string_to_gint64 (
const gchar* str, gint64* v)
189 return parse_chars_into_num<gint64>(str, v);
196 string_to_guint16 (
const gchar* str, guint16* v)
198 return parse_chars_into_num<guint16>(str, v);
205 string_to_guint (
const gchar* str, guint* v)
207 return parse_chars_into_num<guint>(str, v);
215 hex_string_to_binary (
const gchar* str,
void** v, guint64* data_len)
218 const gchar* cursor = str;
220 gboolean error = FALSE;
222 g_return_val_if_fail (str, FALSE);
223 g_return_val_if_fail (v, FALSE);
224 g_return_val_if_fail (data_len, FALSE);
226 str_len = strlen (str);
230 if ((str_len % 2) != 0)
return (FALSE);
232 *v = g_new0 (
char, str_len / 2);
234 g_return_val_if_fail (*v, FALSE);
236 while (*cursor && * (cursor + 1))
241 if (isspace (*cursor) || isspace (* (cursor + 1)))
249 tmpstr[0] = * (cursor + 1);
251 if ((sscanf (tmpstr,
"%x%n", &tmpint, &num_read) < 1)
258 * ((gchar*) (v + *data_len)) = tmpint;
265 if (error || (*data_len != (str_len / 2)))
298 generic_return_chars_end_handler (gpointer data_for_children,
299 GSList* data_from_children,
300 GSList* sibling_data,
301 gpointer parent_data,
302 gpointer global_data,
308 txt = concatenate_child_result_chars (data_from_children);
309 g_return_val_if_fail (txt, FALSE);
316 simple_chars_only_parser_new (sixtp_end_handler end_handler)
318 return sixtp_set_any (
320 SIXTP_END_HANDLER_ID, (end_handler
322 : generic_return_chars_end_handler),
323 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
324 SIXTP_CLEANUP_RESULT_ID, sixtp_child_free_data,
325 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
326 SIXTP_RESULT_FAIL_ID, sixtp_child_free_data,
327 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
328 SIXTP_NO_MORE_HANDLERS);
366 generic_timespec_start_handler (GSList* sibling_data, gpointer parent_data,
367 gpointer global_data,
368 gpointer* data_for_children, gpointer* result,
369 const gchar* tag, gchar** attrs)
372 g_return_val_if_fail (tsp, FALSE);
373 *data_for_children = tsp;
384 return info->s_block_count != 1;
408 generic_timespec_secs_end_handler (gpointer data_for_children,
409 GSList* data_from_children, GSList* sibling_data,
410 gpointer parent_data, gpointer global_data,
411 gpointer* result,
const gchar* tag)
416 g_return_val_if_fail (parent_data, FALSE);
418 txt = concatenate_child_result_chars (data_from_children);
419 g_return_val_if_fail (txt, FALSE);
425 g_return_val_if_fail (info->time < INT64_MAX, FALSE);
427 info->s_block_count++;
449 generic_timespec_nsecs_end_handler (gpointer data_for_children,
450 GSList* data_from_children, GSList* sibling_data,
451 gpointer parent_data, gpointer global_data,
452 gpointer* result,
const gchar* tag)
458 timespec_sixtp_new (sixtp_end_handler ender)
460 return sixtp_set_any (
462 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
463 SIXTP_END_HANDLER_ID, ender,
464 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
465 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
466 SIXTP_NO_MORE_HANDLERS);
470 generic_timespec_parser_new (sixtp_end_handler end_handler)
473 sixtp_set_any (sixtp_new (), FALSE,
474 SIXTP_START_HANDLER_ID, generic_timespec_start_handler,
475 SIXTP_CHARACTERS_HANDLER_ID, allow_and_ignore_only_whitespace,
476 SIXTP_END_HANDLER_ID, end_handler,
477 SIXTP_CLEANUP_RESULT_ID, sixtp_child_free_data,
478 SIXTP_FAIL_HANDLER_ID, generic_free_data_for_children,
479 SIXTP_RESULT_FAIL_ID, sixtp_child_free_data,
480 SIXTP_NO_MORE_HANDLERS);
481 g_return_val_if_fail (top_level, NULL);
483 if (!sixtp_add_some_sub_parsers (
485 "s", timespec_sixtp_new (generic_timespec_secs_end_handler),
486 "ns", timespec_sixtp_new (generic_timespec_nsecs_end_handler),
517 generic_guid_end_handler (gpointer data_for_children,
518 GSList* data_from_children, GSList* sibling_data,
519 gpointer parent_data, gpointer global_data,
520 gpointer* result,
const gchar* tag)
526 txt = concatenate_child_result_chars (data_from_children);
527 g_return_val_if_fail (txt, FALSE);
541 PERR (
"couldn't parse GncGUID");
551 generic_guid_parser_new (
void)
553 return sixtp_set_any (
555 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
556 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
557 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
558 SIXTP_END_HANDLER_ID, generic_guid_end_handler,
559 SIXTP_RESULT_FAIL_ID, sixtp_child_free_data,
560 SIXTP_CLEANUP_RESULT_ID, sixtp_child_free_data,
561 SIXTP_NO_MORE_HANDLERS);
586 generic_gnc_numeric_end_handler (gpointer data_for_children,
587 GSList* data_from_children, GSList* sibling_data,
588 gpointer parent_data, gpointer global_data,
589 gpointer* result,
const gchar* tag)
591 gnc_numeric* num = NULL;
595 txt = concatenate_child_result_chars (data_from_children);
599 num = g_new (gnc_numeric, 1);
614 PERR (
"couldn't parse numeric quantity");
622 generic_gnc_numeric_parser_new (
void)
624 return sixtp_set_any (
626 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
627 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
628 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
629 SIXTP_END_HANDLER_ID, generic_gnc_numeric_end_handler,
630 SIXTP_RESULT_FAIL_ID, sixtp_child_free_data,
631 SIXTP_CLEANUP_RESULT_ID, sixtp_child_free_data,
632 SIXTP_NO_MORE_HANDLERS);
638 restore_char_generator (sixtp_end_handler ender)
640 return sixtp_set_any (
642 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
643 SIXTP_END_HANDLER_ID, ender,
644 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
645 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
646 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.