diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2014-10-15 19:05:43 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2014-10-15 19:05:43 -0700 |
commit | 8eb4688b095bbdadfa05d0b853df662ac653e3d5 (patch) | |
tree | cfd3e5f2be60de09793cea305ad4a68f1a4e5866 | |
parent | 8807a16fe3115e19ce4d65f1c8beb476494ccaec (diff) | |
download | txr-8eb4688b095bbdadfa05d0b853df662ac653e3d5.tar.gz txr-8eb4688b095bbdadfa05d0b853df662ac653e3d5.tar.bz2 txr-8eb4688b095bbdadfa05d0b853df662ac653e3d5.zip |
* match.c (subst_vars): Fix buggy rendering of TXR Lisp expressions
that evaluate to lists. For instance `@(list)` renders to the
string "nil", and `@(list 1 2)` renders as "(1 2)". The desired
behavior is "" and "1 2", respectively.
(do_output_line): In output directives, there is a similar problem.
A @(list) in the middle of an output block turns to nil, and
a @(list 1 2) renders in parentheses as (1 2). Furthermore,
there is the additional problem that no filtering is applied
to the interpolated value. These behaviors are subject to the
compatibility option, since they change the externally visible
behavior of TXR programs.
* txr.1: Document that empty lists in @(output) variable substitutions
turn into nothing. Document value of 100 for -C option, describing
the above issue.
-rw-r--r-- | ChangeLog | 18 | ||||
-rw-r--r-- | match.c | 29 | ||||
-rw-r--r-- | txr.1 | 15 |
3 files changed, 57 insertions, 5 deletions
@@ -1,3 +1,21 @@ +2014-10-15 Kaz Kylheku <kaz@kylheku.com> + + * match.c (subst_vars): Fix buggy rendering of TXR Lisp expressions + that evaluate to lists. For instance `@(list)` renders to the + string "nil", and `@(list 1 2)` renders as "(1 2)". The desired + behavior is "" and "1 2", respectively. + (do_output_line): In output directives, there is a similar problem. + A @(list) in the middle of an output block turns to nil, and + a @(list 1 2) renders in parentheses as (1 2). Furthermore, + there is the additional problem that no filtering is applied + to the interpolated value. These behaviors are subject to the + compatibility option, since they change the externally visible + behavior of TXR programs. + + * txr.1: Document that empty lists in @(output) variable substitutions + turn into nothing. Document value of 100 for -C option, describing + the above issue. + 2014-10-14 Kaz Kylheku <kaz@kylheku.com> More type safety, with help from C++ compiler. @@ -1422,9 +1422,19 @@ static val subst_vars(val spec, val bindings, val filter) spec = cdr(spec); continue; } else if (sym == expr_s) { - val result = eval(rest(elem), make_env(bindings, nil, nil), elem); - spec = cons(filter_string_tree(filter, tostringp(result)), rest(spec)); - continue; + if (opt_compat && opt_compat < 100) { + val result = eval(rest(elem), make_env(bindings, nil, nil), elem); + spec = cons(filter_string_tree(filter, tostringp(result)), rest(spec)); + continue; + } else { + val str = eval(rest(elem), make_env(bindings, nil, nil), elem); + if (listp(str)) + str = cat_str(mapcar(func_n1(tostringp), str), lit(" ")); + else if (!stringp(str)) + str = tostringp(str); + spec = cons(filter_string_tree(filter, tostringp(str)), rest(spec)); + continue; + } } else { val nested = subst_vars(elem, bindings, filter); iter = list_collect_append(iter, nested); @@ -1774,8 +1784,17 @@ static void do_output_line(val bindings, val specline, val filter, val out) } } else if (directive == expr_s) { - format(out, lit("~a"), - eval(rest(elem), make_env(bindings, nil, nil), elem), nao); + if (opt_compat && opt_compat < 100) { + format(out, lit("~a"), + eval(rest(elem), make_env(bindings, nil, nil), elem), nao); + } else { + val str = cat_str(subst_vars(cons(elem, nil), + bindings, filter), nil); + if (str == nil) + sem_error(specline, lit("bad substitution: ~a"), + second(elem), nao); + put_string(str, out); + } } } break; @@ -6731,6 +6731,7 @@ A list is converted to a string in a special way: the elements are individually converted to a string and then they are catenated together. The default separator string is a single space: an alternate separation can be specified as an argument in the brace substitution syntax. +Empty lists turn into an empty string. Lists may be output within .code @(repeat) @@ -25322,6 +25323,20 @@ can be emulated is \*(TX 97. Here are values which have a special meaning as arguments to the .code -C option, along with a description of what behaviors are affected: +.IP 99 +Up to \*(TX 99, the substitution of TXR Lisp expressions in +.code @(output) +directives and in the quasistrings of the pattern language +exhibited the buggy behavior that if the TXR Lisp expression +produced a list, the list was rendered as a parenthesized +representation, or the text +.code nil +in the empty list case. Moreover, in the +.code @(output) +case, the value of TXR Lisp expressions was not subject to filtering. +Starting with \*(TX 100, these issues +are fixed, making the the behavior is consistent with +the behavior of TXR Lisp quasiliterals. .IP 97 Up to \*(TX 97, the error exception symbols such as .code file-error |