summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2011-10-23 21:56:57 -0400
committerKaz Kylheku <kaz@kylheku.com>2011-10-23 21:56:57 -0400
commitbb8705bd33c1cfa89cf07573dc5c477bdae1d6d0 (patch)
treeb62c87c230a2aace61851fe09040471a3157b1d2
parent047116716e98766487f4a808ad53e097565dede2 (diff)
downloadtxr-bb8705bd33c1cfa89cf07573dc5c477bdae1d6d0.tar.gz
txr-bb8705bd33c1cfa89cf07573dc5c477bdae1d6d0.tar.bz2
txr-bb8705bd33c1cfa89cf07573dc5c477bdae1d6d0.zip
* match.c (list_k, string_k): New keyword symbol variables.
(v_next): Implement :list and :string keywords. (syms_init): New keyword variables initialized. NOTE: the :var keyword is deprecated. * txr.1: Documented :list and :string.
-rw-r--r--ChangeLog9
-rw-r--r--match.c39
-rw-r--r--txr.120
3 files changed, 59 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 1f3f9e76..bc97d097 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2011-10-23 Kaz Kylheku <kaz@kylheku.com>
+ * match.c (list_k, string_k): New keyword symbol variables.
+ (v_next): Implement :list and :string keywords.
+ (syms_init): New keyword variables initialized.
+ NOTE: the :var keyword is deprecated.
+
+ * txr.1: Documented :list and :string.
+
+2011-10-23 Kaz Kylheku <kaz@kylheku.com>
+
* match.c (h_skip): Bugfix: bad agument list in debugf call.
2011-10-22 Kaz Kylheku <kaz@kylheku.com>
diff --git a/match.c b/match.c
index 06145609..aaab3bc2 100644
--- a/match.c
+++ b/match.c
@@ -53,7 +53,7 @@ val mingap_k, maxgap_k, gap_k, mintimes_k, maxtimes_k, times_k;
val lines_k, chars_k;
val choose_s, longest_k, shortest_k, greedy_k;
val vars_k;
-val append_k, into_k, var_k;
+val append_k, into_k, var_k, list_k, string_k;
static val h_directive_table, v_directive_table;
@@ -1685,13 +1685,21 @@ static val v_next(match_files_ctx c, match_files_ctx *cout)
{
val alist = improper_plist_to_alist(args, list(nothrow_k, nao));
val from_var = cdr(assoc(alist, var_k));
+ val list_expr = cdr(assoc(alist, list_k));
+ val string_expr = cdr(assoc(alist, string_k));
val nothrow = cdr(assoc(alist, nothrow_k));
val eval = eval_form(spec_linenum, source, c.bindings);
val str = cdr(eval);
- if (!from_var && !source)
+ if (!from_var && !source && !string_expr && !list_expr)
sem_error(spec_linenum, lit("next: source required before keyword arguments"), nao);
+ if ((from_var && string_expr) || (string_expr && list_expr) ||
+ (from_var && list_expr))
+ {
+ sem_error(spec_linenum, lit("next: only one of :var, :list or :string can be specified"), nao);
+ }
+
if (from_var) {
val existing = assoc(c.bindings, from_var);
@@ -1711,6 +1719,31 @@ static val v_next(match_files_ctx c, match_files_ctx *cout)
if3(c.data, cons(c.data, c.data_lineno), t));
return nil;
}
+ } else if (list_expr) {
+ val list_val = cdr(eval_form(spec_linenum, list_expr, c.bindings));
+ cons_bind (new_bindings, success,
+ match_files(mf_file_data(c, lit("var"),
+ flatten(list_val), num(1))));
+
+ if (success)
+ return cons(new_bindings,
+ if3(c.data, cons(c.data, c.data_lineno), t));
+ return nil;
+ } else if (string_expr) {
+ val str_val = cdr(eval_form(spec_linenum, string_expr, c.bindings));
+ if (!stringp(str_val))
+ sem_error(spec_linenum, lit(":string arg ~s evaluated to non-string ~s"), string_expr, str_val, nao);
+
+ {
+ cons_bind (new_bindings, success,
+ match_files(mf_file_data(c, lit("var"),
+ split_str(str_val, lit("\n")), num(1))));
+
+ if (success)
+ return cons(new_bindings,
+ if3(c.data, cons(c.data, c.data_lineno), t));
+ return nil;
+ }
} else if (nothrow) {
if (str) {
c.files = cons(cons(nothrow_k, str), c.files);
@@ -2769,6 +2802,8 @@ static void syms_init(void)
append_k = intern(lit("append"), keyword_package);
into_k = intern(lit("into"), keyword_package);
var_k = intern(lit("var"), keyword_package);
+ list_k = intern(lit("list"), keyword_package);
+ string_k = intern(lit("string"), keyword_package);
}
static void dir_tables_init(void)
diff --git a/txr.1 b/txr.1
index 49ea719c..79a49a68 100644
--- a/txr.1
+++ b/txr.1
@@ -1090,7 +1090,8 @@ with, or without arguments:
@(next SOURCE)
@(next SOURCE :nothrow)
@(next :args)
- @(next :var SYMBOL)
+ @(next :list EXPR)
+ @(next :string EXPR)
The lone @(next) without arguments switches to the next file in the
argument list which was passed to the
@@ -1126,10 +1127,16 @@ open the input source named by that argument. If the very first directive of a q
avoids opening the first input source, but it does open the input source for
any other directive, even one which does not consume any data.
-The variant @(next :var SYMBOL) treats a the variable named by SYMBOL
-as a source of text. The contents of the variable are flattened to a list as if
-by the @(flatten) directive (but without modifying the variable).
-The resulting list is treated as if it were the lines of a text file.
+The syntax @(next :list EXPR) treats the expression as a source of
+text. The value of the expression is flattened to a list in a way similar
+to the @(flatten) directive. The resulting list is treated as if it were the
+lines of a text file: each element of the list is a line. If the lines
+happen contain embedded newline characters, they are a visible constituent
+of the line, and do not act as line separators.
+
+The syntax @(next :string EXPR) treats the expression as a source of
+text. The value of the expression must be a string. Newlines in the string are
+interpreted as line terminators.
Note that "remainder of the query" refers to the subquery in which
the next directive appears, not necessarily the entire query.
@@ -1142,8 +1149,7 @@ previous file again.
@(some)
@(next "foo.txt")
xyz@suffix
- @(end)
- abc
+ @(end) abc
However, if the @(some) subquery successfully matched "xyz@suffix" within the
file foo.text, there is now a binding for the suffix variable, which