mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
James LewisMoss's patch.
2001-02-07 James LewisMoss <dres@phoenixdsl.com> * make-gnucash-patch.in: Add a file ending that is ignored. * src/doc/xml/types.dtd: Change currency-type -> commodity-type. Add defs for cmd:space and cmd:id. * src/doc/xml/io-gncxml-version1.dtd: Change currency-type -> commodity-type. * src/doc/xml/account-v2.dtd: Change currency-type -> commodity-type. 2001-02-06 James LewisMoss <dres@phoenixdsl.com> * src/engine/sixtp.c: Use frame creator. Move sixtp_handle_catastrophe to here. Add functions sixtp_context_new, sixtp_context_destroy. And change and move sixtp_parse_file and sixtp_parse_buffer here from io-gncxml-r.c Add concept of a parsing context to hold data. * src/engine/sixtp-stack.h: Add creator. Add headers. * src/engine/sixtp-stack.c: Add creator. * src/engine/sixtp-parsers.h: add needed headers. Add func from sixtp-to-dom-parser.c * src/engine/io-gncxml.h: Fix name. * src/engine/io-gncxml-w.c: Fix name. * src/engine/io-gncxml-r.c: Fix name. Create stack frame creator function and use here. 2001-02-05 James LewisMoss <dres@phoenixdsl.com> * src/engine/sixtp-stack.h: Add glib.h include (needed for GSList) * src/engine/sixtp.c: Add catchall tag for parsing handlers. Use name instead of next_parser_tag since that can now contain a magic value. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3618 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
7d546af657
commit
fa9cff9ce9
43
ChangeLog
43
ChangeLog
@ -1,3 +1,46 @@
|
|||||||
|
2001-02-07 James LewisMoss <dres@phoenixdsl.com>
|
||||||
|
|
||||||
|
* make-gnucash-patch.in: Add a file ending that is ignored.
|
||||||
|
|
||||||
|
* src/doc/xml/types.dtd: Change currency-type -> commodity-type.
|
||||||
|
Add defs for cmd:space and cmd:id.
|
||||||
|
|
||||||
|
* src/doc/xml/io-gncxml-version1.dtd: Change currency-type ->
|
||||||
|
commodity-type.
|
||||||
|
|
||||||
|
* src/doc/xml/account-v2.dtd: Change currency-type ->
|
||||||
|
commodity-type.
|
||||||
|
|
||||||
|
2001-02-06 James LewisMoss <dres@phoenixdsl.com>
|
||||||
|
|
||||||
|
* src/engine/sixtp.c: Use frame creator.
|
||||||
|
Move sixtp_handle_catastrophe to here. Add functions
|
||||||
|
sixtp_context_new, sixtp_context_destroy. And change and move
|
||||||
|
sixtp_parse_file and sixtp_parse_buffer here from io-gncxml-r.c
|
||||||
|
Add concept of a parsing context to hold data.
|
||||||
|
|
||||||
|
* src/engine/sixtp-stack.h: Add creator. Add headers.
|
||||||
|
|
||||||
|
* src/engine/sixtp-stack.c: Add creator.
|
||||||
|
|
||||||
|
* src/engine/sixtp-parsers.h: add needed headers.
|
||||||
|
Add func from sixtp-to-dom-parser.c
|
||||||
|
|
||||||
|
* src/engine/io-gncxml.h: Fix name.
|
||||||
|
|
||||||
|
* src/engine/io-gncxml-w.c: Fix name.
|
||||||
|
|
||||||
|
* src/engine/io-gncxml-r.c: Fix name. Create stack frame creator
|
||||||
|
function and use here.
|
||||||
|
|
||||||
|
2001-02-05 James LewisMoss <dres@phoenixdsl.com>
|
||||||
|
|
||||||
|
* src/engine/sixtp-stack.h: Add glib.h include (needed for GSList)
|
||||||
|
|
||||||
|
* src/engine/sixtp.c: Add catchall tag for parsing handlers. Use
|
||||||
|
name instead of next_parser_tag since that can now contain a magic
|
||||||
|
value.
|
||||||
|
|
||||||
2001-02-05 Bill Gribble <grib@billgribble.com>
|
2001-02-05 Bill Gribble <grib@billgribble.com>
|
||||||
|
|
||||||
* src/scm/qif-import/qif-merge-groups.scm: new file. Utilities
|
* src/scm/qif-import/qif-merge-groups.scm: new file. Utilities
|
||||||
|
17
configure.in
17
configure.in
@ -52,6 +52,22 @@ then
|
|||||||
AC_MSG_ERROR([Cannot find glib.])
|
AC_MSG_ERROR([Cannot find glib.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_CHECK_HEADERS(dlfcn.h dl.h utmp.h locale.h mcheck.h unistd.h)
|
||||||
|
|
||||||
|
DL_LIB=
|
||||||
|
AC_CHECK_FUNCS(dlopen,,[
|
||||||
|
AC_CHECK_LIB(dl, dlopen, DL_LIB="-ldl",[
|
||||||
|
AC_CHECK_LIB(dld, shl_load, DL_LIB="-ldld",[
|
||||||
|
AC_CHECK_FUNCS(dlopen, DL_LIB="",
|
||||||
|
AC_MSG_ERROR(Dynamic linking is not available on this platform. Some apps,
|
||||||
|
like panel, will not run properly.))
|
||||||
|
])])])
|
||||||
|
oLIBS="$LIBS"
|
||||||
|
LIBS="$LIBS $DL_LIB"
|
||||||
|
AC_CHECK_FUNCS(dlerror,,)
|
||||||
|
LIBS="$oLIBS"
|
||||||
|
AC_SUBST(DL_LIB)
|
||||||
|
|
||||||
GNOME_INIT
|
GNOME_INIT
|
||||||
|
|
||||||
GNOME_COMPILE_WARNINGS
|
GNOME_COMPILE_WARNINGS
|
||||||
@ -512,6 +528,7 @@ AC_OUTPUT(
|
|||||||
src/scm/qif-import/Makefile
|
src/scm/qif-import/Makefile
|
||||||
src/scm/report/Makefile
|
src/scm/report/Makefile
|
||||||
src/scm/srfi/Makefile
|
src/scm/srfi/Makefile
|
||||||
|
src/test/Makefile
|
||||||
dnl # non-makefiles
|
dnl # non-makefiles
|
||||||
dnl # Please read doc/build-system before adding *anything* here
|
dnl # Please read doc/build-system before adding *anything* here
|
||||||
,
|
,
|
||||||
|
@ -109,7 +109,7 @@ if (not defined($old)) {
|
|||||||
|
|
||||||
chdir $gnc_home . "/" . $new or die "Can't cd!\n";
|
chdir $gnc_home . "/" . $new or die "Can't cd!\n";
|
||||||
# Start out with our basic makepatch arguments
|
# Start out with our basic makepatch arguments
|
||||||
my @args = ('-verbose', '-diff', 'diff -u', '-exclude-vc');
|
my @args = ('-verbose', '-diff', 'diff -up', '-exclude-vc');
|
||||||
|
|
||||||
if (not $::ask_description) {
|
if (not $::ask_description) {
|
||||||
push(@args, '-description', '');
|
push(@args, '-description', '');
|
||||||
@ -221,6 +221,7 @@ __DATA__
|
|||||||
*.moc
|
*.moc
|
||||||
*.o
|
*.o
|
||||||
*.orig
|
*.orig
|
||||||
|
*.ignmgp
|
||||||
*.patch
|
*.patch
|
||||||
*.rej
|
*.rej
|
||||||
*.tar.gz
|
*.tar.gz
|
||||||
|
@ -10,7 +10,8 @@ SUBDIRS = \
|
|||||||
scm \
|
scm \
|
||||||
quotes \
|
quotes \
|
||||||
pixmaps \
|
pixmaps \
|
||||||
optional
|
optional \
|
||||||
|
test
|
||||||
|
|
||||||
# Engine Makefile.am file.
|
# Engine Makefile.am file.
|
||||||
bin_PROGRAMS = gnucash
|
bin_PROGRAMS = gnucash
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
|
|
||||||
<!ELEMENT act:type (#PCDATA)>
|
<!ELEMENT act:type (#PCDATA)>
|
||||||
|
|
||||||
<!ELEMENT act:currency %currency-type;>
|
<!ELEMENT act:currency %commodity-type;>
|
||||||
|
|
||||||
<!ELEMENT act:security %currency-type;>
|
<!ELEMENT act:security %commodity-type;>
|
||||||
|
|
||||||
<!ELEMENT act:slots %slot-type;>
|
<!ELEMENT act:slots %slot-type;>
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
"( guid, num?, date-posted, date-entered, description?,
|
"( guid, num?, date-posted, date-entered, description?,
|
||||||
slots?, split+)">
|
slots?, split+)">
|
||||||
<!ENTITY % combined-restores "%commodity-restore; | %account-restore; | %transaction-restore;">
|
<!ENTITY % combined-restores "%commodity-restore; | %account-restore; | %transaction-restore;">
|
||||||
<!ENTITY % currency-type "(space, id)">
|
<!ENTITY % commodity-type "(space, id)">
|
||||||
<!ENTITY % commodity-new "ANY">
|
<!ENTITY % commodity-new "ANY">
|
||||||
<!ENTITY % account-new "ANY">
|
<!ENTITY % account-new "ANY">
|
||||||
<!ENTITY % transaction-new "ANY">
|
<!ENTITY % transaction-new "ANY">
|
||||||
@ -47,8 +47,8 @@
|
|||||||
|
|
||||||
<!ELEMENT guid (#PCDATA)>
|
<!ELEMENT guid (#PCDATA)>
|
||||||
<!ELEMENT type (#PCDATA)>
|
<!ELEMENT type (#PCDATA)>
|
||||||
<!ELEMENT security %currency-type;>
|
<!ELEMENT security %commodity-type;>
|
||||||
<!ELEMENT currency %currency-type;>
|
<!ELEMENT currency %commodity-type;>
|
||||||
<!ELEMENT slots (s+)>
|
<!ELEMENT slots (s+)>
|
||||||
|
|
||||||
<!-- used in two contexts as item in slots list and as a date in -->
|
<!-- used in two contexts as item in slots list and as a date in -->
|
||||||
|
@ -2,8 +2,12 @@
|
|||||||
<!ENTITY % id-type "(guid, new)">
|
<!ENTITY % id-type "(guid, new)">
|
||||||
<!ENTITY % default-id-type "guid">
|
<!ENTITY % default-id-type "guid">
|
||||||
|
|
||||||
<!ENTITY % currency-type "(cur:space, cur:id)">
|
<!ELEMENT cmd:space (#PCDATA)>
|
||||||
|
<!ELEMENT cmd:id (#PCDATA)>
|
||||||
|
|
||||||
|
<!ENTITY % commodity-type "(cmd:space, cmd:id)">
|
||||||
|
|
||||||
|
<!-- need to replace the etc here -->
|
||||||
<!ENTITY % slot-types "(string | integer | double | etc)">
|
<!ENTITY % slot-types "(string | integer | double | etc)">
|
||||||
|
|
||||||
<!ELEMENT slot (key, value)>
|
<!ELEMENT slot (key, value)>
|
||||||
|
@ -37,6 +37,7 @@ libgncengine_la_SOURCES = \
|
|||||||
sixtp-stack.c \
|
sixtp-stack.c \
|
||||||
sixtp-utils.c \
|
sixtp-utils.c \
|
||||||
sixtp-xml-write-utils.c \
|
sixtp-xml-write-utils.c \
|
||||||
|
sixtp-to-dom-parser.c \
|
||||||
sixtp.c \
|
sixtp.c \
|
||||||
Account-xml-parser-v1.c \
|
Account-xml-parser-v1.c \
|
||||||
Commodity-xml-parser-v1.c \
|
Commodity-xml-parser-v1.c \
|
||||||
|
@ -75,249 +75,7 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static short module = MOD_IO;
|
/* static short module = MOD_IO; */
|
||||||
|
|
||||||
static xmlEntityPtr
|
|
||||||
sixtp_sax_get_entity_handler(void *user_data, const CHAR *name) {
|
|
||||||
return xmlGetPredefinedEntity(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
sixtp_handle_catastrophe(sixtp_sax_data *sax_data) {
|
|
||||||
/* Something has gone wrong. To handle it, we have to traverse the
|
|
||||||
stack, calling, at each level, the frame failure handler (the
|
|
||||||
handler for the current, unfinished block) and then the sibling
|
|
||||||
handlers. The order is reverse chronological - oldest child
|
|
||||||
results cleaned up last. This holds overall as well, stack
|
|
||||||
frames are cleaned up in their order on the stack which will be
|
|
||||||
youngest to oldest. */
|
|
||||||
|
|
||||||
GSList *lp;
|
|
||||||
GSList **stack = &(sax_data->stack);
|
|
||||||
|
|
||||||
PERR("parse failed at \n");
|
|
||||||
sixtp_print_frame_stack(sax_data->stack, stderr);
|
|
||||||
|
|
||||||
while(*stack) {
|
|
||||||
sixtp_stack_frame *current_frame = (sixtp_stack_frame *) (*stack)->data;
|
|
||||||
|
|
||||||
/* cleanup the current frame */
|
|
||||||
if(current_frame->parser->fail_handler) {
|
|
||||||
GSList *sibling_data;
|
|
||||||
gpointer parent_data;
|
|
||||||
|
|
||||||
if((*stack)->next == NULL) {
|
|
||||||
/* This is the top of the stack... */
|
|
||||||
parent_data = NULL;
|
|
||||||
sibling_data = NULL;
|
|
||||||
} else {
|
|
||||||
sixtp_stack_frame *parent_frame =
|
|
||||||
(sixtp_stack_frame *) (*stack)->next->data;
|
|
||||||
parent_data = parent_frame->data_for_children;
|
|
||||||
sibling_data = parent_frame->data_from_children;
|
|
||||||
}
|
|
||||||
|
|
||||||
current_frame->parser->fail_handler(current_frame->data_for_children,
|
|
||||||
current_frame->data_from_children,
|
|
||||||
sibling_data,
|
|
||||||
parent_data,
|
|
||||||
sax_data->global_data,
|
|
||||||
¤t_frame->frame_data,
|
|
||||||
current_frame->tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now cleanup any children's results */
|
|
||||||
for(lp = current_frame->data_from_children; lp; lp = lp->next) {
|
|
||||||
sixtp_child_result *cresult = (sixtp_child_result *) lp->data;
|
|
||||||
if(cresult->fail_handler) {
|
|
||||||
cresult->fail_handler(cresult);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*stack = sixtp_pop_and_destroy_frame(*stack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================================================== */
|
|
||||||
/* initialize misc structures so that we can call the libxml
|
|
||||||
* parser.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
sixtp_setup_parser (sixtp *sixtp,
|
|
||||||
gpointer data_for_top_level,
|
|
||||||
gpointer global_data,
|
|
||||||
xmlSAXHandler *sax_handler,
|
|
||||||
sixtp_sax_data *sax_data,
|
|
||||||
sixtp_stack_frame *top_frame
|
|
||||||
)
|
|
||||||
{
|
|
||||||
memset(sax_handler, '\0', sizeof(xmlSAXHandler));
|
|
||||||
sax_handler->startElement = sixtp_sax_start_handler;
|
|
||||||
sax_handler->endElement = sixtp_sax_end_handler;
|
|
||||||
sax_handler->characters = sixtp_sax_characters_handler;
|
|
||||||
sax_handler->getEntity = sixtp_sax_get_entity_handler;
|
|
||||||
|
|
||||||
memset(sax_data, '\0', sizeof(sixtp_sax_data));
|
|
||||||
sax_data->parsing_ok = TRUE;
|
|
||||||
sax_data->stack = NULL;
|
|
||||||
sax_data->global_data = global_data;
|
|
||||||
|
|
||||||
top_frame->parser = sixtp;
|
|
||||||
top_frame->tag = NULL;
|
|
||||||
top_frame->data_from_children = NULL;
|
|
||||||
top_frame->data_for_children = NULL;
|
|
||||||
top_frame->frame_data = NULL;
|
|
||||||
|
|
||||||
sax_data->stack = g_slist_prepend(sax_data->stack, (gpointer) top_frame);
|
|
||||||
|
|
||||||
if(sixtp->start_handler) {
|
|
||||||
sax_data->parsing_ok =
|
|
||||||
sixtp->start_handler(NULL,
|
|
||||||
data_for_top_level,
|
|
||||||
sax_data->global_data,
|
|
||||||
&top_frame->data_for_children,
|
|
||||||
&top_frame->frame_data,
|
|
||||||
NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!sax_data->parsing_ok) {
|
|
||||||
PERR ("parsing catastrophe");
|
|
||||||
sixtp_handle_catastrophe(sax_data);
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ========================================================== */
|
|
||||||
/* misc structure celanup after parsing */
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
sixtp_teardown_parser(sixtp *sixtp,
|
|
||||||
gpointer data_for_top_level,
|
|
||||||
gpointer global_data,
|
|
||||||
gpointer *parse_result,
|
|
||||||
sixtp_sax_data *sax_data,
|
|
||||||
sixtp_stack_frame *top_frame)
|
|
||||||
{
|
|
||||||
if(!sax_data->parsing_ok) {
|
|
||||||
PERR ("couldn't parse, handle catastrophe");
|
|
||||||
sixtp_handle_catastrophe(sax_data);
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sixtp->end_handler) {
|
|
||||||
sax_data->parsing_ok =
|
|
||||||
sixtp->end_handler(top_frame->data_for_children,
|
|
||||||
top_frame->data_from_children,
|
|
||||||
NULL,
|
|
||||||
data_for_top_level,
|
|
||||||
sax_data->global_data,
|
|
||||||
&top_frame->frame_data,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if(!sax_data->parsing_ok) {
|
|
||||||
PERR ("couldn't call end handler, cleanup catastrophe");
|
|
||||||
sixtp_handle_catastrophe(sax_data);
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* put the result where the caller can see it */
|
|
||||||
if(top_frame->frame_data) *parse_result = top_frame->frame_data;
|
|
||||||
|
|
||||||
{
|
|
||||||
GSList *lp = NULL;
|
|
||||||
for(lp = sax_data->stack; lp; lp = lp->next)
|
|
||||||
sixtp_stack_frame_destroy((sixtp_stack_frame *) lp->data);
|
|
||||||
}
|
|
||||||
g_slist_free(sax_data->stack);
|
|
||||||
return(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================================================== */
|
|
||||||
/* parse the contents of a file */
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
sixtp_parse_file(sixtp *sixtp,
|
|
||||||
const char *filename,
|
|
||||||
gpointer data_for_top_level,
|
|
||||||
gpointer global_data,
|
|
||||||
gpointer *parse_result)
|
|
||||||
{
|
|
||||||
xmlSAXHandler sax_handler;
|
|
||||||
sixtp_sax_data sax_data;
|
|
||||||
sixtp_stack_frame *top_frame = NULL;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
/* hack alert -- XXX -- where is top_frame released?? */
|
|
||||||
/* looks like a mem leak to me ... */
|
|
||||||
top_frame = g_new0(sixtp_stack_frame, 1);
|
|
||||||
rc = sixtp_setup_parser (sixtp,
|
|
||||||
data_for_top_level,
|
|
||||||
global_data,
|
|
||||||
&sax_handler,
|
|
||||||
&sax_data,
|
|
||||||
top_frame);
|
|
||||||
|
|
||||||
if(!rc) return(FALSE);
|
|
||||||
|
|
||||||
xmlSAXUserParseFile(&sax_handler, &sax_data, filename);
|
|
||||||
|
|
||||||
rc = sixtp_teardown_parser(sixtp,
|
|
||||||
data_for_top_level,
|
|
||||||
global_data,
|
|
||||||
parse_result,
|
|
||||||
&sax_data,
|
|
||||||
top_frame);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================================================== */
|
|
||||||
/* parse the contents of a buffer in memory */
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
sixtp_parse_buffer(sixtp *sixtp,
|
|
||||||
char *bufp,
|
|
||||||
int bufsz,
|
|
||||||
gpointer data_for_top_level,
|
|
||||||
gpointer global_data,
|
|
||||||
gpointer *parse_result)
|
|
||||||
{
|
|
||||||
xmlSAXHandler sax_handler;
|
|
||||||
sixtp_sax_data sax_data;
|
|
||||||
sixtp_stack_frame *top_frame = NULL;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
/* hack alert -- XXX -- where is top_frame released?? */
|
|
||||||
/* looks like a mem leak to me ... */
|
|
||||||
top_frame = g_new0(sixtp_stack_frame, 1);
|
|
||||||
rc = sixtp_setup_parser (sixtp,
|
|
||||||
data_for_top_level,
|
|
||||||
global_data,
|
|
||||||
&sax_handler,
|
|
||||||
&sax_data,
|
|
||||||
top_frame);
|
|
||||||
|
|
||||||
if(!rc) return(FALSE);
|
|
||||||
|
|
||||||
xmlSAXUserParseMemory(&sax_handler, &sax_data, bufp, bufsz);
|
|
||||||
|
|
||||||
rc = sixtp_teardown_parser(sixtp,
|
|
||||||
data_for_top_level,
|
|
||||||
global_data,
|
|
||||||
parse_result,
|
|
||||||
&sax_data,
|
|
||||||
top_frame);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================================================== */
|
/* ========================================================== */
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
* HISTORY:
|
* HISTORY:
|
||||||
* Initial code by Rob L. Browning 4Q 2000
|
* Initial code by Rob L. Browning 4Q 2000
|
||||||
* Tuneups by James Lewis Moss Dec 2000
|
* Tuneups by James LewisMoss Dec 2000-Feb 2001
|
||||||
* Generic I/O hack by Linas Vepstas January 2001
|
* Generic I/O hack by Linas Vepstas January 2001
|
||||||
*
|
*
|
||||||
* Copyright (c) 2000,2001 Gnumatic Incorporated
|
* Copyright (c) 2000,2001 Gnumatic Incorporated
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#ifndef _SIXTP_PARSERS_H_
|
#ifndef _SIXTP_PARSERS_H_
|
||||||
#define _SIXTP_PARSERS_H_
|
#define _SIXTP_PARSERS_H_
|
||||||
|
|
||||||
|
#include "sixtp.h"
|
||||||
|
|
||||||
/* from Transaction-xml-parser-v1.c */
|
/* from Transaction-xml-parser-v1.c */
|
||||||
sixtp* gnc_transaction_parser_new(void);
|
sixtp* gnc_transaction_parser_new(void);
|
||||||
|
|
||||||
@ -23,6 +25,8 @@ sixtp* query_server_parser_new (void);
|
|||||||
/* from sixtp-kvp-parser.c */
|
/* from sixtp-kvp-parser.c */
|
||||||
sixtp* kvp_frame_parser_new(void);
|
sixtp* kvp_frame_parser_new(void);
|
||||||
|
|
||||||
|
/* from sixtp-to-dom-parser.c */
|
||||||
|
sixtp* sixtp_dom_parser_new(sixtp_end_handler ender);
|
||||||
|
|
||||||
|
|
||||||
#endif /* _SIXTP_PARSERS_H_ */
|
#endif /* _SIXTP_PARSERS_H_ */
|
||||||
|
@ -12,9 +12,29 @@ sixtp_stack_frame_destroy(sixtp_stack_frame *sf) {
|
|||||||
g_slist_free(sf->data_from_children);
|
g_slist_free(sf->data_from_children);
|
||||||
sf->data_from_children = NULL;
|
sf->data_from_children = NULL;
|
||||||
|
|
||||||
|
/* if(sf->tag) */
|
||||||
|
/* { */
|
||||||
|
/* g_free(sf->tag); */
|
||||||
|
/* } */
|
||||||
|
|
||||||
g_free(sf);
|
g_free(sf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sixtp_stack_frame*
|
||||||
|
sixtp_stack_frame_new(sixtp* next_parser, char *tag)
|
||||||
|
{
|
||||||
|
sixtp_stack_frame* new_frame;
|
||||||
|
|
||||||
|
new_frame = g_new0(sixtp_stack_frame, 1);
|
||||||
|
new_frame->parser = next_parser;
|
||||||
|
new_frame->tag = tag;
|
||||||
|
new_frame->data_for_children = NULL;
|
||||||
|
new_frame->data_from_children = NULL;
|
||||||
|
new_frame->frame_data = NULL;
|
||||||
|
|
||||||
|
return new_frame;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sixtp_stack_frame_print(sixtp_stack_frame *sf, gint indent, FILE *f) {
|
sixtp_stack_frame_print(sixtp_stack_frame *sf, gint indent, FILE *f) {
|
||||||
gchar *is = g_strnfill(indent, ' ');
|
gchar *is = g_strnfill(indent, ' ');
|
||||||
@ -63,3 +83,72 @@ sixtp_print_frame_stack(GSList *stack, FILE *f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Parser context */
|
||||||
|
sixtp_parser_context*
|
||||||
|
sixtp_context_new(sixtp *initial_parser, gpointer global_data,
|
||||||
|
gpointer top_level_data)
|
||||||
|
{
|
||||||
|
sixtp_parser_context* ret;
|
||||||
|
|
||||||
|
ret = g_new0(sixtp_parser_context, 1);
|
||||||
|
|
||||||
|
ret->handler.startElement = sixtp_sax_start_handler;
|
||||||
|
ret->handler.endElement = sixtp_sax_end_handler;
|
||||||
|
ret->handler.characters = sixtp_sax_characters_handler;
|
||||||
|
ret->handler.getEntity = sixtp_sax_get_entity_handler;
|
||||||
|
|
||||||
|
ret->data.parsing_ok = TRUE;
|
||||||
|
ret->data.stack = NULL;
|
||||||
|
ret->data.global_data = global_data;
|
||||||
|
|
||||||
|
ret->top_frame = sixtp_stack_frame_new(initial_parser, NULL);
|
||||||
|
|
||||||
|
ret->top_frame_data = top_level_data;
|
||||||
|
|
||||||
|
ret->data.stack = g_slist_prepend(ret->data.stack,
|
||||||
|
(gpointer) ret->top_frame);
|
||||||
|
|
||||||
|
if(initial_parser->start_handler)
|
||||||
|
{
|
||||||
|
if(!initial_parser->start_handler(NULL,
|
||||||
|
&ret->top_frame_data,
|
||||||
|
&ret->data.global_data,
|
||||||
|
&ret->top_frame->data_for_children,
|
||||||
|
&ret->top_frame->frame_data,
|
||||||
|
NULL, NULL))
|
||||||
|
{
|
||||||
|
sixtp_handle_catastrophe(&ret->data);
|
||||||
|
sixtp_context_destroy(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sixtp_context_run_end_handler(sixtp_parser_context* ctxt)
|
||||||
|
{
|
||||||
|
if(ctxt->top_frame->parser->end_handler)
|
||||||
|
{
|
||||||
|
ctxt->data.parsing_ok =
|
||||||
|
ctxt->top_frame->parser->end_handler(
|
||||||
|
ctxt->top_frame->data_for_children,
|
||||||
|
ctxt->top_frame->data_from_children,
|
||||||
|
NULL,
|
||||||
|
ctxt->top_frame_data,
|
||||||
|
ctxt->data.global_data,
|
||||||
|
&ctxt->top_frame->frame_data,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sixtp_context_destroy(sixtp_parser_context* context)
|
||||||
|
{
|
||||||
|
sixtp_stack_frame_destroy(context->top_frame);
|
||||||
|
g_slist_free(context->data.stack);
|
||||||
|
g_free(context);
|
||||||
|
}
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
#ifndef _SIXTP_STACK_H_
|
#ifndef _SIXTP_STACK_H_
|
||||||
#define _SIXTP_STACK_H_
|
#define _SIXTP_STACK_H_
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "sixtp.h"
|
||||||
|
|
||||||
typedef struct sixtp_stack_frame {
|
typedef struct sixtp_stack_frame {
|
||||||
sixtp *parser;
|
sixtp *parser;
|
||||||
gchar *tag;
|
gchar *tag;
|
||||||
@ -10,6 +14,15 @@ typedef struct sixtp_stack_frame {
|
|||||||
gpointer frame_data;
|
gpointer frame_data;
|
||||||
} sixtp_stack_frame;
|
} sixtp_stack_frame;
|
||||||
|
|
||||||
|
struct _sixtp_parser_context_struct
|
||||||
|
{
|
||||||
|
xmlSAXHandler handler;
|
||||||
|
sixtp_sax_data data;
|
||||||
|
sixtp_stack_frame *top_frame;
|
||||||
|
gpointer top_frame_data;
|
||||||
|
};
|
||||||
|
typedef struct _sixtp_parser_context_struct sixtp_parser_context;
|
||||||
|
|
||||||
void sixtp_stack_frame_destroy(sixtp_stack_frame *sf);
|
void sixtp_stack_frame_destroy(sixtp_stack_frame *sf);
|
||||||
|
|
||||||
void sixtp_stack_frame_print(sixtp_stack_frame *sf, gint indent, FILE *f);
|
void sixtp_stack_frame_print(sixtp_stack_frame *sf, gint indent, FILE *f);
|
||||||
@ -18,5 +31,12 @@ GSList* sixtp_pop_and_destroy_frame(GSList *frame_stack);
|
|||||||
|
|
||||||
void sixtp_print_frame_stack(GSList *stack, FILE *f);
|
void sixtp_print_frame_stack(GSList *stack, FILE *f);
|
||||||
|
|
||||||
|
sixtp_stack_frame* sixtp_stack_frame_new(sixtp* next_parser, char *tag);
|
||||||
|
|
||||||
|
sixtp_parser_context* sixtp_context_new(sixtp *initial_parser,
|
||||||
|
gpointer global_data,
|
||||||
|
gpointer top_level_data);
|
||||||
|
void sixtp_context_destroy(sixtp_parser_context* context);
|
||||||
|
void sixtp_context_run_end_handler(sixtp_parser_context* ctxt);
|
||||||
|
|
||||||
#endif /* _SIXTP_STACK_H_ */
|
#endif /* _SIXTP_STACK_H_ */
|
||||||
|
@ -193,35 +193,6 @@ sixtp_set_any(sixtp *tochange, int cleanup, ...)
|
|||||||
return tochange;
|
return tochange;
|
||||||
}
|
}
|
||||||
|
|
||||||
sixtp*
|
|
||||||
sixtp_new_full(sixtp_start_handler starter,
|
|
||||||
sixtp_before_child_handler cdbeforer,
|
|
||||||
sixtp_after_child_handler chafterer,
|
|
||||||
sixtp_end_handler ender,
|
|
||||||
sixtp_characters_handler charer,
|
|
||||||
sixtp_fail_handler failer,
|
|
||||||
sixtp_result_handler cleanresulter,
|
|
||||||
sixtp_result_handler cleancharer,
|
|
||||||
sixtp_result_handler resultfailer,
|
|
||||||
sixtp_result_handler charsfailer)
|
|
||||||
{
|
|
||||||
sixtp *ret = sixtp_new();
|
|
||||||
g_return_val_if_fail(ret, NULL);
|
|
||||||
|
|
||||||
sixtp_set_start(ret, starter);
|
|
||||||
sixtp_set_before_child(ret, cdbeforer);
|
|
||||||
sixtp_set_after_child(ret, chafterer);
|
|
||||||
sixtp_set_end(ret, ender);
|
|
||||||
sixtp_set_chars(ret, charer);
|
|
||||||
sixtp_set_fail(ret, failer);
|
|
||||||
sixtp_set_cleanup_result(ret, cleanresulter);
|
|
||||||
sixtp_set_cleanup_chars(ret, cleancharer);
|
|
||||||
sixtp_set_result_fail(ret, resultfailer);
|
|
||||||
sixtp_set_chars_fail(ret, charsfailer);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sixtp_destroy_child(gpointer key, gpointer value,
|
static void sixtp_destroy_child(gpointer key, gpointer value,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
@ -371,10 +342,17 @@ sixtp_sax_start_handler(void *user_data,
|
|||||||
(gpointer) &next_parser);
|
(gpointer) &next_parser);
|
||||||
|
|
||||||
if(!lookup_success) {
|
if(!lookup_success) {
|
||||||
|
/* magic catch all value */
|
||||||
|
lookup_success = g_hash_table_lookup_extended(
|
||||||
|
current_parser->children, SIXTP_MAGIC_CATCHER,
|
||||||
|
(gpointer) &next_parser_tag, (gpointer) &next_parser);
|
||||||
|
if(!lookup_success)
|
||||||
|
{
|
||||||
PERR("Tag <%s> not allowed in current context.\n", name);
|
PERR("Tag <%s> not allowed in current context.\n", name);
|
||||||
pdata->parsing_ok = FALSE;
|
pdata->parsing_ok = FALSE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(current_frame->parser->before_child) {
|
if(current_frame->parser->before_child) {
|
||||||
GSList *parent_data_from_children = NULL;
|
GSList *parent_data_from_children = NULL;
|
||||||
@ -396,24 +374,15 @@ sixtp_sax_start_handler(void *user_data,
|
|||||||
pdata->global_data,
|
pdata->global_data,
|
||||||
&(current_frame->frame_data),
|
&(current_frame->frame_data),
|
||||||
current_frame->tag,
|
current_frame->tag,
|
||||||
next_parser_tag);
|
name);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_return_if_fail(pdata->parsing_ok);
|
g_return_if_fail(pdata->parsing_ok);
|
||||||
|
|
||||||
/* now allocate the new stack frame and shift to it */
|
/* now allocate the new stack frame and shift to it */
|
||||||
new_frame = g_new0(sixtp_stack_frame, 1);
|
new_frame = sixtp_stack_frame_new(next_parser, g_strdup(name));
|
||||||
new_frame->parser = next_parser;
|
|
||||||
new_frame->tag = next_parser_tag;
|
|
||||||
new_frame->data_for_children = NULL;
|
|
||||||
new_frame->data_from_children = NULL;
|
|
||||||
new_frame->frame_data = NULL;
|
|
||||||
|
|
||||||
/*printf("PUSHING FRAME for <%s> parser.\n", next_parser_tag);
|
|
||||||
sixtp_stack_frame_print(new_frame, 2, stderr); */
|
|
||||||
pdata->stack = g_slist_prepend(pdata->stack, (gpointer) new_frame);
|
pdata->stack = g_slist_prepend(pdata->stack, (gpointer) new_frame);
|
||||||
/*printf("RESULTANT STACK: ");
|
|
||||||
sixtp_print_frame_stack(pdata->stack, stderr); */
|
|
||||||
|
|
||||||
if(next_parser->start_handler) {
|
if(next_parser->start_handler) {
|
||||||
pdata->parsing_ok =
|
pdata->parsing_ok =
|
||||||
@ -422,7 +391,7 @@ sixtp_sax_start_handler(void *user_data,
|
|||||||
pdata->global_data,
|
pdata->global_data,
|
||||||
&new_frame->data_for_children,
|
&new_frame->data_for_children,
|
||||||
&new_frame->frame_data,
|
&new_frame->frame_data,
|
||||||
next_parser_tag,
|
name,
|
||||||
(gchar**)attrs);
|
(gchar**)attrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -553,3 +522,135 @@ sixtp_sax_end_handler(void *user_data, const xmlChar *name) {
|
|||||||
child_result_data);
|
child_result_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xmlEntityPtr
|
||||||
|
sixtp_sax_get_entity_handler(void *user_data, const CHAR *name) {
|
||||||
|
return xmlGetPredefinedEntity(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
sixtp_handle_catastrophe(sixtp_sax_data *sax_data) {
|
||||||
|
/* Something has gone wrong. To handle it, we have to traverse the
|
||||||
|
stack, calling, at each level, the frame failure handler (the
|
||||||
|
handler for the current, unfinished block) and then the sibling
|
||||||
|
handlers. The order is reverse chronological - oldest child
|
||||||
|
results cleaned up last. This holds overall as well, stack
|
||||||
|
frames are cleaned up in their order on the stack which will be
|
||||||
|
youngest to oldest. */
|
||||||
|
|
||||||
|
GSList *lp;
|
||||||
|
GSList **stack = &(sax_data->stack);
|
||||||
|
|
||||||
|
PERR("parse failed at \n");
|
||||||
|
sixtp_print_frame_stack(sax_data->stack, stderr);
|
||||||
|
|
||||||
|
while(*stack) {
|
||||||
|
sixtp_stack_frame *current_frame = (sixtp_stack_frame *) (*stack)->data;
|
||||||
|
|
||||||
|
/* cleanup the current frame */
|
||||||
|
if(current_frame->parser->fail_handler) {
|
||||||
|
GSList *sibling_data;
|
||||||
|
gpointer parent_data;
|
||||||
|
|
||||||
|
if((*stack)->next == NULL) {
|
||||||
|
/* This is the top of the stack... */
|
||||||
|
parent_data = NULL;
|
||||||
|
sibling_data = NULL;
|
||||||
|
} else {
|
||||||
|
sixtp_stack_frame *parent_frame =
|
||||||
|
(sixtp_stack_frame *) (*stack)->next->data;
|
||||||
|
parent_data = parent_frame->data_for_children;
|
||||||
|
sibling_data = parent_frame->data_from_children;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_frame->parser->fail_handler(current_frame->data_for_children,
|
||||||
|
current_frame->data_from_children,
|
||||||
|
sibling_data,
|
||||||
|
parent_data,
|
||||||
|
sax_data->global_data,
|
||||||
|
¤t_frame->frame_data,
|
||||||
|
current_frame->tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now cleanup any children's results */
|
||||||
|
for(lp = current_frame->data_from_children; lp; lp = lp->next) {
|
||||||
|
sixtp_child_result *cresult = (sixtp_child_result *) lp->data;
|
||||||
|
if(cresult->fail_handler) {
|
||||||
|
cresult->fail_handler(cresult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*stack = sixtp_pop_and_destroy_frame(*stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
sixtp_parse_file(sixtp *sixtp,
|
||||||
|
const char *filename,
|
||||||
|
gpointer data_for_top_level,
|
||||||
|
gpointer global_data,
|
||||||
|
gpointer *parse_result)
|
||||||
|
{
|
||||||
|
sixtp_parser_context *ctxt;
|
||||||
|
|
||||||
|
if(!(ctxt = sixtp_context_new(sixtp, global_data, data_for_top_level)))
|
||||||
|
{
|
||||||
|
PERR("sixtp_context_new returned null");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlSAXUserParseFile(&ctxt->handler, &ctxt->data, filename);
|
||||||
|
|
||||||
|
sixtp_context_run_end_handler(ctxt);
|
||||||
|
|
||||||
|
if(ctxt->data.parsing_ok)
|
||||||
|
{
|
||||||
|
*parse_result = ctxt->top_frame->frame_data;
|
||||||
|
sixtp_context_destroy(ctxt);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*parse_result = NULL;
|
||||||
|
sixtp_handle_catastrophe(&ctxt->data);
|
||||||
|
sixtp_context_destroy(ctxt);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
sixtp_parse_buffer(sixtp *sixtp,
|
||||||
|
char *bufp,
|
||||||
|
int bufsz,
|
||||||
|
gpointer data_for_top_level,
|
||||||
|
gpointer global_data,
|
||||||
|
gpointer *parse_result)
|
||||||
|
{
|
||||||
|
sixtp_parser_context *ctxt;
|
||||||
|
|
||||||
|
if(!(ctxt = sixtp_context_new(sixtp, global_data, data_for_top_level)))
|
||||||
|
{
|
||||||
|
PERR("sixtp_context_new returned null");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlSAXUserParseMemory(&ctxt->handler, &ctxt->data, bufp, bufsz);
|
||||||
|
|
||||||
|
sixtp_context_run_end_handler(ctxt);
|
||||||
|
|
||||||
|
if(ctxt->data.parsing_ok)
|
||||||
|
{
|
||||||
|
*parse_result = ctxt->top_frame->frame_data;
|
||||||
|
sixtp_context_destroy(ctxt);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*parse_result = NULL;
|
||||||
|
sixtp_handle_catastrophe(&ctxt->data);
|
||||||
|
sixtp_context_destroy(ctxt);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -133,6 +133,9 @@ typedef enum {
|
|||||||
SIXTP_CHARS_FAIL_ID,
|
SIXTP_CHARS_FAIL_ID,
|
||||||
} sixtp_handler_type;
|
} sixtp_handler_type;
|
||||||
|
|
||||||
|
/* completely invalid tag for xml */
|
||||||
|
#define SIXTP_MAGIC_CATCHER "&MAGIX&"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SIXTP_CHILD_RESULT_CHARS,
|
SIXTP_CHILD_RESULT_CHARS,
|
||||||
SIXTP_CHILD_RESULT_NODE
|
SIXTP_CHILD_RESULT_NODE
|
||||||
@ -167,9 +170,18 @@ void sixtp_sax_characters_handler(void *user_data, const xmlChar *text,
|
|||||||
void sixtp_sax_end_handler(void *user_data, const xmlChar *name);
|
void sixtp_sax_end_handler(void *user_data, const xmlChar *name);
|
||||||
|
|
||||||
sixtp* sixtp_new(void);
|
sixtp* sixtp_new(void);
|
||||||
|
|
||||||
void sixtp_destroy(sixtp *sp);
|
void sixtp_destroy(sixtp *sp);
|
||||||
|
|
||||||
|
void sixtp_handle_catastrophe(sixtp_sax_data *sax_data);
|
||||||
|
xmlEntityPtr sixtp_sax_get_entity_handler(void *user_data, const CHAR *name);
|
||||||
|
|
||||||
|
gboolean sixtp_parse_file(sixtp *sixtp, const char *filename,
|
||||||
|
gpointer data_for_top_level, gpointer global_data,
|
||||||
|
gpointer *parse_result);
|
||||||
|
gboolean sixtp_parse_buffer(sixtp *sixtp, char *bufp, int bufsz,
|
||||||
|
gpointer data_for_top_level, gpointer global_data,
|
||||||
|
gpointer *parse_result);
|
||||||
|
|
||||||
void sixtp_set_start(sixtp *parser, sixtp_start_handler start_handler);
|
void sixtp_set_start(sixtp *parser, sixtp_start_handler start_handler);
|
||||||
void sixtp_set_before_child(sixtp *parser, sixtp_before_child_handler handler);
|
void sixtp_set_before_child(sixtp *parser, sixtp_before_child_handler handler);
|
||||||
void sixtp_set_after_child(sixtp *parser, sixtp_after_child_handler handler);
|
void sixtp_set_after_child(sixtp *parser, sixtp_after_child_handler handler);
|
||||||
|
Loading…
Reference in New Issue
Block a user