mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Merge Chris Lam's and Aaron Laws's branch 'time64-ftw' into unstable.
This commit is contained in:
@@ -111,7 +111,6 @@ static xmlNodePtr
|
||||
entry_dom_tree_create (GncEntry* entry)
|
||||
{
|
||||
xmlNodePtr ret;
|
||||
Timespec ts;
|
||||
Account* acc;
|
||||
GncTaxTable* taxtable;
|
||||
GncOrder* order;
|
||||
@@ -123,11 +122,11 @@ entry_dom_tree_create (GncEntry* entry)
|
||||
xmlAddChild (ret, guid_to_dom_tree (entry_guid_string,
|
||||
qof_instance_get_guid (QOF_INSTANCE (entry))));
|
||||
|
||||
ts = gncEntryGetDate (entry);
|
||||
xmlAddChild (ret, timespec_to_dom_tree (entry_date_string, &ts));
|
||||
auto time = gncEntryGetDate (entry);
|
||||
xmlAddChild (ret, time64_to_dom_tree (entry_date_string, time));
|
||||
|
||||
ts = gncEntryGetDateEntered (entry);
|
||||
xmlAddChild (ret, timespec_to_dom_tree (entry_dateentered_string, &ts));
|
||||
time = gncEntryGetDateEntered (entry);
|
||||
xmlAddChild (ret, time64_to_dom_tree (entry_dateentered_string, time));
|
||||
|
||||
maybe_add_string (ret, entry_description_string,
|
||||
gncEntryGetDescription (entry));
|
||||
@@ -241,13 +240,12 @@ set_string (xmlNodePtr node, GncEntry* entry,
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
set_timespec (xmlNodePtr node, GncEntry* entry,
|
||||
void (*func) (GncEntry* entry, Timespec ts))
|
||||
set_time64 (xmlNodePtr node, GncEntry* entry,
|
||||
void (*func) (GncEntry* entry, time64 ts))
|
||||
{
|
||||
Timespec ts = dom_tree_to_timespec (node);
|
||||
if (!dom_tree_valid_timespec (&ts, node->name)) return FALSE;
|
||||
|
||||
func (entry, ts);
|
||||
time64 time = dom_tree_to_time64 (node);
|
||||
if (!dom_tree_valid_time64 (time, node->name)) return FALSE;
|
||||
func (entry, time);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -350,16 +348,14 @@ static gboolean
|
||||
entry_date_handler (xmlNodePtr node, gpointer entry_pdata)
|
||||
{
|
||||
struct entry_pdata* pdata = static_cast<decltype (pdata)> (entry_pdata);
|
||||
|
||||
return set_timespec (node, pdata->entry, gncEntrySetDate);
|
||||
return set_time64 (node, pdata->entry, gncEntrySetDate);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_dateentered_handler (xmlNodePtr node, gpointer entry_pdata)
|
||||
{
|
||||
struct entry_pdata* pdata = static_cast<decltype (pdata)> (entry_pdata);
|
||||
|
||||
return set_timespec (node, pdata->entry, gncEntrySetDateEntered);
|
||||
return set_time64 (node, pdata->entry, gncEntrySetDateEntered);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -81,17 +81,17 @@ maybe_add_string (xmlNodePtr ptr, const char* tag, const char* str)
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_add_timespec (xmlNodePtr ptr, const char* tag, Timespec ts)
|
||||
maybe_add_time64 (xmlNodePtr ptr, const char* tag, time64 time)
|
||||
{
|
||||
if (ts.tv_sec || ts.tv_nsec)
|
||||
xmlAddChild (ptr, timespec_to_dom_tree (tag, &ts));
|
||||
if (time)
|
||||
xmlAddChild (ptr, time64_to_dom_tree (tag, time));
|
||||
}
|
||||
|
||||
static xmlNodePtr
|
||||
invoice_dom_tree_create (GncInvoice* invoice)
|
||||
{
|
||||
xmlNodePtr ret;
|
||||
Timespec ts;
|
||||
time64 time;
|
||||
Transaction* txn;
|
||||
GNCLot* lot;
|
||||
Account* acc;
|
||||
@@ -111,11 +111,10 @@ invoice_dom_tree_create (GncInvoice* invoice)
|
||||
xmlAddChild (ret, gnc_owner_to_dom_tree (invoice_owner_string,
|
||||
gncInvoiceGetOwner (invoice)));
|
||||
|
||||
ts = gncInvoiceGetDateOpened (invoice);
|
||||
xmlAddChild (ret, timespec_to_dom_tree (invoice_opened_string, &ts));
|
||||
time = gncInvoiceGetDateOpened (invoice);
|
||||
xmlAddChild (ret, time64_to_dom_tree (invoice_opened_string, time));
|
||||
|
||||
maybe_add_timespec (ret, invoice_posted_string,
|
||||
gncInvoiceGetDatePosted (invoice));
|
||||
maybe_add_time64 (ret, invoice_posted_string, gncInvoiceGetDatePosted (invoice));
|
||||
|
||||
term = gncInvoiceGetTerms (invoice);
|
||||
if (term)
|
||||
@@ -185,13 +184,12 @@ set_string (xmlNodePtr node, GncInvoice* invoice,
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
set_timespec (xmlNodePtr node, GncInvoice* invoice,
|
||||
void (*func) (GncInvoice* invoice, Timespec ts))
|
||||
set_time64 (xmlNodePtr node, GncInvoice* invoice,
|
||||
void (*func) (GncInvoice* invoice, time64 time))
|
||||
{
|
||||
Timespec ts = dom_tree_to_timespec (node);
|
||||
if (!dom_tree_valid_timespec (&ts, node->name)) return FALSE;
|
||||
|
||||
func (invoice, ts);
|
||||
time64 time = dom_tree_to_time64 (node);
|
||||
if (!dom_tree_valid_time64 (time, node->name)) return FALSE;
|
||||
func (invoice, time);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -247,16 +245,14 @@ static gboolean
|
||||
invoice_opened_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||
{
|
||||
struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
|
||||
|
||||
return set_timespec (node, pdata->invoice, gncInvoiceSetDateOpened);
|
||||
return set_time64 (node, pdata->invoice, gncInvoiceSetDateOpened);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
invoice_posted_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||
{
|
||||
struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
|
||||
|
||||
return set_timespec (node, pdata->invoice, gncInvoiceSetDatePosted);
|
||||
return set_time64 (node, pdata->invoice, gncInvoiceSetDatePosted);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -90,11 +90,11 @@ order_dom_tree_create (GncOrder* order)
|
||||
gncOrderGetOwner (order)));
|
||||
|
||||
ts = gncOrderGetDateOpened (order);
|
||||
xmlAddChild (ret, timespec_to_dom_tree (order_opened_string, &ts));
|
||||
xmlAddChild (ret, time64_to_dom_tree (order_opened_string, ts.tv_sec));
|
||||
|
||||
ts = gncOrderGetDateClosed (order);
|
||||
if (ts.tv_sec || ts.tv_nsec)
|
||||
xmlAddChild (ret, timespec_to_dom_tree (order_closed_string, &ts));
|
||||
if (ts.tv_sec)
|
||||
xmlAddChild (ret, time64_to_dom_tree (order_closed_string, ts.tv_sec));
|
||||
|
||||
maybe_add_string (ret, order_notes_string, gncOrderGetNotes (order));
|
||||
maybe_add_string (ret, order_reference_string, gncOrderGetReference (order));
|
||||
@@ -134,9 +134,9 @@ static inline gboolean
|
||||
set_timespec (xmlNodePtr node, GncOrder* order,
|
||||
void (*func) (GncOrder* order, Timespec ts))
|
||||
{
|
||||
Timespec ts = dom_tree_to_timespec (node);
|
||||
if (!dom_tree_valid_timespec (&ts, node->name)) return FALSE;
|
||||
|
||||
time64 time = dom_tree_to_time64 (node);
|
||||
if (!dom_tree_valid_time64 (time, node->name)) return FALSE;
|
||||
Timespec ts {time, 0};
|
||||
func (order, ts);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -113,9 +113,10 @@ price_parse_xml_sub_node (GNCPrice* p, xmlNodePtr sub_node, QofBook* book)
|
||||
}
|
||||
else if (g_strcmp0 ("price:time", (char*)sub_node->name) == 0)
|
||||
{
|
||||
Timespec t = dom_tree_to_timespec (sub_node);
|
||||
if (!dom_tree_valid_timespec (&t, sub_node->name)) return FALSE;
|
||||
gnc_price_set_time (p, t);
|
||||
time64 time = dom_tree_to_time64 (sub_node);
|
||||
if (!dom_tree_valid_time64 (time, sub_node->name)) return FALSE;
|
||||
Timespec ts {time, 0};
|
||||
gnc_price_set_time (p, ts);
|
||||
}
|
||||
else if (g_strcmp0 ("price:source", (char*)sub_node->name) == 0)
|
||||
{
|
||||
@@ -438,7 +439,7 @@ gnc_price_to_dom_tree (const xmlChar* tag, GNCPrice* price)
|
||||
if (!add_child_or_kill_parent (price_xml, tmpnode)) return NULL;
|
||||
|
||||
timesp = gnc_price_get_time (price);
|
||||
tmpnode = timespec_to_dom_tree ("price:time", ×p);
|
||||
tmpnode = time64_to_dom_tree ("price:time", timesp.tv_sec);
|
||||
if (!add_child_or_kill_parent (price_xml, tmpnode)) return NULL;
|
||||
|
||||
sourcestr = gnc_price_get_source_string (price);
|
||||
|
||||
@@ -56,12 +56,19 @@ add_gnc_num (xmlNodePtr node, const gchar* tag, gnc_numeric num)
|
||||
xmlAddChild (node, gnc_numeric_to_dom_tree (tag, &num));
|
||||
}
|
||||
|
||||
static void
|
||||
add_time64 (xmlNodePtr node, const gchar * tag, time64 time, gboolean always)
|
||||
{
|
||||
if (always || time)
|
||||
xmlAddChild (node, time64_to_dom_tree (tag, time));
|
||||
}
|
||||
|
||||
static void
|
||||
add_timespec (xmlNodePtr node, const gchar* tag, Timespec tms, gboolean always)
|
||||
{
|
||||
if (always || ! ((tms.tv_sec == 0) && (tms.tv_nsec == 0)))
|
||||
if (always || tms.tv_sec)
|
||||
{
|
||||
xmlAddChild (node, timespec_to_dom_tree (tag, &tms));
|
||||
xmlAddChild (node, time64_to_dom_tree (tag, tms.tv_sec));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,10 +179,10 @@ gnc_transaction_dom_tree_create (Transaction* trn)
|
||||
}
|
||||
g_free (str);
|
||||
|
||||
add_timespec (ret, "trn:date-posted", xaccTransRetDatePostedTS (trn), TRUE);
|
||||
add_time64 (ret, "trn:date-posted", xaccTransRetDatePosted (trn), TRUE);
|
||||
|
||||
add_timespec (ret, "trn:date-entered",
|
||||
xaccTransRetDateEnteredTS (trn), TRUE);
|
||||
add_time64 (ret, "trn:date-entered",
|
||||
xaccTransRetDateEntered (trn), TRUE);
|
||||
|
||||
str = g_strdup (xaccTransGetDescription (trn));
|
||||
if (str)
|
||||
@@ -275,13 +282,9 @@ static gboolean
|
||||
spl_reconcile_date_handler (xmlNodePtr node, gpointer data)
|
||||
{
|
||||
struct split_pdata* pdata = static_cast<decltype (pdata)> (data);
|
||||
Timespec ts;
|
||||
|
||||
ts = dom_tree_to_timespec (node);
|
||||
if (!dom_tree_valid_timespec (&ts, node->name)) return FALSE;
|
||||
|
||||
xaccSplitSetDateReconciledTS (pdata->split, &ts);
|
||||
|
||||
time64 time = dom_tree_to_time64 (node);
|
||||
if (!dom_tree_valid_time64 (time, node->name)) return FALSE;
|
||||
xaccSplitSetDateReconciledSecs (pdata->split, time);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -430,18 +433,24 @@ set_tran_string (xmlNodePtr node, Transaction* trn,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_tran_time64 (xmlNodePtr node, Transaction * trn,
|
||||
void (*func) (Transaction *, time64))
|
||||
{
|
||||
time64 time = dom_tree_to_time64 (node);
|
||||
if (!dom_tree_valid_time64 (time, node->name)) return FALSE;
|
||||
func (trn, time);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
set_tran_date (xmlNodePtr node, Transaction* trn,
|
||||
void (*func) (Transaction* trn, const Timespec* tm))
|
||||
{
|
||||
Timespec tm;
|
||||
|
||||
tm = dom_tree_to_timespec (node);
|
||||
|
||||
if (!dom_tree_valid_timespec (&tm, node->name)) return FALSE;
|
||||
|
||||
func (trn, &tm);
|
||||
|
||||
time64 time = dom_tree_to_time64 (node);
|
||||
if (!dom_tree_valid_time64 (time, node->name)) return FALSE;
|
||||
Timespec ts {time, 0};
|
||||
func (trn, &ts);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -489,7 +498,7 @@ trn_date_posted_handler (xmlNodePtr node, gpointer trans_pdata)
|
||||
struct trans_pdata* pdata = static_cast<decltype (pdata)> (trans_pdata);
|
||||
Transaction* trn = pdata->trans;
|
||||
|
||||
return set_tran_date (node, trn, xaccTransSetDatePostedTS);
|
||||
return set_tran_time64 (node, trn, xaccTransSetDatePostedSecs);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -498,7 +507,7 @@ trn_date_entered_handler (xmlNodePtr node, gpointer trans_pdata)
|
||||
struct trans_pdata* pdata = static_cast<decltype (pdata)> (trans_pdata);
|
||||
Transaction* trn = pdata->trans;
|
||||
|
||||
return set_tran_date (node, trn, xaccTransSetDateEnteredTS);
|
||||
return set_tran_time64 (node, trn, xaccTransSetDateEnteredSecs);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -2350,7 +2350,7 @@ txn_rest_date_posted_end_handler (gpointer data_for_children,
|
||||
gpointer* result, const gchar* tag)
|
||||
{
|
||||
Transaction* t = (Transaction*) parent_data;
|
||||
TimespecParseInfo* info = (TimespecParseInfo*) data_for_children;
|
||||
Time64ParseInfo* info = (Time64ParseInfo*) data_for_children;
|
||||
|
||||
g_return_val_if_fail (info, FALSE);
|
||||
if (!t || !timespec_parse_ok (info))
|
||||
@@ -2359,7 +2359,7 @@ txn_rest_date_posted_end_handler (gpointer data_for_children,
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
xaccTransSetDatePostedTS (t, & (info->ts));
|
||||
xaccTransSetDatePostedSecs (t, info->time);
|
||||
g_free (info);
|
||||
return (TRUE);
|
||||
}
|
||||
@@ -2382,7 +2382,7 @@ txn_rest_date_entered_end_handler (gpointer data_for_children,
|
||||
gpointer* result, const gchar* tag)
|
||||
{
|
||||
Transaction* t = (Transaction*) parent_data;
|
||||
TimespecParseInfo* info = (TimespecParseInfo*) data_for_children;
|
||||
Time64ParseInfo* info = (Time64ParseInfo*) data_for_children;
|
||||
|
||||
g_return_val_if_fail (info, FALSE);
|
||||
if (!t || !timespec_parse_ok (info))
|
||||
@@ -2391,7 +2391,7 @@ txn_rest_date_entered_end_handler (gpointer data_for_children,
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
xaccTransSetDateEnteredTS (t, & (info->ts));
|
||||
xaccTransSetDateEnteredSecs (t, info->time);
|
||||
g_free (info);
|
||||
return (TRUE);
|
||||
}
|
||||
@@ -2713,7 +2713,7 @@ txn_restore_split_reconcile_date_end_handler (gpointer data_for_children,
|
||||
gpointer* result, const gchar* tag)
|
||||
{
|
||||
Split* s = (Split*) parent_data;
|
||||
TimespecParseInfo* info = (TimespecParseInfo*) data_for_children;
|
||||
Time64ParseInfo* info = (Time64ParseInfo*) data_for_children;
|
||||
|
||||
g_return_val_if_fail (info, FALSE);
|
||||
if (!s || !timespec_parse_ok (info))
|
||||
@@ -2722,7 +2722,7 @@ txn_restore_split_reconcile_date_end_handler (gpointer data_for_children,
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
xaccSplitSetDateReconciledTS (s, & (info->ts));
|
||||
xaccSplitSetDateReconciledSecs (s, info->time);
|
||||
g_free (info);
|
||||
return (TRUE);
|
||||
}
|
||||
@@ -2959,9 +2959,10 @@ price_parse_xml_sub_node (GNCPrice* p, xmlNodePtr sub_node, QofBook* book)
|
||||
}
|
||||
else if (g_strcmp0 ("price:time", (char*)sub_node->name) == 0)
|
||||
{
|
||||
Timespec t = dom_tree_to_timespec (sub_node);
|
||||
if (!dom_tree_valid_timespec (&t, sub_node->name)) return FALSE;
|
||||
gnc_price_set_time (p, t);
|
||||
time64 time = dom_tree_to_time64 (sub_node);
|
||||
if (!dom_tree_valid_time64 (time, sub_node->name)) return FALSE;
|
||||
Timespec ts = {time, 0};
|
||||
gnc_price_set_time (p, ts);
|
||||
}
|
||||
else if (g_strcmp0 ("price:source", (char*)sub_node->name) == 0)
|
||||
{
|
||||
|
||||
@@ -132,54 +132,23 @@ commodity_ref_to_dom_tree (const char* tag, const gnc_commodity* c)
|
||||
}
|
||||
|
||||
char*
|
||||
timespec_sec_to_string (const Timespec* ts)
|
||||
time64_to_string (time64 time)
|
||||
{
|
||||
return gnc_print_time64 (ts->tv_sec, "%Y-%m-%d %H:%M:%S %q");
|
||||
}
|
||||
|
||||
gchar*
|
||||
timespec_nsec_to_string (const Timespec* ts)
|
||||
{
|
||||
return g_strdup_printf ("%ld", ts->tv_nsec);
|
||||
return gnc_print_time64 (time, TIMESPEC_TIME_FORMAT " %q");
|
||||
}
|
||||
|
||||
xmlNodePtr
|
||||
timespec_to_dom_tree (const char* tag, const Timespec* spec)
|
||||
time64_to_dom_tree (const char* tag, const time64 time)
|
||||
{
|
||||
xmlNodePtr ret;
|
||||
gchar* date_str = NULL;
|
||||
gchar* ns_str = NULL;
|
||||
|
||||
g_return_val_if_fail (spec, NULL);
|
||||
|
||||
date_str = timespec_sec_to_string (spec);
|
||||
|
||||
g_return_val_if_fail (time, NULL);
|
||||
auto date_str = time64_to_string (time);
|
||||
if (!date_str)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = xmlNewNode (NULL, BAD_CAST tag);
|
||||
|
||||
xmlNewTextChild (ret, NULL, BAD_CAST "ts:date",
|
||||
checked_char_cast (date_str));
|
||||
|
||||
if (spec->tv_nsec > 0)
|
||||
{
|
||||
ns_str = timespec_nsec_to_string (spec);
|
||||
if (ns_str)
|
||||
{
|
||||
xmlNewTextChild (ret, NULL, BAD_CAST "ts:ns",
|
||||
checked_char_cast (ns_str));
|
||||
}
|
||||
}
|
||||
|
||||
g_free (date_str);
|
||||
if (ns_str)
|
||||
{
|
||||
g_free (ns_str);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -311,7 +280,7 @@ add_kvp_value_node (xmlNodePtr node, const gchar* tag, KvpValue* val)
|
||||
case KvpValue::Type::TIMESPEC:
|
||||
{
|
||||
auto ts = val->get<Timespec> ();
|
||||
val_node = timespec_to_dom_tree (tag, &ts);
|
||||
val_node = time64_to_dom_tree (tag, ts.tv_sec);
|
||||
xmlSetProp (val_node, BAD_CAST "type", BAD_CAST "timespec");
|
||||
xmlAddChild (node, val_node);
|
||||
break;
|
||||
|
||||
@@ -40,9 +40,8 @@ xmlNodePtr int_to_dom_tree (const char* tag, gint64 val);
|
||||
xmlNodePtr boolean_to_dom_tree (const char* tag, gboolean val);
|
||||
xmlNodePtr guid_to_dom_tree (const char* tag, const GncGUID* gid);
|
||||
xmlNodePtr commodity_ref_to_dom_tree (const char* tag, const gnc_commodity* c);
|
||||
xmlNodePtr timespec_to_dom_tree (const char* tag, const Timespec* spec);
|
||||
gchar* timespec_nsec_to_string (const Timespec* ts);
|
||||
gchar* timespec_sec_to_string (const Timespec* ts);
|
||||
xmlNodePtr time64_to_dom_tree (const char* tag, time64);
|
||||
gchar* time64_to_string (time64);
|
||||
xmlNodePtr gdate_to_dom_tree (const char* tag, const GDate* spec);
|
||||
xmlNodePtr gnc_numeric_to_dom_tree (const char* tag, const gnc_numeric* num);
|
||||
xmlNodePtr qof_instance_slots_to_dom_tree (const char* tag,
|
||||
|
||||
@@ -233,14 +233,9 @@ dom_tree_to_guid_kvp_value (xmlNodePtr node)
|
||||
}
|
||||
|
||||
static KvpValue*
|
||||
dom_tree_to_timespec_kvp_value (xmlNodePtr node)
|
||||
dom_tree_to_time64_kvp_value (xmlNodePtr node)
|
||||
{
|
||||
Timespec ts;
|
||||
KvpValue* ret = nullptr;
|
||||
|
||||
ts = dom_tree_to_timespec (node);
|
||||
ret = new KvpValue {ts};
|
||||
return ret;
|
||||
return new KvpValue {Timespec {dom_tree_to_time64 (node), 0}};
|
||||
}
|
||||
|
||||
static KvpValue*
|
||||
@@ -360,7 +355,7 @@ struct kvp_val_converter val_converters[] =
|
||||
{ "numeric", dom_tree_to_numeric_kvp_value },
|
||||
{ "string", dom_tree_to_string_kvp_value },
|
||||
{ "guid", dom_tree_to_guid_kvp_value },
|
||||
{ "timespec", dom_tree_to_timespec_kvp_value },
|
||||
{ "timespec", dom_tree_to_time64_kvp_value },
|
||||
{ "gdate", dom_tree_to_gdate_kvp_value },
|
||||
{ "list", dom_tree_to_list_kvp_value },
|
||||
{ "frame", dom_tree_to_frame_kvp_value },
|
||||
@@ -528,17 +523,15 @@ dom_tree_to_gnc_numeric (xmlNodePtr node)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline Timespec
|
||||
timespec_failure (Timespec ts)
|
||||
static time64
|
||||
time_parse_failure ()
|
||||
{
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 0;
|
||||
return ts;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Timespec
|
||||
dom_tree_to_timespec (xmlNodePtr node)
|
||||
time64
|
||||
dom_tree_to_time64 (xmlNodePtr node)
|
||||
{
|
||||
/* Turn something like this
|
||||
|
||||
@@ -547,18 +540,15 @@ dom_tree_to_timespec (xmlNodePtr node)
|
||||
<ns>658864000</ns>
|
||||
</date-posted>
|
||||
|
||||
into a Timespec. If this returns FALSE, the effects on *ts are
|
||||
into a time64. If this returns FALSE, the effects on *ts are
|
||||
undefined. The XML is valid if it has at least one of <s> or <ns>
|
||||
and no more than one of each. Order is irrelevant. */
|
||||
|
||||
Timespec ret;
|
||||
time64 ret {0};
|
||||
gboolean seen_s = FALSE;
|
||||
gboolean seen_ns = FALSE;
|
||||
xmlNodePtr n;
|
||||
|
||||
|
||||
ret.tv_sec = 0;
|
||||
ret.tv_nsec = 0;
|
||||
for (n = node->xmlChildrenNode; n; n = n->next)
|
||||
{
|
||||
switch (n->type)
|
||||
@@ -571,52 +561,29 @@ dom_tree_to_timespec (xmlNodePtr node)
|
||||
{
|
||||
if (seen_s)
|
||||
{
|
||||
return timespec_failure (ret);
|
||||
return time_parse_failure ();
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar* content = dom_tree_to_text (n);
|
||||
if (!content)
|
||||
{
|
||||
return timespec_failure (ret);
|
||||
return time_parse_failure ();
|
||||
}
|
||||
|
||||
if (!string_to_timespec_secs (content, &ret))
|
||||
if (!string_to_time64 (content, &ret))
|
||||
{
|
||||
g_free (content);
|
||||
return timespec_failure (ret);
|
||||
return time_parse_failure ();
|
||||
}
|
||||
g_free (content);
|
||||
seen_s = TRUE;
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 ("ts:ns", (char*)n->name) == 0)
|
||||
{
|
||||
if (seen_ns)
|
||||
{
|
||||
return timespec_failure (ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar* content = dom_tree_to_text (n);
|
||||
if (!content)
|
||||
{
|
||||
return timespec_failure (ret);
|
||||
}
|
||||
|
||||
if (!string_to_timespec_nsecs (content, &ret))
|
||||
{
|
||||
g_free (content);
|
||||
return timespec_failure (ret);
|
||||
}
|
||||
g_free (content);
|
||||
seen_ns = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PERR ("unexpected sub-node.");
|
||||
return timespec_failure (ret);
|
||||
return time_parse_failure ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -624,7 +591,7 @@ dom_tree_to_timespec (xmlNodePtr node)
|
||||
if (!seen_s)
|
||||
{
|
||||
PERR ("no ts:date node found.");
|
||||
return timespec_failure (ret);
|
||||
return time_parse_failure ();
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -896,13 +863,11 @@ dom_tree_generic_parse (xmlNodePtr node, struct dom_tree_handler* handlers,
|
||||
}
|
||||
|
||||
gboolean
|
||||
dom_tree_valid_timespec (Timespec* ts, const xmlChar* name)
|
||||
dom_tree_valid_time64 (time64 val, const xmlChar * name)
|
||||
{
|
||||
|
||||
if (ts->tv_sec || ts->tv_nsec)
|
||||
if (val)
|
||||
return TRUE;
|
||||
|
||||
g_warning ("Invalid timestamp in data file. Look for a '%s' entry "
|
||||
"with a date of 1969-12-31 or 1970-01-01.", name);
|
||||
g_warning ("Invalid timestamp in data file. Look for a '%s' entry "
|
||||
"with a date of 1969-12-31 or 1970-01-01.", name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -42,8 +42,8 @@ gnc_commodity* dom_tree_to_commodity_ref_no_engine (xmlNodePtr node, QofBook*);
|
||||
GList* dom_tree_freqSpec_to_recurrences (xmlNodePtr node, QofBook* book);
|
||||
Recurrence* dom_tree_to_recurrence (xmlNodePtr node);
|
||||
|
||||
Timespec dom_tree_to_timespec (xmlNodePtr node);
|
||||
gboolean dom_tree_valid_timespec (Timespec* ts, const xmlChar* name);
|
||||
time64 dom_tree_to_time64 (xmlNodePtr node);
|
||||
gboolean dom_tree_valid_time64 (time64 ts, const xmlChar* name);
|
||||
GDate* dom_tree_to_gdate (xmlNodePtr node);
|
||||
gnc_numeric* dom_tree_to_gnc_numeric (xmlNodePtr node);
|
||||
gchar* dom_tree_to_text (xmlNodePtr tree);
|
||||
|
||||
@@ -356,34 +356,27 @@ simple_chars_only_parser_new (sixtp_end_handler end_handler)
|
||||
<ns>658864000</ns>
|
||||
</date-posted>
|
||||
|
||||
and produce a Timespec*. The start handler for the top allocates
|
||||
the Timespec * and passes it to the children. The <s> block sets
|
||||
the seconds and the <ns> block (if any) sets the nanoseconds. If
|
||||
all goes well, returns the Timespec* as the result.
|
||||
and produce a time64. The start handler for the top allocates
|
||||
the time64 and passes it to the children. The <s> block sets
|
||||
the seconds and the <ns> block is ignored. If
|
||||
all goes well, returns the time64 as the result.
|
||||
*/
|
||||
|
||||
gboolean
|
||||
string_to_timespec_secs (const gchar* str, Timespec* ts)
|
||||
string_to_time64 (const gchar* str, time64* time)
|
||||
{
|
||||
*ts = gnc_iso8601_to_timespec_gmt (str);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
string_to_timespec_nsecs (const gchar* str, Timespec* ts)
|
||||
{
|
||||
/* We don't do nanoseconds anymore. */
|
||||
*time = gnc_iso8601_to_time64_gmt (str);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/* Top level timespec node:
|
||||
|
||||
input: user end handler *
|
||||
returns: Timespec*
|
||||
returns: time64
|
||||
|
||||
start: Allocates TimespecParseInfo* for data_for_children.
|
||||
start: Allocates Time64ParseInfo* for data_for_children.
|
||||
characters: none (whitespace only).
|
||||
end: g_free TimespecParseInfo + any other actions
|
||||
end: g_free Time64ParseInfo + any other actions
|
||||
|
||||
cleanup-result: NA
|
||||
cleanup-chars: NA
|
||||
@@ -399,7 +392,7 @@ generic_timespec_start_handler (GSList* sibling_data, gpointer parent_data,
|
||||
gpointer* data_for_children, gpointer* result,
|
||||
const gchar* tag, gchar** attrs)
|
||||
{
|
||||
TimespecParseInfo* tsp = g_new0 (TimespecParseInfo, 1);
|
||||
Time64ParseInfo* tsp = g_new0 (Time64ParseInfo, 1);
|
||||
g_return_val_if_fail (tsp, FALSE);
|
||||
*data_for_children = tsp;
|
||||
return (TRUE);
|
||||
@@ -410,18 +403,9 @@ generic_timespec_start_handler (GSList* sibling_data, gpointer parent_data,
|
||||
new timespec. Otherwise, you can presume that everything's been
|
||||
cleaned up properly and return FALSE. */
|
||||
gboolean
|
||||
timespec_parse_ok (TimespecParseInfo* info)
|
||||
timespec_parse_ok (Time64ParseInfo* info)
|
||||
{
|
||||
|
||||
if ((info->s_block_count > 1) || (info->ns_block_count > 1) ||
|
||||
((info->s_block_count == 0) && (info->ns_block_count == 0)))
|
||||
{
|
||||
return (FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
return info->s_block_count != 1;
|
||||
}
|
||||
|
||||
/* generic_timespec_end_handler - must be customized and provided by
|
||||
@@ -429,12 +413,12 @@ timespec_parse_ok (TimespecParseInfo* info)
|
||||
|
||||
/* <s> (parent timespec-node)
|
||||
|
||||
input: TimespecParseInfo *
|
||||
input: Time64ParseInfo *
|
||||
returns: NA
|
||||
|
||||
start: NA
|
||||
characters: accumulate.
|
||||
end: convert characters to secs part of input Timespec and inc s_block_count.
|
||||
end: convert characters to secs part of input time64 and inc s_block_count.
|
||||
|
||||
cleanup-result: NA
|
||||
cleanup-chars: g_free data.
|
||||
@@ -451,7 +435,7 @@ generic_timespec_secs_end_handler (gpointer data_for_children,
|
||||
gpointer* result, const gchar* tag)
|
||||
{
|
||||
gchar* txt = NULL;
|
||||
TimespecParseInfo* info = (TimespecParseInfo*) parent_data;
|
||||
Time64ParseInfo* info = (Time64ParseInfo*) parent_data;
|
||||
gboolean ok;
|
||||
|
||||
g_return_val_if_fail (parent_data, FALSE);
|
||||
@@ -459,7 +443,7 @@ generic_timespec_secs_end_handler (gpointer data_for_children,
|
||||
txt = concatenate_child_result_chars (data_from_children);
|
||||
g_return_val_if_fail (txt, FALSE);
|
||||
|
||||
ok = string_to_timespec_secs (txt, & (info->ts));
|
||||
ok = string_to_time64 (txt, & info->time);
|
||||
g_free (txt);
|
||||
|
||||
g_return_val_if_fail (ok, FALSE);
|
||||
@@ -470,15 +454,15 @@ generic_timespec_secs_end_handler (gpointer data_for_children,
|
||||
|
||||
/* <s> (parent timespec-node)
|
||||
|
||||
input: TimespecParseInfo *
|
||||
input: Time64ParseInfo *
|
||||
returns: NA
|
||||
|
||||
start: NA
|
||||
characters: accumulate.
|
||||
end: convert characters to secs part of input Timespec and inc s_block_count.
|
||||
end: NA
|
||||
|
||||
cleanup-result: NA
|
||||
cleanup-chars: g_free data.
|
||||
cleanup-chars: NA.
|
||||
fail: NA
|
||||
result-fail: NA
|
||||
chars-fail: g_free data.
|
||||
@@ -491,22 +475,7 @@ generic_timespec_nsecs_end_handler (gpointer data_for_children,
|
||||
gpointer parent_data, gpointer global_data,
|
||||
gpointer* result, const gchar* tag)
|
||||
{
|
||||
gchar* txt = NULL;
|
||||
TimespecParseInfo* info = (TimespecParseInfo*) parent_data;
|
||||
gboolean ok;
|
||||
|
||||
g_return_val_if_fail (parent_data, FALSE);
|
||||
|
||||
txt = concatenate_child_result_chars (data_from_children);
|
||||
g_return_val_if_fail (txt, FALSE);
|
||||
|
||||
ok = string_to_timespec_nsecs (txt, & (info->ts));
|
||||
g_free (txt);
|
||||
|
||||
g_return_val_if_fail (ok, FALSE);
|
||||
|
||||
info->ns_block_count++;
|
||||
return (TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static sixtp*
|
||||
|
||||
@@ -31,10 +31,9 @@ extern "C"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Timespec ts;
|
||||
time64 time;
|
||||
guint s_block_count;
|
||||
guint ns_block_count;
|
||||
} TimespecParseInfo;
|
||||
} Time64ParseInfo;
|
||||
|
||||
#define TIMESPEC_TIME_FORMAT "%Y-%m-%d %H:%M:%S"
|
||||
#define TIMESPEC_PARSE_TIME_FORMAT "%Y-%m-%d %H:%M:%S"
|
||||
@@ -85,8 +84,7 @@ gboolean generic_return_chars_end_handler (gpointer data_for_children,
|
||||
|
||||
sixtp* simple_chars_only_parser_new (sixtp_end_handler end_handler);
|
||||
|
||||
gboolean string_to_timespec_secs (const gchar* str, Timespec* ts);
|
||||
gboolean string_to_timespec_nsecs (const gchar* str, Timespec* ts);
|
||||
gboolean string_to_time64 (const gchar* str, time64* ts);
|
||||
|
||||
gboolean generic_timespec_start_handler (GSList* sibling_data,
|
||||
gpointer parent_data,
|
||||
@@ -95,7 +93,7 @@ gboolean generic_timespec_start_handler (GSList* sibling_data,
|
||||
gpointer* result,
|
||||
const gchar* tag, gchar** attrs);
|
||||
|
||||
gboolean timespec_parse_ok (TimespecParseInfo* info);
|
||||
gboolean timespec_parse_ok (Time64ParseInfo* info);
|
||||
|
||||
gboolean generic_timespec_secs_end_handler (
|
||||
gpointer data_for_children,
|
||||
|
||||
@@ -41,51 +41,26 @@ main (int argc, char** argv)
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
{
|
||||
Timespec* spec1;
|
||||
Timespec spec2;
|
||||
gchar* sec_str;
|
||||
gchar* nsec_str;
|
||||
|
||||
spec1 = get_random_timespec ();
|
||||
|
||||
sec_str = timespec_sec_to_string (spec1);
|
||||
nsec_str = timespec_nsec_to_string (spec1);
|
||||
|
||||
if (!string_to_timespec_secs (sec_str, &spec2))
|
||||
time64 spec2;
|
||||
auto spec1 = get_random_time ();
|
||||
auto sec_str = time64_to_string (spec1);
|
||||
if (!string_to_time64 (sec_str, &spec2))
|
||||
{
|
||||
failure_args ("string_to_timespec_secs", __FILE__, __LINE__,
|
||||
"string is %s", sec_str);
|
||||
}
|
||||
|
||||
else if (!string_to_timespec_nsecs (nsec_str, &spec2))
|
||||
{
|
||||
failure_args ("string_to_timespec_nsecs", __FILE__, __LINE__,
|
||||
"string is %s", nsec_str);
|
||||
}
|
||||
|
||||
else if (spec1->tv_sec != spec2.tv_sec)
|
||||
else if (spec1 != spec2)
|
||||
{
|
||||
failure_args ("timespec_secs", __FILE__, __LINE__,
|
||||
"not equal ints are %" G_GINT64_FORMAT
|
||||
" and %" G_GINT64_FORMAT "\n",
|
||||
spec1->tv_sec, spec2.tv_sec);
|
||||
spec1, spec2);
|
||||
}
|
||||
|
||||
else if (spec1->tv_nsec != spec2.tv_nsec)
|
||||
{
|
||||
failure_args ("timespec_nsecs", __FILE__, __LINE__,
|
||||
"not equal ints are %ld and %ld\n",
|
||||
spec1->tv_nsec, spec2.tv_nsec);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
success ("timespec");
|
||||
}
|
||||
|
||||
g_free (spec1);
|
||||
g_free (sec_str);
|
||||
g_free (nsec_str);
|
||||
}
|
||||
print_test_results ();
|
||||
exit (get_rv ());
|
||||
|
||||
@@ -132,17 +132,11 @@ test_dom_tree_to_timespec (void)
|
||||
int i;
|
||||
for (i = 0; i < 20; i++)
|
||||
{
|
||||
Timespec* test_spec1;
|
||||
Timespec test_spec2;
|
||||
xmlNodePtr test_node;
|
||||
|
||||
test_spec1 = get_random_timespec ();
|
||||
|
||||
test_node = timespec_to_dom_tree ("test-spec", test_spec1);
|
||||
|
||||
test_spec2 = dom_tree_to_timespec (test_node);
|
||||
|
||||
if (!dom_tree_valid_timespec (&test_spec2, (const xmlChar*)"test-spec"))
|
||||
time64 test_spec1 = get_random_time ();
|
||||
test_node = time64_to_dom_tree ("test-spec", test_spec1);
|
||||
time64 test_spec2 = dom_tree_to_time64 (test_node);
|
||||
if (!dom_tree_valid_time64 (test_spec2, (const xmlChar*)"test-spec"))
|
||||
{
|
||||
failure_args ("dom_tree_to_timespec",
|
||||
__FILE__, __LINE__, "NULL return");
|
||||
@@ -150,8 +144,7 @@ test_dom_tree_to_timespec (void)
|
||||
xmlElemDump (stdout, NULL, test_node);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
else if (timespec_cmp (test_spec1, &test_spec2) == 0)
|
||||
else if (test_spec1 == test_spec2)
|
||||
{
|
||||
success ("dom_tree_to_timespec");
|
||||
}
|
||||
@@ -161,15 +154,9 @@ test_dom_tree_to_timespec (void)
|
||||
printf ("Node looks like:\n");
|
||||
xmlElemDump (stdout, NULL, test_node);
|
||||
printf ("\n");
|
||||
printf ("Secs are %" G_GUINT64_FORMAT " vs %" G_GUINT64_FORMAT " :: ",
|
||||
test_spec1->tv_sec,
|
||||
test_spec2.tv_sec);
|
||||
printf ("NSecs are %ld vs %ld\n",
|
||||
test_spec1->tv_nsec,
|
||||
test_spec2.tv_nsec);
|
||||
printf ("passed: %" G_GUINT64_FORMAT " got: %" G_GUINT64_FORMAT ".\n",
|
||||
test_spec1, test_spec2);
|
||||
}
|
||||
|
||||
g_free (test_spec1);
|
||||
xmlFreeNode (test_node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,18 +277,9 @@ equals_node_val_vs_kvp_frame (xmlNodePtr node, const KvpFrame* frm)
|
||||
}
|
||||
|
||||
gboolean
|
||||
equals_node_val_vs_date (xmlNodePtr node, const Timespec tm)
|
||||
equals_node_val_vs_date (xmlNodePtr node, time64 time)
|
||||
{
|
||||
Timespec tm_test = dom_tree_to_timespec (node);
|
||||
|
||||
if (tm_test.tv_sec == tm.tv_sec && tm_test.tv_nsec == tm.tv_nsec)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return time == dom_tree_to_time64 (node);
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
@@ -57,7 +57,7 @@ gboolean equals_node_val_vs_guid (xmlNodePtr node, const GncGUID* id);
|
||||
gboolean equals_node_val_vs_commodity (xmlNodePtr node,
|
||||
const gnc_commodity* com, QofBook*);
|
||||
gboolean equals_node_val_vs_kvp_frame (xmlNodePtr node, const KvpFrame* frm);
|
||||
gboolean equals_node_val_vs_date (xmlNodePtr node, const Timespec tm);
|
||||
gboolean equals_node_val_vs_date (xmlNodePtr node, time64);
|
||||
gboolean equals_node_val_vs_int (xmlNodePtr node, gint64 val);
|
||||
gboolean equals_node_val_vs_boolean (xmlNodePtr node, gboolean val);
|
||||
|
||||
|
||||
@@ -287,14 +287,14 @@ node_and_transaction_equal (xmlNodePtr node, Transaction* trn)
|
||||
}
|
||||
else if (g_strcmp0 ((char*)mark->name, "trn:date-posted") == 0)
|
||||
{
|
||||
if (!equals_node_val_vs_date (mark, xaccTransRetDatePostedTS (trn)))
|
||||
if (!equals_node_val_vs_date (mark, xaccTransRetDatePosted (trn)))
|
||||
{
|
||||
return "posted dates differ";
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 ((char*)mark->name, "trn:date-entered") == 0)
|
||||
{
|
||||
if (!equals_node_val_vs_date (mark, xaccTransRetDateEnteredTS (trn)))
|
||||
if (!equals_node_val_vs_date (mark, xaccTransRetDateEntered (trn)))
|
||||
{
|
||||
return "entered dates differ";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user