Home modules.gotpike.org
Username: Password: [Create Account]
[Forgot Password?]
Return to module

File Contents

Contents of /Public_Parser_XML2-1.42/XML2.c:

/* Generated from "XML2.cmod" by precompile.pike
 *
 * Do NOT edit this file.
 */

#undef PRECOMPILE_API_VERSION
#define PRECOMPILE_API_VERSION 2


#line 1 "XML2.cmod"
/*
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: XML2.cmod,v 1.106 2008-02-01 19:55:58 hww3 Exp $
 */

/*
 * File licensing and authorship information block.
 *
 * Version: MPL 1.1/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Initial Developer of the Original Code is
 *
 * Bill Welliver <hww3@riverweb.com>
 *
 * Portions created by the Initial Developer are Copyright (C) Bill Welliver
 * All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of the LGPL, and not to allow others to use your version
 * of this file under the terms of the MPL, indicate your decision by
 * deleting the provisions above and replace them with the notice
 * and other provisions required by the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL or the LGPL.
 *
 * Significant Contributors to this file are:
 *
 *
 */

#include "xml2.h"

/*! @module Public
 */

/*! @module Parser
 */

/*! @module XML2
 */

/*
  
    start of Public.Parser.XML2 module functions

*/

static void
xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
    if (ctxt == NULL) return;
#ifdef LIBXML_SAX1_ENABLED 
    if ((ctxt->sax) &&  (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
        ((ctxt->sax->startElementNs != NULL) ||
         (ctxt->sax->endElementNs != NULL))) ctxt->sax2 = 1;
#else
    ctxt->sax2 = 1;
#endif /* LIBXML_SAX1_ENABLED */
 
    ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
    ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
    ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
    if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) ||
                (ctxt->str_xml_ns == NULL)) {
        xmlErrMemory(ctxt, NULL);
    }
}



#undef var_object_data_defined
#define var_object_data_defined

#undef var_silent_defined
#define var_silent_defined

#undef THIS
#define THIS ((struct _struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef THIS_
#define THIS_ ((struct _struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef OBJ2_
#define OBJ2_(o) ((struct _struct *)(o->storage+_storage_offset))

#undef GET__STORAGE
#define GET__STORAGE ((struct _struct *)(o->storage+_storage_offset)
static ptrdiff_t _storage_offset;
struct _struct {

#ifdef var_object_data_defined
#line 97 "XML2.cmod"
PARSER_OBJECT_DATA * object_data;
#endif /* var_object_data_defined */

#ifdef var_silent_defined
  INT_TYPE silent;

#endif /* var_silent_defined */
};
#define f_create_defined
ptrdiff_t f_create_fun_num = 0;
void f_create(INT32 args) {
#line 100 "XML2.cmod"
if(args != 0) wrong_number_of_args_error("create",args,0);
{

}

}
/*! @decl array(Node) select_xpath_nodes(string xpath, object node)
 *!
 *! selects nodes based on an XPath query and returns the result.
 */
#define f_select_xpath_nodes_defined
ptrdiff_t f_select_xpath_nodes_fun_num = 0;
void f_select_xpath_nodes(INT32 args) {
#line 109 "XML2.cmod"
struct pike_string * xpath;
#line 109 "XML2.cmod"
struct object * node;
#line 109 "XML2.cmod"
if(args != 2) wrong_number_of_args_error("select_xpath_nodes",args,2);
#line 109 "XML2.cmod"
if(Pike_sp[0-2].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("select_xpath_nodes",1,"string");
#line 109 "XML2.cmod"
debug_malloc_pass(xpath=Pike_sp[0-2].u.string);
#line 109 "XML2.cmod"
if(Pike_sp[1-2].type != PIKE_T_OBJECT) SIMPLE_BAD_ARG_ERROR("select_xpath_nodes",2,"object");
#line 109 "XML2.cmod"
debug_malloc_pass(node=Pike_sp[1-2].u.object);
{
  xmlXPathContextPtr xpathCtx;
  xmlXPathObjectPtr xpathObj;
  xmlNodeSetPtr set;
  xmlNodePtr xn;
  xmlNsPtr xmlns;
  struct object * o;
  int num_nodes = 0;

  CHECK_NODE_PASSED(node);

  if(OBJ2_NODE(node)->object_data->node == NULL)
  { 
    pop_n_elems(2);
    Pike_error("Node not initialized.\n");
  }

  xpathCtx = xmlXPathNewContext(OBJ2_NODE(node)->object_data->node->doc);
  if(xpathCtx == NULL)
  {
    pop_n_elems(2);
    Pike_error("Unable to create new XPath context.\n");
  }

/*

  xmlns = xmlGetNsList(OBJ2_NODE(node)->object_data->node->doc,
              OBJ2_NODE(node)->object_data->node);

  while(xmlns != NULL)
  {
    printf("registering ns %s, %s\n", xmlns->prefix, xmlns->href);
    xmlXPathRegisterNs(xpathCtx, xmlns->prefix, xmlns->href);
    xmlns = xmlns->next;
  }

*/
  xpathCtx->node = OBJ2_NODE(node)->object_data->node;

  xpathObj = xmlXPathEvalExpression((xmlChar *)xpath->str, xpathCtx);
  if(xpathObj == NULL) {  
    pop_n_elems(2);
    xmlXPathFreeContext(xpathCtx);
    Pike_error("Unable to evaluate the XPath expression.\n");
  }

  /* now we should generate an array from the node set. */
  set = xpathObj->nodesetval;


  if(set == NULL)
  {
    pop_n_elems(2);
    push_int(0);
    xmlXPathFreeContext(xpathCtx);
    xmlXPathFreeObject(xpathObj);
    return;
  }  

  pop_n_elems(2);

  if(set->nodeNr > 0)
  {
  xn = set->nodeTab[0];
    if(xn != NULL && set->nodeNr > 0) do
    {
      struct Node_struct * ns;
      NODE_OBJECT_DATA * od;
      apply(Pike_fp->current_object, "Node", 0);
      ns = OBJ2_NODE((Pike_sp[0-1].u.object));
      od = (NODE_OBJECT_DATA *)(ns->object_data);

      od->node=xn;
      od->parser = this_object();
      od->refs = OBJ2_NODE(node)->object_data->refs;
    
      (* od->refs)++;

      num_nodes++;
      xn = set->nodeTab[num_nodes];
    } 
    while (((num_nodes +1) <= set->nodeNr) && xn != NULL);

    if(num_nodes>0) {
      f_aggregate(num_nodes);
    }
  }
  else push_int(0);

  xmlXPathFreeContext(xpathCtx);
  xmlXPathFreeObject(xpathObj);

  return;
}

}
/*! @decl void set_xml_parser_options(int options)
 *!
 *! sets parser options. 
 *! 
 *! @param options
 *!   a bitwise or of @[Public.Parser.XML2.Constants] options 
 *!   where valid options start with PARSE_. 
 */
#define f_set_xml_parser_options_defined
ptrdiff_t f_set_xml_parser_options_fun_num = 0;
void f_set_xml_parser_options(INT32 args) {
#line 213 "XML2.cmod"
INT_TYPE options;
#line 213 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("set_xml_parser_options",args,1);
#line 213 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("set_xml_parser_options",1,"int");
options=Pike_sp[0-1].u.integer;
#line 214 "XML2.cmod"
{
  THIS->object_data->xml_parser_options = options;
  pop_stack();
}

}
/*! @decl int get_xml_parser_options()
 *!
 *! gets parser options for XML mode parsing. 
 *! 
 *! @returns
 *!   a bitwise or of @[Public.Parser.XML2.Constants] options 
 *!   where valid options start with PARSE_. 
 */
#define f_get_xml_parser_options_defined
ptrdiff_t f_get_xml_parser_options_fun_num = 0;
void f_get_xml_parser_options(INT32 args) {
#line 227 "XML2.cmod"
if(args != 0) wrong_number_of_args_error("get_xml_parser_options",args,0);
{
  push_int(THIS->object_data->xml_parser_options);
}

}
/*! @decl int get_html_parser_options()
 *!
 *! gets parser options for HTML mode parsing. 
 *! 
 *! @returns
 *!   a bitwise or of @[Public.Parser.XML2.Constants] options 
 *!   where valid options start with PARSE_. 
 */
#define f_get_html_parser_options_defined
ptrdiff_t f_get_html_parser_options_fun_num = 0;
void f_get_html_parser_options(INT32 args) {
#line 240 "XML2.cmod"
if(args != 0) wrong_number_of_args_error("get_html_parser_options",args,0);
{
  push_int(THIS->object_data->html_parser_options);
}

}
/*! @decl void set_auto_utf8_convert(int flag)
 *!
 *! sets whether the parser should automatically convert input to the parser to and from UTF-8.
 *! libxml2 requires input (aside from data to be parsed, which may be encoded differently) to be
 *! UTF-8 encoded. This module will automatically convert all string input to and from UTF-8. Calling
 *! this function with an argument of zero (0) will turn this feature off. In this case, you will be
 *! responsible for ensuring that any input is properly encoded (if necessary).
 *! 
 *! @param flag
 *!   a boolean value: 0 disables auto conversion, 1 enables.
 */
#define f_set_auto_utf8_convert_defined
ptrdiff_t f_set_auto_utf8_convert_fun_num = 0;
void f_set_auto_utf8_convert(INT32 args) {
#line 256 "XML2.cmod"
INT_TYPE flag;
#line 256 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("set_auto_utf8_convert",args,1);
#line 256 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("set_auto_utf8_convert",1,"int");
flag=Pike_sp[0-1].u.integer;
#line 257 "XML2.cmod"
{
  THIS->object_data->auto_encode = flag;
  pop_stack();
}

}
#line 262 "XML2.cmod"
void f_convert_string_utf8(INT32 args)
{
  if(  OBJ2_(THIS_NODE->object_data->parser)->object_data->auto_encode !=0)
  {
    f_string_to_utf8(args);
  }
}

void f_convert_utf8_string(INT32 args)
{
  if(  OBJ2_(THIS_NODE->object_data->parser)->object_data->auto_encode !=0)
  {
    f_utf8_to_string(args);
  }
}

void f_rconvert_string_utf8(INT32 args)
{
  if(THIS_XMLREADER->object_data->autoencode !=0)
  {
    f_string_to_utf8(args);
  }
}

void f_rconvert_utf8_string(INT32 args)
{
  if(  OBJ2_(THIS_XMLREADER->object_data->parser)->object_data->auto_encode !=0)
  {
    f_utf8_to_string(args);
  }
}

/*! @decl void set_html_parser_options(int options)
 *!
 *! sets parser options. 
 *! 
 *! @param options
 *!   a bitwise or of @[Public.Parser.XML2.Constants] options 
 *!   where valid options start with PARSE_. 
 */
#define f_set_html_parser_options_defined
ptrdiff_t f_set_html_parser_options_fun_num = 0;
void f_set_html_parser_options(INT32 args) {
#line 302 "XML2.cmod"
INT_TYPE options;
#line 302 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("set_html_parser_options",args,1);
#line 302 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("set_html_parser_options",1,"int");
options=Pike_sp[0-1].u.integer;
#line 303 "XML2.cmod"
{
  THIS->object_data->html_parser_options = options;
  pop_stack();
}

}
/*! @decl int substituteEntitiesDefault(int def)
 */
#define f_substituteEntitiesDefault_defined
ptrdiff_t f_substituteEntitiesDefault_fun_num = 0;
void f_substituteEntitiesDefault(INT32 args) {
#line 310 "XML2.cmod"
INT_TYPE def;
#line 310 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("substituteEntitiesDefault",args,1);
#line 310 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("substituteEntitiesDefault",1,"int");
def=Pike_sp[0-1].u.integer;
#line 311 "XML2.cmod"
{
  def = def ? 1 : 0;

  pop_n_elems(args);

  xmlSubstituteEntitiesDefault(def);

  push_int(def);
}

}
#line 321 "XML2.cmod"
/* @decl int keepBlanksDefault(int def)
 */
#define f_keepBlanksDefault_defined
ptrdiff_t f_keepBlanksDefault_fun_num = 0;
void f_keepBlanksDefault(INT32 args) {
#line 323 "XML2.cmod"
INT_TYPE def;
#line 323 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("keepBlanksDefault",args,1);
#line 323 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("keepBlanksDefault",1,"int");
def=Pike_sp[0-1].u.integer;
#line 324 "XML2.cmod"
{
  def = def ? 1 : 0;

  pop_n_elems(args);

  push_int(xmlKeepBlanksDefault(def));
}

}
/*!  @decl string utf8_to_html(string str)
 *!
 */
#define f_utf8_to_html_defined
ptrdiff_t f_utf8_to_html_fun_num = 0;
void f_utf8_to_html(INT32 args) {
#line 335 "XML2.cmod"
struct pike_string * str;
#line 335 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("utf8_to_html",args,1);
#line 335 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("utf8_to_html",1,"string");
#line 335 "XML2.cmod"
debug_malloc_pass(str=Pike_sp[0-1].u.string);
{
  char *html = NULL;
  int outlen, inlen;

  outlen = str->len << 1;
  html = (char*)malloc(outlen + 1);
  if (!html)
    Pike_error("Out of memory");

  inlen = str->len;
  if ( UTF8ToHtml(html, &outlen, str->str, &inlen) < 0 ) {
    free(html);
    Pike_error("Cannot convert to html!");
  }
  html[outlen] = '\0';
  pop_n_elems(args);
  push_text(html);
  free(html);
}


}
/*!  @decl string utf8_to_isolat1(string str)
 *!
 */
#define f_utf8_to_isolat1_defined
ptrdiff_t f_utf8_to_isolat1_fun_num = 0;
void f_utf8_to_isolat1(INT32 args) {
#line 360 "XML2.cmod"
struct pike_string * str;
#line 360 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("utf8_to_isolat1",args,1);
#line 360 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("utf8_to_isolat1",1,"string");
#line 360 "XML2.cmod"
debug_malloc_pass(str=Pike_sp[0-1].u.string);
{
  char *html = NULL;
  int outlen, inlen;

  outlen = str->len << 1;
  html = (char*)malloc(outlen + 1);
  if (!html)
    Pike_error("Out of memory");

  inlen = str->len;
  if ( UTF8Toisolat1(html, &outlen, str->str, &inlen) < 0 ) {
    free(html);
    Pike_error("Cannot convert to isolat1!");
  }
  html[outlen] = '\0';
  pop_n_elems(args);
  push_text(html);
  free(html);
}

}
/*! @decl int utf8_check(string str)
 *!
 */
#define f_utf8_check_defined
ptrdiff_t f_utf8_check_fun_num = 0;
void f_utf8_check(INT32 args) {
#line 384 "XML2.cmod"
struct pike_string * str;
#line 384 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("utf8_check",args,1);
#line 384 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("utf8_check",1,"string");
#line 384 "XML2.cmod"
debug_malloc_pass(str=Pike_sp[0-1].u.string);
{
  int result;

  result = xmlCheckUTF8(str->str);
  pop_n_elems(args);
  push_int(result);
}

}
/*! @decl array(int) get_encodings()
 *!
 *! gets the list of available character encoders.
 *!
 *! @returns
 *!  an array of available encoder identifiers.
 *!
 */
#define f_get_encodings_defined
ptrdiff_t f_get_encodings_fun_num = 0;
void f_get_encodings(INT32 args) {
#line 401 "XML2.cmod"
if(args != 0) wrong_number_of_args_error("get_encodings",args,0);
{
   int num = 0;
   int cur = 0;
   int upper_limit = 25;
   xmlCharEncodingHandlerPtr encoder;

   for (cur = 0; cur < upper_limit; cur++)
   {
     encoder = xmlGetCharEncodingHandler((xmlCharEncoding)cur);
     if(encoder != NULL)
     {
       push_int(cur);
       num++;
       xmlFree(encoder);
     }
   }
   f_aggregate(num);
   return;  
}

}
/*!  @decl string get_encoding_name(int e)
 *!
 */
#define f_get_encoding_name_defined
ptrdiff_t f_get_encoding_name_fun_num = 0;
void f_get_encoding_name(INT32 args) {
#line 425 "XML2.cmod"
INT_TYPE e;
#line 425 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("get_encoding_name",args,1);
#line 425 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("get_encoding_name",1,"int");
e=Pike_sp[0-1].u.integer;
#line 426 "XML2.cmod"
{
  const char * enc = NULL;

  enc = xmlGetCharEncodingName(e);

  if(enc != NULL)
    push_text(enc);

  else 
     push_int(0);
}

}
/*!  @decl string get_encoding_alias(string e)
 *!
 */
#define f_get_encoding_alias_defined
ptrdiff_t f_get_encoding_alias_fun_num = 0;
void f_get_encoding_alias(INT32 args) {
#line 441 "XML2.cmod"
struct pike_string * e;
#line 441 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("get_encoding_alias",args,1);
#line 441 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("get_encoding_alias",1,"string");
#line 441 "XML2.cmod"
debug_malloc_pass(e=Pike_sp[0-1].u.string);
{
  const char * enc = NULL;

  enc = xmlGetEncodingAlias(e->str);

  if(enc != NULL)
    push_text(enc);
  else 
     push_int(0);
}

}
/*! @decl string render_xml(Node n)
 *!   Renders a node tree as an XML string. The entire document tree will 
 *!  be rendered. To render a portion of a tree, use @[Node.render_xml].
 *!
 *!   @param n
 *!     a Node object for a given XML document.
 *!
 */
#define f_render_xml_defined
ptrdiff_t f_render_xml_fun_num = 0;
void f_render_xml(INT32 args) {
#line 461 "XML2.cmod"
struct object * n;
#line 461 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("render_xml",args,1);
#line 461 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_OBJECT) SIMPLE_BAD_ARG_ERROR("render_xml",1,"object");
#line 461 "XML2.cmod"
debug_malloc_pass(n=Pike_sp[0-1].u.object);
{
  int dumped;
  xmlChar * buf;
  char * str;
  int bufsize;

  CHECK_NODE_PASSED(n);

/*  check_node_created(); */
  if(OBJ2_NODE(n)->object_data->node == NULL)
  { 
    Pike_error("Node not initialized.\n");
  }

  xmlDocDumpFormatMemory(OBJ2_NODE(n)->object_data->node->doc, &buf, &bufsize, 1);

  if(buf!=NULL)
  {
    str = (char *)xmlStrdup(buf);
    xmlFree(buf);
    push_text(str);
  }  
  else
  {
    push_int(0);
  }
}

}
/*! @decl string render_html(Node n)
 *!   Renders a node tree as an HTML string. The entire document tree will 
 *!  be rendered. To render a portion of a tree, use @[Node.render_html].
 *!
 *!   @param n
 *!     a Node object for a given HTML document.
 *!
 */
#define f_render_html_defined
ptrdiff_t f_render_html_fun_num = 0;
void f_render_html(INT32 args) {
#line 498 "XML2.cmod"
struct object * n;
#line 498 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("render_html",args,1);
#line 498 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_OBJECT) SIMPLE_BAD_ARG_ERROR("render_html",1,"object");
#line 498 "XML2.cmod"
debug_malloc_pass(n=Pike_sp[0-1].u.object);
{
  int dumped;
  xmlChar * buf;
  char * str;
  int bufsize;

  CHECK_NODE_PASSED(n);

/*  check_node_created(); */
  if(OBJ2_NODE(n)->object_data->node == NULL)
  { 
    Pike_error("Node not initialized.\n");
  }

  htmlDocDumpMemory(OBJ2_NODE(n)->object_data->node->doc, &buf, &bufsize, 1);

  if(buf!=NULL)
  {
    str = (char *)xmlStrdup(buf);
    xmlFree(buf);
    push_text(str);
  }  
  else
  {
    push_int(0);
  }
}


}
#line 528 "XML2.cmod"
void my_relaxng_generic_error(void * userData, const char * error)
{
printf("%s\n", error);
/*  push_text(error); */
/*  f_werror(1); */
}

void my_structured_error(void * userData, xmlErrorPtr error)
{
  char err[255];

  if(THIS->silent == 0)
  {
    snprintf(err, sizeof(err), "Public.Parser.XML error: %d, message: %s", 
             error->level, error->message);
   /* push_text(err); */
   /* f_werror(1); */
   printf("%s\n", err);
  }

}

/*! @decl Node parse_xml_force(string xml)
 *!   Parse an string containing XML, even if it is not Well Formed.
 *!  @param xml
 *!   String containing XML data to parse.
 *!
 *!  @returns
 *!    a @[Node] object containing the root of the tree.
 */
#define f_parse_xml_force_defined
ptrdiff_t f_parse_xml_force_fun_num = 0;
void f_parse_xml_force(INT32 args) {
#line 558 "XML2.cmod"
struct pike_string * xml;
#line 558 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("parse_xml_force",args,1);
#line 558 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_xml_force",1,"string");
#line 558 "XML2.cmod"
debug_malloc_pass(xml=Pike_sp[0-1].u.string);
{
  xmlDocPtr doc;
  xmlNodePtr node;
  struct Node_struct * ns;
  NODE_OBJECT_DATA * od;

  doc = xmlRecoverMemory(xml->str, xml->len);

  if(doc == NULL)
  {
    pop_n_elems(2);
    Pike_error("Unable to parse XML.\n");
  }  

  node = xmlDocGetRootElement(doc);
  if(node == NULL)
  {
    pop_n_elems(2);
    xmlFreeDoc(doc);
    Pike_error("Unable to find Root Node.\n");
  }

  /* ok, we have a parsed file. now let's turn it into a real live pike object. */

  pop_n_elems(2);

  apply(Pike_fp->current_object, "Node", 0);
  
  ns = OBJ2_NODE((Pike_sp[0-1].u.object));
  od = (NODE_OBJECT_DATA *)(ns->object_data);

  od->parser = this_object();
  od->refs = malloc(sizeof(INT32));
  (* od->refs)=1;
  od->node = node;
}

}
#line 596 "XML2.cmod"
xmlParserInputPtr my_entity_loader(const char * URL, const char * ID,
   xmlParserCtxtPtr context)
{
  printf("request for entity %s\n", URL);
  return NULL; 
}

/*! @decl Node parse_xml(string xml, string|void name, string|void encoding)
 *!   Parse an string containing XML.
 *!  @param xml
 *!   String containing XML data to parse.
 *!  @param name
 *!   String containing name/URI of file.
 *!
 *!  @returns
 *!    a @[Node] object containing the root of the tree.
 */
#define f_parse_xml_1_defined
ptrdiff_t f_parse_xml_1_fun_num = 0;
void f_parse_xml_1(INT32 args) {
#line 613 "XML2.cmod"
struct pike_string * xml;
#line 613 "XML2.cmod"
struct pike_string * name;
#line 613 "XML2.cmod"
struct pike_string * encoding;
#line 613 "XML2.cmod"
if(args != 3) wrong_number_of_args_error("parse_xml",args,3);
#line 613 "XML2.cmod"
if(Pike_sp[0-3].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_xml",1,"string");
#line 613 "XML2.cmod"
debug_malloc_pass(xml=Pike_sp[0-3].u.string);
#line 613 "XML2.cmod"
if(Pike_sp[1-3].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_xml",2,"string");
#line 613 "XML2.cmod"
debug_malloc_pass(name=Pike_sp[1-3].u.string);
#line 613 "XML2.cmod"
if(Pike_sp[2-3].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_xml",3,"string");
#line 613 "XML2.cmod"
debug_malloc_pass(encoding=Pike_sp[2-3].u.string);
{
  xmlDocPtr doc;

  entity_loader = my_entity_loader;

  /*  xmlSetExternalEntityLoader(entity_loader); */

  doc = xmlReadMemory(xml->str, xml->len, name->str, 
                      (const char *)encoding->str, 
                      THIS->object_data->xml_parser_options);

  handle_parsed_tree(doc, args);
}

}
#line 628 "XML2.cmod"
xmlEntityPtr my_xml_getent(void * ctx, const xmlChar * name)
{
    xmlEntityPtr ent;
    
    if(strcmp(name, "boo") != 0)
    {
      printf("somebody else's entity: %s!\n", name);
      return xmlSAX2GetEntity(ctx, name);
     }
    ent = xmlMalloc(sizeof(xmlEntity)); 
    if(ent == NULL) printf("unable to allocate entity storage.\n");
        
    memset(ent, 0, sizeof(xmlEntity));
      
    ent->type = XML_ENTITY_DECL;
    ent->etype = XML_INTERNAL_GENERAL_ENTITY;
    ent->name = xmlStrdup(name);   
    ent->content = xmlStrdup(name);
        
    return ent;

}

#define f_parse_xml_sax_defined
ptrdiff_t f_parse_xml_sax_fun_num = 0;
void f_parse_xml_sax(INT32 args) {
#line 651 "XML2.cmod"
struct pike_string * xml;
#line 651 "XML2.cmod"
struct pike_string * name;
#line 651 "XML2.cmod"
struct pike_string * encoding;
#line 651 "XML2.cmod"
if(args != 3) wrong_number_of_args_error("parse_xml_sax",args,3);
#line 651 "XML2.cmod"
if(Pike_sp[0-3].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_xml_sax",1,"string");
#line 651 "XML2.cmod"
debug_malloc_pass(xml=Pike_sp[0-3].u.string);
#line 651 "XML2.cmod"
if(Pike_sp[1-3].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_xml_sax",2,"string");
#line 651 "XML2.cmod"
debug_malloc_pass(name=Pike_sp[1-3].u.string);
#line 651 "XML2.cmod"
if(Pike_sp[2-3].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_xml_sax",3,"string");
#line 651 "XML2.cmod"
debug_malloc_pass(encoding=Pike_sp[2-3].u.string);
{
  xmlDocPtr doc;
  xmlSAXHandler * sax;
  xmlParserCtxtPtr ctxt;

  ctxt = xmlCreateMemoryParserCtxt(xml->str, xml->len);

  if(ctxt == NULL) Pike_error("unable to allocate context.\n");

  sax = xmlMalloc(sizeof(xmlSAXHandler));
  xmlSAXVersion(sax, 2);
  sax->getEntity = my_xml_getent;  

  if(ctxt->sax != NULL)
    xmlFree(ctxt->sax);

  ctxt->sax = sax;

  xmlDetectSAX2(ctxt);
  ctxt->recovery = 0;
/*  ctxt->replaceEntities = 0; */

  xmlParseDocument(ctxt);
  /*  entity_loader = my_entity_loader; */
  /*  xmlSetExternalEntityLoader(entity_loader); */

  doc = ctxt->myDoc;

   if (sax != NULL)
        ctxt->sax = NULL;
    xmlFreeParserCtxt(ctxt);

  handle_parsed_tree(doc, args);
}

}
#line 687 "XML2.cmod"
void handle_parsed_tree(xmlDocPtr doc, INT32 args)
{
  xmlNodePtr node;
  struct Node_struct * ns;
  NODE_OBJECT_DATA * od;
  char * err_ctx = "parse_xml";

  if(doc == NULL)
  {
    pop_n_elems(args);
    Pike_error("Unable to parse XML.\n");
  }  

  node = xmlDocGetRootElement(doc);
  if(node == NULL)
  {
    pop_n_elems(args);
    xmlFreeDoc(doc);
    Pike_error("Unable to find Root Node.\n");
  }

  /* ok, we have a parsed file. now let's turn it into a real live pike object. */

  pop_n_elems(args);

  apply(Pike_fp->current_object, "Node", 0);
  
  ns = OBJ2_NODE((Pike_sp[0-1].u.object));
  od = (NODE_OBJECT_DATA *)(ns->object_data);

  od->refs = malloc(sizeof(INT32));
  (* od->refs)=1;
  od->node = node;
  od->parser = this_object();
}

#define f_parse_xml_2_defined
ptrdiff_t f_parse_xml_2_fun_num = 0;
void f_parse_xml_2(INT32 args) {
#line 723 "XML2.cmod"
struct pike_string * xml;
#line 723 "XML2.cmod"
struct pike_string * name;
#line 723 "XML2.cmod"
if(args != 2) wrong_number_of_args_error("parse_xml",args,2);
#line 723 "XML2.cmod"
if(Pike_sp[0-2].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_xml",1,"string");
#line 723 "XML2.cmod"
debug_malloc_pass(xml=Pike_sp[0-2].u.string);
#line 723 "XML2.cmod"
if(Pike_sp[1-2].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_xml",2,"string");
#line 723 "XML2.cmod"
debug_malloc_pass(name=Pike_sp[1-2].u.string);
{
  xmlDocPtr doc;

  entity_loader = my_entity_loader;

  /*  xmlSetExternalEntityLoader(entity_loader); */
  if(!xml || !name || !THIS || !THIS->object_data) 
  {
	Pike_error("missing arguments at c level!\n");
  }
  doc = xmlReadMemory(xml->str, xml->len, name->str, 
                      NULL, 
                      THIS->object_data->xml_parser_options);

  handle_parsed_tree(doc, args);
  
}

}
#define f_parse_xml_3_defined
ptrdiff_t f_parse_xml_3_fun_num = 0;
void f_parse_xml_3(INT32 args) {
#line 742 "XML2.cmod"
struct pike_string * xml;
#line 742 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("parse_xml",args,1);
#line 742 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_xml",1,"string");
#line 742 "XML2.cmod"
debug_malloc_pass(xml=Pike_sp[0-1].u.string);
{
  push_text("noname.xml");
  f_parse_xml(2);
}

}

#if defined(f_parse_xml_1_defined) || defined(f_parse_xml_2_defined) || defined(f_parse_xml_3_defined)
#define f_parse_xml_defined
ptrdiff_t f_parse_xml_fun_num = 0;
void f_parse_xml(INT32 args) {
  switch(args) {
   case 1:

#ifdef f_parse_xml_3_defined
    f_parse_xml_3(args);
    return;

#endif /* f_parse_xml_3_defined */
    break;
   case 2:

#ifdef f_parse_xml_2_defined
    f_parse_xml_2(args);
    return;

#endif /* f_parse_xml_2_defined */
    break;
   case 3:

#ifdef f_parse_xml_1_defined
    f_parse_xml_1(args);
    return;

#endif /* f_parse_xml_1_defined */
    break;
   default:
    wrong_number_of_args_error("parse_xml",args,1);
  }
}

#endif /* f_parse_xml_1_defined, f_parse_xml_2_defined, f_parse_xml_3_defined */
/*! @decl Node parse_html(string html, string|void name, string|void encoding)
 *!   Parse an string containing HTML.
 *!  @param html
 *!   String containing HTML data to parse.
 *!  @param name
 *!   String containing name/URI of file.
 *!
 *!  @returns
 *!    a @[Node] object containing the root of the tree.
 */
#define f_parse_html_1_defined
ptrdiff_t f_parse_html_1_fun_num = 0;
void f_parse_html_1(INT32 args) {
#line 758 "XML2.cmod"
struct pike_string * html;
#line 758 "XML2.cmod"
struct pike_string * name;
#line 758 "XML2.cmod"
struct pike_string * encoding;
#line 758 "XML2.cmod"
if(args != 3) wrong_number_of_args_error("parse_html",args,3);
#line 758 "XML2.cmod"
if(Pike_sp[0-3].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_html",1,"string");
#line 758 "XML2.cmod"
debug_malloc_pass(html=Pike_sp[0-3].u.string);
#line 758 "XML2.cmod"
if(Pike_sp[1-3].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_html",2,"string");
#line 758 "XML2.cmod"
debug_malloc_pass(name=Pike_sp[1-3].u.string);
#line 758 "XML2.cmod"
if(Pike_sp[2-3].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_html",3,"string");
#line 758 "XML2.cmod"
debug_malloc_pass(encoding=Pike_sp[2-3].u.string);
{
  xmlDocPtr doc;

  entity_loader = my_entity_loader;

  /*  xmlSetExternalEntityLoader(entity_loader); */

  doc = htmlReadMemory(html->str, html->len, name->str, 
                      (const char *)encoding->str, 
                      THIS->object_data->html_parser_options);

  handle_parsed_tree(doc, args);
}

}
#define f_parse_html_2_defined
ptrdiff_t f_parse_html_2_fun_num = 0;
void f_parse_html_2(INT32 args) {
#line 773 "XML2.cmod"
struct pike_string * html;
#line 773 "XML2.cmod"
struct pike_string * name;
#line 773 "XML2.cmod"
if(args != 2) wrong_number_of_args_error("parse_html",args,2);
#line 773 "XML2.cmod"
if(Pike_sp[0-2].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_html",1,"string");
#line 773 "XML2.cmod"
debug_malloc_pass(html=Pike_sp[0-2].u.string);
#line 773 "XML2.cmod"
if(Pike_sp[1-2].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_html",2,"string");
#line 773 "XML2.cmod"
debug_malloc_pass(name=Pike_sp[1-2].u.string);
{
  xmlDocPtr doc;

  entity_loader = my_entity_loader;

  /*  xmlSetExternalEntityLoader(entity_loader); */

  doc = htmlReadMemory(html->str, html->len, name->str, 
                      NULL, 
                      THIS->object_data->html_parser_options);

  handle_parsed_tree(doc, args);
  
}

}
#define f_parse_html_3_defined
ptrdiff_t f_parse_html_3_fun_num = 0;
void f_parse_html_3(INT32 args) {
#line 789 "XML2.cmod"
struct pike_string * html;
#line 789 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("parse_html",args,1);
#line 789 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_html",1,"string");
#line 789 "XML2.cmod"
debug_malloc_pass(html=Pike_sp[0-1].u.string);
{
  push_text("noname.html");
  f_parse_html(2);
}

}

#if defined(f_parse_html_1_defined) || defined(f_parse_html_2_defined) || defined(f_parse_html_3_defined)
#define f_parse_html_defined
ptrdiff_t f_parse_html_fun_num = 0;
void f_parse_html(INT32 args) {
  switch(args) {
   case 1:

#ifdef f_parse_html_3_defined
    f_parse_html_3(args);
    return;

#endif /* f_parse_html_3_defined */
    break;
   case 2:

#ifdef f_parse_html_2_defined
    f_parse_html_2(args);
    return;

#endif /* f_parse_html_2_defined */
    break;
   case 3:

#ifdef f_parse_html_1_defined
    f_parse_html_1(args);
    return;

#endif /* f_parse_html_1_defined */
    break;
   default:
    wrong_number_of_args_error("parse_html",args,1);
  }
}

#endif /* f_parse_html_1_defined, f_parse_html_2_defined, f_parse_html_3_defined */
/*! @decl int validate(Node doc)
 *!
 *! validates a document against its internal and external DTDs.
 *!
 */
#define f_validate_defined
ptrdiff_t f_validate_fun_num = 0;
void f_validate(INT32 args) {
#line 800 "XML2.cmod"
struct object * doc;
#line 800 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("validate",args,1);
#line 800 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_OBJECT) SIMPLE_BAD_ARG_ERROR("validate",1,"object");
#line 800 "XML2.cmod"
debug_malloc_pass(doc=Pike_sp[0-1].u.object);
{
  int r;
  xmlValidCtxtPtr valid;
  CHECK_NODE_PASSED(doc);

  if(OBJ2_NODE(doc)->object_data->node->doc==NULL)
  {
    pop_stack();
    Pike_error("whoa, horsie! we don't have an xml document!\n");
  }

  valid = xmlNewValidCtxt();
  if(valid == NULL)
  {
    pop_stack();
    Pike_error("unable to allocate a validation context\n");
  }

  r = xmlValidateDocument(valid, OBJ2_NODE(doc)->object_data->node->doc);

  xmlFreeValidCtxt(valid);

  pop_stack();

  push_int(r);
}

}
/*! @decl Node new_xml(string version, string root_name)
 *!   Create a new XML document with a root node.
 *!
 *!  @param version
 *!     the version of XML to create
 *!  @param root_name
 *!      the name of the root node
 *!  @returns
 *!    a @[Node] object containing the root of the tree.
 */
#define f_new_xml_defined
ptrdiff_t f_new_xml_fun_num = 0;
void f_new_xml(INT32 args) {
#line 838 "XML2.cmod"
struct pike_string * version;
#line 838 "XML2.cmod"
struct pike_string * root_name;
#line 838 "XML2.cmod"
if(args != 2) wrong_number_of_args_error("new_xml",args,2);
#line 838 "XML2.cmod"
if(Pike_sp[0-2].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("new_xml",1,"string");
#line 838 "XML2.cmod"
debug_malloc_pass(version=Pike_sp[0-2].u.string);
#line 838 "XML2.cmod"
if(Pike_sp[1-2].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("new_xml",2,"string");
#line 838 "XML2.cmod"
debug_malloc_pass(root_name=Pike_sp[1-2].u.string);
{
  xmlDocPtr doc;
  xmlNodePtr node;
  struct Node_struct * ns;
  NODE_OBJECT_DATA * od;

  /* TODO: we need to encode this value! */
  doc = xmlNewDoc(version->str);

  if(doc == NULL)
  {
    Pike_error("Unable to create new XML document.\n");
  }  

  /* TODO: we need to encode this value! */
  node = xmlNewNode(NULL, (xmlChar *)root_name->str);
  xmlDocSetRootElement(doc, node);
  if(node == NULL)
  {
    xmlFreeDoc(doc);
    Pike_error("Unable to find Root Node.\n");
  }

  /* ok, we have a parsed file. now let's turn it into a real live pike object. */

  pop_stack();

  apply(Pike_fp->current_object, "Node", 0);
  
  ns = OBJ2_NODE((Pike_sp[0-1].u.object));
  od = (NODE_OBJECT_DATA *)(ns->object_data);

  od->refs = malloc(sizeof(INT32));
  (* od->refs)=1;
  od->node = node;
  od->parser = this_object();
}

}
/*! @decl Node new_node(string name)
 *!   Create a new unlinked XML node.
 *!
 *!  @param name
 *!      the node name
 *!  @returns
 *!    a new @[Node] object.
 */
#define f_new_node_defined
ptrdiff_t f_new_node_fun_num = 0;
void f_new_node(INT32 args) {
#line 885 "XML2.cmod"
struct pike_string * name;
#line 885 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("new_node",args,1);
#line 885 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("new_node",1,"string");
#line 885 "XML2.cmod"
debug_malloc_pass(name=Pike_sp[0-1].u.string);
{
  xmlNodePtr node;
  struct Node_struct * ns;
  NODE_OBJECT_DATA * od;

  /* TODO: we need to encode this value! */
  node = xmlNewNode(NULL, (xmlChar *)name->str);

  if(node == NULL)
  {
    Pike_error("Unable to create new node.\n");
  }  

  pop_stack();

  apply(Pike_fp->current_object, "Node", 0);
  
  ns = OBJ2_NODE((Pike_sp[0-1].u.object));
  od = (NODE_OBJECT_DATA *)(ns->object_data);

  od->refs = malloc(sizeof(INT32));
  (* od->refs)=1;
  od->unlinked = 1;
  od->node = node;
  od->parser = this_object();
}

}
/*! @decl Node parse_relaxng(string relaxng, string|void name)
/*! @decl Node parse_relaxng(Node relaxng)
 *!   Parse a string containing an RelaxNG schema.
 *!
 *!  @param name
 *!   String containing name/URI of file.
 *!
 *!  @returns
 *!    a @[RelaxNG] object containing the parsed schema.
 */
#define f_parse_relaxng_1_defined
ptrdiff_t f_parse_relaxng_1_fun_num = 0;
void f_parse_relaxng_1(INT32 args) {
#line 923 "XML2.cmod"
struct pike_string * relaxng;
#line 923 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("parse_relaxng",args,1);
#line 923 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_relaxng",1,"string");
#line 923 "XML2.cmod"
debug_malloc_pass(relaxng=Pike_sp[0-1].u.string);
{
  push_text("noname.rlx");
  f_parse_relaxng(2);
}

}
#define f_parse_relaxng_2_defined
ptrdiff_t f_parse_relaxng_2_fun_num = 0;
void f_parse_relaxng_2(INT32 args) {
#line 929 "XML2.cmod"
struct object * relaxng;
#line 929 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("parse_relaxng",args,1);
#line 929 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_OBJECT) SIMPLE_BAD_ARG_ERROR("parse_relaxng",1,"object");
#line 929 "XML2.cmod"
debug_malloc_pass(relaxng=Pike_sp[0-1].u.object);
{
  CHECK_NODE_PASSED(relaxng);

  handle_parse_relaxng(args);

}

}
#define f_parse_relaxng_3_defined
ptrdiff_t f_parse_relaxng_3_fun_num = 0;
void f_parse_relaxng_3(INT32 args) {
#line 937 "XML2.cmod"
struct pike_string * relaxng;
#line 937 "XML2.cmod"
struct pike_string * name;
#line 937 "XML2.cmod"
if(args != 2) wrong_number_of_args_error("parse_relaxng",args,2);
#line 937 "XML2.cmod"
if(Pike_sp[0-2].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_relaxng",1,"string");
#line 937 "XML2.cmod"
debug_malloc_pass(relaxng=Pike_sp[0-2].u.string);
#line 937 "XML2.cmod"
if(Pike_sp[1-2].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_relaxng",2,"string");
#line 937 "XML2.cmod"
debug_malloc_pass(name=Pike_sp[1-2].u.string);
{
  /* first, we must parse the xml file. conveniently, we have a function */
  /* that does that already! */
  f_parse_xml(2);

  handle_parse_relaxng(args);
}

}

#if defined(f_parse_relaxng_1_defined) || defined(f_parse_relaxng_2_defined) || defined(f_parse_relaxng_3_defined)
#define f_parse_relaxng_defined
ptrdiff_t f_parse_relaxng_fun_num = 0;
void f_parse_relaxng(INT32 args) {
  switch(args) {
   case 1:
    switch(Pike_sp[0-1].type) {
     case PIKE_T_STRING:

#ifdef f_parse_relaxng_1_defined
      f_parse_relaxng_1(args);
      return;

#endif /* f_parse_relaxng_1_defined */
      break;
     case PIKE_T_OBJECT:

#ifdef f_parse_relaxng_2_defined
      f_parse_relaxng_2(args);
      return;

#endif /* f_parse_relaxng_2_defined */
      break;
     default:
      SIMPLE_BAD_ARG_ERROR("parse_relaxng",1,"string|object");
    }
   case 2:

#ifdef f_parse_relaxng_3_defined
    f_parse_relaxng_3(args);
    return;

#endif /* f_parse_relaxng_3_defined */
    break;
   default:
    wrong_number_of_args_error("parse_relaxng",args,1);
  }
}

#endif /* f_parse_relaxng_1_defined, f_parse_relaxng_2_defined, f_parse_relaxng_3_defined */
#line 946 "XML2.cmod"
void handle_parse_relaxng(INT32 args)
{
  struct object * node_obj = NULL;
  xmlDocPtr doc = NULL;
  xmlRelaxNGParserCtxtPtr parser;
  xmlRelaxNGPtr relax;
  struct RelaxNG_struct * rn;
  RELAXNG_OBJECT_DATA * od;

  /* we're going to hang on to the node object. */
  node_obj = Pike_sp[0-1].u.object;
  add_ref(node_obj);

  doc = OBJ2_NODE(node_obj)->object_data->node->doc;

  if(doc==NULL)
  {
    pop_stack();
    Pike_error("whoa, horsie! we don't have an xml document!\n");
  }

  parser = xmlRelaxNGNewDocParserCtxt(doc);
  if(parser == NULL)
  {
    pop_stack();
    Pike_error("Unable to create relaxng parser context.\n");
  }  
  
  relaxng_error_handler = (xmlRelaxNGValidityErrorFunc)my_relaxng_generic_error;
  relaxng_warning_handler = (xmlRelaxNGValidityWarningFunc)my_relaxng_generic_error;

  xmlRelaxNGSetParserErrors(parser, relaxng_error_handler, 
                            relaxng_warning_handler, NULL);

  relax = xmlRelaxNGParse(parser);

  if(relax == NULL)
  {
    pop_stack();
    Pike_error("Unable to parse the relaxng data.\n");
  }  


  /* ok, we have a parsed schema. now let's turn it into a real live pike object. */

  pop_stack();

  apply(Pike_fp->current_object, "RelaxNG", 0);
  
  rn = OBJ2_RELAXNG((Pike_sp[0-1].u.object));
  od = (RELAXNG_OBJECT_DATA *)(rn->object_data);
  od->parser = this_object();

  od->refs = malloc(sizeof(INT32));
  (* od->refs)=1;

  /* TODO: not sure if this is a leak, but we need it to prevent the 
     xmlNode from being freed a second time at the pike Node's destruction  
     (the Stylesheet will free that itself. Note that this is a tricky 
     subject... since the two are linked, perhaps we should call 
     Node.destroy() when the Stylesheet is destroyed... */
  *(OBJ2_NODE(node_obj)->object_data->refs)++;
  od->context = parser;
  od->valid = relax;
  rn->node = node_obj;
}

/*! @decl Node parse_xslt(string xslt, string|void name)
/*! @decl Node parse_xslt(Node xslt)
 *!   Parse a string containing an XSLT stylesheet.
 *!
 *!  @param name
 *!   String containing name/URI of file.
 *!
 *!  @returns
 *!    a @[Stylesheet] object containing the parsed stylesheet.
 */
#define f_parse_xslt_1_defined
ptrdiff_t f_parse_xslt_1_fun_num = 0;
void f_parse_xslt_1(INT32 args) {
#line 1023 "XML2.cmod"
struct pike_string * xslt;
#line 1023 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("parse_xslt",args,1);
#line 1023 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_xslt",1,"string");
#line 1023 "XML2.cmod"
debug_malloc_pass(xslt=Pike_sp[0-1].u.string);
{
  push_text("noname.xsl");
  f_parse_xslt(2);
}

}
#define f_parse_xslt_2_defined
ptrdiff_t f_parse_xslt_2_fun_num = 0;
void f_parse_xslt_2(INT32 args) {
#line 1029 "XML2.cmod"
struct object * xslt;
#line 1029 "XML2.cmod"
if(args != 1) wrong_number_of_args_error("parse_xslt",args,1);
#line 1029 "XML2.cmod"
if(Pike_sp[0-1].type != PIKE_T_OBJECT) SIMPLE_BAD_ARG_ERROR("parse_xslt",1,"object");
#line 1029 "XML2.cmod"
debug_malloc_pass(xslt=Pike_sp[0-1].u.object);
{
  CHECK_NODE_PASSED(xslt);

  handle_parse_stylesheet(args);
}

}
#define f_parse_xslt_3_defined
ptrdiff_t f_parse_xslt_3_fun_num = 0;
void f_parse_xslt_3(INT32 args) {
#line 1036 "XML2.cmod"
struct pike_string * xslt;
#line 1036 "XML2.cmod"
struct pike_string * name;
#line 1036 "XML2.cmod"
if(args != 2) wrong_number_of_args_error("parse_xslt",args,2);
#line 1036 "XML2.cmod"
if(Pike_sp[0-2].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_xslt",1,"string");
#line 1036 "XML2.cmod"
debug_malloc_pass(xslt=Pike_sp[0-2].u.string);
#line 1036 "XML2.cmod"
if(Pike_sp[1-2].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("parse_xslt",2,"string");
#line 1036 "XML2.cmod"
debug_malloc_pass(name=Pike_sp[1-2].u.string);
{
  /* first, we must parse the xml file. conveniently, we have a function */
  /* that does that already! */
  f_parse_xml(2);

  handle_parse_stylesheet(args);
}

}

#if defined(f_parse_xslt_1_defined) || defined(f_parse_xslt_2_defined) || defined(f_parse_xslt_3_defined)
#define f_parse_xslt_defined
ptrdiff_t f_parse_xslt_fun_num = 0;
void f_parse_xslt(INT32 args) {
  switch(args) {
   case 1:
    switch(Pike_sp[0-1].type) {
     case PIKE_T_STRING:

#ifdef f_parse_xslt_1_defined
      f_parse_xslt_1(args);
      return;

#endif /* f_parse_xslt_1_defined */
      break;
     case PIKE_T_OBJECT:

#ifdef f_parse_xslt_2_defined
      f_parse_xslt_2(args);
      return;

#endif /* f_parse_xslt_2_defined */
      break;
     default:
      SIMPLE_BAD_ARG_ERROR("parse_xslt",1,"string|object");
    }
   case 2:

#ifdef f_parse_xslt_3_defined
    f_parse_xslt_3(args);
    return;

#endif /* f_parse_xslt_3_defined */
    break;
   default:
    wrong_number_of_args_error("parse_xslt",args,1);
  }
}

#endif /* f_parse_xslt_1_defined, f_parse_xslt_2_defined, f_parse_xslt_3_defined */
#line 1045 "XML2.cmod"
void handle_parse_stylesheet(INT32 args)
{
  struct object * node_obj = NULL;
  xsltStylesheetPtr sty = NULL;
  xmlDocPtr doc = NULL;
  struct Stylesheet_struct * ss;
  STYLESHEET_OBJECT_DATA * od;

  /* we're going to hang on to the node object. */
  node_obj = Pike_sp[0-1].u.object;
  add_ref(node_obj);

  doc = OBJ2_NODE(node_obj)->object_data->node->doc;

  if(doc==NULL)
  {
    pop_stack();
    Pike_error("whoa, horsie! we don't have an xml document!\n");
  }

  sty = xsltParseStylesheetDoc(doc);

  if(sty == NULL)
  {
    pop_stack();
    Pike_error("Unable to parse stylesheet node.\n");
  }  

  /* ok, we have a parsed sheet. now let's turn it into a real live pike object. */

  pop_stack();

  apply(Pike_fp->current_object, "Stylesheet", 0);
  
  ss = OBJ2_STYLESHEET((Pike_sp[0-1].u.object));
  od = (STYLESHEET_OBJECT_DATA *)(ss->object_data);
  od->parser = this_object();

  od->refs = malloc(sizeof(INT32));
  (* od->refs)=1;
  add_ref(node_obj);
/*  (*(OBJ2_NODE(node_obj)->object_data->refs))++; */
  od->stylesheet = sty;
  ss->node = node_obj;
}


#undef extra_defined
#define extra_defined

#undef internal_init_defined
#define internal_init_defined

#undef event_handler_defined
#define event_handler_defined
static void init_struct(void)
#line 1113 "XML2.cmod"
{
  PARSER_OBJECT_DATA * dta;

  dta = (PARSER_OBJECT_DATA*)malloc(sizeof(PARSER_OBJECT_DATA));
  if(dta == NULL)
  {
    Pike_error("xml2_init: unable to allocate memory.\n");
  }

  dta->xml_parser_options = 0;
  dta->html_parser_options = 0;
  dta->auto_encode = 1;
  if(THIS!=NULL && THIS->object_data != NULL && THIS->object_data != NULL && dta != NULL)
    THIS->object_data = dta;
 
  LIBXML_TEST_VERSION
}


#undef internal_exit_defined
#define internal_exit_defined

#undef event_handler_defined
#define event_handler_defined
static void exit_struct(void)
#line 1132 "XML2.cmod"
{

  pike_exit_xml2_relaxng();
  pike_exit_xml2_xmlreader();
  pike_exit_xml2_stylesheet();
  pike_exit_xml2_sax();
  pike_exit_xml2_node();
  pike_exit_xml2_html();
  pike_exit_xml2_constants();
  
#ifdef HAVE_XSLT
xsltCleanupGlobals();
#endif /* HAVE_XSLT */

  xmlCleanupParser();
}

/*! @endmodule
 */

/*! @endmodule
 */

/*! @endmodule
 */




#ifdef event_handler_defined
static void event_handler(int ev) {
  switch(ev) {

#ifdef internal_init_defined
  case PROG_EVENT_INIT: init_struct(); break;

#endif /* internal_init_defined */

#ifdef internal_exit_defined
  case PROG_EVENT_EXIT: exit_struct(); break;

#endif /* internal_exit_defined */
  default: break; 
  }
}

#endif /* event_handler_defined */
PIKE_MODULE_INIT {

#ifdef THIS_
  _storage_offset = ADD_STORAGE(struct _struct);
#endif /* THIS_ */

#ifdef var_silent_defined
  PIKE_MAP_VARIABLE("silent", _storage_offset + OFFSETOF(_struct, silent),
                    "\10\200\0\0\0\177\377\377\377", PIKE_T_INT, 0);
#endif /* var_silent_defined */

#ifdef extra_defined
#line 1092 "XML2.cmod"
{
  struct pike_string * ps;
  char * err_ctx = "parse_xml";

  add_string_constant("__version", "1.42", 0);
  add_string_constant("__author", "Bill Welliver <bill@welliver.org>", 0);

  structured_handler = my_structured_error;
  xmlSetStructuredErrorFunc((void *)err_ctx, structured_handler);

  pike_init_xml2_constants();
  pike_init_xml2_html();
  pike_init_xml2_node();
  pike_init_xml2_sax();
  pike_init_xml2_stylesheet();
  pike_init_xml2_xmlreader();
  pike_init_xml2_relaxng();

}


#endif /* extra_defined */

#ifdef event_handler_defined
  pike_set_prog_event_callback(event_handler);

#endif /* event_handler_defined */

#ifdef f_create_defined
  f_create_fun_num =
#line 100 "XML2.cmod"
    ADD_FUNCTION2("create", f_create, tFunc(tNone,tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_create_defined */

#ifdef f_select_xpath_nodes_defined
  f_select_xpath_nodes_fun_num =
#line 109 "XML2.cmod"
    ADD_FUNCTION2("select_xpath_nodes", f_select_xpath_nodes, tFunc(tString tObj,tArray), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_select_xpath_nodes_defined */

#ifdef f_set_xml_parser_options_defined
  f_set_xml_parser_options_fun_num =
#line 213 "XML2.cmod"
    ADD_FUNCTION2("set_xml_parser_options", f_set_xml_parser_options, tFunc("\10\200\0\0\0\177\377\377\377",tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_set_xml_parser_options_defined */

#ifdef f_get_xml_parser_options_defined
  f_get_xml_parser_options_fun_num =
#line 227 "XML2.cmod"
    ADD_FUNCTION2("get_xml_parser_options", f_get_xml_parser_options, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_get_xml_parser_options_defined */

#ifdef f_get_html_parser_options_defined
  f_get_html_parser_options_fun_num =
#line 240 "XML2.cmod"
    ADD_FUNCTION2("get_html_parser_options", f_get_html_parser_options, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_get_html_parser_options_defined */

#ifdef f_set_auto_utf8_convert_defined
  f_set_auto_utf8_convert_fun_num =
#line 256 "XML2.cmod"
    ADD_FUNCTION2("set_auto_utf8_convert", f_set_auto_utf8_convert, tFunc("\10\200\0\0\0\177\377\377\377",tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_set_auto_utf8_convert_defined */

#ifdef f_set_html_parser_options_defined
  f_set_html_parser_options_fun_num =
#line 302 "XML2.cmod"
    ADD_FUNCTION2("set_html_parser_options", f_set_html_parser_options, tFunc("\10\200\0\0\0\177\377\377\377",tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_set_html_parser_options_defined */

#ifdef f_substituteEntitiesDefault_defined
  f_substituteEntitiesDefault_fun_num =
#line 310 "XML2.cmod"
    ADD_FUNCTION2("substituteEntitiesDefault", f_substituteEntitiesDefault, tFunc("\10\200\0\0\0\177\377\377\377","\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_substituteEntitiesDefault_defined */

#ifdef f_keepBlanksDefault_defined
  f_keepBlanksDefault_fun_num =
#line 323 "XML2.cmod"
    ADD_FUNCTION2("keepBlanksDefault", f_keepBlanksDefault, tFunc("\10\200\0\0\0\177\377\377\377","\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_keepBlanksDefault_defined */

#ifdef f_utf8_to_html_defined
  f_utf8_to_html_fun_num =
#line 335 "XML2.cmod"
    ADD_FUNCTION2("utf8_to_html", f_utf8_to_html, tFunc(tString,tString), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_utf8_to_html_defined */

#ifdef f_utf8_to_isolat1_defined
  f_utf8_to_isolat1_fun_num =
#line 360 "XML2.cmod"
    ADD_FUNCTION2("utf8_to_isolat1", f_utf8_to_isolat1, tFunc(tString,tString), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_utf8_to_isolat1_defined */

#ifdef f_utf8_check_defined
  f_utf8_check_fun_num =
#line 384 "XML2.cmod"
    ADD_FUNCTION2("utf8_check", f_utf8_check, tFunc(tString,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_utf8_check_defined */

#ifdef f_get_encodings_defined
  f_get_encodings_fun_num =
#line 401 "XML2.cmod"
    ADD_FUNCTION2("get_encodings", f_get_encodings, tFunc(tNone,tArray), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_get_encodings_defined */

#ifdef f_get_encoding_name_defined
  f_get_encoding_name_fun_num =
#line 425 "XML2.cmod"
    ADD_FUNCTION2("get_encoding_name", f_get_encoding_name, tFunc("\10\200\0\0\0\177\377\377\377",tString), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_get_encoding_name_defined */

#ifdef f_get_encoding_alias_defined
  f_get_encoding_alias_fun_num =
#line 441 "XML2.cmod"
    ADD_FUNCTION2("get_encoding_alias", f_get_encoding_alias, tFunc(tString,tString), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_get_encoding_alias_defined */

#ifdef f_render_xml_defined
  f_render_xml_fun_num =
#line 461 "XML2.cmod"
    ADD_FUNCTION2("render_xml", f_render_xml, tFunc(tObj,tString), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_render_xml_defined */

#ifdef f_render_html_defined
  f_render_html_fun_num =
#line 498 "XML2.cmod"
    ADD_FUNCTION2("render_html", f_render_html, tFunc(tObj,tString), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_render_html_defined */

#ifdef f_parse_xml_force_defined
  f_parse_xml_force_fun_num =
#line 558 "XML2.cmod"
    ADD_FUNCTION2("parse_xml_force", f_parse_xml_force, tFunc(tString,tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_parse_xml_force_defined */

#ifdef f_parse_xml_sax_defined
  f_parse_xml_sax_fun_num =
#line 651 "XML2.cmod"
    ADD_FUNCTION2("parse_xml_sax", f_parse_xml_sax, tFunc(tString tString tString,tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_parse_xml_sax_defined */

#ifdef f_parse_xml_defined
  f_parse_xml_fun_num =
#line 742 "XML2.cmod"
    ADD_FUNCTION2("parse_xml", f_parse_xml, tOr3(tFunc(tString tString tString,tObj),tFunc(tString tString,tObj),tFunc(tString,tObj)), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_parse_xml_defined */

#ifdef f_parse_html_defined
  f_parse_html_fun_num =
#line 789 "XML2.cmod"
    ADD_FUNCTION2("parse_html", f_parse_html, tOr3(tFunc(tString tString tString,tObj),tFunc(tString tString,tObj),tFunc(tString,tObj)), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_parse_html_defined */

#ifdef f_validate_defined
  f_validate_fun_num =
#line 800 "XML2.cmod"
    ADD_FUNCTION2("validate", f_validate, tFunc(tObj,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_validate_defined */

#ifdef f_new_xml_defined
  f_new_xml_fun_num =
#line 838 "XML2.cmod"
    ADD_FUNCTION2("new_xml", f_new_xml, tFunc(tString tString,tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_new_xml_defined */

#ifdef f_new_node_defined
  f_new_node_fun_num =
#line 885 "XML2.cmod"
    ADD_FUNCTION2("new_node", f_new_node, tFunc(tString,tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_new_node_defined */

#ifdef f_parse_relaxng_defined
  f_parse_relaxng_fun_num =
#line 937 "XML2.cmod"
    ADD_FUNCTION2("parse_relaxng", f_parse_relaxng, tOr3(tFunc(tString,tObj),tFunc(tObj,tObj),tFunc(tString tString,tObj)), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_parse_relaxng_defined */

#ifdef f_parse_xslt_defined
  f_parse_xslt_fun_num =
#line 1036 "XML2.cmod"
    ADD_FUNCTION2("parse_xslt", f_parse_xslt, tOr3(tFunc(tString,tObj),tFunc(tObj,tObj),tFunc(tString tString,tObj)), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_parse_xslt_defined */
}
PIKE_MODULE_EXIT {
}

gotpike.org | Copyright © 2004 - 2011 | Pike is a trademark of Department of Computer and Information Science, Linköping University