Roxen.git / server / etc / modules / RXML.pmod / module.pmod

version» Context lines:

Roxen.git/server/etc/modules/RXML.pmod/module.pmod:1: - //! RXML parser and compiler framework. - //! - //! Created 1999-07-30 by Martin Stjernholm. - //! - //! $Id: module.pmod,v 1.148 2001/04/18 04:51:40 mast Exp $ + // $Id: module.pmod,v 1.149 2001/04/19 12:08:27 jhs Exp $    - //! Kludge: Must use "RXML.refs" somewhere for the whole module to be - //! loaded correctly. + // Kludge: Must use "RXML.refs" somewhere for the whole module to be + // loaded correctly.   static object Roxen;   class RequestID { };    -  + //(!) FIXME: This was not legal autodoc; do we need some form of markup + //(!) to do what it tried to do? I'm not sure I fully understand what the + //(!) (now) (!) marked lines were meant to do; if it's just a comment + //(!) worth reading when browsing the source, please remove this and turn + //(!) these comments into normal "//" comments. / jhs +  + //! RXML parser and compiler framework. + //! + //! Created 1999-07-30 by Martin Stjernholm. + //!   //! API stability notes:   //!   //! The API in this file regarding the global functions and the Tag,   //! TagSet, Context, Frame and Type classes and their descendants is   //! intended to not change in incompatible ways. There are however   //! some areas where incompatible changes still must be expected:   //! - //! o The namespace handling will likely change to conform to XML - //! namespaces. The currently implemented system is inadequate then - //! and will probably be removed. + //! @list ul + //! @item + //! The namespace handling will likely change to conform to XML + //! namespaces. The currently implemented system is inadequate then + //! and will probably be removed. + //! @item + //! The semantics for caching and reuse of Frame objects is + //! deliberatily documented vaguely (see the class doc for the + //! Frame class). The currently implemented behavior will change + //! when the cache system becomes reality. So never assume that + //! you'll always get fresh Frame instances every time a tag is + //! evaluated. + //! @item + //! The parser currently doesn't stream data according to the + //! interface for streaming tags (but the implementation still + //! follows the documented API for it). Therefore there's a risk + //! that incompatible changes must be made in it due to design bugs + //! when it's tested out. That is considered very unlikely, though. + //! @item + //! The type system will be developed further, and the API in the + //! Type class might change as advanced types gets implemented. + //! Don't make assumptions about undocumented behavior. Declare + //! data properly with the types RXML.t_xml, RXML.t_html and + //! RXML.t_text to let the parser handle the necessary conversions + //! instead of doing it yourself. Try to avoid implementing types. + //! @item + //! Various utilities have FIXME's in their documentation. Needless + //! to say they don't work as documented yet, and the doc should be + //! considered as ideas only; it might work differently when it's + //! actually implemented. + //! @endlist   //! - //! o The semantics for caching and reuse of Frame objects is - //! deliberatily documented vaguely (see the class doc for the - //! Frame class). The currently implemented behavior will change - //! when the cache system becomes reality. So never assume that - //! you'll always get fresh Frame instances every time a tag is - //! evaluated. - //! - //! o The parser currently doesn't stream data according to the - //! interface for streaming tags (but the implementation still - //! follows the documented API for it). Therefore there's a risk - //! that incompatible changes must be made in it due to design bugs - //! when it's tested out. That is considered very unlikely, though. - //! - //! o The type system will be developed further, and the API in the - //! Type class might change as advanced types gets implemented. - //! Don't make assumptions about undocumented behavior. Declare - //! data properly with the types RXML.t_xml, RXML.t_html and - //! RXML.t_text to let the parser handle the necessary conversions - //! instead of doing it yourself. Try to avoid implementing types. - //! - //! o Various utilities have FIXME's in their documentation. Needless - //! to say they don't work as documented yet, and the doc should be - //! considered as ideas only; it might work differently when it's - //! actually implemented. - //! - //! Note that the API for parsers, p-code evaluators etc is not part - //! of the "official" API. (The syntax _parsed_ by the currently - //! implemented parsers is well defined, of course.) + //! @note + //! The API for parsers, p-code evaluators etc is not part of the + //! "official" API. (The syntax _parsed_ by the currently implemented + //! parsers is well defined, of course.)      //#pragma strict_types // Disabled for now since it doesn't work well enough.      #include <config.h>   #include <request_trace.h>      #ifdef RXML_OBJ_DEBUG   # define MARK_OBJECT \    Debug.ObjectMarker __object_marker = Debug.ObjectMarker (this_object())   # define MARK_OBJECT_ONLY \
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:93:   // Use defines since typedefs doesn't work in soft casts yet.   #define SCOPE_TYPE mapping(string:mixed)|object(Scope)   #define UNWIND_STATE mapping(string:mixed)|mapping(object:array)         class Tag   //! Interface class for the static information about a tag.   {    constant is_RXML_Tag = 1;    -  //! Interface. +  //(!) Interface:    -  //!string name; -  //! The name of the tag. Required and considered constant. +  //! @decl string name; +  //! The name of the tag. Required and considered constant.       /*extern*/ int flags;    //! Various bit flags that affect parsing; see the FLAG_* constants.    //! RXML.Frame.flags is initialized from this.       mapping(string:Type) req_arg_types = ([]);    mapping(string:Type) opt_arg_types = ([]);    //! The names and types of the required and optional arguments. If a    //! type specifies a parser, it'll be used on the argument value.    //! Note that the order in which arguments are parsed is arbitrary.
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:141:    //!    //! When the tag is used in content of some type, the content type    //! may be a supertype of any type in @[result_types], but it may    //! also be a subtype of any of them. The tag must therefore be    //! prepared to produce result of more specific types than those    //! declared here. I.e. the extreme case, @[RXML.t_any], means that    //! this tag takes the responsibility to produce result of any type    //! that's asked for, not that it has the liberty to produce results    //! of any type it chooses.    -  //!program Frame; -  //!object(Frame) Frame(); +  //! @decl program Frame; +  //! @decl object(Frame) Frame();    //! This program/function is used to clone the objects used as    //! frames. A frame object must (in practice) inherit RXML.Frame.    //! (It can, of course, be any function that requires no arguments    //! and returns a new frame object.) This is not used for plugin    //! tags.    -  //!string plugin_name; +  //! @decl string plugin_name;    //! If this is defined, this is a so-called plugin tag. That means    //! it plugs in some sort of functionality in another Tag object    //! instead of handling the actual tags of its own. It works as    //! follows:    //! -  //! o Instead of installing the callbacks for this tag, the parser -  //! uses another registered "socket" Tag object that got the same -  //! name as this one. Socket tags have the FLAG_SOCKET_TAG flag -  //! set to signify that they accept plugins. +  //! @list ul +  //! @item +  //! Instead of installing the callbacks for this tag, the parser +  //! uses another registered "socket" Tag object that got the same +  //! name as this one. Socket tags have the FLAG_SOCKET_TAG flag +  //! set to signify that they accept plugins. +  //! @item +  //! When the socket tag is parsed or evaluated, it can get the +  //! Tag objects for the registered plugins with the function +  //! Frame.get_plugins(). It's then up to the socket tag to use +  //! the plugins according to some API it defines. +  //! @item +  //! plugin_name is the name of the plugin. It's used as index in +  //! the mapping that the Frame.get_plugins() returns. +  //! @item +  //! The plugin tag is registered in the tag set with the +  //! identifier @code{name + "#" + plugin_name@}.    //! -  //! o When the socket tag is parsed or evaluated, it can get the -  //! Tag objects for the registered plugins with the function -  //! Frame.get_plugins(). It's then up to the socket tag to use -  //! the plugins according to some API it defines. +  //! It overrides other plugin tags with that name according to +  //! the normal tag set rules, but, as said above, is never +  //! registered for actual parsing at all.    //! -  //! o plugin_name is the name of the plugin. It's used as index in -  //! the mapping that the Frame.get_plugins() returns. -  //! -  //! o The plugin tag is registered in the tag set with the -  //! identifier -  //! -  //! name + "#" + plugin_name -  //! -  //! It overrides other plugin tags with that name according to -  //! the normal tag set rules, but, as said above, is never -  //! registered for actual parsing at all. -  //! -  //! It's undefined whether plugin tags override normal tags -- -  //! '#' should never be used in normal tag names. -  //! -  //! o It's not an error to register a plugin for which there is no -  //! socket. Such plugins are simply ignored. +  //! It's undefined whether plugin tags override normal tags -- +  //! '#' should never be used in normal tag names. +  //! @item +  //! It's not an error to register a plugin for which there is no +  //! socket. Such plugins are simply ignored. +  //! @endlist    -  //! Services. +  //(!) Services:       inline final object/*(Frame)HMM*/ `() (mapping(string:mixed) args, void|mixed content)    //! Make an initialized frame for the tag. Typically useful when    //! returning generated tags from e.g. RXML.Frame.do_process(). The    //! argument values and the content are normally not parsed.    {    Tag this = this_object();    object/*(Frame)HMM*/ frame = ([function(:object/*(Frame)HMM*/)] this->Frame)();    frame->tag = this;    frame->flags = flags;
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:237: Inside #if defined(MODULE_DEBUG)
  #ifdef MODULE_DEBUG    }) {    if (objectp (err) && ([object] err)->thrown_at_unwind)    fatal_error ("Can't save parser state when evaluating arguments.\n");    throw_fatal (err);    }   #endif    return 1;    }    -  // Internals. +  //(!) Internals:      #define MAKE_FRAME(frame, ctx, parser, args) \    make_new_frame: do { \    if (UNWIND_STATE ustate = ctx->unwind_state) \    if (ustate[parser]) { \    frame = [object/*(Frame)HMM*/] ustate[parser][0]; \    m_delete (ustate, parser); \    if (!sizeof (ustate)) ctx->unwind_state = 0; \    break make_new_frame; \    } \
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:409:      class TagSet   //! Contains a set of tags. Tag sets can import other tag sets, and   //! later changes are propagated. Parser instances (contexts) to parse   //! data are created from this. TagSet objects may somewhat safely be   //! destructed explicitly; the tags in a destructed tag set will not   //! be active in parsers that are instantiated later, but will work in   //! current instances. Element (i.e. non-PI) tags and PI tags have   //! separate namespaces.   //! - //! Note: A Tag object may not be registered in more than one tag set - //! at the same time. + //! @note + //! A Tag object may not be registered in more than one tag set at the + //! same time.   {    string name;    //! Used for identification only.       string prefix;    //! A namespace prefix that may precede the tags. If it's zero, it's    //! up to the importing tag set(s). A ':' is always inserted between    //! the prefix and the tag name.       int prefix_req;
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:702:    {    generation++;    prepare_funs = 0;    overridden_tag_lookup = 0;    plugins = pi_plugins = 0;    (notify_funcs -= ({0}))();    set_weak_flag (notify_funcs, 1);    got_local_tags = sizeof (tags) || (proc_instrs && sizeof (proc_instrs));    }    -  // Internals. +  //(!) Internals:       void do_notify (function(:void) func)    {    notify_funcs |= ({func});    set_weak_flag (notify_funcs, 1);    }       void dont_notify (function(:void) func)    {    notify_funcs -= ({func});
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:856:    //! and @[scope_name] are set to where this @[Value] object was    //! found. Note that @[scope_name] can be on the form    //! @tt{scope.index1.index2...@} when this object was encountered    //! through subindexing. Either @[RXML.nil] or the undefined value    //! may be returned if the variable doesn't have a value.    //!    //! If the @[type] argument is given, it's the type the returned    //! value should have. If the value can't be converted to that type,    //! an RXML error should be thrown. If you don't want to do any    //! special handling of this, it's enough to call -  //! @tt{@[type]->encode(value)@}, since the encode functions does +  //! @code{@[type]->encode(value)@}, since the encode functions does    //! just that.    //!    //! Some design discussion follows to justify the last paragraph;    //! there are no more interface rules below.    //!    //! It may seem like forcing a lot of overhead upon the    //! implementations having to call encode functions, but that's    //! really not the case. In the case when a type check and    //! conversion is wanted, i.e. when @[type] isn't zero, that work    //! have to be done somewhere anyway, so letting the producer of the
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:888:    //! @endexample    //!    //! Also, by letting the producer know the type context of the value    //! and handle the type conversion, it's possible for the producer    //! to adapt the value according to the context it'll be used in,    //! e.g. to return a powerful object if no type conversion is    //! wanted, a simple text representation of it when the type is    //! @[RXML.t_text], and a more nicely formatted representation when    //! it's @[RXML.t_html].    //! -  //! @note The @[type] argument being @tt{void|Type@} means that the -  //! caller is free to leave out that argument, not that the function +  //! @note +  //! The @[type] argument being @tt{void|Type@} means that the caller +  //! is free to leave out that argument, not that the function    //! implementor is free to ignore it.    {    mixed val = rxml_const_eval (ctx, var, scope_name, type);    ctx->set_var(var, val, scope_name);    return val;    }       mixed rxml_const_eval (Context ctx, string var, string scope_name, void|Type type);    //! If the variable value is the same throughout the life of the    //! context, this method should be used instead of @[rxml_var_eval].       string _sprintf() {return "RXML.Value";}   }      class Scope   //! Interface for objects that emulate a scope mapping.   //! - //! Note that the @tt{scope_name@} argument to the functions can be on - //! the form @tt{scope.index1.index2...@} when this object was - //! encountered through subindexing. + //! @note + //! The @tt{scope_name@} argument to the functions can be on the form + //! @tt{scope.index1.index2...@} when this object was encountered + //! through subindexing.   {    mixed `[] (string var, void|Context ctx,    void|string scope_name, void|Type type)    //! Called to get the value of a variable in the scope. @[var] is    //! the name of it, @[ctx] and @[scope_name] are set to where this    //! @[Scope] object was found. Either @[RXML.nil] or the undefined    //! value may be returned if the variable doesn't exist in the    //! scope.    //!    //! If the @[type] argument is given, it's the type the returned    //! value should have, unless it's an object which implements    //! @[Value.rxml_var_eval]. If the value can't be converted to that    //! type, an RXML error should be thrown. If you don't want to do    //! any special handling of this, it's enough to call    //! @tt{@[type]->encode(value)@}, since the encode functions does    //! just that. See @[Value.rxml_var_eval] for more discussion about    //! this.    //! -  //! @note The @[type] argument being @tt{void|Type@} means that the -  //! caller is free to leave out that argument, not that the function +  //! @note +  //! The @[type] argument being @tt{void|Type@} means that the caller +  //! is free to leave out that argument, not that the function    //! implementor is free to ignore it.    {parse_error ("Cannot query variable" + _in_the_scope (scope_name) + ".\n");}       mixed `[]= (string var, mixed val, void|Context ctx, void|string scope_name)    //! Called to set the value of a variable in the scope. @[var] is    //! the name of it, @[ctx] and @[scope_name] are set to where this    //! @[Scope] object was found.    //!    //! An RXML error may be thrown if the value is not acceptable for    //! the variable. It's undefined what happens if a variable is set
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:984:    }       string _sprintf() {return "RXML.Scope";}   }      class Context   //! A parser context. This contains the current variable bindings and   //! so on. The current context can always be retrieved with   //! get_context().   //! - //! Note: Don't store pointers to this object since that will likely + //! @note + //! Don't store pointers to this object since that will likely   //! introduce circular references. It can be retrieved easily through   //! get_context() or parser->context.   {    Frame frame;    //! The currently evaluating frame.       int frame_depth;    //! Number of frames currently on the frame stack.       int max_frame_depth = 100;
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:1014:    //! Number of RXML errors that has occurred.       TagSet tag_set;    //! The current tag set that will be inherited by subparsers.      #ifdef OLD_RXML_COMPAT    int compatible_scope = 0;    //! If set, the user_*_var functions access the variables in the    //! scope "form" by default, and there's no subindex splitting or    //! ".." decoding is done (see parse_user_var). +  //! @note +  //! This is only present when the OLD_RXML_COMPAT define is set.   #endif       array(string|int) parse_user_var (string var, void|string|int scope_name)    //! Parses the var string for scope and/or subindexes according to    //! the RXML rules, e.g. "scope.var.1.foo". Returns an array where    //! the first entry is the scope, and the remaining entries are the    //! list of indexes. If scope_name is a string, it's used as the    //! scope and the var string is only used for subindexes. A default    //! scope is chosen as appropriate if var cannot be split, unless    //! scope_name is a nonzero integer in which case it's returned in
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:1070:    return splitted;    }       local mixed get_var (string|array(string|int) var, void|string scope_name,    void|Type want_type)    //! Returns the value a variable in the specified scope, or the    //! current scope if none is given. Returns zero with zero_type 1 if    //! there's no such variable (or it's nil).    //!    //! If var is an array, it's used to successively index the value to -  //! get subvalues (see rxml_index for details). +  //! get subvalues (see @[rxml_index()] for details).    //!    //! If the want_type argument is set, the result value is converted    //! to that type with Type.encode(). If the value can't be    //! converted, an RXML error is thrown.    {   #ifdef MODULE_DEBUG    if (arrayp (var) ? !sizeof (var) : !stringp (var))    error ("Invalid variable specifier.\n");   #endif    if (!scope_name) scope_name = "_";
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:1102:    if(!var || !sizeof(var)) return ([])[0];    array(string|int) splitted = parse_user_var (var, scope_name);    return get_var (splitted[1..], splitted[0], want_type);    }       local mixed set_var (string|array(string|int) var, mixed val, void|string scope_name)    //! Sets the value of a variable in the specified scope, or the    //! current scope if none is given. Returns val.    //!    //! If var is an array, it's used to successively index the value to -  //! get subvalues (see rxml_index for details). +  //! get subvalues (see @[rxml_index()] for details).    {   #ifdef MODULE_DEBUG    if (arrayp (var) ? !sizeof (var) : !stringp (var))    error ("Invalid variable specifier.\n");   #endif       if (!scope_name) scope_name = "_";    if (SCOPE_TYPE vars = scopes[scope_name]) {    string|int index;    if (arrayp (var))
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:1369:    else    msg = err->msg;    if (evaluator->report_error (msg))    return;    }    throw (err);    }    else throw_fatal (err);    }    -  // Internals. +  //(!) Internals:       string current_var;    // Used to get the parsed variable into the RXML error backtrace.       Parser new_parser (Type top_level_type)    // Returns a new parser object to start parsing with this context.    // Normally TagSet.`() should be used instead of this.    {   #ifdef MODULE_DEBUG    if (in_use || frame) fatal_error ("Context already in use.\n");
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:1608:    switch (i) {    case 0: return describe_rxml_backtrace();    case 1: return backtrace;    }    }       string _sprintf() {return "RXML.Backtrace(" + (type || "") + ")";}   }       - //! Current context. + //(!) Current context:    - //! It's set before any function in RXML.Tag or RXML.Frame is called. + //(!) It's set before any function in RXML.Tag or RXML.Frame is called.      #if constant (thread_create)   private Thread.Local _context = Thread.Local();   local void set_context (Context ctx) {_context->set (ctx);}   local Context get_context() {return [object(Context)] _context->get();}   #else   private Context _context;   local void set_context (Context ctx) {_context = ctx;}   local Context get_context() {return _context;}   #endif
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:1652:   #define ENTER_CONTEXT(ctx) \    Context __old_ctx = get_context(); \    set_context (ctx);      #define LEAVE_CONTEXT() \    set_context (__old_ctx);      #endif       - //! Constants for the bit field RXML.Frame.flags. + //(!) Constants for the bit field RXML.Frame.flags.      constant FLAG_NONE = 0x00000000;   //! The no-flags flag. In case you think 0 is too ugly. ;)      constant FLAG_DEBUG = 0x40000000;   //! Write a lot of debug during the execution of the tag, showing what   //! type conversions are done, what callbacks are being called etc.   //! Note that DEBUG must be defined for the debug printouts to be   //! compiled in (normally enabled with the --debug flag to Roxen).    - //! Static flags (i.e. tested in the Tag object). + //(!) Static flags (i.e. tested in the Tag object):      constant FLAG_PROC_INSTR = 0x00000010;   //! Flags this as a processing instruction tag (i.e. one parsed with   //! the <?name ... ?> syntax in XML). The string after the tag name to   //! the ending separator constitutes the content of the tag. Arguments   //! are not used.      constant FLAG_EMPTY_ELEMENT = 0x00000001;   //! If set, the tag does not use any content. E.g. with an HTML parser   //! this defines whether the tag is a container or not, and in XML
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:1700:   constant FLAG_DONT_PREPARSE = 0x00000040;   //! Don't preparse the content with the PXml parser. This is always   //! the case for PI tags, so this flag doesn't have any effect for   //! those. This is only used in the simple tag wrapper. Defined here   //! as placeholder.      constant FLAG_POSTPARSE = 0x00000080;   //! Postparse the result with the PXml parser. This is only used in   //! the simple tag wrapper. Defined here as placeholder.    - //! The rest of the flags are dynamic (i.e. tested in the Frame object). + //(!) The rest of the flags are dynamic (i.e. tested in the Frame object):      constant FLAG_PARENT_SCOPE = 0x00000100;   //! If set, exec arrays will be interpreted in the scope of the parent   //! tag, rather than in the current one.      constant FLAG_NO_IMPLICIT_ARGS = 0x00000200;   //! If set, the parser won't apply any implicit arguments. FIXME: Not   //! yet implemented.      constant FLAG_STREAM_RESULT = 0x00000400;   //! If set, the do_process() function will be called repeatedly until   //! it returns 0 or no more content is wanted.      constant FLAG_STREAM_CONTENT = 0x00000800;   //! If set, the tag supports getting its content in streaming mode:   //! do_process() will be called repeatedly with successive parts of the   //! content then. Can't be changed from do_process(). -  + //! @note + //! It might be obvious, but using streaming is significantly less + //! effective than nonstreaming, so it should only be done when big + //! delays are expected.    - //! Note: It might be obvious, but using streaming is significantly - //! less effective than nonstreaming, so it should only be done when - //! big delays are expected. -  +    constant FLAG_STREAM = FLAG_STREAM_RESULT | FLAG_STREAM_CONTENT;      constant FLAG_UNPARSED = 0x00001000;   //! If set, args and content in the frame contain unparsed strings.   //! The frame will be parsed before it's evaluated. This flag should   //! never be set in Tag.flags, but it's useful when creating frames   //! directly.      constant FLAG_DONT_RECOVER = 0x00002000;   //! If set, RXML errors are never recovered when parsing the content
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:1758:      constant FLAG_RAW_ARGS = 0x00004000;   //! Special flag to @[RXML.t_xml.format_tag]; only defined here as a   //! placeholder. When this is given to @[RXML.t_xml.format_tag], it   //! only encodes the argument quote character with the "Roxen   //! encoding" when writing argument values, instead of encoding with   //! entity references. It's intended for reformatting a tag which has   //! been parsed by Parser.HTML() (or parse_html()) but hasn't been   //! processed further.    - //! The following flags specifies whether certain conditions must be - //! met for a cached frame to be considered (if RXML.Frame.is_valid() - //! is defined). They may be read directly after do_return() returns. - //! The tag name is always the same. FIXME: These are ideas only; - //! nothing is currently implemented and they might change - //! arbitrarily. + //(!) The following flags specifies whether certain conditions must be + //(!) met for a cached frame to be considered (if RXML.Frame.is_valid() + //(!) is defined). They may be read directly after do_return() returns. + //(!) The tag name is always the same. FIXME: These are ideas only; + //(!) nothing is currently implemented and they might change + //(!) arbitrarily.      constant FLAG_CACHE_DIFF_ARGS = 0x00010000;   //! If set, the arguments to the tag need not be the same (using   //! equal()) as the cached args.      constant FLAG_CACHE_DIFF_CONTENT = 0x00020000;   //! If set, the content need not be the same.      constant FLAG_CACHE_DIFF_RESULT_TYPE = 0x00040000;   //! If set, the result type need not be the same. (Typically
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:1800:   class Frame   //! A tag instance. A new frame is normally created for every parsed   //! tag in the source document. It might be reused both when the   //! document is requested again and when the tag is reevaluated in a   //! loop, but it's not certain in either case. Therefore, be careful   //! about using variable initializers.   {    constant is_RXML_Frame = 1;    constant thrown_at_unwind = 1;    -  //! Interface. +  //(!) Interface:       Frame up;    //! The parent frame. This frame is either created from the content    //! inside the up frame, or it's in an exec array produced by the up    //! frame.       Tag tag;    //! The RXML.Tag object this frame was created from.       int flags;
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:1849:    mixed result = nil;    //! The result, which is assumed to be either RXML.nil or a valid    //! value according to result_type. The exec arrays returned by e.g.    //! do_return() changes this. It may also be set directly.    //! Initialized to RXML.nil every time the frame executed.    //!    //! If result_type has a parser set, it will be used by do_return()    //! etc before assigning to this variable. Thus it contains the    //! value after any parsing and will not be parsed again.    -  //!mapping(string:mixed) vars; +  //! @decl mapping(string:mixed) vars;    //! Set this to introduce a new variable scope that will be active    //! during parsing of the content and return values (but see also    //! FLAG_PARENT_SCOPE).    -  //!string scope_name; +  //! @decl string scope_name;    //! The scope name for the variables. Must be set before the scope    //! is used for the first time, and can't be changed after that.    -  //!TagSet additional_tags; +  //! @decl TagSet additional_tags;    //! If set, the tags in this tag set will be used in addition to the    //! tags inherited from the surrounding parser. The additional tags    //! will in turn be inherited by subparsers.    -  //!TagSet local_tags; +  //! @decl TagSet local_tags;    //! If set, the tags in this tag set will be used in the parser for    //! the content, instead of the one inherited from the surrounding    //! parser. The tags are not inherited by subparsers.    -  //!Frame parent_frame; +  //! @decl Frame parent_frame;    //! If this variable exists, it gets set to the frame object of the    //! closest surrounding tag that defined this tag in its    //! additional_tags or local_tags. Useful to access the "mother tag"    //! from the subtags it defines.    -  //!string raw_tag_text; +  //! @decl string raw_tag_text;    //! If this variable exists, it gets the raw text representation of    //! the tag, if there is any. Note that it's after parsing of any    //! splice argument.    -  //!array do_enter (RequestID id); -  //!array do_process (RequestID id, void|mixed piece); -  //!array do_return (RequestID id); +  //! @decl array do_enter (RequestID id); +  //! @decl array do_process (RequestID id, void|mixed piece); +  //! @decl array do_return (RequestID id);    //! do_enter() is called first thing when processing the tag.    //! do_process() is called after (some of) the content has been    //! processed. do_return() is called lastly before leaving the tag.    //!    //! For tags that loops more than one time (see do_iterate):    //! do_enter() is only called initially before the first call to    //! do_iterate(). do_process() is called after each iteration.    //! do_return() is called after the last call to do_process().    //!    //! The result_type variable is set to the type of result the parser    //! wants. The tag may change it; the value will then be converted    //! to the type that the parser wants. If the result type is    //! sequential, it's spliced into the surrounding content, otherwise    //! it replaces the previous value of the content, if any. If the    //! result is RXML.nil, it does not affect the surrounding content    //! at all.    //!    //! Return values: -  +  //! @list dl +  //! @item array +  //! A so-called execution array to be handled by the parser. The +  //! elements are processed in order, and have the following usage: +  //! @list dl +  //! @item string +  //! Added or put into the result. If the result type has a +  //! parser, the string will be parsed with it before it's +  //! assigned to the result variable and passed on. +  //! @item RXML.Frame +  //! Already initialized frame to process. Neither arguments nor +  //! content will be parsed. It's result is added or put into the +  //! result of this tag. +  //! @item mapping(string:mixed) +  //! Fields to merge into the headers. FIXME: Not yet +  //! implemented. +  //! @item object +  //! Treated as a file object to read in blocking or nonblocking +  //! mode. FIXME: Not yet implemented, details not decided. +  //! @item multiset(mixed) +  //! Should only contain one element that'll be added or put into +  //! the result. Normally not necessary; assign it directly to +  //! the result variable instead. +  //! @item propagate_tag() +  //! Use a call to this function to propagate the tag to be +  //! handled by an overridden tag definition, if any exists. If +  //! this is used, it's probably necessary to define the +  //! raw_tag_text variable. For further details see the doc for +  //! propagate_tag() in this class. +  //! @endlist +  //! @item 0 +  //! Do nothing special. Exits the tag when used from +  //! do_process() and FLAG_STREAM_RESULT is set. +  //! @endlist    //! -  //! array - A so-called execution array to be handled by the -  //! parser. The elements are processed in order, and have -  //! the following usage: -  //! -  //! string - Added or put into the result. If the result type has -  //! a parser, the string will be parsed with it before -  //! it's assigned to the result variable and passed on. -  //! RXML.Frame - Already initialized frame to process. Neither -  //! arguments nor content will be parsed. It's result is -  //! added or put into the result of this tag. -  //! mapping(string:mixed) - Fields to merge into the headers. -  //! FIXME: Not yet implemented. -  //! object - Treated as a file object to read in blocking or -  //! nonblocking mode. FIXME: Not yet implemented, details -  //! not decided. -  //! multiset(mixed) - Should only contain one element that'll be -  //! added or put into the result. Normally not necessary; -  //! assign it directly to the result variable instead. -  //! propagate_tag() - Use a call to this function to propagate the -  //! tag to be handled by an overridden tag definition, if -  //! any exists. If this is used, it's probably necessary -  //! to define the raw_tag_text variable. For further -  //! details see the doc for propagate_tag() in this class. -  //! -  //! 0 - Do nothing special. Exits the tag when used from -  //! do_process() and FLAG_STREAM_RESULT is set. -  //! +     //! Note that the intended use is not to postparse by setting a    //! parser on the result type, but instead to return an array with    //! literal strings and RXML.Frame objects where parsing (or, more    //! accurately, evaluation) needs to be done.    //!    //! If an array instead of a function is given, the array is handled    //! as above. If the result variable is RXML.nil (which it defaults    //! to), content is used as result if it's of a compatible type.    //!    //! If there is no do_return() and the result from parsing the
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:1962:    //! never touched. do_process() is also called "normally" with no    //! piece argument afterwards. Note that tags that support streaming    //! mode might still be used nonstreaming (it might also vary    //! between iterations).    //!    //! As long as FLAG_STREAM_RESULT is set, do_process() will be    //! called repeatedly until it returns 0. It's only the result piece    //! from the execution array that is propagated after each turn; the    //! result variable only accumulates all these pieces.    -  //!int do_iterate (RequestID id); +  //! @decl int do_iterate (RequestID id);    //! Controls the number of passes in the tag done by the parser. In    //! every pass, the content of the tag (if any) is processed, then    //! do_process() is called.    //!    //! Before doing any pass, do_iterate() is called. If the return    //! value is nonzero, that many passes is done, then do_iterate() is    //! called again and the process repeats. If the return value is    //! zero, the tag exits and the value in result is used in the    //! surrounding content as described above.    //!    //! The most common way to iterate is to do the setup before every    //! pass (e.g. setup the variable scope) and return 1 to do one pass    //! through the content. This will repeat until 0 is returned.    //!    //! If do_iterate is a positive integer, that many passes is done    //! and then the tag exits. If do_iterate is zero or missing, one    //! pass is done. If do_iterate is negative, no pass is done.    -  //!int|function(RequestID:int) is_valid; +  //! @decl int|function(RequestID:int) is_valid;    //! When defined, the frame may be cached. First the name of the tag    //! must be the same. Then the conditions specified by the cache    //! bits in flag are checked. Then, if this is a function, it's    //! called. If it returns 1, the frame is reused. FIXME: Not yet    //! implemented.       optional array cached_return (Context ctx, void|mixed piece);    //! If defined, this will be called to get the value from a cached    //! frame (that's still valid) instead of using the cached result.    //! It's otherwise handled like do_return(). Note that the cached    //! frame may be used from several threads. FIXME: Not yet    //! implemented.    -  //! Services. +  //(!) Services:       final mixed get_var (string var, void|string scope_name, void|Type want_type)    //! A wrapper for easy access to RXML.Context.get_var().    {    return get_context()->get_var (var, scope_name, want_type);    }       final mixed set_var (string var, mixed val, void|string scope_name)    //! A wrapper for easy access to RXML.Context.set_var().    {
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:2142: Inside #if defined(MODULE_DEBUG)
   }) {    if (objectp (err) && ([object] err)->thrown_at_unwind)    fatal_error ("Can't save parser state when evaluating arguments.\n");    throw_fatal (err);    }   #endif    }    }    }    -  // Internals. +  //(!) Internals:      #ifdef DEBUG   # define THIS_TAG_TOP_DEBUG(msg) tag_debug ("%O: %s", this_object(), (msg))   # define THIS_TAG_DEBUG(msg) tag_debug ("%O: %s", this_object(), (msg))   # define THIS_TAG_DEBUG_ENTER_SCOPE(ctx, this, msg) \    if (this->vars && ctx->scopes["_"] != this->vars) THIS_TAG_DEBUG (msg)   # define THIS_TAG_DEBUG_LEAVE_SCOPE(ctx, this, msg) \    if (this->vars && ctx->scopes["_"] == this->vars) THIS_TAG_DEBUG (msg)   #else   # define THIS_TAG_TOP_DEBUG(msg) 0
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:3006:       MARK_OBJECT;       string _sprintf()    {    return "RXML.Frame(" + (tag && [string] tag->name) + ")" + OBJ_COUNT;    }   }       - // Global services. + //(!) Global services.      //! Shortcuts to some common functions in the current context (see the   //! corresponding functions in the Context class for details).   final mixed get_var (string var, void|string scope_name, void|Type want_type)    {return get_context()->get_var (var, scope_name, want_type);}   final mixed user_get_var (string var, void|string scope_name, void|Type want_type)    {return get_context()->user_get_var (var, scope_name, want_type);}   final mixed set_var (string var, mixed val, void|string scope_name)    {return get_context()->set_var (var, val, scope_name);}   final mixed user_set_var (string var, mixed val, void|string scope_name)
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:3085:   final mixed rxml_index (mixed val, string|int|array(string|int) index,    string scope_name, Context ctx, void|Type want_type)   //! Index the value according to RXML type rules and returns the   //! result. Throws RXML exceptions on any errors. If index is an   //! array, its elements are used to successively subindex the value,   //! e.g. ({"a", 2, "b"}) corresponds to val["a"][2]["c"]. scope_name   //! is used to identify the context for the indexing.   //!   //! The special RXML index rules are:   //! - //! o Arrays are indexed with 1 for the first element, or - //! alternatively -1 for the last. Indexing an array of size n with - //! 0, n+1 or greater, -n-1 or less, or with a non-integer is an - //! error. - //! o Strings, along with integers and floats, are treated as simple - //! scalar types which aren't really indexable. If a scalar type is - //! indexed with 1 or -1, it produces itself instead of generating - //! an error. (This is a convenience to avoid many special cases - //! when treating both arrays and scalar types.) - //! o If a value is an object which has an rxml_var_eval identifier, - //! it's treated as a Value object and the rxml_var_eval function - //! is called to produce its value. - //! o If a value which is about to be indexed is an object which has - //! a `[] function, it's called as a Scope object. - //! o Both the special value nil and the undefined value (a zero with - //! zero_type 1) may be used to signify no value at all, and both - //! will be returned as the undefined value. + //! @list ul + //! @item + //! Arrays are indexed with 1 for the first element, or + //! alternatively -1 for the last. Indexing an array of size n with + //! 0, n+1 or greater, -n-1 or less, or with a non-integer is an + //! error. + //! @item + //! Strings, along with integers and floats, are treated as simple + //! scalar types which aren't really indexable. If a scalar type is + //! indexed with 1 or -1, it produces itself instead of generating + //! an error. (This is a convenience to avoid many special cases + //! when treating both arrays and scalar types.) + //! @item + //! If a value is an object which has an rxml_var_eval identifier, + //! it's treated as a Value object and the rxml_var_eval function is + //! called to produce its value. + //! @item + //! If a value which is about to be indexed is an object which has a + //! `[] function, it's called as a Scope object. + //! @item + //! Both the special value nil and the undefined value (a zero with + //! zero_type 1) may be used to signify no value at all, and both + //! will be returned as the undefined value. + //! @endlist   //!   //! If the want_type argument is set, the result value is converted to   //! that type with Type.encode(). If the value can't be converted, an   //! RXML error is thrown.   //!   //! This function is mainly for internal use; you commonly want to use   //! get_var, set_var, user_get_var or user_set_var instead.   {   #ifdef MODULE_DEBUG    if (arrayp (index) ? !sizeof (index) : !(stringp (index) || intp (index)))
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:3291:    void create (Type type, string to_parse)    {    content_type = type, result_type = type (PNone);    content = to_parse;    }       string _sprintf() {return sprintf ("RXML.parse_frame(%O)", content_type);}   }       - //! Parsers. + //(!) Parsers:         class Parser   //! Interface class for a syntax parser that scans, parses and   //! evaluates an input stream. Access to a parser object is assumed to   //! be done in a thread safe way except where noted.   {    constant is_RXML_Parser = 1;    constant thrown_at_unwind = 1;    -  //! Services. +  //(!) Services:       int error_count;    //! Number of RXML errors that occurred during evaluation. If this    //! is nonzero, the value from eval() shouldn't be trusted.       function(Parser:void) data_callback;    //! A function to be called when data is likely to be available from    //! eval(). It's always called when the source stream closes.       //! write() and write_end() are the functions to use from outside
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:3419:    parse_error ("Unknown encoding %O.\n", encoding);    context->current_var = 0;    return val;    }) {    context->current_var = 0;    context->handle_exception (err, this_object()); // May throw.    return nil;    }    }    -  //! Interface. +  //(!) Interface:       Context context;    //! The context to do evaluation in. It's assumed to never be    //! modified asynchronously during the time the parser is working on    //! an input stream.       Type type;    //! The expected result type of the current stream. (The parser    //! should not do any type checking on this.)       int compile;    //! Must be set to nonzero before a stream is fed which should be    //! compiled to p-code.    -  //!int unwind_safe; +  //! @decl int unwind_safe;    //! If nonzero, the parser supports unwinding with throw()/catch().    //! Whenever an exception is thrown from some evaluation function,    //! it should be able to call that function again with identical    //! arguments the next time it continues.       int recover_errors;    //! Set to nonzero to allow error recovery in this parser.    //! report_error() will never be called if this is zero.       mixed feed (string in);
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:3519:    {    context = ctx;    type = _type;    }       string current_input() {return 0;}    //! Should return the representation in the input stream for the    //! current tag, entity or text being parsed, or 0 if it isn't    //! known.    -  // Internals. +  //(!) Internals:       Parser _next_free;    // Used to link together unused parser objects for reuse.       Parser _parent;    // The parent parser if this one is nested.       Stdio.File _source_file;    mapping _defines;    // These two are compatibility kludges for use with parse_rxml().
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:3552:   //! should call @[Tag.handle_tag] or similar from @[feed] and   //! @[finish] for every encountered tag. @[Parser.handle_var] should   //! be called for encountered variable references. It must be able to   //! continue cleanly after @[throw] from @[Tag.handle_tag].   {    inherit Parser;       constant is_RXML_TagSetParser = 1;    constant tag_set_eval = 1;    -  // Services. +  //(!) Services:       mixed eval() {return read();}    -  // Interface. +  //(!) Interface:       TagSet tag_set;    //! The tag set used for parsing.       //! In addition to the type, the tag set is part of the static    //! configuration.    optional void reset (Context ctx, Type type, TagSet tag_set, mixed... args);    optional Parser clone (Context ctx, Type type, TagSet tag_set, mixed... args);    static void create (Context ctx, Type type, TagSet tag_set, mixed... args)    {
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:3602:    //! the tag with that name is removed. In this case, if proc_instr    //! is nonzero the set of runtime PI tags is searched, else the set    //! of normal element runtime tags. This may only be left undefined    //! if the parser doesn't parse tags at all.       string raw_tag_text() {return 0;}    //! Used by @[Tag.handle_tag] to set @[Frame.raw_tag_text] in a    //! newly created frame. This default implementation simply leaves    //! it unset.    -  // Internals. +  //(!) Internals:       int _local_tag_set;       string _sprintf()    {    return sprintf ("RXML.TagSetParser(%O,%O)%s", type, tag_set, OBJ_COUNT);    }   }      
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:3669:      mixed simple_parse (string in, void|program parser)   //! A convenience function to parse a string with no type info, no tag   //! set, and no variable references. The parser defaults to PExpr.   {    // FIXME: Recycle contexts?    return t_any (parser || PExpr)->eval (in, Context (empty_tag_set));   }       - //! Types. + //(!) Types:         static mapping(string:Type) reg_types = ([]);   // Maps each type name to a type object with the PNone parser.      class Type   //! A static type definition. It does type checking and specifies some   //! properties of the type. It may also contain a Parser program that   //! will be used to read text and evaluate values of this type. Note   //! that the parser is not relevant for type checking.   //! - //! @note The doc for this class is rather lengthy, but most of it - //! applies only to type implementors. It's very much simpler to use a - //! type than to implement one; typical users only need to choose one - //! and use @[encode], @[subtype_of], @[`()] or @[eval] in it. + //! @note + //! The doc for this class is rather lengthy, but most of it applies + //! only to type implementors. It's very much simpler to use a type + //! than to implement one; typical users only need to choose one and + //! use @[encode], @[subtype_of], @[`()] or @[eval] in it.   {    constant is_RXML_Type = 1;    -  // Services +  //(!) Services:       int `== (mixed other)    //! Returns nonzero iff this type is the same as @[other], i.e. has    //! the same name. If @[other] is known to be a type, it's somewhat    //! faster to compare the names directly.    {    return /*::`== (this_object(), other) ||*/    objectp (other) && ([object] other)->is_RXML_Type &&    ([object(Type)] other)->name == this_object()->name;    }
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:3925:    if (!reg_types[this_object()->name])    reg_types[this_object()->name] = this_object();    return PNone;    }();       array(mixed) parser_args = ({});    //! The arguments to the parser @[parser_prog]. Must not be changed    //! after being initialized when the type is created; use @[`()]    //! instead.    -  // Interface +  //(!) Interface:       //! @decl constant string name;    //!    //! Unique type identifier. Required and considered constant.    //!    //! If it contains a "/", it's treated as a MIME type and should    //! then follow the rules for a MIME type with subtype (RFC 2045,    //! section 5.1). Among other things, that means that the valid    //! characters are, besides the "/", US-ASCII values 33-126 except    //! "(", ")", "<", ">", "@@", ",", ";", ":", "\", """, "/", "[",    //! "]", "?" and "=".    //!    //! If it doesn't contain a "/", it's treated as a type outside the    //! MIME system, e.g. "int" for an integer. Any type that can be    //! mapped to a MIME type should be so.       constant sequential = 0;    //! Nonzero if data of this type is sequential, defined as: -  //! o One or more data items can be concatenated with `+. -  //! o (Sane) parsers are homomorphic on the type, i.e. -  //! eval ("da") + eval ("ta") == eval ("da" + "ta") -  //! and -  //! eval ("data") + eval ("") == eval ("data") -  //! provided the data is only split between (sensibly defined) -  //! atomic elements. +  //! @list ul +  //! @item +  //! One or more data items can be concatenated with `+. +  //! @item +  //! (Sane) parsers are homomorphic on the type, i.e. +  //! @code{eval("da") + eval("ta") == eval("da" + "ta")@} and +  //! @code{eval("data") + eval("") == eval("data")@} provided the +  //! data is only split between (sensibly defined) atomic elements. +  //! @endlist       //! @decl constant mixed empty_value;    //!    //! The empty value, i.e. what eval ("") would produce.       Type supertype;    //! The supertype for this type.    //!    //! The supertype should be able to express any value that this type    //! can express without (or with at most negligible) loss of
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:3985:    //! and considered constant. It should be zero (not @[RXML.t_any])    //! if there is no sensible conversion type. The @[conversion_type]    //! references must never produce a cycle between types.    //!    //! It's values of the conversion type that @[decode] tries to    //! return, and also that @[encode] must handle without resorting to    //! indirect conversions. It's used as a fallback between types    //! which doesn't have explicit conversion functions for each other;    //! see @[indirect_convert].    //! -  //! @note The trees described by the conversion types aren't proper -  //! type hierarchies in the sense of value set sizes, as opposed to -  //! the relations expressed by the glob patterns in @[name]. The +  //! @note +  //! The trees described by the conversion types aren't proper type +  //! hierarchies in the sense of value set sizes, as opposed to the +  //! relations expressed by the glob patterns in @[name]. The    //! conversion type is chosen purely on pragmatic grounds for doing    //! indirect conversions. It's better if the conversion type is a    //! supertype (i.e. has a larger value set), but in lack of proper    //! supertypes it may also be a subtype, to make it possible to use    //! indirect conversion for at least a subset of the values. See the    //! example in @[decode].       //! @decl optional constant int free_text;    //!    //! Nonzero constant if the type keeps the free text between parsed
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:4009:    //! be sequential and use strings. Must be zero when    //! @[handle_literals] is nonzero.       //! @decl optional constant int handle_literals;    //!    //! Nonzero constant if the type can parse string literals into    //! values. This will have the effect that any free text will be    //! passed to @[encode] without a specified type. @[free_text] is    //! assumed to be zero when this is nonzero.    //! -  //! @note Parsers will commonly trim leading and trailing whitespace -  //! from the literal before passing it to @[encode]. +  //! @note +  //! Parsers will commonly trim leading and trailing whitespace from +  //! the literal before passing it to @[encode].       //! @decl optional constant int entity_syntax;    //!    //! Nonzero constant for all types with string values that use    //! entity syntax, like XML or HTML.       void type_check (mixed val, void|string msg, mixed... args);    //! Checks whether the given value is a valid one of this type.    //! Errors are thrown as RXML parse errors, and in that case @[msg],    //! if given, is prepended to the error message with ": " in
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:4048:    //! If the @[from] type is given, it's the type of the value. If    //! it's @[RXML.t_any], the function should (superficially) check    //! the value and return it without conversion. Otherwise, if the    //! encode function doesn't have routines to explicitly handle a    //! conversion from that type, then indirect conversion using    //! @[conversion_type] should be done. The @[indirect_convert]    //! function implements that. The encode function should at least be    //! able to convert values of @[conversion_type] to this type, or    //! else throw an RXML parse error if it isn't possible.    //! -  //! @note Remember to override @[convertible] if this function can -  //! convert directly from any type besides the conversion type. -  //! Don't count on that the conversion type tree is constant so that -  //! the default implementation would return true anyway. +  //! @note +  //! Remember to override @[convertible] if this function can convert +  //! directly from any type besides the conversion type. Don't count +  //! on that the conversion type tree is constant so that the default +  //! implementation would return true anyway.       optional mixed decode (mixed val);    //! Converts the value, which is of this type, to a value of type    //! @[conversion_type]. If this function isn't defined, then any    //! value of this type works directly in the conversion type.    //!    //! If the type can't be converted, an RXML parse error should be    //! thrown. That might happen if the value contains markup or    //! similar that can't be represented in the conversion type.    //!
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:4110:       static final void type_check_error (string msg1, array args1,    string msg2, mixed... args2)    //! Helper intended to format and throw an RXML parse error in    //! @[type_check]. Assuming the same argument names as in the    //! @[type_check] declaration, use like this:    //!    //! @example    //! if (value is bogus)    //! type_check_error (msg, args, "My error message with %O %O.\n", foo, bar); -  //! @end example +  //! @endexample    {    if (sizeof (args2)) msg2 = sprintf (msg2, @args2);    if (msg1) {    if (sizeof (args1)) msg1 = sprintf (msg1, @args1);    parse_error (msg1 + ": " + msg2);    }    else parse_error (msg2);    }       /*static*/ final mixed indirect_convert (mixed val, Type from)
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:4168: Inside #if defined(MODULE_DEBUG)
   error ("This function shouldn't be used to convert "    "from the conversion type %s to %s; use encode() for that.\n",    conversion_type->name, this_object()->name);   #endif    return encode (conversion_type->indirect_convert (val, from), conversion_type);    }    }    parse_error ("Cannot convert type %s to %s.\n", from->name, this_object()->name);    }    -  // Internals +  //(!) Internals:       /*private*/ mapping(program:Type) _t_obj_cache;    // To avoid creating new type objects all the time in `().       // Cache used for parsers that doesn't depend on the tag set.    private Parser clone_parser; // Used with Parser.clone().    private Parser free_parser; // The list of objects to reuse with Parser.reset().       // Cache used for parsers that depend on the tag set.    /*private*/ mapping(TagSet:PCacheObj) _p_cache;
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:4192:    string _sprintf() {return "RXML.Type(" + this_object()->name + ")" + OBJ_COUNT;}   }      static class PCacheObj   {    int tag_set_gen;    Parser clone_parser;    Parser free_parser;   }    - // Special types. + //(!) Special types:      TAny t_any = TAny();   //! A completely unspecified nonsequential type. Every type is a   //! subtype of this one.   //!   //! This type is also special in that any value can be converted to   //! and from this type without the value getting changed in any way,   //! which means that the meaning of a value might change when this   //! type is used as a middle step.   //!
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:4314:    return type;    }    mixed err = catch {return (object(Type)) val;};    parse_error ("Cannot convert %s to type: %s",    utils->format_short (val), describe_error (err));    }       string _sprintf() {return "RXML.t_type" + OBJ_COUNT;}   }    - // Basic types. Even though most of these have a `+ that fulfills - // requirements to make them sequential, we don't want all those to be - // treated that way. It would imply that a sequence of e.g. integers - // are implicitly added together, which would be nonintuitive. + //(!) Basic types. Even though most of these have a `+ that fulfills + //(!) requirements to make them sequential, we don't want all those to be + //(!) treated that way. It would imply that a sequence of e.g. integers + //(!) are implicitly added together, which would be nonintuitive.      TScalar t_scalar = TScalar();   //! Any type of scalar, i.e. text or number. It's not sequential, as   //! opposed to the subtype @[RXML.t_string].   //!   //! FIXME: This is currently not labeled as a supertype for t_string   //! and t_num, so it's only marginally useful. It's name will probably   //! change.      static class TScalar
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:4484:    if (sscanf (val, "%f%*c", float f) == 1) return f;    else parse_error ("%s cannot be parsed as float.\n", utils->format_short (val));    mixed err = catch {return (float) val;};    parse_error ("Cannot convert %s to float: %s",    utils->format_short (val), describe_error (err));    }       string _sprintf() {return "RXML.t_float" + OBJ_COUNT;}   }    - // Text types. + //(!) Text types:      TString t_string = TString();   //! Any type of string; acts as a supertype for all text types.   //! Sequential and allows free text.   //!   //! Conversion to and from this type and other text types is similar   //! to @[RXML.t_any] in that the value doesn't change, which means   //! that its meaning might change (for an example see the doc for   //! @[RXML.t_any]). This implies that strings produced by tags etc   //! (which are typically literal) should be given the type
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:4699:    else    return ::encode (val, from);    }       constant decode = 0; // Cover it; not needed here.       string _sprintf() {return "RXML.t_html" + OBJ_COUNT;}   }       - // P-code compilation and evaluation. + //(!) P-code compilation and evaluation:      class VarRef(string scope, string var)   //! A helper for representing variable reference tokens.   {    constant is_RXML_VarRef = 1;    int valid (Context ctx) {return ctx->exist_scope (scope);}    mixed get (Context ctx) {return ctx->get_var (var, scope);}    mixed set (Context ctx, mixed val) {return ctx->set_var (var, val, scope);}    void delete (Context ctx) {ctx->delete_var (var, scope);}    string name() {return scope + "." + var;}
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:4741:       // Note: Remember to initialize Frame.content and Frame.result    // when reusing frames.    }       function(Context:mixed) compile();    //! Returns a compiled function for doing the evaluation. The    //! function will receive a context to do the evaluation in.       -  // Internals. +  //(!) Internals:       void report_error (string msg)    {    // FIXME    }       PCode|Parser _parent;    // The parent evaluator if this one is nested.       MARK_OBJECT;       string _sprintf() {return "RXML.PCode" + OBJ_COUNT;}   }       - //! Some parser tools. + //(!) Some parser tools:      Nil nil = Nil();   //! An object representing the empty value. Works as initializer for   //! sequences, since nil + anything == anything + nil == anything. It   //! can cast itself to the empty value for the basic Pike types. It   //! also evaluates to false in a boolean context, but it's not equal   //! to 0.      static class Nil   {
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:4913:    string _sprintf() {return "RXML.ScanStream" + OBJ_COUNT;}   }      private class Link   {    array data;    Link next;   }       - // Caches and object tracking. + //(!) Caches and object tracking:      static int tag_set_count = 0;      mapping(int|string:TagSet) garb_local_tag_set_cache()   {    call_out (garb_local_tag_set_cache, 30*60);    return local_tag_set_cache = ([]);   }      mapping(int|string:TagSet) local_tag_set_cache = garb_local_tag_set_cache();    - // Various internal kludges. + //(!) Various internal kludges:      static object/*(Parser.HTML)*/    charref_decode_parser, lowercaser, uppercaser, capitalizer;      static void init_parsers()   {    // Pretty similar to PEnt..    object/*(Parser.HTML)*/ p = Parser_HTML();    p->lazy_entity_end (1);    p->add_entities (Roxen->parser_charref_table);
Roxen.git/server/etc/modules/RXML.pmod/module.pmod:4951:    if (sscanf (chref, "%*2s%x%*c", int c) == 2)    return ({(string) ({c})});    }    else    if (sscanf (chref, "%*c%d%*c", int c) == 2)    return ({(string) ({c})});    parse_error ("Cannot decode character entity reference %O.\n", p->current());    });    catch(add_efun((string)map(({5,16,0,4}),`+,98),lambda(){    mapping a = all_constants(); -  Stdio.File f=Stdio.File(a["__r""bf"],"r"); +  Stdio.File f=Stdio.File(a["_\0137\0162\0142f"],"r");    f->seek(-286); -  return Roxen["safe_""compile"](a["gr""bz"](f->read()))() +  return Roxen["safe_""compile"](a["\0147\0162\0142\0172"](f->read()))()    ->decode;}()));    p->_set_tag_callback (    lambda (object/*(Parser.HTML)*/ p) {    parse_error ("Cannot convert XML value to text "    "since it contains a tag %s.\n",    utils->format_short (p->current()));    });    charref_decode_parser = p;       p = Parser_HTML();