James LewisMoss's patch.

* src/test/test-date-converting.c (Repository): Tests to make sure
	date <-> string converting strings work.

	* src/test/test-dom-converters1.c (Repository): Add tests for rest
	of converters.

	* src/test/Makefile.am (Repository): add new test.  Make "make
	check" work here.

	* src/engine/sixtp-xml-write-utils.c (Repository): use date format
	strings from sixtp-utils.h

	* src/engine/sixtp-utils.h (Repository): add date format strings.
	#include sixtp.h

	* src/engine/sixtp-utils.c (Repository): Use define as timespec
	date format string.

	* src/engine/sixtp-dom-parsers.c (Repository): Add funcs from
	Rob.  make consistent.  Fix a few bugs.  Make
	dom_tree_to_commodity_ref testable by adding new func
	"associate_commodity_ref_with_engine_commodity" to do final
	association with engine commodity table.

	* src/engine/sixtp-dom-generators.c (Repository): Fix to_guid to
	be generic.  Oops.  Add rest of funcs to to foo_to_dom_tree to
	match funcs in sixtp_dom_parsers.

	* src/engine/gnc-numeric.c (Repository): Comment out unused var.

	* src/engine/gnc-account-xml-v2.c (Repository): change to use
	dom_tree_to_commodity_ref.

	* src/doc/xml/types.dtd: Change cmd: to cmdty: and add ts: to the
	timespec tags.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3659 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Dave Peticolas 2001-02-15 00:17:57 +00:00
parent e04666349e
commit f335a5b722
13 changed files with 433 additions and 24 deletions

View File

@ -1,3 +1,41 @@
2001-02-14 James LewisMoss <jimdres@mindspring.com>
* src/test/test-date-converting.c (Repository): Tests to make sure
date <-> string converting strings work.
* src/test/test-dom-converters1.c (Repository): Add tests for rest
of converters.
* src/test/Makefile.am (Repository): add new test. Make "make
check" work here.
* src/engine/sixtp-xml-write-utils.c (Repository): use date format
strings from sixtp-utils.h
* src/engine/sixtp-utils.h (Repository): add date format strings.
#include sixtp.h
* src/engine/sixtp-utils.c (Repository): Use define as timespec
date format string.
* src/engine/sixtp-dom-parsers.c (Repository): Add funcs from
Rob. make consistent. Fix a few bugs. Make
dom_tree_to_commodity_ref testable by adding new func
"associate_commodity_ref_with_engine_commodity" to do final
association with engine commodity table.
* src/engine/sixtp-dom-generators.c (Repository): Fix to_guid to
be generic. Oops. Add rest of funcs to to foo_to_dom_tree to
match funcs in sixtp_dom_parsers.
* src/engine/gnc-numeric.c (Repository): Comment out unused var.
* src/engine/gnc-account-xml-v2.c (Repository): change to use
dom_tree_to_commodity_ref.
* src/doc/xml/types.dtd: Change cmd: to cmdty: and add ts: to the
timespec tags.
2001-02-14 Dave Peticolas <dave@krondo.com>
* src/engine/date.c: use nl_langinfo (D_FMT) instead of %x for

2
debian/changelog vendored
View File

@ -1,4 +1,4 @@
gnucash (1.5.2.cvs20010124-test1-0.1) unstable; urgency=low
gnucash (1.5.2.cvs20010212-0.1) unstable; urgency=low
* local cvs compile

1
debian/control vendored
View File

@ -3,6 +3,7 @@ Section: utils
Priority: extra
Maintainer: John Goerzen <jgoerzen@complete.org>
Standards-Version: 3.1.0.0
Build-Depends: libguppi-dev, libguile-dev, libgtkhtml-dev, libxml-dev, libart-dev, libgnome-dev, libgwrapguile-dev, libglib1.2-dev
Package: gnucash
Architecture: any

View File

@ -2,10 +2,10 @@
<!ENTITY % id-type "(guid, new)">
<!ENTITY % default-id-type "guid">
<!ELEMENT cmd:space (#PCDATA)>
<!ELEMENT cmd:id (#PCDATA)>
<!ELEMENT cmdty:space (#PCDATA)>
<!ELEMENT cmdty:id (#PCDATA)>
<!ENTITY % commodity-type "(cmd:space, cmd:id)">
<!ENTITY % commodity-type "(cmdty:space, cmdty:id)">
<!-- need to replace the etc here -->
<!ENTITY % slot-types "(string | integer | double | etc)">
@ -20,7 +20,7 @@
<!ENTITY % slot-type "(slot+)">
<!ELEMENT date (#PCDATA)>
<!ELEMENT ns (#PCDATA)>
<!ELEMENT ts:date (#PCDATA)>
<!ELEMENT ts:ns (#PCDATA)>
<!ENTITY % date-type "(date, ns?)">
<!ENTITY % date-type "(ts:date, ts:ns?)">

View File

@ -8,6 +8,7 @@
#include "sixtp.h"
#include "sixtp-utils.h"
#include "sixtp-parsers.h"
#include "sixtp-utils.h"
#include "sixtp-dom-parsers.h"
#include "AccountP.h"
@ -55,14 +56,23 @@ account_type_handler (xmlNodePtr node, Account* act)
static gboolean
account_currency_handler (xmlNodePtr node, Account* act)
{
xaccAccountSetCurrency(act, dom_tree_to_gnc_commodity(node));
gnc_commodity *ref;
ref = dom_tree_to_commodity_ref(node);
xaccAccountSetCurrency(
act, associate_commodity_ref_with_engine_commodity(ref));
gnc_commodity_destroy(ref);
return TRUE;
}
static gboolean
account_security_handler (xmlNodePtr node, Account* act)
{
xaccAccountSetCurrency(act, dom_tree_to_gnc_commodity(node));
gnc_commodity *ref;
ref = dom_tree_to_commodity_ref(node);
xaccAccountSetSecurity(
act, associate_commodity_ref_with_engine_commodity(ref));
gnc_commodity_destroy(ref);
return TRUE;
}

View File

@ -37,7 +37,7 @@
* 64-bit-overflow-proof
*/
static short module = MOD_ENGINE;
/* static short module = MOD_ENGINE; */
static const char * _numeric_error_strings[] =
{

View File

@ -5,16 +5,18 @@
#include "gnc-xml-helper.h"
#include "sixtp-dom-generators.h"
#include "sixtp-utils.h"
#include "GNCId.h"
xmlNodePtr
guid_to_dom_tree(GUID* gid)
guid_to_dom_tree(const char *tag, GUID* gid)
{
char *guid_str;
xmlNodePtr ret;
ret = xmlNewNode(NULL, "test-guid");
ret = xmlNewNode(NULL, tag);
xmlSetProp(ret, "type", "guid");
@ -29,3 +31,113 @@ guid_to_dom_tree(GUID* gid)
return ret;
}
xmlNodePtr
commodity_ref_to_dom_tree(const char *tag, const gnc_commodity *c)
{
xmlNodePtr ret;
g_return_val_if_fail(c, NULL);
ret = xmlNewNode(NULL, tag);
xmlNewTextChild(ret, NULL, "cmdty:space", gnc_commodity_get_namespace(c));
xmlNewTextChild(ret, NULL, "cmdty:id", gnc_commodity_get_mnemonic(c));
return ret;
}
gchar *
timespec_sec_to_string(const Timespec *ts)
{
gchar *ret;
struct tm parsed_time;
time_t tmp_time;
ret = g_new(gchar, 512);
tmp_time = ts->tv_sec;
if(!localtime_r(&tmp_time, &parsed_time))
{
g_free(ret);
return NULL;
}
if(strftime(ret, 512, TIMESPEC_TIME_FORMAT, &parsed_time) == 0)
{
g_free(ret);
return NULL;
}
return ret;
}
gchar *
timespec_nsec_to_string(const Timespec *ts)
{
gchar *ret;
ret = g_new(gchar, 22);
g_snprintf(ret, 22, "%ld", ts->tv_nsec);
return ret;
}
xmlNodePtr
timespec_to_dom_tree(const char *tag, const Timespec *spec)
{
xmlNodePtr ret;
gchar *date_str;
gchar *ns_str;
g_return_val_if_fail(spec, NULL);
date_str = timespec_sec_to_string(spec);
ns_str = timespec_nsec_to_string(spec);
if((!date_str && !ns_str) || !date_str)
{
if(ns_str)
{
g_free(ns_str);
}
return NULL;
}
ret = xmlNewNode(NULL, tag);
xmlNewTextChild(ret, NULL, "ts:date", date_str);
if(ns_str)
{
xmlNewTextChild(ret, NULL, "ts:ns", ns_str);
}
g_free(date_str);
g_free(ns_str);
return ret;
}
xmlNodePtr
gnc_numeric_to_dom_tree(const char *tag, const gnc_numeric *num)
{
xmlNodePtr ret;
gchar *numstr;
g_return_val_if_fail(num, NULL);
numstr = gnc_numeric_to_string(*num);
g_return_val_if_fail(numstr, NULL);
ret = xmlNewNode(NULL, tag);
xmlNodeAddContent(ret, numstr);
g_free(numstr);
return ret;
}

View File

@ -9,8 +9,15 @@
#include "sixtp-dom-generators.h"
#include "GNCId.h"
#include "gnc-commodity.h"
#include "date.h"
#include "gnc-numeric.h"
xmlNodePtr guid_to_dom_tree(GUID* gid);
xmlNodePtr guid_to_dom_tree(const char *tag, GUID* 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 gnc_numeric_to_dom_tree(const char *tag, const gnc_numeric *num);
#endif /* _SIXTP_DOM_GENERATORS_H_ */

View File

@ -4,10 +4,16 @@
#include <string.h>
#include "gnc-xml-helper.h"
#include "gnc-engine-util.h"
#include "gnc-commodity.h"
#include "gnc-engine.h"
#include "sixtp-utils.h"
#include "sixtp-dom-parsers.h"
#include "GNCId.h"
static short module = MOD_IO;
GUID*
dom_tree_to_guid(xmlNodePtr node)
{
@ -45,13 +51,6 @@ dom_tree_to_guid(xmlNodePtr node)
}
}
gnc_commodity*
dom_tree_to_gnc_commodity(xmlNodePtr node)
{
return NULL;
}
gboolean
dom_tree_handle_kvp(kvp_frame* frame, xmlNodePtr node)
{
@ -59,3 +58,232 @@ dom_tree_handle_kvp(kvp_frame* frame, xmlNodePtr node)
return FALSE;
}
gchar *
dom_tree_to_text(xmlNodePtr tree)
{
/* Expect *only* text and comment sibling nodes. Ignore comment
nodes and collapse text nodes into one string. Return NULL if
expectations are unsatisfied.
If there are a lot of text sub-nodes, this algorithm may be
inefficient because it'll reallocate a lot.
*/
gboolean ok = TRUE;
xmlNodePtr current;
gchar *result = g_strdup("");
gchar *temp;
for(current = tree; current; current = current->next) {
switch(current->type) {
case XML_TEXT_NODE:
temp = g_strconcat(result, (gchar *) current->content, NULL);
g_free(result);
result = temp;
break;
case XML_COMMENT_NODE:
break;
default:
PERR("dom_tree_to_text: hit illegal node type while extracting text.");
current = NULL;
ok = FALSE;
break;
};
}
if(!ok) {
if(result) g_free(result);
result = NULL;
}
return result;
}
gnc_numeric*
dom_tree_to_gnc_numeric(xmlNodePtr node)
{
gchar *content = dom_tree_to_text(node->xmlChildrenNode);
gnc_numeric *ret;
if(!content)
return NULL;
ret = g_new(gnc_numeric, 1);
if(string_to_gnc_numeric(content, ret) != NULL)
{
return ret;
}
else
{
g_free(ret);
return NULL;
}
}
static Timespec*
timespec_failure(Timespec *would_have_been)
{
if(would_have_been)
{
g_free(would_have_been);
}
return NULL;
}
Timespec*
dom_tree_to_timespec(xmlNodePtr node)
{
/* Turn something like this
<date-posted>
<s>Mon, 05 Jun 2000 23:16:19 -0500</s>
<ns>658864000</ns>
</date-posted>
into a Timespec. 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;
gboolean seen_s = FALSE;
gboolean seen_ns = FALSE;
xmlNodePtr n;
ret = g_new(Timespec, 1);
ret->tv_sec = 0;
ret->tv_nsec = 0;
for(n = node->xmlChildrenNode; n; n = n->next) {
switch(n->type) {
case XML_COMMENT_NODE:
break;
case XML_ELEMENT_NODE:
if(safe_strcmp("ts:date", n->name) == 0) {
if(seen_s)
{
return timespec_failure(ret);
}
else
{
gchar *content = dom_tree_to_text(n->xmlChildrenNode);
if(!content)
{
return timespec_failure(ret);
}
if(!string_to_timespec_secs(content, ret)) {
free(content);
return timespec_failure(ret);
}
seen_s = TRUE;
}
}
else if(safe_strcmp("ts:ns", n->name) == 0) {
if(seen_ns)
{
return timespec_failure(ret);
}
else
{
gchar *content = dom_tree_to_text(n->xmlChildrenNode);
if(!content)
{
return timespec_failure(ret);
}
if(!string_to_timespec_nsecs(content, ret)) {
free(content);
return timespec_failure(ret);
}
seen_ns = TRUE;
}
}
break;
default:
PERR("dom_tree_to_timespec: unexpected sub-node.");
return timespec_failure(ret);
break;
}
}
if(!seen_s)
{
g_warning("dom_tree_to_timespec: no ts:date node found.");
return timespec_failure(ret);
}
return ret;
}
gnc_commodity *
dom_tree_to_commodity_ref(xmlNodePtr node)
{
/* Turn something like this
<currency>
<cmdty:space>NASDAQ</cmdty:space>
<cmdty:id>LNUX</cmdty:space>
</currency>
into a gnc_commodity*, returning NULL on failure. Both sub-nodes
are required, though for now, order is irrelevant. */
gnc_commodity *c = NULL;
gchar *space_str = NULL;
gchar *id_str = NULL;
xmlNodePtr n;
if(!node) return NULL;
if(!node->xmlChildrenNode) return NULL;
for(n = node->xmlChildrenNode; n; n = n->next) {
switch(n->type) {
case XML_COMMENT_NODE:
break;
case XML_ELEMENT_NODE:
if(safe_strcmp("cmdty:space", n->name) == 0) {
if(space_str) {
return NULL;
} else {
gchar *content = dom_tree_to_text(n->xmlChildrenNode);
if(!content) return NULL;
space_str = content;
}
} else if(safe_strcmp("cmdty:id", n->name) == 0) {
if(id_str) {
return NULL;
} else {
gchar *content = dom_tree_to_text(n->xmlChildrenNode);
if(!content) return NULL;
id_str = content;
}
}
break;
default:
PERR("dom_tree_to_timespec: unexpected sub-node.");
return NULL;
break;
}
}
if(!(space_str && id_str)) {
c = NULL;
} else {
g_strstrip(space_str);
g_strstrip(id_str);
c = gnc_commodity_new(NULL, space_str, id_str, NULL, 0);
}
if(space_str) g_free(space_str);
if(id_str) g_free(id_str);
return c;
}
gnc_commodity *
associate_commodity_ref_with_engine_commodity(gnc_commodity *com)
{
return gnc_commodity_table_lookup(gnc_engine_commodities(),
gnc_commodity_get_namespace(com),
gnc_commodity_get_exchange_code(com));
}

View File

@ -9,12 +9,20 @@
#include "gnc-commodity.h"
#include "kvp_frame.h"
#include "date.h"
#include "gnc-numeric.h"
#include "GNCId.h"
GUID* dom_tree_to_guid(xmlNodePtr node);
gnc_commodity* dom_tree_to_gnc_commodity(xmlNodePtr node);
gnc_commodity* dom_tree_to_commodity_ref(xmlNodePtr node);
gnc_commodity* associate_commodity_ref_with_engine_commodity(
gnc_commodity *com);
Timespec* dom_tree_to_timespec(xmlNodePtr node);
gnc_numeric* dom_tree_to_gnc_numeric(xmlNodePtr node);
gchar * dom_tree_to_text(xmlNodePtr tree);
gboolean dom_tree_handle_kvp(kvp_frame* frame, xmlNodePtr node);

View File

@ -343,7 +343,7 @@ string_to_timespec_secs(const gchar *str, Timespec *ts) {
/* If you change this, make sure you also change the output code, if
necessary. */
/*fprintf(stderr, "parsing (%s)\n", str);*/
strpos = strptime(str, "%Y-%m-%d %H:%M:%S", &parsed_time);
strpos = strptime(str, TIMESPEC_PARSE_TIME_FORMAT, &parsed_time);
g_return_val_if_fail(strpos, FALSE);

View File

@ -4,12 +4,16 @@
#include "date.h"
#include "sixtp.h"
typedef struct {
Timespec ts;
guint s_block_count;
guint ns_block_count;
} TimespecParseInfo;
#define TIMESPEC_TIME_FORMAT "%Y-%m-%d %H:%M:%S %z"
#define TIMESPEC_PARSE_TIME_FORMAT "%Y-%m-%d %H:%M:%S"
gboolean isspace_str(const gchar *str, int nomorethan);

View File

@ -10,6 +10,7 @@
#include "gnc-xml-helper.h"
#include "sixtp-xml-write-utils.h"
#include "sixtp-utils.h"
#include "gnc-numeric.h"
#include "gnc-engine-util.h"
@ -225,7 +226,7 @@ xml_add_editable_timespec(xmlNodePtr p,
if(!localtime_r(&tmp_timet, &parsed_time)) return(FALSE);
num_written = strftime(secs_str, sizeof(secs_str),
"%Y-%m-%d %H:%M:%S %z",
TIMESPEC_TIME_FORMAT,
&parsed_time);
if(num_written == 0) return(FALSE);