summaryrefslogtreecommitdiffstats
path: root/match.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2011-10-07 21:19:04 -0700
committerKaz Kylheku <kaz@kylheku.com>2011-10-07 21:19:04 -0700
commit81c5eee132546c90d878065722f52e70b27c359f (patch)
tree41e8b45cc3e000898b5c532c7a0fd4282159ff46 /match.c
parentf5af9dd56254dd90f5985eb3e1dcbab042d72431 (diff)
downloadtxr-81c5eee132546c90d878065722f52e70b27c359f.tar.gz
txr-81c5eee132546c90d878065722f52e70b27c359f.tar.bz2
txr-81c5eee132546c90d878065722f52e70b27c359f.zip
* lib.c (eol_s): New symbol variable.
(obj_init): New variable initialized. * lib.h (eol_s): Declared. * match.c (match_line): Implemented horizontal skip as and new eol directive. (match_lines): Vertical skip defers to horizontal skip if there is trailing material. * txr.1: Updated. * lib.c (eol_s): New symbol variable. (obj_init): New variable initialized. * lib.h (eol_s): Declared. * match.c (match_line): Implemented horizontal skip as and new eol directive. (match_lines): Vertical skip defers to horizontal skip if there is trailing material. * txr.1: Updated.
Diffstat (limited to 'match.c')
-rw-r--r--match.c67
1 files changed, 60 insertions, 7 deletions
diff --git a/match.c b/match.c
index 19b527b5..b310afcb 100644
--- a/match.c
+++ b/match.c
@@ -486,6 +486,54 @@ static val match_line(val bindings, val specline, val dataline,
}
LOG_MATCH("regex", past);
pos = past;
+ } else if (directive == skip_s) {
+ val max = second(elem);
+ val min = third(elem);
+ cnum cmax = nump(max) ? c_num(max) : 0;
+ cnum cmin = nump(min) ? c_num(min) : 0;
+
+ if (!rest(specline))
+ break;
+
+ {
+ cnum reps_max = 0, reps_min = 0;
+
+ while (length_str_gt(dataline, pos) && min && reps_min < cmin) {
+ pos = plus(pos, one);
+ reps_min++;
+ }
+
+ if (min) {
+ if (reps_min != cmin) {
+ debuglf(spec_lineno,
+ lit("skipped only ~a/~a chars to ~a:~a:~a"),
+ num(reps_min), num(cmin),
+ file, data_lineno, pos, nao);
+ return nil;
+ }
+
+ debuglf(spec_lineno, lit("skipped ~a chars to ~a:~a:~a"),
+ num(reps_min), file, data_lineno, pos, nao);
+ }
+
+ while (!max || reps_max++ < cmax) {
+ val result = match_line(bindings, rest(specline), dataline, pos,
+ spec_lineno, data_lineno, file);
+
+ if (result) {
+ LOG_MATCH("skip", pos);
+ return result;
+ }
+
+ if (length_str_le(dataline, pos))
+ break;
+
+ pos = plus(pos, one);
+ }
+ }
+
+ LOG_MISMATCH("skip");
+ return nil;
} else if (directive == coll_s) {
val coll_specline = second(elem);
val until_last_specline = third(elem);
@@ -682,6 +730,13 @@ next_coll:
}
LOG_MATCH("trailer", new_pos);
return cons(bindings, pos);
+ } else if (directive == eol_s) {
+ if (length_str_le(dataline, pos)) {
+ LOG_MATCH("eol", pos);
+ return cons(bindings, t);
+ }
+ LOG_MISMATCH("eol");
+ return nil;
} else if (consp(directive) || stringp(directive)) {
cons_bind (find, len, search_str_tree(dataline, elem, pos, nil));
val newpos;
@@ -1187,16 +1242,14 @@ repeat_spec_same_data:
if (consp(first_spec)) {
val sym = first(first_spec);
- if (sym == skip_s) {
- val max = first(rest(first_spec));
- val min = second(rest(first_spec));
+
+ if (sym == skip_s && rest(specline) == nil) {
+ val args = rest(first_spec);
+ val max = first(args);
+ val min = second(args);
cnum cmax = nump(max) ? c_num(max) : 0;
cnum cmin = nump(min) ? c_num(min) : 0;
- if (rest(specline))
- sem_error(spec_linenum,
- lit("unexpected material after skip directive"), nao);
-
if ((spec = rest(spec)) == nil)
break;