diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-09-20 15:52:18 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-09-20 15:52:18 +0300 |
commit | 7f3dd0599ac3fb3a69c512b0ecfd043c67ca94ee (patch) | |
tree | 422bda7fdce2709ea0b4c67c42e6f9a7cecc4918 /src/eclat.c | |
parent | 205d53a8e930d3fd126075ab083d316cc344ebaf (diff) | |
download | eclat-7f3dd0599ac3fb3a69c512b0ecfd043c67ca94ee.tar.gz eclat-7f3dd0599ac3fb3a69c512b0ecfd043c67ca94ee.tar.bz2 |
Parse returned XML into a grecs tree structure.
* lib/xmltree.c: New file.
* lib/Makefile.am: Add new file.
* lib/libeclat.h: Include expat.h and grecs.h
(eclat_partial_tree_t): New typedef.
(eclat_partial_tree_create,eclat_partial_tree_destroy)
(eclat_partial_tree_finish,eclat_partial_tree_data_handler)
(eclat_partial_tree_start_handler)
(eclat_partial_tree_end_handler): New protos.
* src/eclat.c (main): Initialize XML parser with eclat_partial_tree
handlers and bind it to the CURL output handler.
* tests/.gitignore: Add txml
* tests/Makefile.am (TESTSUITE_AT): Add xml01.at
Build txml
* tests/testsuite.at: Include xml01.at
* tests/txml.c: New file.
* tests/xml01.at: New file.
Diffstat (limited to 'src/eclat.c')
-rw-r--r-- | src/eclat.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/eclat.c b/src/eclat.c index c5994fe..3703376 100644 --- a/src/eclat.c +++ b/src/eclat.c @@ -169,7 +169,52 @@ eclat_trace_fun(CURL *handle, curl_infotype type, dump(text, stderr, (unsigned char *)data, size); return 0; } + +static void +dump_text(FILE *stream, int line, int column, const char *text, size_t len) +{ + fprintf(stream, "%02d:%02d: ", line, column); + while (len--) { + char c = *text++; + if (c == '\r') + continue; + fputc(c, stream); + ++column; + if (c == '\n') { + ++line; + column = 0; + fprintf(stream, "%02d:%02d: ", line, column); + } + } + fputc('\n', stream); +} +static size_t +write_callback(void *ptr, size_t size, size_t nmemb, void *data) +{ + size_t realsize = size * nmemb; + XML_Parser parser = data; + enum XML_Status status; + int line = XML_GetCurrentLineNumber(parser); + int column = XML_GetCurrentColumnNumber(parser); + + /* FIXME: Debugging level. */ + if (debug_level[ECLAT_DEBCAT_MAIN] > 10) { + dump_text(stderr, line, column, ptr, realsize); + } + status = XML_Parse(parser, ptr, realsize, 0); + if (status == XML_STATUS_ERROR) { + enum XML_Error error = XML_GetErrorCode(parser); + + line = XML_GetCurrentLineNumber(parser); + column = XML_GetCurrentColumnNumber(parser); + + /* FIXME: better diagnostics. */ + die(EX_SOFTWARE, "XML parse error at %d:%d: %s", + line, column, XML_ErrorString(error)); + } + return realsize; +} #include "cmdline.h" @@ -187,6 +232,9 @@ main(int argc, char **argv) int index, rc; struct grecs_node *tree; CURL *curl; + XML_Parser parser; + eclat_partial_tree_t part; + struct grecs_node *xmltree; set_program_name(argv[0]); config_init(); @@ -250,8 +298,33 @@ main(int argc, char **argv) curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, eclat_trace_fun); } + + + /* Create XML parser */ + parser = XML_ParserCreate("UTF-8"); + if (!parser) + die(EX_SOFTWARE, "cannot create XML parser"); + + XML_SetElementHandler(parser, + eclat_partial_tree_start_handler, + eclat_partial_tree_end_handler); + XML_SetCharacterDataHandler(parser, + eclat_partial_tree_data_handler); + part = eclat_partial_tree_create(); + XML_SetUserData(parser, part); + + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, parser); rc = handler_tab[eclat_command](curl, argc, argv); curl_easy_cleanup(curl); + XML_Parse(parser, "", 0, 1); + + xmltree = eclat_partial_tree_finish(part); + + grecs_print_node(xmltree, GRECS_NODE_FLAG_DEFAULT, stdout); + fputc('\n', stdout); + + exit(rc); } |