This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/packages/raptor/xml2_yap.c
Vítor Santos Costa 3704392811 xml2 early support
2016-01-06 12:36:36 +00:00

167 lines
4.4 KiB
C

/* Copyright (C) 2013 David Vaz <davidvaz@dcc.fc.up.pt>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include "Yap.h"
#include "Yatom.h"
#include <libxml/parser.h>
#include <libxml/tree.h>
void libxml2_yap_init (void);
struct exo_aux {
YAP_Functor functor;
YAP_PredEntryPtr pred;
size_t n;
};
static Term read_atts(xmlAttr *att_node, sigjmp_buf *ji USES_REGS)
{
if (att_node == NULL)
return TermNil;
Term ttail = read_atts(att_node->next, ji PASS_REGS);
Term thead;
Term tf;
if (HR > ASP-1024)
siglongjmp(*ji, 2);
if (att_node->children) {
if (att_node->children->type == XML_TEXT_NODE) {
Term ts[2];
ts[0] = MkAtomTerm(Yap_LookupAtom((const char *)att_node->name));
ts[1] = MkStringTerm((const char *)att_node->children->content);
thead = Yap_MkApplTerm(FunctorEq, 2, ts );
tf = MkPairTerm(thead, ttail);
} else {
// error
tf = TermNil;
}
} else {
tf = MkAtomTerm(Yap_LookupAtom((const char *)att_node->name));
}
if (att_node->ns) {
Term ts[2];
ts[0] = MkAtomTerm(Yap_LookupAtom((const char *)att_node->ns->prefix));
ts[1] = tf;
tf = Yap_MkApplTerm( FunctorModule, 2, ts );
}
return tf;
}
/**
* load_element_names:
* @a_node: the initial xml node to consider.
*
* Prints the names of the all the xml elements
* that are siblings or children of a given xml node.
*/
static Term
print_element_names(xmlNode * a_node, sigjmp_buf *ji USES_REGS)
{
xmlNode *cur_node = NULL;
int count = 0;
for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
if (cur_node->type == XML_ELEMENT_NODE) {
count++;
}
}
if (HR > ASP-(1024+count))
siglongjmp(*ji, 1);
Atom at = Yap_LookupAtom((char *)a_node->name);
Functor f = Yap_MkFunctor(at, count+1);
Term t = Yap_MkNewApplTerm(f, count+1);
CELL *s = RepAppl(t) + 2;
s[-1] = read_atts(a_node->properties, ji PASS_REGS);
int i = 0;
for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
if (cur_node->type == XML_ELEMENT_NODE) {
s[i++] = print_element_names(cur_node, ji PASS_REGS);
}
}
if (a_node->ns) {
Term ts[2];
ts[0] = MkAtomTerm(Yap_LookupAtom((const char *)a_node->ns->prefix));
ts[1] = t;
t = Yap_MkApplTerm( FunctorModule, 2, ts );
}
return t;
}
static Int
load_xml ( void )
{
CACHE_REGS
sigjmp_buf jmp_info;
xmlDoc *doc = NULL;
xmlNode *root_element = NULL;
CELL *h0 = HR;
const char *f = AtomOfTerm(Deref(ARG1))->StrOfAE;
/*
* this initialize the library and check potential ABI mismatches
* between the version it was compiled for and the actual shared
* library used.
*/
LIBXML_TEST_VERSION
/*parse the file and get the DOM */
doc = xmlReadFile(f, NULL, 0);
if (doc == NULL) {
fprintf(stderr, "error: could not parse file %s\n", f);
return false;
}
/*Get the root element node */
root_element = xmlDocGetRootElement(doc);
if (sigsetjmp(jmp_info, 0)) {
HR = h0;
Yap_gc(2, ENV, P);
h0 = HR;
}
Term t = print_element_names(root_element, &jmp_info PASS_REGS);
/*free the document */
xmlFreeDoc(doc);
/*
*Free the global variables that may
*have been allocated by the parser.
*/
xmlCleanupParser();
return Yap_unify(ARG2, t);
}
extern Int YAP_UserCPredicate(const char *, Int f(void), int arity);
void libxml2_yap_init (void)
{
YAP_UserCPredicate("load_xml", load_xml, 2);
YAP_UserCPredicate("load_xml2", load_xml, 2);
}