summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-03-26 20:28:53 -0700
committerKaz Kylheku <kaz@kylheku.com>2012-03-26 20:28:53 -0700
commit3a39417c79287b8231e70c4a2742fd8ebe3331ef (patch)
treede10b519a6e283115595dc661d64ae40c64df373
parenta039c6a600ec6e1ad03fb0c5b1ada336ddf8fdb7 (diff)
downloadtxr-3a39417c79287b8231e70c4a2742fd8ebe3331ef.tar.gz
txr-3a39417c79287b8231e70c4a2742fd8ebe3331ef.tar.bz2
txr-3a39417c79287b8231e70c4a2742fd8ebe3331ef.zip
Filtering on lists and nested lists is hereby made to work.
For instance given @(bind a ("a" "b" "c")) it is now possible to do @(filter :upcase a) whereby a promptly takes on the value ("A" "B" "C"). * filter.c (string_filter): Function renamed to string_tree_filter. (compound_filter): Follows rename. (filter_string): Function renamed to filter string tree. Can filter tree of strings, or possibly other objects, if the filter function allows. (filter_equal): No special case test for objects that are strings. Just put them through the filter. * filter.h (filter_string): Declaration updated. * match.c (format_field, subst_vars, v_filter): Follow rename.
-rw-r--r--ChangeLog19
-rw-r--r--filter.c42
-rw-r--r--filter.h2
-rw-r--r--match.c6
4 files changed, 48 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index d6b2e1e6..29472e77 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
2012-03-26 Kaz Kylheku <kaz@kylheku.com>
+ Filtering on lists and nested lists is hereby made to work.
+ For instance given @(bind a ("a" "b" "c")) it is now possible
+ to do @(filter :upcase a) whereby a promptly takes on the value
+ ("A" "B" "C").
+
+ * filter.c (string_filter): Function renamed to string_tree_filter.
+ (compound_filter): Follows rename.
+ (filter_string): Function renamed to filter string tree.
+ Can filter tree of strings, or possibly other objects,
+ if the filter function allows.
+ (filter_equal): No special case test for objects that are strings.
+ Just put them through the filter.
+
+ * filter.h (filter_string): Declaration updated.
+
+ * match.c (format_field, subst_vars, v_filter): Follow rename.
+
+2012-03-26 Kaz Kylheku <kaz@kylheku.com>
+
* match.c (v_output): Bugfix: we should flush the stream
after each @(output) block. Otherwise if output blocks
that go to standard output are interleaved with output blocks
diff --git a/filter.c b/filter.c
index 3fc262a7..958d4911 100644
--- a/filter.c
+++ b/filter.c
@@ -134,14 +134,14 @@ val trie_lookup_feed_char(val node, val ch)
return nil;
}
-static val string_filter(val str, val filter)
+static val string_tree_filter(val tree, val filter)
{
- return filter_string(filter, str);
+ return filter_string_tree(filter, tree);
}
static val compound_filter(val filter_list, val string)
{
- return reduce_left(func_n2(string_filter), filter_list, string, nil);
+ return reduce_left(func_n2(string_tree_filter), filter_list, string, nil);
}
val get_filter(val spec)
@@ -233,25 +233,33 @@ static val trie_filter_string(val filter, val str)
return out;
}
-val filter_string(val filter, val str)
+val filter_string_tree(val filter, val obj)
{
- val type = typeof(filter);
-
- if (eq(type, null))
- return str;
- if (eq(type, hash_s) || eq(type, cons_s))
- return trie_filter_string(filter, str);
- else if (type == fun_s)
- return funcall1(filter, str);
- return str;
- uw_throwf(error_s, lit("filter_string: invalid filter ~a"), filter, nao);
+ switch (type(obj)) {
+ case NIL:
+ return nil;
+ case CONS:
+ return mapcar(curry_12_2(func_n2(filter_string_tree), filter), obj);
+ default:
+ {
+ val type = typeof(filter);
+
+ if (eq(type, null))
+ return obj;
+ if (eq(type, hash_s) || eq(type, cons_s))
+ return trie_filter_string(filter, obj);
+ else if (type == fun_s)
+ return funcall1(filter, obj);
+ return obj;
+ uw_throwf(error_s, lit("filter_string: invalid filter ~a"), filter, nao);
+ }
+ }
}
val filter_equal(val lfilt, val rfilt, val left, val right)
{
- if (stringp(left) && stringp(right))
- return equal(filter_string(lfilt, left), filter_string(rfilt, right));
- return equal(left, right);
+ return equal(filter_string_tree(lfilt, left),
+ filter_string_tree(rfilt, right));
}
val register_filter(val sym, val table)
diff --git a/filter.h b/filter.h
index 8c1c0df4..c9ab513f 100644
--- a/filter.h
+++ b/filter.h
@@ -34,7 +34,7 @@ val trie_lookup_begin(val trie);
val trie_value_at(val node);
val trie_lookup_feed_char(val node, val ch);
val get_filter(val sym);
-val filter_string(val trie, val str);
+val filter_string_tree(val trie, val str_tree);
val filter_equal(val lfilt, val rfilt, val left, val right);
val register_filter(val sym, val table);
diff --git a/match.c b/match.c
index b70a796e..e2128111 100644
--- a/match.c
+++ b/match.c
@@ -1291,7 +1291,7 @@ val format_field(val obj, val modifier, val filter, val eval_fun)
}
if (filter)
- str = filter_string(filter, str);
+ str = filter_string_tree(filter, str);
}
{
@@ -1347,7 +1347,7 @@ static val subst_vars(val spec, val bindings, val filter)
else
str = if3(stringp(str), str, tostringp(str));
- spec = cons(filter_string(filter, str), rest(spec));
+ spec = cons(filter_string_tree(filter, str), rest(spec));
}
continue;
@@ -3312,7 +3312,7 @@ static val v_filter(match_files_ctx *c)
if (!existing)
sem_error(specline, lit("filter: variable ~a is unbound"), var, nao);
- *cdr_l(existing) = filter_string(filter, cdr(existing));
+ *cdr_l(existing) = filter_string_tree(filter, cdr(existing));
}
uw_env_end;