Branch: Tag:

2001-04-18

2001-04-18 04:51:42 by Martin Stjernholm <mast@lysator.liu.se>

Added feature to let types parse literal values. Added the type t_type.
Don't glob on the type name to decide subtype relationships. Somewhat
better error messages. Cleaned up the PXml specific callbacks in Tag and
Parser. Fixed bug with leftover frame when an error is thrown during
argument parsing.

Rev: server/etc/modules/RXML.pmod/PEnt.pike:1.20
Rev: server/etc/modules/RXML.pmod/PXml.pike:1.54
Rev: server/etc/modules/RXML.pmod/module.pmod:1.148
Rev: server/etc/modules/RXML.pmod/refs.pmod:1.9
Rev: server/etc/modules/RXML.pmod/utils.pmod:1.20

7:   //!   //! Created 2000-01-21 by Martin Stjernholm   //! - //! $Id: utils.pmod,v 1.19 2001/03/23 22:49:43 mast Exp $ + //! $Id: utils.pmod,v 1.20 2001/04/18 04:51:42 mast Exp $       - array return_zero (mixed... ignored) {return 0;} - array return_empty_array (mixed... ignored) {return ({});} + final string format_short (mixed val) + { +  if (stringp (val)) +  if (sizeof (val) <= 30) +  return sprintf ("%O", val); +  else +  return sprintf ("%O/.../", val[..29]); +  else { +  val = sprintf ("%O", val); +  if (sizeof (val) <= 30) +  return val; +  else +  return val[..29] + "/.../"; +  } + }    - int(1..1)|string|array free_text_error (Parser.HTML p, string str) + final array return_zero (mixed... ignored) {return 0;} + final array return_empty_array (mixed... ignored) {return ({});} +  + final int(1..1)|string|array free_text_error (object/*(RMXL.PXml)*/ p, string str)   {    sscanf (str, "%[ \t\n\r]", string ws); -  if (str != ws) { -  sscanf (reverse (str), "%*[ \t\n\r]%s", str); -  sscanf (reverse (str), "%*[ \t\n\r]%s", str); -  RXML.parse_error ("Free text %O is not allowed in %s context.\n", str, p->type->name); +  if (str != ws) +  RXML.parse_error ("Free text %s is not allowed in context of type %s.\n", +  format_short (String.trim_all_whites (str)), p->type->name); +  return ({});   } -  +  + final int(1..1)|string|array unknown_tag_error (object/*(RMXL.PXml)*/ p, string str) + { +  RXML.parse_error ("Unknown tag %s is not allowed in context of type %s.\n", +  format_short (p->tag_name()), p->type->name);    return ({});   }    - int(1..1)|string|array unknown_tag_error (Parser.HTML p, string str) + final int(1..1)|string|array unknown_pi_tag_error (object/*(RMXL.PXml)*/ p, string str)   { -  RXML.parse_error ("Unknown tag %O. Unknown tags are not " -  "allowed in %s context.\n", p->tag_name(), p->type->name); +  sscanf (str, "%[^ \t\n\r]", str); +  RXML.parse_error ( +  "Unknown processing instruction %s not allowed in context of type %s.\n", +  format_short ("<" + p->tag_name() + str), p->type->name);    return ({});   }    - int(1..1)|string|array output_error_cb (Parser.HTML p, string str) + final int(1..1)|string|array invalid_cdata_error (object/*(RXML.PXml)*/ p, string str)   { -  +  RXML.parse_error ("CDATA text %O is not allowed in context of type %s.\n", +  format_short (str), p->type->name); +  return ({}); + } +  + final int(1..1)|string|array output_error_cb (object/*(RMXL.PXml)*/ p, string str) + {    if (p->errmsgs) str = p->errmsgs + str, p->errmsgs = 0;    if (p->type->free_text) p->_set_data_callback (0);    else p->_set_data_callback (free_text_error);
42:      // PXml and PEnt callbacks.    - int(1..1)|string|array p_xml_comment_cb (Parser.HTML p, string str) + final int(1..1)|string|array p_xml_comment_cb (object/*(RXML.PXml)*/ p, string str)   // FIXME: This is a kludge until quote tags are handled like other tags.   { -  +  if (p->type->handle_literals) p->handle_literal();    string name = p->parse_tag_name (str);    if (sizeof (name)) {    name = p->tag_name() + name;
63:    return p->type->free_text ? 0 : ({});   }    - int(1..1)|string|array p_xml_entity_cb (Parser.HTML p, string str) + final int(1..1)|string|array p_xml_cdata_cb (object/*(RXML.PXml)*/ p, string str)   { -  +  return ({str}); + } +  + final int(1..1)|string|array p_xml_entity_cb (object/*(RXML.PXml)*/ p, string str) + { +  RXML.Type type = p->type;    string entity = p->tag_name(); -  if (sizeof (entity)) { -  if (entity[0] != '#') -  return p->handle_var (entity, -  p->html_context() == "splice_arg" ? -  // No quoting of splice args. FIXME: Add -  // some sort of safeguard against splicing -  // in things like "nice><evil stuff='...'"? -  RXML.t_string : -  p->type); +  if (sizeof (entity)) +  if (entity[0] == '#') {    if (!p->type->entity_syntax) {    // Don't decode normal entities if we're outputting xml-like stuff. -  if (!p->type->free_text) -  RXML.parse_error ("Unknown entity &%s; not allowed in this context.\n", entity); +     if (sscanf (entity,    (<"#x", "#X">)[entity[..1]] ? "%*2s%x%*c" : "%*c%d%*c",    int char) == 2) -  catch {return ({(string) ({char})});}; +  catch (str = (string) ({char}));    // Lax error handling: Just let it through if it can't be    // converted. Not really good, though.    }    } -  if (!p->type->free_text) -  RXML.parse_error ("Unknown entity &%s; not allowed in this context.\n", entity); -  return 0; +  else +  if (entity[0] == ':') str = entity[1..]; +  else if (has_value (entity, ".")) { +  if (type->handle_literals) p->handle_literal(); +  mixed value = p->handle_var ( +  entity, +  // No quoting of splice args. FIXME: Add some sort of +  // safeguard against splicing in things like "nice><evil +  // stuff='...'"? +  p->html_context() == "splice_arg" ? RXML.t_string : type); +  if (value != RXML.nil) { +  if (type->free_text) return ({value}); +  p->add_value (value);    } -  +  return ({}); +  } +  if (!type->free_text) +  RXML.parse_error ("Unknown entity \"&%s;\" not allowed context of type %s.\n", +  entity, type->name); +  return ({str}); + }    - int(1..1)|string|array p_xml_compat_entity_cb (Parser.HTML p, string str) + final int(1..1)|string|array p_xml_compat_entity_cb (object/*(RMXL.PXml)*/ p, string str)   { -  +  RXML.Type type = p->type;    string entity = p->tag_name();    if (sizeof (entity) && entity[0] != '#') -  return p->handle_var (entity, -  p->html_context() == "splice_arg" ? -  // No quoting of splice args. FIXME: Add -  // some sort of safeguard against splicing -  // in things like "nice><evil stuff='...'"? -  RXML.t_string : -  p->type); -  if (!p->type->free_text) -  RXML.parse_error ("Unknown entity &%s; not allowed in this context.\n", entity); -  return 0; +  if (entity[0] == ':') str = entity[1..]; +  else if (has_value (entity, ".")) { +  if (type->handle_literals) p->handle_literal(); +  mixed value = p->handle_var ( +  entity, +  // No quoting of splice args. FIXME: Add some sort of +  // safeguard against splicing in things like "nice><evil +  // stuff='...'"? +  p->html_context() == "splice_arg" ? RXML.t_string : p->type); +  if (value != RXML.nil) { +  if (type->free_text) return ({value}); +  p->add_value (value);    } -  +  return ({}); +  } +  if (!type->free_text) +  RXML.parse_error ("Unknown entity \"&%s;\" not allowed in context of type %s.\n", +  entity, type->name); +  return ({str}); + }