diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2011-10-07 21:19:04 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2011-10-07 21:19:04 -0700 |
commit | 81c5eee132546c90d878065722f52e70b27c359f (patch) | |
tree | 41e8b45cc3e000898b5c532c7a0fd4282159ff46 /match.c | |
parent | f5af9dd56254dd90f5985eb3e1dcbab042d72431 (diff) | |
download | txr-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.c | 67 |
1 files changed, 60 insertions, 7 deletions
@@ -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; |