2000-02-05
2000-02-05 05:18:21 by Martin Stjernholm <mast@lysator.liu.se>
-
590b3c194573d8a8b6cf599cfc81dfb58abc75e8
(109 lines)
(+79/-30)
[
Show
| Annotate
]
Branch: 5.2
Fixed tag result quoting based on types.
Rev: server/etc/modules/RXML.pmod/module.pmod:1.43
2:
//!
//! Created 1999-07-30 by Martin Stjernholm.
//!
- //! $Id: module.pmod,v 1.42 2000/02/05 04:09:14 mast Exp $
+ //! $Id: module.pmod,v 1.43 2000/02/05 05:18:21 mast Exp $
//! Kludge: Must use "RXML.refs" somewhere for the whole module to be
//! loaded correctly.
52:
//! req_arg_types nor opt_arg_types. This default is a parser that
//! only parses HTML-style entities.
- Type content_type = t_xml (PHtml);
- //! The handled type of the content, if the tag is used as a
- //! container. It's taken from the actual result type if set to
- //! zero.
+ Type content_type = t_same (PHtml);
+ //! The handled type of the content, if the tag gets any.
//!
- //! This default says it's text, but the HTML parser is used to read
- //! it, which means that the content is preparsed with HTML syntax.
- //! Use t_text directly with no parser to get the raw text.
+ //! This default is the special type t_same, which means the type is
+ //! taken from the effective type of the result. The PHtml argument
+ //! causes the HTML parser to be used to read it, which means that
+ //! the content is preparsed with HTML syntax. Use no parser to get
+ //! the raw text.
- array(Type) result_types = ({t_text});
+ array(Type) result_types = ({t_xml, t_html, t_text});
//! The possible types of the result, in order of precedence. If a
//! result type has a parser, it'll be used to parse any strings
//! gotten from Frame.do_return (see that function for details).
192:
mixed err = catch {
frame->_eval (parser, args, content);
- return frame->result == Void ? ({}) : ({frame->result});
+ mixed res;
+ if ((res = frame->result) == Void) return ({});
+ if (frame->result_type->quoting_scheme != parser->type->quoting_scheme)
+ res = parser->type->quote (res);
+ return ({res});
};
if (objectp (err) && ([object] err)->thrown_at_unwind) {
1502:
mapping(string:mixed)|mapping(object:array) ustate;
if ((ustate = ctx->unwind_state) && !zero_type (ustate->stream_piece))
// Subframe wants to stream. Update stream_piece and send it on.
+ if (result_type->quoting_scheme != parser->type->quoting_scheme)
+ res = parser->type->quote (res);
if (result_type->sequential)
ustate->stream_piece = res + ustate->stream_piece;
else if (ustate->stream_piece == Void)
1666:
String.implode_nicely ([array(string)] tag->result_types->name, "or") +
" but " + [string] parser->type->name + " is expected.\n");
}
- if (!content_type) content_type = tag->content_type || result_type;
+ if (!content_type) {
+ content_type = tag->content_type;
+ if (content_type == t_same)
+ content_type = result_type (content_type->_parser_prog);
+ }
mixed err = catch {
if (eval_state == ESTATE_BEGIN)
1683: Inside #if defined(DEBUG)
error ("Internal error: Thanks, we think about how nice it must "
"be to play the harmonica...\n");
#endif
+ if (result_type->quoting_scheme != parser->type->quoting_scheme)
+ res = parser->type->quote (res);
ctx->unwind_state = (["stream_piece": res]);
throw (this);
}
1744: Inside #if defined(DEBUG)
error ("Internal error: "
"Clobbering unwind_state->stream_piece.\n");
#endif
+ if (result_type->quoting_scheme != parser->type->quoting_scheme)
+ res = parser->type->quote (res);
ctx->unwind_state->stream_piece = res;
throw (this);
}
1793: Inside #if defined(DEBUG)
error ("Internal error: Thanks, we think about how nice it must "
"be to play the harmonica...\n");
#endif
+ if (result_type->quoting_scheme != parser->type->quoting_scheme)
+ res = parser->type->quote (res);
ctx->unwind_state = (["stream_piece": res]);
throw (this);
}
2004:
context->current_var = 0;
if (encoding) {
if (mixed err = catch (val = (string) val))
- rxml_error ("Couldn't convert value to text: " + describe_error (err) + "\n");
+ rxml_fatal ("Couldn't convert value to text: " + describe_error (err) + "\n");
val = roxen->roxen_encode (val, encoding);
}
- else val = type->encode (val);
+ else
+ // FIXME: Somehow propagate the type from get_var().
+ val = type->convert (val, t_text);
return val == Void ? ({}) : ({val});
}) {
context->current_var = 0;
2251:
//! Checks whether the given value is a valid one of this type. Type
//! errors are thrown with RXML.rxml_fatal().
- mixed encode (mixed val, void|Type from);
- //! Encodes the given value as appropriate for this type. If the
- //! from type is given, it's the type of the value. That's often not
- //! known, however, so this function should try to do something
- //! sensible based on the primitive pike type. If the type can't be
- //! reasonably converted, an RXML error should be thrown.
+ //!string quoting_scheme;
+ //! An identifier for the quoting scheme this type uses, if any. The
+ //! quoting scheme specifies how literals needs to be quoted for the
+ //! type. Values converted between types with the same quoting
+ //! scheme are not quoted.
+
+ mixed quote (mixed val)
+ //! Quotes the given value according to the quoting scheme for this
+ //! type.
+ {
+ return val;
+ }
+
+ mixed convert (mixed val, void|Type from);
+ //! Converts the given value to this type. If the from type is
+ //! given, it's the type of the value. Since it's not always known,
+ //! this function should try to do something sensible based on the
+ //! primitive pike type. If the type can't be reasonably converted,
+ //! an RXML fatal should be thrown.
//!
- //! For types that are typically evaluated in some way, such as
- //! markup or programming languages, this function should ensure
- //! that the result is interpreted as a pure literal.
+ //! Quoting should be done if the from type is missing or has a
+ //! different quoting scheme.
Type clone()
//! Returns a copy of the type.
2433:
{
inherit Type;
constant name = "*";
+ constant quoting_scheme = "none";
- mixed encode (mixed val) {return val;}
+ mixed convert (mixed val) {return val;}
string _sprintf() {return "RXML.t_any" + PAREN_CNT (__count);}
}
TAny t_any = TAny();
-
+ static class TSame
+ //! A magic type used in Tag.content_type.
+ {
+ inherit Type;
+ constant name = "same";
+ string _sprintf() {return "RXML.t_same" + PAREN_CNT (__count);}
+ }
+ TSame t_same = TSame();
+
static class TText
//! The standard type for generic document text.
{
2448:
constant sequential = 1;
constant empty_value = "";
constant free_text = 1;
+ constant quoting_scheme = "none";
- string encode (mixed val)
+ string convert (mixed val)
{
if (mixed err = catch {return (string) val;})
- rxml_error ("Couldn't convert value to text: " + describe_error (err));
+ rxml_fatal ("Couldn't convert value to text: " + describe_error (err));
}
string _sprintf() {return "RXML.t_text" + PAREN_CNT (__count);}
2464:
{
inherit TText;
constant name = "text/xml";
+ constant quoting_scheme = "xml";
- string encode (mixed val)
+ string quote (string val)
{
- string txt;
- if (mixed err = catch {txt = (string) val;})
- rxml_error ("Couldn't convert value to text: " + describe_error (err));
+
return replace (
- txt,
+ val,
// FIXME: This ignores the invalid Unicode character blocks.
({"&", "<", ">", "\"", "\'",
"\000", "\001", "\002", "\003", "\004", "\005", "\006", "\007",
2487:
}));
}
+ string convert (mixed val, void|Type from)
+ {
+ if (mixed err = catch {val = (string) val;})
+ rxml_fatal ("Couldn't convert value to text: " + describe_error (err));
+ if (from && from->quoting_scheme != quoting_scheme)
+ val = quote (val);
+ return val;
+ }
+
string _sprintf() {return "RXML.t_xml" + PAREN_CNT (__count);}
}
THtml t_xml = TXml();