2001-05-17
2001-05-17 02:55:22 by Martin Stjernholm <mast@lysator.liu.se>
-
4c2b510ad9072b2280178cd65e377190e96e44ca
(327 lines)
(+160/-167)
[
Show
| Annotate
]
Branch: 5.2
Fixed a bogus debug check. Some cleanups. Do the conversion to the
surrounding content type in Frame._eval to get better error reports if
it fails.
Rev: server/etc/modules/RXML.pmod/module.pmod:1.155
1:
- // $Id: module.pmod,v 1.154 2001/05/16 12:57:49 per Exp $
+ // $Id: module.pmod,v 1.155 2001/05/17 02:55:22 mast Exp $
// Kludge: Must use "RXML.refs" somewhere for the whole module to be
// loaded correctly.
121:
#endif
#ifdef DEBUG
- # define TAG_DEBUG(frame, msg) (frame)->tag_debug ("%O: %s", (frame), (msg))
+ # define TAG_DEBUG(frame, msg, args...) \
+ (frame)->tag_debug ("%O: " + (msg), (frame), args)
# define DO_IF_DEBUG(code...) code
#else
- # define TAG_DEBUG(frame, msg) 0
+ # define TAG_DEBUG(frame, msg, args...) 0
# define DO_IF_DEBUG(code...)
#endif
302:
break make_new_frame; \
} \
frame = `() (args, nil); \
+ DO_IF_DEBUG( \
+ if (args && ([mapping] args)["-debug-tag-"]) { \
+ frame->flags |= FLAG_DEBUG; \
+ m_delete (args, "-debug-tag-"); \
+ } \
+ ); \
TAG_DEBUG (frame, "New frame\n"); \
} while (0)
- #define EVAL_FRAME(frame, ctx, parser, type, args, content, result) \
- eval_frame: do { \
- mixed err = catch { \
- frame->_eval (parser, args, content); \
- if ((result = frame->result) != nil) \
- if (frame->result_type->name != type->name) { \
- TAG_DEBUG ( \
- frame, sprintf ( \
- "Converting result from %s to %s of surrounding content\n", \
- frame->result_type->name, type->name)); \
- result = type->encode (result, frame->result_type); \
- } \
- break eval_frame; \
- }; \
+ #define EVAL_FRAME(frame, ctx, parser, type, args, content, result) \
+ eval_frame: do { \
+ mixed err = catch { \
+ result = frame->_eval (parser, type, args, content); \
+ break eval_frame; \
+ }; \
\
- if (objectp (err) && ([object] err)->thrown_at_unwind) { \
- UNWIND_STATE ustate = ctx->unwind_state; \
- if (!ustate) ustate = ctx->unwind_state = ([]); \
- DO_IF_DEBUG ( \
- if (err != frame) \
- fatal_error ("Internal error: " \
- "Unexpected unwind object catched.\n"); \
- if (ustate[parser]) \
- fatal_error ("Internal error: " \
- "Clobbering unwind state for parser.\n"); \
- ); \
- ustate[parser] = ({err}); \
- throw (err = parser); \
- } \
- else { \
- /* Will rethrow unknown errors. */ \
- ctx->handle_exception (err, parser); \
- result = nil; \
- } \
+ if (objectp (err) && ([object] err)->thrown_at_unwind) { \
+ UNWIND_STATE ustate = ctx->unwind_state; \
+ if (!ustate) ustate = ctx->unwind_state = ([]); \
+ DO_IF_DEBUG ( \
+ if (err != frame) \
+ fatal_error ("Internal error: " \
+ "Unexpected unwind object catched.\n"); \
+ if (ustate[parser]) \
+ fatal_error ("Internal error: " \
+ "Clobbering unwind state for parser.\n"); \
+ ); \
+ ustate[parser] = ({err}); \
+ throw (err = parser); \
+ } \
+ else { \
+ /* Will rethrow unknown errors. */ \
+ ctx->handle_exception (err, parser); \
+ result = nil; \
+ } \
} while (0)
final mixed handle_tag (TagSetParser parser, mapping(string:string) args,
2264: Inside #if defined(DEBUG)
if (!mappingp (args))
fatal_error ("Failed to parse tag args for <%s> from %O.\n",
tag->name, this_object()->raw_tag_text);
- if (!stringp (content))
+ if (!stringp (content) && !(flags & FLAG_EMPTY_ELEMENT))
fatal_error ("Failed to parse tag content for <%s> from %O.\n",
tag->name, this_object()->raw_tag_text);
#endif
2344:
//(!) 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)
+ # define THIS_TAG_TOP_DEBUG(msg, args...) tag_debug ("%O: " + (msg), this_object(), args)
+ # define THIS_TAG_DEBUG(msg, args...) tag_debug ("%O: " + (msg), this_object(), args)
+ # define THIS_TAG_DEBUG_ENTER_SCOPE(ctx, this, msg, args...) \
+ if (this->vars && ctx->scopes["_"] != this->vars) THIS_TAG_DEBUG (msg, args)
+ # define THIS_TAG_DEBUG_LEAVE_SCOPE(ctx, this, msg, args...) \
+ if (this->vars && ctx->scopes["_"] == this->vars) THIS_TAG_DEBUG (msg, args)
#else
- # define THIS_TAG_TOP_DEBUG(msg) 0
- # define THIS_TAG_DEBUG(msg) 0
+ # define THIS_TAG_TOP_DEBUG(msg, args...) 0
+ # define THIS_TAG_DEBUG(msg, args...) 0
# define THIS_TAG_DEBUG_ENTER_SCOPE(ctx, this, msg) 0
# define THIS_TAG_DEBUG_LEAVE_SCOPE(ctx, this, msg) 0
#endif
2377:
switch (sprintf ("%t", elem)) {
case "string":
if (result_type->parser_prog == PNone) {
- THIS_TAG_DEBUG (sprintf ("Exec[%d]: String\n", i));
+ THIS_TAG_DEBUG ("Exec[%d]: String\n", i);
piece = elem;
}
else {
subparser = result_type->get_parser (ctx, 0, parser);
if (parser->recover_errors && !(flags & FLAG_DONT_RECOVER))
subparser->recover_errors = 1;
- THIS_TAG_DEBUG (sprintf ("Exec[%d]: Parsing string with %O\n",
- i, subparser));
+ THIS_TAG_DEBUG ("Exec[%d]: Parsing string with %O\n", i, subparser);
subparser->finish ([string] elem); // Might unwind.
piece = subparser->eval(); // Might unwind.
subparser = 0;
2393:
break;
case "mapping":
- THIS_TAG_DEBUG (sprintf ("Exec[%d]: Header mapping\n", i));
+ THIS_TAG_DEBUG ("Exec[%d]: Header mapping\n", i);
fatal_error ("Header mappings not yet implemented.\n");
break;
case "multiset":
if (sizeof ([multiset] elem) == 1) {
piece = ((array) elem)[0];
- THIS_TAG_DEBUG (sprintf ("Exec[%d]: Verbatim %t value\n", i, piece));
+ THIS_TAG_DEBUG ("Exec[%d]: Verbatim %t value\n", i, piece);
}
else if (sizeof ([multiset] elem) > 1)
- fatal_error (sizeof ([multiset] elem) +
- " values in multiset in exec array.\n");
- else fatal_error ("No value in multiset in exec array.\n");
+ fatal_error ("%d values in multiset in position %d in exec array.\n",
+ sizeof ([multiset] elem), i);
+ else fatal_error ("No value in multiset in position %d in exec array.\n", i);
break;
default:
2413:
// Can't count on that sprintf ("%t", ...) on an object
// returns "object".
if (([object] elem)->is_RXML_Frame) {
- THIS_TAG_DEBUG (sprintf ("Exec[%d]: Evaluating frame %O\n",
- i, ([object] elem)));
- ([object(Frame)] elem)->_eval (parser); // Might unwind.
- piece = ([object(Frame)] elem)->result;
+ THIS_TAG_DEBUG ("Exec[%d]: Evaluating frame %O\n", i, ([object] elem));
+ piece = ([object(Frame)] elem)->_eval (
+ parser, result_type); // Might unwind.
}
else if (([object] elem)->is_RXML_Parser) {
// The subparser above unwound.
- THIS_TAG_DEBUG (sprintf ("Exec[%d]: Continuing eval of frame %O\n",
- i, ([object] elem)));
+ THIS_TAG_DEBUG ("Exec[%d]: Continuing eval of frame %O\n",
+ i, ([object] elem));
([object(Parser)] elem)->finish(); // Might unwind.
piece = ([object(Parser)] elem)->eval(); // Might unwind.
}
else
fatal_error ("File objects not yet implemented.\n");
else
- fatal_error ("Invalid type %t in exec array.\n", elem);
+ fatal_error ("Invalid type %t in position %d in exec array.\n", elem, i);
}
if (result_type->sequential) {
- THIS_TAG_DEBUG (sprintf ("Exec[%d]: Adding %t to result\n", i, piece));
+ THIS_TAG_DEBUG ("Exec[%d]: Adding %t to result\n", i, piece);
res += piece;
}
else if (piece != nil) {
- THIS_TAG_DEBUG (sprintf ("Exec[%d]: Setting result to %t\n", i, piece));
+ THIS_TAG_DEBUG ("Exec[%d]: Setting result to %t\n", i, piece);
result = res = piece;
}
}
2456:
if (result_type->sequential) result += res;
if (objectp (err) && ([object] err)->thrown_at_unwind) {
- THIS_TAG_DEBUG (sprintf ("Exec: Interrupted at position %d\n", i));
+ THIS_TAG_DEBUG ("Exec: Interrupted at position %d\n", i);
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.
2487:
for (Parser p = parser; p; p = p->_parent)
if (p->tag_set_eval && !p->_local_tag_set && p->add_runtime_tag) {
foreach (arr_add_tags, Tag tag) {
- THIS_TAG_DEBUG (sprintf ("Adding runtime tag %O\n", tag));
+ THIS_TAG_DEBUG ("Adding runtime tag %O\n", tag);
([object(TagSetParser)] p)->add_runtime_tag (tag);
}
foreach (arr_rem_tags, string tag) {
- THIS_TAG_DEBUG (sprintf ("Removing runtime tag %s\n", tag));
+ THIS_TAG_DEBUG ("Removing runtime tag %s\n", tag);
([object(TagSetParser)] p)->remove_runtime_tag (tag);
}
foreach (arr_rem_pi_tags, string tag) {
- THIS_TAG_DEBUG (sprintf ("Removing runtime tag %s\n", tag));
+ THIS_TAG_DEBUG ("Removing runtime tag %s\n", tag);
([object(TagSetParser)] p)->remove_runtime_tag (tag, 1);
}
}
2503:
ctx->new_runtime_tags = 0;
}
- void _eval (TagSetParser parser,
+ mixed _eval (TagSetParser parser, Type type,
void|mapping(string:string) raw_args,
void|string raw_content)
// Note: It might be somewhat tricky to override this function.
// Note: Might be destructive on raw_args.
{
-
+
Frame this = this_object();
Context ctx = parser->context;
RequestID id = ctx->id;
2598:
#undef PRE_INIT_ERROR
ctx->frame = this;
+ mixed conv_result; // Result converted to the expected type.
mixed err1 = 0;
process_tag: {
if ((err1 = catch {
2647: Inside #if defined(DEBUG)
Type t = atypes[arg] || tag->def_arg_type;
if (t->parser_prog != PNone) {
Parser p = t->get_parser (ctx, 0, parser);
- THIS_TAG_DEBUG (sprintf ("Evaluating argument %O with %O\n", arg, p));
+ THIS_TAG_DEBUG ("Evaluating argument %O with %O\n", arg, p);
p->finish (raw_args[arg]); // Should not unwind.
raw_args[arg] = p->eval(); // Should not unwind.
}
2672:
if (!zero_type (this->parent_frame))
if (up->local_tags && up->local_tags->has_tag (tag)) {
- THIS_TAG_DEBUG (sprintf ("Setting parent_frame to %O from local_tags\n", up));
+ THIS_TAG_DEBUG ("Setting parent_frame to %O from local_tags\n", up);
this->parent_frame = up;
}
else
for (Frame f = up; f; f = f->up)
if (f->additional_tags && f->additional_tags->has_tag (tag)) {
- THIS_TAG_DEBUG (sprintf ("Setting parent_frame to %O "
- "from additional_tags\n", f));
+ THIS_TAG_DEBUG ("Setting parent_frame to %O from additional_tags\n", f);
this->parent_frame = f;
break;
}
2687:
if (TagSet add_tags = raw_content && [object(TagSet)] this->additional_tags) {
TagSet tset = ctx->tag_set;
if (!tset->has_effective_tags (add_tags)) {
- THIS_TAG_DEBUG (sprintf ("Installing additional_tags %O\n", add_tags));
+ THIS_TAG_DEBUG ("Installing additional_tags %O\n", add_tags);
int hash = HASH_INT2 (tset->id_number, add_tags->id_number);
orig_tag_set = tset;
TagSet local_ts;
2699:
ctx->tag_set = local_ts;
}
else
- THIS_TAG_DEBUG (sprintf ("Not installing additional_tags %O "
- "since they're already in the tag set\n", add_tags));
+ THIS_TAG_DEBUG ("Not installing additional_tags %O "
+ "since they're already in the tag set\n", add_tags);
}
if (!result_type) {
2709: Inside #if defined(MODULE_DEBUG)
"and it has no Tag object to use for inferring it.\n",
this_object());
#endif
- Type ptype = parser->type;
+
find_result_type: {
// First check if any of the types is a subtype of the
// wanted type. If so, we can use it directly.
foreach (tag->result_types, Type rtype)
- if (rtype->subtype_of (ptype)) {
+ if (rtype->subtype_of (type)) {
result_type = rtype;
break find_result_type;
}
2723:
// type, since the tag has the responsibility to produce a
// value of that type.
foreach (tag->result_types, Type rtype)
- if (ptype->subtype_of (rtype)) {
- result_type = ptype (rtype->parser_prog, @rtype->parser_args);
+ if (type->subtype_of (rtype)) {
+ result_type = type (rtype->parser_prog, @rtype->parser_args);
break find_result_type;
}
parse_error (
- "Tag returns " +
- String.implode_nicely ([array(string)] tag->result_types->name, "or") +
- " but " + [string] parser->type->name + " is expected.\n");
+ "Tag returns %s but %s is expected.\n",
+ String.implode_nicely ([array(string)] tag->result_types->name, "or"),
+ type->name);
}
- THIS_TAG_DEBUG (sprintf ("Resolved result_type to %O from surrounding %O\n",
- result_type, ptype));
+ THIS_TAG_DEBUG ("Resolved result_type to %s from surrounding %s\n",
+ result_type->name, type->name);
}
- else THIS_TAG_DEBUG (sprintf ("Keeping result_type %O\n", result_type));
+ else THIS_TAG_DEBUG ("Keeping result_type %s\n", result_type->name);
if (!content_type) {
#ifdef MODULE_DEBUG
2747:
if (content_type == t_same) {
content_type =
result_type (content_type->parser_prog, @content_type->parser_args);
- THIS_TAG_DEBUG (sprintf ("Resolved t_same to content_type %O\n",
- content_type));
+ THIS_TAG_DEBUG ("Resolved t_same to content_type %O\n", content_type);
}
- else THIS_TAG_DEBUG (sprintf ("Setting content_type to %O from tag\n",
- content_type));
+ else THIS_TAG_DEBUG ("Setting content_type to %O from tag\n", content_type);
}
- else THIS_TAG_DEBUG (sprintf ("Keeping content_type %O\n", content_type));
+ else THIS_TAG_DEBUG ("Keeping content_type %O\n", content_type);
if (raw_content) {
THIS_TAG_DEBUG ("Initializing the content variable to nil\n");
2779:
exec = ([function(RequestID:array)] do_enter) (id); // Might unwind.
COND_PROF_LEAVE(tag,tag->name,"tag");
PROFILE_SWITCH (ctx, "tag:" + tag->name, "rxml internal");
- THIS_TAG_DEBUG ((exec ? "Exec array" : "Zero") +
- " returned from do_enter\n");
+ THIS_TAG_DEBUG ((exec ? "Exec array of length " + sizeof (exec) :
+ "Zero") + " returned from do_enter\n");
}
if (ctx->new_runtime_tags)
_handle_runtime_tags (ctx, parser);
2802: Inside #if defined(DEBUG)
fatal_error ("Internal error: Thanks, we think about how nice "
"it must be to play the harmonica...\n");
#endif
- if (result_type->name != parser->type->name) {
- THIS_TAG_DEBUG (sprintf ("Converting result from %s to %s of "
+ if (result_type->name != type->name) {
+ THIS_TAG_DEBUG ("Converting result from %s to %s of "
"surrounding content\n",
- result_type->name, parser->type->name));
- res = parser->type->encode (res, result_type);
+ result_type->name, type->name);
+ res = type->encode (res, result_type);
}
ctx->unwind_state = (["stream_piece": res]);
- THIS_TAG_DEBUG (sprintf ("Streaming %t from do_enter\n", res));
+ THIS_TAG_DEBUG ("Streaming %t from do_enter\n", res);
throw (this);
}
2817:
}
}
eval_state = EVSTAT_ENTERED;
-
+
/* Fall through. */
-
+
case EVSTAT_ENTERED:
case EVSTAT_LAST_ITER:
do {
2830: Inside #if defined(DEBUG)
eval_state = EVSTAT_LAST_ITER;
#ifdef DEBUG
if (iter > 1)
- THIS_TAG_DEBUG (sprintf ("Getting %d iterations from do_iterate\n",
- iter));
+ THIS_TAG_DEBUG ("Getting %d iterations from do_iterate\n", iter);
else if (iter < 0)
THIS_TAG_DEBUG ("Skipping to finish since do_iterate is negative\n");
#endif
2844:
id); // Might unwind.
COND_PROF_LEAVE(tag,tag->name,"tag");
PROFILE_SWITCH (ctx, "tag:" + tag->name, "rxml internal");
- THIS_TAG_DEBUG (sprintf ("%O returned from do_iterate\n", iter));
+ THIS_TAG_DEBUG ("%O returned from do_iterate\n", iter);
if (ctx->new_runtime_tags)
_handle_runtime_tags (ctx, parser);
if (!iter) eval_state = EVSTAT_LAST_ITER;
2871:
subparser = content_type->get_parser (
ctx, [object(TagSet)] this->local_tags, parser);
subparser->_local_tag_set = 1;
- THIS_TAG_DEBUG (
- sprintf ("Iter[%d]: Evaluating content with %O "
- "from local_tags\n", debug_iter, subparser));
+ THIS_TAG_DEBUG ("Iter[%d]: Evaluating content with %O "
+ "from local_tags\n", debug_iter, subparser);
}
else {
subparser = content_type->get_parser (ctx, 0, parser);
#ifdef DEBUG
if (content_type->parser_prog != PNone)
- THIS_TAG_DEBUG (sprintf ("Iter[%d]: Evaluating content "
- "with %O\n", debug_iter, subparser));
+ THIS_TAG_DEBUG ("Iter[%d]: Evaluating content with %O\n",
+ debug_iter, subparser);
#endif
}
if (parser->recover_errors && !(flags & FLAG_DONT_RECOVER))
2897:
mixed res = subparser->read();
if (content_type->sequential) piece = res + piece;
else if (piece == nil) piece = res;
- THIS_TAG_DEBUG (
- sprintf ("Iter[%d]: Got %s %t stream piece\n",
- debug_iter, finished ? "ending" : "a", piece));
+ THIS_TAG_DEBUG ("Iter[%d]: Got %s %t stream piece\n",
+ debug_iter, finished ? "ending" : "a", piece);
if (piece != nil) {
array|function(RequestID,void|mixed:array) do_process;
2908:
this->do_process) &&
!arrayp (do_process)) {
if (!exec) {
- THIS_TAG_DEBUG (sprintf ("Iter[%d]: Calling do_process in "
- "streaming mode\n", debug_iter));
+ THIS_TAG_DEBUG ("Iter[%d]: Calling do_process in "
+ "streaming mode\n", debug_iter);
PROFILE_SWITCH (ctx, "rxml internal", "tag:" + tag->name);
COND_PROF_ENTER(tag,tag->name,"tag");
exec = do_process (id, piece); // Might unwind.
COND_PROF_LEAVE(tag,tag->name,"tag");
PROFILE_SWITCH (ctx, "tag:" + tag->name, "rxml internal");
- THIS_TAG_DEBUG (sprintf ("Iter[%d]: %s returned from "
- "do_process\n", debug_iter,
- exec ? "Exec array" : "Zero"));
+ THIS_TAG_DEBUG ("Iter[%d]: %s returned from do_process\n",
+ debug_iter, exec ? "Exec array of length " +
+ sizeof (exec) : "Zero");
if (ctx->new_runtime_tags)
_handle_runtime_tags (ctx, parser);
}
if (exec) {
THIS_TAG_DEBUG_ENTER_SCOPE (
- ctx, this, sprintf ("Iter[%d]: Entering scope\n",
- debug_iter));
+ ctx, this, "Iter[%d]: Entering scope\n", debug_iter);
ENTER_SCOPE (ctx, this);
mixed res = _exec_array (
parser, exec, flags & FLAG_PARENT_SCOPE); // Might unwind.
2936: Inside #if defined(DEBUG)
fatal_error ("Internal error: Clobbering "
"unwind_state->stream_piece.\n");
#endif
- if (result_type->name != parser->type->name) {
+ if (result_type->name != type->name) {
THIS_TAG_DEBUG (
- sprintf ("Iter[%d]: Converting result from %s to %s"
+ "Iter[%d]: Converting result from %s to %s"
" of surrounding content\n", debug_iter,
- result_type->name, parser->type->name));
- res = parser->type->encode (res, result_type);
+ result_type->name, type->name);
+ res = type->encode (res, result_type);
}
ctx->unwind_state->stream_piece = res;
- THIS_TAG_DEBUG (
- sprintf ("Iter[%d]: Streaming %t from "
- "do_process\n", debug_iter, res));
+ THIS_TAG_DEBUG ("Iter[%d]: Streaming %t from "
+ "do_process\n", debug_iter, res);
throw (this);
}
exec = 0;
}
else if (flags & FLAG_STREAM_RESULT) {
- THIS_TAG_DEBUG (
- sprintf ("Iter[%d]: do_process finished the stream; "
- "ignoring remaining content\n", debug_iter));
+ THIS_TAG_DEBUG ("Iter[%d]: do_process finished the stream; "
+ "ignoring remaining content\n", debug_iter);
ctx->unwind_state = 0;
piece = nil;
break process_subparser;
2971:
if (finished) {
mixed res = subparser->eval(); // Might unwind.
if (content_type->sequential) {
- THIS_TAG_DEBUG (sprintf ("Iter[%d]: Adding %t to content\n",
- debug_iter, res));
+ THIS_TAG_DEBUG ("Iter[%d]: Adding %t to content\n",
+ debug_iter, res);
content += res;
}
else if (res != nil) {
- THIS_TAG_DEBUG (sprintf ("Iter[%d]: Setting content to %t\n",
- debug_iter, res));
+ THIS_TAG_DEBUG ("Iter[%d]: Setting content to %t\n",
+ debug_iter, res);
content = res;
}
break process_subparser;
2995:
[array|function(RequestID,void|mixed:array)] this->do_process) {
if (!exec) {
if (arrayp (do_process)) {
- THIS_TAG_DEBUG (sprintf ("Iter[%d]: Getting exec array from "
- "do_process\n", debug_iter));
+ THIS_TAG_DEBUG ("Iter[%d]: Getting exec array from do_process\n",
+ debug_iter);
exec = [array] do_process;
}
else {
- THIS_TAG_DEBUG (sprintf ("Iter[%d]: Calling do_process\n",
- debug_iter));
+ THIS_TAG_DEBUG ("Iter[%d]: Calling do_process\n", debug_iter);
PROFILE_SWITCH (ctx, "rxml internal", "tag:" + tag->name);
COND_PROF_ENTER(tag,tag->name,"tag");
exec = ([function(RequestID,void|mixed:array)] do_process) (
id); // Might unwind.
COND_PROF_LEAVE(tag,tag->name,"tag");
PROFILE_SWITCH (ctx, "tag:" + tag->name, "rxml internal");
- THIS_TAG_DEBUG (sprintf ("Iter[%d]: %s returned from do_process\n",
- debug_iter, exec ? "Exec array" : "Zero"));
+ THIS_TAG_DEBUG ("Iter[%d]: %s returned from do_process\n",
+ debug_iter, exec ? "Exec array of length " +
+ sizeof (exec) : "Zero");
}
if (ctx->new_runtime_tags)
_handle_runtime_tags (ctx, parser);
3017:
if (exec) {
THIS_TAG_DEBUG_ENTER_SCOPE (
- ctx, this, sprintf ("Iter[%d]: Entering scope\n", debug_iter));
+ ctx, this, "Iter[%d]: Entering scope\n", debug_iter);
ENTER_SCOPE (ctx, this);
mixed res = _exec_array (
parser, exec, flags & FLAG_PARENT_SCOPE); // Might unwind.
3031: Inside #if defined(DEBUG)
fatal_error ("Internal error: Thanks, we think about how nice "
"it must be to play the harmonica...\n");
#endif
- if (result_type->name != parser->type->name) {
- THIS_TAG_DEBUG (sprintf ("Iter[%d]: Converting result from "
- "type %s to type %s of surrounding "
- "content\n", debug_iter,
- result_type->name, parser->type->name));
- res = parser->type->encode (res, result_type);
+ if (result_type->name != type->name) {
+ THIS_TAG_DEBUG ("Iter[%d]: Converting result from "
+ "type %s to type %s of surrounding content\n",
+ debug_iter,
+ result_type->name, type->name);
+ res = type->encode (res, result_type);
}
ctx->unwind_state = (["stream_piece": res]);
- THIS_TAG_DEBUG (sprintf ("Iter[%d]: Streaming %t from "
- "do_process\n", debug_iter, res));
+ THIS_TAG_DEBUG ("Iter[%d]: Streaming %t from do_process\n",
+ debug_iter, res);
throw (this);
}
3050:
}
} while (eval_state != EVSTAT_LAST_ITER);
-
+
/* Fall through. */
-
+
case EVSTAT_ITER_DONE:
if (array|function(RequestID:array) do_return =
[array|function(RequestID:array)] this->do_return) {
3068:
exec = ([function(RequestID:array)] do_return) (id); // Might unwind.
COND_PROF_LEAVE(tag,tag->name,"tag");
PROFILE_SWITCH (ctx, "tag:" + tag->name, "rxml internal");
- THIS_TAG_DEBUG ((exec ? "Exec array" : "Zero") +
- " returned from do_return\n");
+ THIS_TAG_DEBUG ((exec ? "Exec array of length " + sizeof (exec) :
+ "Zero") + " returned from do_return\n");
}
if (ctx->new_runtime_tags)
_handle_runtime_tags (ctx, parser);
3086:
else if (result == nil && !(flags & FLAG_EMPTY_ELEMENT)) {
if (result_type->parser_prog == PNone) {
if (content_type->name != result_type->name) {
- THIS_TAG_DEBUG (sprintf ("Assigning content to result after "
+ THIS_TAG_DEBUG ("Assigning content to result after "
"converting from %s to %s\n",
- content_type->name, result_type->name));
+ content_type->name, result_type->name);
result = result_type->encode (content, content_type);
}
else {
3108:
exec = 0;
}
}
- else {
+
#ifdef DEBUG
- if (!(flags & FLAG_EMPTY_ELEMENT))
- THIS_TAG_DEBUG ("Skipping nil result\n");
+ if (result == nil) THIS_TAG_DEBUG ("Skipping nil result\n");
#endif
-
+
+ if (result != nil && result_type->name != type->name) {
+ THIS_TAG_DEBUG (
+ "Converting result from %s to %s of surrounding content\n",
+ result_type->name, type->name);
+ conv_result = type->encode (result, result_type);
}
-
+ else conv_result = result;
THIS_TAG_DEBUG_LEAVE_SCOPE (ctx, this, "Leaving scope\n");
LEAVE_SCOPE (ctx, this);
- }
+
if (ctx->new_runtime_tags)
_handle_runtime_tags (ctx, parser);
-
+ }
}) {
THIS_TAG_DEBUG_LEAVE_SCOPE (ctx, this, "Leaving scope\n");
3195:
#endif
throw (this);
case "continue": // Continue in this frame through tail recursion.
- _eval (parser);
- return;
+ return _eval (parser, type);
case "return": // A normal return.
break process_tag;
default:
3215:
ctx->frame = up;
ctx->frame_depth--;
if (err1) throw (err1);
+ return conv_result;
}
MARK_OBJECT;
3300:
//! 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.
+ //! e.g. @tt{({"a", 2, "b"})@} corresponds to @tt{val["a"][2]["c"]@}.
+ //! @[scope_name] is used to identify the context for the indexing.
//!
//! The special RXML index rules are:
//!