summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-10-03 20:06:41 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-10-03 20:06:41 -0700
commitb74633f86d69cf1aabebe0b976d695b7a61bddc6 (patch)
treef20f6760810eaf33f2615a23284559ce3f5a668f
parentebfe50c31d62d647b586619f56aa754971cfdf69 (diff)
downloadtxr-b74633f86d69cf1aabebe0b976d695b7a61bddc6.tar.gz
txr-b74633f86d69cf1aabebe0b976d695b7a61bddc6.tar.bz2
txr-b74633f86d69cf1aabebe0b976d695b7a61bddc6.zip
New function rra.
* regex.c (range_regex_all, regex_range_all): New functions. (regex_init): Register rra intrinsic function. * regex.c (range_regex_all, regex_range_all): Declared. * txr.1: Documented rra.
-rw-r--r--regex.c50
-rw-r--r--regex.h2
-rw-r--r--txr.161
3 files changed, 113 insertions, 0 deletions
diff --git a/regex.c b/regex.c
index e95561ff..e72fc110 100644
--- a/regex.c
+++ b/regex.c
@@ -2477,6 +2477,44 @@ val range_regex(val haystack, val needle_regex, val start,
return result;
}
+val range_regex_all(val haystack, val needle_regex, val start, val end)
+{
+ list_collect_decl (out, ptail);
+ val slen = length_str(haystack);
+
+ if (null_or_missing_p(start)) {
+ start = zero;
+ } else if (minusp(start)) {
+ start = minus(start, slen);
+ if (minusp(start))
+ start = zero;
+ }
+
+ if (null_or_missing_p(end)) {
+ end = slen;
+ } else if (minusp(end)) {
+ end = minus(start, slen);
+ if (minusp(end))
+ return nil;
+ }
+
+ for (;;) {
+ val range = range_regex(haystack, needle_regex, start, nil);
+
+ if (!range)
+ break;
+
+ ptail = list_collect(ptail, range);
+
+ {
+ val rt = to(range);
+ start = if3(eql(start, rt), succ(start), rt);
+ }
+ }
+
+ return out;
+}
+
val match_regex(val str, val reg, val pos)
{
regex_machine_t regm;
@@ -2823,6 +2861,17 @@ val regex_range_search(val regex, val arg1, val arg2, val arg3)
}
}
+val regex_range_all(val regex, val arg1, val arg2, val arg3)
+{
+ if (missingp(arg2)) {
+ return range_regex_all(arg1, regex, zero, nil);
+ } else if (missingp(arg3)) {
+ return range_regex_all(arg2, regex, arg1, nil);
+ } else {
+ return range_regex_all(arg3, regex, arg1, arg2);
+ }
+}
+
val read_until_match(val regex, val stream_in, val include_match_in)
{
regex_machine_t regm;
@@ -3010,6 +3059,7 @@ void regex_init(void)
reg_fun(intern(lit("r^"), user_package), func_n3o(regex_range_left, 2));
reg_fun(intern(lit("r$"), user_package), func_n3o(regex_range_right, 2));
reg_fun(intern(lit("rr"), user_package), func_n4o(regex_range_search, 2));
+ reg_fun(intern(lit("rra"), user_package), func_n4o(regex_range_all, 2));
init_special_char_sets();
}
diff --git a/regex.h b/regex.h
index f2e89cfb..8d51669c 100644
--- a/regex.h
+++ b/regex.h
@@ -35,6 +35,7 @@ val regexp(val);
val regex_source(val regex);
val search_regex(val haystack, val needle_regex, val start_num, val from_end);
val range_regex(val haystack, val needle_regex, val start_num, val from_end);
+val range_regex_all(val haystack, val needle_regex, val start, val end);
val match_regex(val str, val regex, val pos);
val match_regex_len(val str, val regex, val pos);
val match_regex_right(val str, val regex, val end);
@@ -53,6 +54,7 @@ val regex_range_full(val regex, val arg1, val arg2);
val regex_range_left(val regex, val arg1, val arg2);
val regex_range_right(val regex, val arg1, val arg2);
val regex_range_search(val regex, val arg1, val arg2, val arg3);
+val regex_range_all(val regex, val arg1, val arg2, val arg3);
int wide_display_char_p(wchar_t ch);
void regex_init(void);
void regex_free_all(void);
diff --git a/txr.1 b/txr.1
index 108dc600..51f35bc8 100644
--- a/txr.1
+++ b/txr.1
@@ -32872,6 +32872,67 @@ function is equivalent to the
function, such that correspondingly named
arguments have the same semantics.
+.coNP Function @ rra
+.synb
+.mets (rra < regex >> [ start <> [ end ]] << string )
+.syne
+.desc
+The
+.code rra
+function searches
+.meta string
+between the
+.meta start
+and
+.meta end
+position for matches for the regular expression
+.metn regex .
+
+The matches are returned as a list of range objects.
+
+The
+.meta start
+argument defaults to zero, and
+.meta end
+defaults to the length of the string (the position one
+past the last character).
+
+Negative values of
+.meta start
+and
+.meta end
+indicate positions from the end of the string, such that -1
+denotes the last character, -2 the second-to-last and so forth.
+
+If
+.meta start
+is so negative that it refers before the start of
+.metn string ,
+it is treated as zero. If this situation is true of the
+.meta end
+argument, then the function returns
+.codn nil .
+
+If
+.meta start
+refers to a character position beyond the length of
+.meta string
+(two characters or more beyond the end of the string),
+then the function returns
+.codn nil .
+If this situation is true of
+.metn end ,
+then
+.meta end
+is is curtailed to the the string length.
+
+The
+.code rra
+function returns all non-overlapping matches, including
+zero length matches. Zero length matches may occur before
+the first character of the string, or after the last
+character. If so, these are included.
+
.coNP Functions @, f^$ @ f^ and @ f$
.synb
.mets (f^$ < regex <> [ position ])