167 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			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);
							 | 
						||
| 
								 | 
							
								}
							 |