summaryrefslogtreecommitdiffstats
path: root/match.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-01-26 12:26:16 -0800
committerKaz Kylheku <kaz@kylheku.com>2012-01-26 12:26:16 -0800
commitb58791b726228b97297cc4512476f6016b9346a2 (patch)
tree2ed1b157bb29f6f90c97565adac4b2d54c2e1912 /match.c
parentb7aae46f879bfc8a43781a08aaef9f506f7211bf (diff)
downloadtxr-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.c59
1 files changed, 43 insertions, 16 deletions
diff --git a/match.c b/match.c
index 66236781..eb6e347e 100644
--- a/match.c
+++ b/match.c
@@ -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));
}
}
}