ba32ec2000-02-13Martin Stjernholm //! The standard RXML content parser.
ed81751999-12-11Martin Stjernholm //!
ba32ec2000-02-13Martin Stjernholm //! Parses entities and tags according to XML syntax. Entities on the //! form &scope.variable; are expanded with variables. //!
24f9e82000-08-05Martin Stjernholm //! Note: This parser does not conform to the XML specification in //! some important ways: //! //! o It does not understand DTD declarations. //! o It's not as restrictive in syntax as the standard requires, //! i.e. several construct that aren't well-formed are accepted //! without error.
9a44932000-01-07Martin Stjernholm //!
a6fa9a2000-01-08Martin Stjernholm //! Created 1999-07-30 by Martin Stjernholm. //!
0917d32013-03-04Anders Johansson //! $Id$
ed81751999-12-11Martin Stjernholm 
d8769c2000-02-08Martin Stjernholm //#pragma strict_types // Disabled for now since it doesn't work well enough.
56532d1999-12-19Martin Stjernholm 
cd7d5f2000-02-16Martin Stjernholm #include <config.h>
9f74bb2000-02-15Martin Stjernholm 
7dd3f82001-04-18Martin Stjernholm inherit Parser.HTML: low_parser; inherit RXML.TagSetParser: TagSetParser;
ed81751999-12-11Martin Stjernholm 
840ba52000-01-10Martin Stjernholm constant unwind_safe = 1;
6570bf2001-06-29Martin Stjernholm constant name = "xml";
7dd3f82001-04-18Martin Stjernholm #define EmptyTagFunc \
2bd21a2000-01-05Martin Stjernholm  function(:int(1..1)|string|array)| \ function(Parser.HTML,mapping(string:string): \ int(1..1)|string|array)
7dd3f82001-04-18Martin Stjernholm #define EmptyTagDef string|array|EmptyTagFunc
2bd21a2000-01-05Martin Stjernholm 
7dd3f82001-04-18Martin Stjernholm #define ContainerFunc \
2bd21a2000-01-05Martin Stjernholm  function(:int(1..1)|string|array)| \ function(Parser.HTML,mapping(string:string),string: \ int(1..1)|string|array)
7dd3f82001-04-18Martin Stjernholm #define ContainerDef string|array|ContainerFunc
2bd21a2000-01-05Martin Stjernholm 
7dd3f82001-04-18Martin Stjernholm #define QuoteTagFunc \
24f9e82000-08-05Martin Stjernholm  function(:int(1..1)|string|array)| \ function(Parser.HTML,string: \ int(1..1)|string|array)
7dd3f82001-04-18Martin Stjernholm #define QuoteTagDef string|array|QuoteTagFunc
24f9e82000-08-05Martin Stjernholm 
7dd3f82001-04-18Martin Stjernholm #define EntityDef \
b835122000-01-05Martin Stjernholm  string|array| \
7dd3f82001-04-18Martin Stjernholm  function(void|Parser.HTML:int(1..1)|string|array)
b835122000-01-05Martin Stjernholm 
7dd3f82001-04-18Martin Stjernholm #define TagDef array(EmptyTagDef|ContainerDef)
d0cebe2000-02-17Martin Stjernholm // A tag definition is an array of ({noncontainer definition, // container definition}).
a6fa9a2000-01-08Martin Stjernholm // Kludge to get to the functions in Parser.HTML from inheriting // programs.. :P
fc40392008-08-15Martin Stjernholm /*protected*/ this_program _low_add_tag (string name, EmptyTagDef tdef)
a6fa9a2000-01-08Martin Stjernholm  {return [object(this_program)] low_parser::add_tag (name, tdef);}
fc40392008-08-15Martin Stjernholm /*protected*/ this_program _low_add_container (string name, ContainerDef tdef)
a6fa9a2000-01-08Martin Stjernholm  {return [object(this_program)] low_parser::add_container (name, tdef);}
fc40392008-08-15Martin Stjernholm /*protected*/ this_program _low_add_quote_tag (string beg, QuoteTagDef tdef, string end)
24f9e82000-08-05Martin Stjernholm  {return [object(this_program)] low_parser::add_quote_tag (beg, tdef, end);}
fc40392008-08-15Martin Stjernholm protected this_program _low_clone (mixed... args)
a6fa9a2000-01-08Martin Stjernholm  {return [object(this_program)] low_parser::clone (@args);}
b6c3192000-03-04Martin Stjernholm 
2c52962000-03-04Martin Stjernholm string html_context() {return low_parser::context();}
b04dea2000-06-23Martin Stjernholm string current_input() {return low_parser::current();}
a6fa9a2000-01-08Martin Stjernholm 
da0c882000-03-18Martin Stjernholm constant reset = 0;
fc40392008-08-15Martin Stjernholm protected void set_quote_tag_cbs (QuoteTagDef unknown_pi_tag_cb, QuoteTagDef cdata_cb)
7f0cf22000-01-11Martin Stjernholm {
b1c1d32000-03-06Martin Stjernholm  add_quote_tag ("!--", .utils.p_xml_comment_cb, "--");
7dd3f82001-04-18Martin Stjernholm  add_quote_tag ("?", unknown_pi_tag_cb, "?");
22984d2001-06-18Martin Stjernholm  add_quote_tag ("![CDATA[", cdata_cb, "]]");
7f0cf22000-01-11Martin Stjernholm }
446bfa2001-06-21Martin Stjernholm this_program clone (RXML.Context ctx, RXML.Type type, RXML.PCode p_code, RXML.TagSet tag_set)
2bd21a2000-01-05Martin Stjernholm {
9f74bb2000-02-15Martin Stjernholm #ifdef OLD_RXML_COMPAT
848c5b2000-03-16Martin Stjernholm  int new_not_compat = !(ctx && ctx->id && ctx->id->conf->old_rxml_compat);
446bfa2001-06-21Martin Stjernholm  if (new_not_compat != not_compat) return this_program (ctx, type, p_code, tag_set);
9f74bb2000-02-15Martin Stjernholm #endif
848c5b2000-03-16Martin Stjernholm  return [object(this_program)] low_parser::clone (
446bfa2001-06-21Martin Stjernholm  ctx, type, p_code, tag_set, rt_replacements || 1, rt_pi_replacements);
2bd21a2000-01-05Martin Stjernholm }
9f74bb2000-02-15Martin Stjernholm #ifdef OLD_RXML_COMPAT
fc40392008-08-15Martin Stjernholm protected int not_compat = 1;
9f74bb2000-02-15Martin Stjernholm #endif
446bfa2001-06-21Martin Stjernholm // Decide some alternative behaviors at initialization.
fc40392008-08-15Martin Stjernholm protected int alternative; protected constant FREE_TEXT = 2; protected constant FREE_TEXT_P_CODE = 3; protected constant LITERALS = 4; protected constant LITERALS_P_CODE = 5; protected constant NO_LITERALS = 6; protected constant NO_LITERALS_P_CODE = 7; protected void create (
446bfa2001-06-21Martin Stjernholm  RXML.Context ctx, RXML.Type type, RXML.PCode p_code, RXML.TagSet tag_set,
7dd3f82001-04-18Martin Stjernholm  void|int|mapping(string:TagDef) orig_rt_replacements, void|mapping(string:QuoteTagDef) orig_rt_pi_replacements
9f74bb2000-02-15Martin Stjernholm )
2bd21a2000-01-05Martin Stjernholm {
9f74bb2000-02-15Martin Stjernholm #ifdef OLD_RXML_COMPAT
b6c3192000-03-04Martin Stjernholm  not_compat = !(ctx && ctx->id && ctx->id->conf->old_rxml_compat);
9f74bb2000-02-15Martin Stjernholm #endif
446bfa2001-06-21Martin Stjernholm  if (type->free_text) alternative = FREE_TEXT; else { _set_tag_callback (.utils.unknown_tag_error); alternative = type->handle_literals ? LITERALS : NO_LITERALS; } initialize (ctx, type, p_code, tag_set);
ed81751999-12-11Martin Stjernholm 
24f9e82000-08-05Martin Stjernholm  if (orig_rt_replacements) { // We're cloned. if (mappingp (orig_rt_replacements))
848c5b2000-03-16Martin Stjernholm  rt_replacements = orig_rt_replacements + ([]);
24f9e82000-08-05Martin Stjernholm  if (orig_rt_pi_replacements) rt_pi_replacements = orig_rt_pi_replacements + ([]);
848c5b2000-03-16Martin Stjernholm  return;
2bd21a2000-01-05Martin Stjernholm  }
ed81751999-12-11Martin Stjernholm 
da0c882000-03-18Martin Stjernholm #ifdef RXML_OBJ_DEBUG master_parser = 1; __object_marker->create (this_object()); #elif defined (OBJ_COUNT_DEBUG) master_parser = 1; #endif
1b2b752000-01-07Martin Stjernholm  array(RXML.TagSet) list = ({tag_set}); array(string) plist = ({tag_set->prefix});
2bd21a2000-01-05Martin Stjernholm  for (int i = 0; i < sizeof (list); i++) { array(RXML.TagSet) sublist = list[i]->imported; if (sizeof (sublist)) { list = list[..i] + sublist + list[i + 1..]; plist = plist[..i] + replace (sublist->prefix, 0, plist[i]) + plist[i + 1..]; } } for (int i = sizeof (list) - 1; i >= 0; i--) { RXML.TagSet tset = list[i]; string prefix = plist[i]; array(RXML.Tag) tlist = tset->get_local_tags();
24f9e82000-08-05Martin Stjernholm  // Note: Similar things done in add_runtime_tag() and add_runtime_pi_tag().
2bd21a2000-01-05Martin Stjernholm  if (prefix) {
cede492000-02-15Martin Stjernholm #ifdef OLD_RXML_COMPAT if (not_compat) { #endif foreach (tlist, RXML.Tag tag)
24f9e82000-08-05Martin Stjernholm  if (!(tag->plugin_name || tag->flags & RXML.FLAG_NO_PREFIX)) { string name = prefix + ":" + [string] tag->name; if (tag->flags & RXML.FLAG_PROC_INSTR)
7dd3f82001-04-18Martin Stjernholm  add_quote_tag ("?" + name, tag->_p_xml_handle_pi_tag, "?");
24f9e82000-08-05Martin Stjernholm  else
7dd3f82001-04-18Martin Stjernholm  add_tag (name, 0), add_container (name, tag->_p_xml_handle_tag);
24f9e82000-08-05Martin Stjernholm  }
cede492000-02-15Martin Stjernholm #ifdef OLD_RXML_COMPAT }
4d32262000-02-20Martin Stjernholm  else
cede492000-02-15Martin Stjernholm  foreach (tlist, RXML.Tag tag)
24f9e82000-08-05Martin Stjernholm  if (!(tag->plugin_name || tag->flags & RXML.FLAG_NO_PREFIX)) { string name = prefix + ":" + [string] tag->name; if (tag->flags & RXML.FLAG_PROC_INSTR)
7dd3f82001-04-18Martin Stjernholm  add_quote_tag ("?" + name, tag->_p_xml_handle_pi_tag, "?");
24f9e82000-08-05Martin Stjernholm  else if (tag->flags & RXML.FLAG_EMPTY_ELEMENT)
7dd3f82001-04-18Martin Stjernholm  add_tag (name, tag->_p_xml_handle_tag), add_container (name, 0);
24f9e82000-08-05Martin Stjernholm  else
7dd3f82001-04-18Martin Stjernholm  add_tag (name, 0), add_container (name, tag->_p_xml_handle_tag);
24f9e82000-08-05Martin Stjernholm  }
cede492000-02-15Martin Stjernholm #endif } #ifdef OLD_RXML_COMPAT if (not_compat) { #endif
2bd21a2000-01-05Martin Stjernholm  foreach (tlist, RXML.Tag tag)
24f9e82000-08-05Martin Stjernholm  if (!tag->plugin_name && (!tset->prefix_req || tag->flags & RXML.FLAG_NO_PREFIX)) { string name = [string] tag->name; if (tag->flags & RXML.FLAG_PROC_INSTR)
7dd3f82001-04-18Martin Stjernholm  add_quote_tag ("?" + name, tag->_p_xml_handle_pi_tag, "?");
24f9e82000-08-05Martin Stjernholm  else if ((tag->flags & (RXML.FLAG_COMPAT_PARSE|RXML.FLAG_EMPTY_ELEMENT)) == (RXML.FLAG_COMPAT_PARSE|RXML.FLAG_EMPTY_ELEMENT))
7dd3f82001-04-18Martin Stjernholm  add_tag (name, tag->_p_xml_handle_tag), add_container (name, 0);
24f9e82000-08-05Martin Stjernholm  else
7dd3f82001-04-18Martin Stjernholm  add_tag (name, 0), add_container (name, tag->_p_xml_handle_tag);
24f9e82000-08-05Martin Stjernholm  }
cede492000-02-15Martin Stjernholm #ifdef OLD_RXML_COMPAT
2bd21a2000-01-05Martin Stjernholm  }
4d32262000-02-20Martin Stjernholm  else
cede492000-02-15Martin Stjernholm  foreach (tlist, RXML.Tag tag)
24f9e82000-08-05Martin Stjernholm  if (!tag->plugin_name && (!tset->prefix_req || tag->flags & RXML.FLAG_NO_PREFIX)) { string name = [string] tag->name; if (tag->flags & RXML.FLAG_PROC_INSTR)
7dd3f82001-04-18Martin Stjernholm  add_quote_tag ("?" + name, tag->_p_xml_handle_pi_tag, "?");
24f9e82000-08-05Martin Stjernholm  else if (tag->flags & RXML.FLAG_EMPTY_ELEMENT)
7dd3f82001-04-18Martin Stjernholm  add_tag (name, tag->_p_xml_handle_tag), add_container (name, 0);
24f9e82000-08-05Martin Stjernholm  else
7dd3f82001-04-18Martin Stjernholm  add_tag (name, 0), add_container (name, tag->_p_xml_handle_tag);
24f9e82000-08-05Martin Stjernholm  }
cede492000-02-15Martin Stjernholm #endif
2e0a6d2000-07-06Martin Stjernholm  }
2bd21a2000-01-05Martin Stjernholm 
ca680b2001-03-01Martin Stjernholm  if (!type->entity_syntax
9f74bb2000-02-15Martin Stjernholm #ifdef OLD_RXML_COMPAT
2e0a6d2000-07-06Martin Stjernholm  && not_compat
9f74bb2000-02-15Martin Stjernholm #endif
2e0a6d2000-07-06Martin Stjernholm  )
ca680b2001-03-01Martin Stjernholm  // Don't decode normal entities if we're outputting xml-like stuff.
2e0a6d2000-07-06Martin Stjernholm  add_entities (tag_set->get_string_entities());
7f0cf22000-01-11Martin Stjernholm 
9f74bb2000-02-15Martin Stjernholm  lazy_entity_end (1); match_tag (0); splice_arg ("::");
b04dea2000-06-23Martin Stjernholm  xml_tag_syntax (2);
9f74bb2000-02-15Martin Stjernholm  #ifdef OLD_RXML_COMPAT if (not_compat) { #endif _set_entity_callback (.utils.p_xml_entity_cb);
7dd3f82001-04-18Martin Stjernholm  if (type->free_text) set_quote_tag_cbs ( .utils.return_zero, // Decode CDATA sections if the type doesn't have xml syntax. type->entity_syntax ? .utils.return_zero : .utils.p_xml_cdata_cb); else set_quote_tag_cbs ( .utils.unknown_pi_tag_error, type->handle_literals ? .utils.p_xml_cdata_cb : .utils.invalid_cdata_error);
9f74bb2000-02-15Martin Stjernholm #ifdef OLD_RXML_COMPAT } else { case_insensitive_tag (1); ignore_unknown (1); ws_before_tag_name (1); _set_entity_callback (.utils.p_xml_compat_entity_cb); } #endif
ed81751999-12-11Martin Stjernholm }
fc40392008-08-15Martin Stjernholm protected void initialize (RXML.Context ctx, RXML.Type type, RXML.PCode p_code, RXML.TagSet tag_set)
a08cd72001-06-09Martin Stjernholm {
446bfa2001-06-21Martin Stjernholm  TagSetParser::initialize (ctx, type, p_code, tag_set); if (type->sequential)
893ac12001-06-21Martin Stjernholm  if (type->empty_value == "") value = String.Buffer(); else
446bfa2001-06-21Martin Stjernholm  value = type->empty_value; else value = RXML.nil; if (p_code) alternative |= 1; else alternative &= ~1;
a08cd72001-06-09Martin Stjernholm }
fc40392008-08-15Martin Stjernholm protected mixed value;
7dd3f82001-04-18Martin Stjernholm 
446bfa2001-06-21Martin Stjernholm void add_value (mixed val)
ed81751999-12-11Martin Stjernholm {
7dd3f82001-04-18Martin Stjernholm  if (type->sequential)
9d1f862008-10-29Martin Stjernholm  // Keep one ref to value. (This is probably not necessary in // modern pikes.) value = value + (value = 0, val);
ed81751999-12-11Martin Stjernholm  else {
4c72302001-05-19Martin Stjernholm  if (value != RXML.nil)
7dd3f82001-04-18Martin Stjernholm  RXML.parse_error ( "Cannot append another value %s to non-sequential type %s.\n",
4c72302001-05-19Martin Stjernholm  .utils.format_short (val), type->name);
7dd3f82001-04-18Martin Stjernholm  value = val; } }
446bfa2001-06-21Martin Stjernholm void drain_output()
7dd3f82001-04-18Martin Stjernholm {
446bfa2001-06-21Martin Stjernholm  switch (alternative) { case FREE_TEXT: { value = value + (value = 0, low_parser::read()); // Keep one ref to value. break; } case FREE_TEXT_P_CODE: { string literal = low_parser::read(); value = value + (value = 0, literal); // Keep one ref to value.
d0dcda2001-07-20Martin Stjernholm  if (sizeof (literal)) p_code->add (context, literal, literal);
446bfa2001-06-21Martin Stjernholm  break; } case LITERALS: case LITERALS_P_CODE: if (mixed err = catch { string literal = String.trim_all_whites (low_parser::read()); if (sizeof (literal)) { mixed newval; if (type->sequential) value = value + (value = 0, newval = type->encode (literal)); else { if (value != RXML.nil) RXML.parse_error ( "Cannot append another value %s to non-sequential type %s.\n", .utils.format_short (literal), type->name); value = newval = type->encode (literal); }
d0dcda2001-07-20Martin Stjernholm  if (p_code) p_code->add (context, newval, newval);
446bfa2001-06-21Martin Stjernholm  }
6f77372002-04-03Martin Stjernholm  }) context->handle_exception (err, this_object(), p_code);
446bfa2001-06-21Martin Stjernholm  break; case NO_LITERALS: case NO_LITERALS_P_CODE: { string literal = low_parser::read(); sscanf (literal, "%[ \t\n\r]", string ws); if (literal != ws) context->handle_exception ( catch (RXML.parse_error ( "Free text %s is not allowed in context of type %s.\n",
6f77372002-04-03Martin Stjernholm  .utils.format_short (literal), type->name)), this_object(), p_code);
446bfa2001-06-21Martin Stjernholm  break;
ed81751999-12-11Martin Stjernholm  }
446bfa2001-06-21Martin Stjernholm  default: error ("Bogus alternative %d\n", alternative);
a08cd72001-06-09Martin Stjernholm  }
4c72302001-05-19Martin Stjernholm }
446bfa2001-06-21Martin Stjernholm mixed read()
4c72302001-05-19Martin Stjernholm {
446bfa2001-06-21Martin Stjernholm  if (objectp (value) && object_program (value) == String.Buffer) return value->get(); else { mixed val = value; value = RXML.nil; return val;
a08cd72001-06-09Martin Stjernholm  }
7dd3f82001-04-18Martin Stjernholm }
fc40392008-08-15Martin Stjernholm protected string errmsgs;
446bfa2001-06-21Martin Stjernholm  int output_errors()
7dd3f82001-04-18Martin Stjernholm {
446bfa2001-06-21Martin Stjernholm  if (errmsgs) { value = value + (value = 0, errmsgs); // Keep one ref to value. errmsgs = 0; }
ed81751999-12-11Martin Stjernholm }
ba32ec2000-02-13Martin Stjernholm int report_error (string msg) { if (errmsgs) errmsgs += msg; else errmsgs = msg; if (low_parser::context() != "data") _set_data_callback (.utils.output_error_cb);
446bfa2001-06-21Martin Stjernholm  else output_errors();
ba32ec2000-02-13Martin Stjernholm  return 1; }
a36ce22000-01-14Martin Stjernholm 
446bfa2001-06-21Martin Stjernholm mixed feed (string in) { return low_parser::feed (in); }
ba32ec2000-02-13Martin Stjernholm void finish (void|string in) { low_parser::finish (in);
446bfa2001-06-21Martin Stjernholm  drain_output(); output_errors();
22984d2001-06-18Martin Stjernholm  context->eval_finish();
ba32ec2000-02-13Martin Stjernholm }
9a44932000-01-07Martin Stjernholm 
c6245b1999-12-31Martin Stjernholm 
2bd21a2000-01-05Martin Stjernholm // Runtime tags.
fc40392008-08-15Martin Stjernholm protected mapping(string:TagDef) rt_replacements; protected mapping(string:QuoteTagDef) rt_pi_replacements;
2bd21a2000-01-05Martin Stjernholm 
d0cebe2000-02-17Martin Stjernholm local void add_runtime_tag (RXML.Tag tag)
c6245b1999-12-31Martin Stjernholm {
d0cebe2000-02-17Martin Stjernholm  string name = tag->name;
c6245b1999-12-31Martin Stjernholm 
24f9e82000-08-05Martin Stjernholm  if (tag->flags & RXML.FLAG_PROC_INSTR) { if (!rt_pi_replacements) rt_pi_replacements = ([]); else remove_runtime_tag (tag); if (!tag_set->prefix_req || tag->flags & RXML.FLAG_NO_PREFIX) { rt_pi_replacements[name] = quote_tags()[name];
7dd3f82001-04-18Martin Stjernholm  add_quote_tag ("?" + name, tag->_p_xml_handle_pi_tag, "?");
24f9e82000-08-05Martin Stjernholm  } if (tag_set->prefix && !(tag->flags & RXML.FLAG_NO_PREFIX)) { name = tag_set->prefix + ":" + name; rt_pi_replacements[name] = quote_tags()[name];
7dd3f82001-04-18Martin Stjernholm  add_quote_tag ("?" + name, tag->_p_xml_handle_pi_tag, "?");
24f9e82000-08-05Martin Stjernholm  } } else { if (!rt_replacements) rt_replacements = ([]); else remove_runtime_tag (tag); if (!tag_set->prefix_req || tag->flags & RXML.FLAG_NO_PREFIX) { rt_replacements[name] = ({tags()[name], containers()[name]});
d0cebe2000-02-17Martin Stjernholm #ifdef OLD_RXML_COMPAT
24f9e82000-08-05Martin Stjernholm  if (not_compat)
d0cebe2000-02-17Martin Stjernholm #endif
24f9e82000-08-05Martin Stjernholm  if ((tag->flags & (RXML.FLAG_COMPAT_PARSE|RXML.FLAG_EMPTY_ELEMENT)) == (RXML.FLAG_COMPAT_PARSE|RXML.FLAG_EMPTY_ELEMENT))
7dd3f82001-04-18Martin Stjernholm  add_tag (name, tag->_p_xml_handle_tag), add_container (name, 0);
24f9e82000-08-05Martin Stjernholm  else
7dd3f82001-04-18Martin Stjernholm  add_tag (name, 0), add_container (name, tag->_p_xml_handle_tag);
d0cebe2000-02-17Martin Stjernholm #ifdef OLD_RXML_COMPAT else
24f9e82000-08-05Martin Stjernholm  if (tag->flags & RXML.FLAG_EMPTY_ELEMENT)
7dd3f82001-04-18Martin Stjernholm  add_tag (name, tag->_p_xml_handle_tag), add_container (name, 0);
24f9e82000-08-05Martin Stjernholm  else
7dd3f82001-04-18Martin Stjernholm  add_tag (name, 0), add_container (name, tag->_p_xml_handle_tag);
d0cebe2000-02-17Martin Stjernholm #endif
24f9e82000-08-05Martin Stjernholm  }
2bd21a2000-01-05Martin Stjernholm 
24f9e82000-08-05Martin Stjernholm  if (tag_set->prefix && !(tag->flags & RXML.FLAG_NO_PREFIX)) { name = tag_set->prefix + ":" + name; rt_replacements[name] = ({tags()[name], containers()[name]});
d0cebe2000-02-17Martin Stjernholm #ifdef OLD_RXML_COMPAT
24f9e82000-08-05Martin Stjernholm  if (not_compat)
d0cebe2000-02-17Martin Stjernholm #endif
24f9e82000-08-05Martin Stjernholm  if ((tag->flags & (RXML.FLAG_COMPAT_PARSE|RXML.FLAG_EMPTY_ELEMENT)) == (RXML.FLAG_COMPAT_PARSE|RXML.FLAG_EMPTY_ELEMENT))
7dd3f82001-04-18Martin Stjernholm  add_tag (name, tag->_p_xml_handle_tag), add_container (name, 0);
24f9e82000-08-05Martin Stjernholm  else
7dd3f82001-04-18Martin Stjernholm  add_tag (name, 0), add_container (name, tag->_p_xml_handle_tag);
d0cebe2000-02-17Martin Stjernholm #ifdef OLD_RXML_COMPAT else
24f9e82000-08-05Martin Stjernholm  if (tag->flags & RXML.FLAG_EMPTY_ELEMENT)
7dd3f82001-04-18Martin Stjernholm  add_tag (name, tag->_p_xml_handle_tag), add_container (name, 0);
24f9e82000-08-05Martin Stjernholm  else
7dd3f82001-04-18Martin Stjernholm  add_tag (name, 0), add_container (name, tag->_p_xml_handle_tag);
d0cebe2000-02-17Martin Stjernholm #endif
24f9e82000-08-05Martin Stjernholm  }
2bd21a2000-01-05Martin Stjernholm  } }
24f9e82000-08-05Martin Stjernholm local void remove_runtime_tag (string|RXML.Tag tag, void|int proc_instr)
2bd21a2000-01-05Martin Stjernholm {
24f9e82000-08-05Martin Stjernholm  int no_prefix = 0; if (!stringp (tag)) { proc_instr = tag->flags & RXML.FLAG_PROC_INSTR; no_prefix = tag->flags & RXML.FLAG_NO_PREFIX; tag = tag->name;
c6245b1999-12-31Martin Stjernholm  }
ed81751999-12-11Martin Stjernholm 
24f9e82000-08-05Martin Stjernholm  if (proc_instr) { if (!stringp (tag)) { tag = tag->name; no_prefix = tag->flags & RXML.FLAG_NO_PREFIX; }
2bd21a2000-01-05Martin Stjernholm 
24f9e82000-08-05Martin Stjernholm  if (!tag_set->prefix_req || no_prefix)
7dd3f82001-04-18Martin Stjernholm  if (TagDef def = rt_pi_replacements && rt_pi_replacements[tag]) {
24f9e82000-08-05Martin Stjernholm  m_delete (rt_pi_replacements, tag); add_quote_tag ("?" + tag, def, "?"); } if (tag_set->prefix && !no_prefix)
7dd3f82001-04-18Martin Stjernholm  if (TagDef def = rt_pi_replacements[tag = tag_set->prefix + ":" + tag]) {
24f9e82000-08-05Martin Stjernholm  m_delete (rt_pi_replacements, tag); add_quote_tag ("?" + tag, def, "?"); } }
2bd21a2000-01-05Martin Stjernholm 
24f9e82000-08-05Martin Stjernholm  else { if (!tag_set->prefix_req || no_prefix)
7dd3f82001-04-18Martin Stjernholm  if (TagDef def = rt_replacements && rt_replacements[tag]) {
24f9e82000-08-05Martin Stjernholm  m_delete (rt_replacements, tag); add_tag (tag, def[0]), add_container (tag, def[1]); } if (tag_set->prefix && !no_prefix)
8480582001-08-13Martin Stjernholm  if (TagDef def = rt_replacements && rt_replacements[tag = tag_set->prefix + ":" + tag]) {
24f9e82000-08-05Martin Stjernholm  m_delete (rt_replacements, tag); add_tag (tag, def[0]), add_container (tag, def[1]);
840ba52000-01-10Martin Stjernholm  }
2bd21a2000-01-05Martin Stjernholm  } }
f49c402000-01-08Martin Stjernholm 
da0c882000-03-18Martin Stjernholm #if defined (OBJ_COUNT_DEBUG) || defined (RXML_OBJ_DEBUG)
fc40392008-08-15Martin Stjernholm protected int master_parser; protected string _sprintf()
da0c882000-03-18Martin Stjernholm {
f232d02000-09-08Martin Stjernholm  return sprintf ("RXML.PXml(%s,%O,%O)%s", master_parser ? "master" : "clone", type, tag_set,
da0c882000-03-18Martin Stjernholm  __object_marker ? "[" + __object_marker->count + "]" : ""); }
26ff092000-01-21Martin Stjernholm #else
fc40392008-08-15Martin Stjernholm protected string _sprintf()
da0c882000-03-18Martin Stjernholm {
f232d02000-09-08Martin Stjernholm  return sprintf ("RXML.PXml(%O,%O)", type, tag_set);
da0c882000-03-18Martin Stjernholm }
26ff092000-01-21Martin Stjernholm #endif