summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2011-10-18 02:38:00 -0400
committerKaz Kylheku <kaz@kylheku.com>2011-10-18 02:38:00 -0400
commitbfdebfbea53a440d279e535c75bec78931c7ded9 (patch)
treed4441b48d2484269be97247918a0840a0b11a197
parent934400e65056e4a85af3bebd7ce8d7ac2ea1f426 (diff)
downloadtxr-bfdebfbea53a440d279e535c75bec78931c7ded9.tar.gz
txr-bfdebfbea53a440d279e535c75bec78931c7ded9.tar.bz2
txr-bfdebfbea53a440d279e535c75bec78931c7ded9.zip
Task #11425
* match.c (spec_bind): New macro. (v_freeform): New function. (match_files): Freeform logic moved to function. (dir_tables_init): v_freeform entered into table.
-rw-r--r--ChangeLog9
-rw-r--r--match.c88
2 files changed, 58 insertions, 39 deletions
diff --git a/ChangeLog b/ChangeLog
index 8a61a226..d4439db4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,15 @@
Task #11425
+ * match.c (spec_bind): New macro.
+ (v_freeform): New function.
+ (match_files): Freeform logic moved to function.
+ (dir_tables_init): v_freeform entered into table.
+
+2011-10-18 Kaz Kylheku <kaz@kylheku.com>
+
+ Task #11425
+
* match.c (same_data_k): Symbol variable renamed to next_spec_k.
(v_skip): Restructured not to return next_spec_k when there
are no more specs, but rather thread directly to what match_file
diff --git a/match.c b/match.c
index 9a88b552..682469bd 100644
--- a/match.c
+++ b/match.c
@@ -1314,6 +1314,12 @@ static val match_files(match_files_ctx a);
typedef val (*v_match_func)(match_files_ctx c, match_files_ctx *cout);
+#define spec_bind(specline_var, spec_linenum_var, first_spec_var, spec) \
+ val s_p_ ## specline_var = first(spec); \
+ val specline_var = rest(s_p_ ## specline_var); \
+ val spec_linenum_var = first(s_p_ ## specline_var); \
+ val first_spec = first(specline_var)
+
static val v_skip(match_files_ctx c, match_files_ctx *cout)
{
val specline = rest(first(c.spec));
@@ -1419,6 +1425,47 @@ static val v_trailer(match_files_ctx c, match_files_ctx *cout)
}
}
+static val v_freeform(match_files_ctx c, match_files_ctx *cout)
+{
+ spec_bind (specline, spec_linenum, first_spec, c.spec);
+
+ val args = rest(first_spec);
+ val vals = mapcar(func_n1(cdr),
+ mapcar(curry_123_2(func_n3(eval_form),
+ spec_linenum, c.bindings), args));
+
+ if ((c.spec = rest(c.spec)) == nil) {
+ sem_error(spec_linenum,
+ lit("freeform must be followed by a query line"), nao);
+ } else {
+ val limit = or2(if2(nump(first(vals)), first(vals)),
+ if2(nump(second(vals)), second(vals)));
+ val term = or2(if2(stringp(first(vals)), first(vals)),
+ if2(stringp(second(vals)), second(vals)));
+ val ff_specline = rest(first(c.spec));
+ val ff_dataline = lazy_str(c.data, term, limit);
+
+ cons_bind (new_bindings, success,
+ match_line(c.bindings, ff_specline, ff_dataline, zero,
+ spec_linenum, c.data_lineno, first(c.files)));
+
+ if (!success) {
+ debuglf(spec_linenum, lit("freeform match failure"), nao);
+ return nil;
+ }
+
+ if (nump(success)) {
+ c.data = lazy_str_get_trailing_list(ff_dataline, success);
+ c.data_lineno = plus(c.data_lineno, num(1));
+ }
+
+ c.bindings = new_bindings;
+ }
+
+ *cout = c;
+ return next_spec_k;
+}
+
static val match_files(match_files_ctx c)
{
gc_hint(c.data);
@@ -1489,45 +1536,7 @@ repeat_spec_same_data:
}
}
- if (sym == freeform_s) {
- val args = rest(first_spec);
- val vals = mapcar(func_n1(cdr),
- mapcar(curry_123_2(func_n3(eval_form),
- spec_linenum, c.bindings), args));
-
- if ((c.spec = rest(c.spec)) == nil) {
- sem_error(spec_linenum,
- lit("freeform must be followed by a query line"), nao);
- } else {
- val limit = or2(if2(nump(first(vals)), first(vals)),
- if2(nump(second(vals)), second(vals)));
- val term = or2(if2(stringp(first(vals)), first(vals)),
- if2(stringp(second(vals)), second(vals)));
- val ff_specline = rest(first(c.spec));
- val ff_dataline = lazy_str(c.data, term, limit);
-
- cons_bind (new_bindings, success,
- match_line(c.bindings, ff_specline, ff_dataline, zero,
- spec_linenum, c.data_lineno, first(c.files)));
-
- if (!success) {
- debuglf(spec_linenum, lit("freeform match failure"), nao);
- return nil;
- }
-
- if (nump(success)) {
- c.data = lazy_str_get_trailing_list(ff_dataline, success);
- c.data_lineno = plus(c.data_lineno, num(1));
- }
-
- c.bindings = new_bindings;
- }
-
- if ((c.spec = rest(c.spec)) == nil)
- break;
-
- goto repeat_spec_same_data;
- } else if (sym == block_s) {
+ if (sym == block_s) {
val name = first(rest(first_spec));
if (rest(specline))
sem_error(spec_linenum,
@@ -2462,6 +2471,7 @@ static void dir_tables_init(void)
sethash(v_directive_table, skip_s, cptr((mem_t *) v_skip));
sethash(v_directive_table, trailer_s, cptr((mem_t *) v_trailer));
+ sethash(v_directive_table, freeform_s, cptr((mem_t *) v_freeform));
}
void match_init(void)