23a0882000-08-12Martin Stjernholm //! Things that belong elsewhere but can't lie there for various silly //! reasons. Everything here is considered internal and not part of //! the RXML.pmod API.
26ff092000-01-21Martin Stjernholm //! //! E.g. one reason is to avoid circular references in the parser //! objects when the callbacks are defined in them. //! //! Created 2000-01-21 by Martin Stjernholm //!
7dd3f82001-04-18Martin Stjernholm //! $Id: utils.pmod,v 1.20 2001/04/18 04:51:42 mast Exp $
26ff092000-01-21Martin Stjernholm 
7dd3f82001-04-18Martin Stjernholm 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] + "/.../"; } }
26ff092000-01-21Martin Stjernholm 
7dd3f82001-04-18Martin Stjernholm 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)
ea3bfd2000-02-13Martin Stjernholm { sscanf (str, "%[ \t\n\r]", string ws);
7dd3f82001-04-18Martin Stjernholm  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);
ea3bfd2000-02-13Martin Stjernholm  return ({}); }
7dd3f82001-04-18Martin Stjernholm final int(1..1)|string|array unknown_tag_error (object/*(RMXL.PXml)*/ p, string str)
9265b52000-02-11Martin Stjernholm {
7dd3f82001-04-18Martin Stjernholm  RXML.parse_error ("Unknown tag %s is not allowed in context of type %s.\n", format_short (p->tag_name()), p->type->name);
9265b52000-02-11Martin Stjernholm  return ({}); }
7dd3f82001-04-18Martin Stjernholm final int(1..1)|string|array unknown_pi_tag_error (object/*(RMXL.PXml)*/ p, string str) { 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 ({}); } 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)
f9dcf62000-02-13Martin Stjernholm { 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); return ({str}); }
26ff092000-01-21Martin Stjernholm 
9f74bb2000-02-15Martin Stjernholm // PXml and PEnt callbacks.
26ff092000-01-21Martin Stjernholm 
7dd3f82001-04-18Martin Stjernholm final int(1..1)|string|array p_xml_comment_cb (object/*(RXML.PXml)*/ p, string str)
b1c1d32000-03-06Martin Stjernholm // FIXME: This is a kludge until quote tags are handled like other tags. {
7dd3f82001-04-18Martin Stjernholm  if (p->type->handle_literals) p->handle_literal();
5eef022000-03-06Martin Stjernholm  string name = p->parse_tag_name (str);
b1c1d32000-03-06Martin Stjernholm  if (sizeof (name)) { name = p->tag_name() + name; if (string|array|function tdef = p->tags()[name]) { if (stringp (tdef)) return ({tdef}); else if (arrayp (tdef)) return tdef[0] (p, p->parse_tag_args (str), @tdef[1..]); else return tdef (p, p->parse_tag_args (str)); } else if (p->containers()[name]) RXML.parse_error ("Sorry, can't handle containers beginning with " + p->tag_name() + ".\n"); } return p->type->free_text ? 0 : ({}); }
7dd3f82001-04-18Martin Stjernholm 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)
26ff092000-01-21Martin Stjernholm {
7dd3f82001-04-18Martin Stjernholm  RXML.Type type = p->type;
26ff092000-01-21Martin Stjernholm  string entity = p->tag_name();
7dd3f82001-04-18Martin Stjernholm  if (sizeof (entity)) if (entity[0] == '#') { if (!p->type->entity_syntax) { // Don't decode normal entities if we're outputting xml-like stuff. if (sscanf (entity, (<"#x", "#X">)[entity[..1]] ? "%*2s%x%*c" : "%*c%d%*c", int char) == 2) catch (str = (string) ({char})); // Lax error handling: Just let it through if it can't be // converted. Not really good, though. }
26ff092000-01-21Martin Stjernholm  }
7dd3f82001-04-18Martin Stjernholm  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});
26ff092000-01-21Martin Stjernholm }
7dd3f82001-04-18Martin Stjernholm final int(1..1)|string|array p_xml_compat_entity_cb (object/*(RMXL.PXml)*/ p, string str)
26ff092000-01-21Martin Stjernholm {
7dd3f82001-04-18Martin Stjernholm  RXML.Type type = p->type;
26ff092000-01-21Martin Stjernholm  string entity = p->tag_name();
b8e84a2000-03-04Martin Stjernholm  if (sizeof (entity) && entity[0] != '#')
7dd3f82001-04-18Martin Stjernholm  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});
26ff092000-01-21Martin Stjernholm }