diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2012-01-26 12:26:16 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2012-01-26 12:26:16 -0800 |
commit | b58791b726228b97297cc4512476f6016b9346a2 (patch) | |
tree | 2ed1b157bb29f6f90c97565adac4b2d54c2e1912 /match.c | |
parent | b7aae46f879bfc8a43781a08aaef9f506f7211bf (diff) | |
download | txr-b58791b726228b97297cc4512476f6016b9346a2.tar.gz txr-b58791b726228b97297cc4512476f6016b9346a2.tar.bz2 txr-b58791b726228b97297cc4512476f6016b9346a2.zip |
* eval.c (dwim_loc, dwim_op): Eliminated redundant re-evaluation
of range arguments. They are already evaluated since the cons
expression is evaluates as part of the dwim arglist.
Replaced some open code with function calls to the new listref
and listref_l functions.
(tostring, tostringp): made extern and moved to lib.c.
* lib.c (listref, listref_l): New functions.
(tostring, tostringp): moved here from eval.c.
* lib.h (listref, listref_l, tostring, tostringp): Declared.
* match.c (format_field): Handle index and range references.
* txr.1: Documented new output variable syntax.
Diffstat (limited to 'match.c')
-rw-r--r-- | match.c | 59 |
1 files changed, 43 insertions, 16 deletions
@@ -1206,33 +1206,60 @@ static val match_line(match_line_ctx c) debug_leave; } -val format_field(val string_or_list, val modifier, val filter, val eval_fun) +val format_field(val obj, val modifier, val filter, val eval_fun) { - val n = zero; + val n = zero, sep = lit(" "); val plist = nil; - - if (!stringp(string_or_list)) - return string_or_list; + val str; for (; modifier; pop(&modifier)) { val item = first(modifier); - if (regexp(item)) + if (regexp(item)) { uw_throw(query_error_s, lit("format_field: regex modifier in output")); - if (keywordp(item)) { + } else if (keywordp(item)) { plist = modifier; break; - } + } else if (consp(item)) { + if (car(item) == dwim_s) { + val arg_expr = second(item); - { + if (consp(arg_expr) && car(arg_expr) == cons_s) { + val from = funcall1(eval_fun, second(arg_expr)); + val to = funcall1(eval_fun, third(arg_expr)); + + obj = if3((vectorp(obj)), + sub_vec(obj, from, to), + sub_list(obj, from, to)); + } else { + val arg = funcall1(eval_fun, arg_expr); + if (bignump(arg) || fixnump(arg)) { + if (vectorp(obj)) + obj = vecref(obj, arg); + else + obj = listref(obj, arg); + } else { + uw_throwf(query_error_s, lit("format_field: bad index: ~s"), + arg, nao); + } + } + } + } else { val v = funcall1(eval_fun, item); if (fixnump(v)) n = v; + else if (stringp(v)) + sep = v; else uw_throwf(query_error_s, lit("format_field: bad modifier object: ~s"), item, nao); } } + if (listp(obj)) + str = cat_str(mapcar(func_n1(tostringp), obj), sep); + else + str = if3(stringp(obj), obj, tostringp(obj)); + { val filter_sym = getplist(plist, filter_k); @@ -1246,27 +1273,27 @@ val format_field(val string_or_list, val modifier, val filter, val eval_fun) } if (filter) - string_or_list = filter_string(filter, cat_str(list(string_or_list, nao), + str = filter_string(filter, cat_str(list(str, nao), nil)); } { val right = lt(n, zero); val width = if3(lt(n, zero), neg(n), n); - val diff = minus(width, length_str(string_or_list)); + val diff = minus(width, length_str(str)); if (le(diff, zero)) - return string_or_list; + return str; - if (ge(length_str(string_or_list), width)) - return string_or_list; + if (ge(length_str(str), width)) + return str; { val padding = mkstring(diff, chr(' ')); return if3(right, - cat_str(list(padding, string_or_list, nao), nil), - cat_str(list(string_or_list, padding, nao), nil)); + cat_str(list(padding, str, nao), nil), + cat_str(list(str, padding, nao), nil)); } } } |