summaryrefslogtreecommitdiffstats
path: root/stream.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2011-10-26 13:23:38 -0400
committerKaz Kylheku <kaz@kylheku.com>2011-10-26 13:23:38 -0400
commitad46d49574ea8ada67d8644c70817502c8591305 (patch)
treefc069f9eefe2edda87733f24937cc4103d7d414d /stream.c
parentdabff9ab6f89a1ec36461022a811c1f10cd09f17 (diff)
downloadtxr-ad46d49574ea8ada67d8644c70817502c8591305.tar.gz
txr-ad46d49574ea8ada67d8644c70817502c8591305.tar.bz2
txr-ad46d49574ea8ada67d8644c70817502c8591305.zip
Parse error handling improvements.
* parser.l (prepared_error_message): New static variable. (yyerror): Emit and clear prepared error message. (yyerrprepf): New static function. (yybadtoken): Function moved into parser.y. (grammar): For irrecoverable lexical errors, stash error message with yyerrprepf and return the special error token ERRTOK to generate a syntax error. I could find no other interface to the parser to make it cleanly exit. * parser.y (ERRTOK): New terminal symbol, does not appear anywhere in the grammar. (spec): Bail after 8 errors, recover to nearest newline, and use yyerrok to clear error situation. (YYEOF): Provided by Bison, conditionally defined for other yacc-s. (yybadtoken): Function moved from parser.l. Checks for the next token being YYEMPTY or YYEOF, and also handles ERRTOK. * stream.c (vformat_to_string): New function. (format): If stream is nil, format to string and return it. * stream.h (vformat_to_string): Declared.
Diffstat (limited to 'stream.c')
-rw-r--r--stream.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/stream.c b/stream.c
index bb9641df..6062d91e 100644
--- a/stream.c
+++ b/stream.c
@@ -998,8 +998,16 @@ toobig:
internal_error("ridiculous precision or field width in format");
}
+val vformat_to_string(val fmtstr, va_list vl)
+{
+ val stream = make_string_output_stream();
+ (void) vformat(stream, fmtstr, vl);
+ return get_string_from_stream(stream);
+}
+
val format(val stream, val str, ...)
{
+ val st = or2(stream, make_string_output_stream());
type_check (stream, COBJ);
type_assert (stream->co.cls == stream_s, (lit("~a is not a stream"),
stream, nao));
@@ -1008,9 +1016,9 @@ val format(val stream, val str, ...)
va_list vl;
val ret;
va_start (vl, str);
- ret = vformat(stream, str, vl);
+ ret = vformat(st, str, vl);
va_end (vl);
- return ret;
+ return (stream) ? ret : get_string_from_stream(st);
}
}