summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--stream.c31
-rw-r--r--stream.h1
-rw-r--r--txr.150
3 files changed, 80 insertions, 2 deletions
diff --git a/stream.c b/stream.c
index 5808aedc..5588804a 100644
--- a/stream.c
+++ b/stream.c
@@ -4102,9 +4102,39 @@ val abs_path_p(val path)
return nil;
}
+static val plp_regex;
+
+val pure_rel_path_p(val path)
+{
+ val ch;
+ val len = length_str(path);
+
+ if (len == zero)
+ return t;
+
+ if ((ch = chr_str(path, zero)) == chr('/') || ch == chr('\\'))
+ return nil;
+
+ if (len == one)
+ return ch == chr('.') ? nil : t;
+
+ if (ch == chr('.') &&
+ ((ch = chr_str(path, one)) == chr('/') || ch == chr('\\')))
+ return nil;
+
+ if (!plp_regex)
+ plp_regex = regex_compile(lit("[A-Za-z0-9]+:"), nil);
+
+ if (match_regex(path, plp_regex, zero))
+ return nil;
+
+ return t;
+}
+
void stream_init(void)
{
prot1(&ap_regex);
+ prot1(&plp_regex);
detect_format_string();
@@ -4208,6 +4238,7 @@ void stream_init(void)
reg_fun(intern(lit("open-files"), user_package), func_n2o(open_files, 1));
reg_fun(intern(lit("open-files*"), user_package), func_n2o(open_files_star, 1));
reg_fun(intern(lit("abs-path-p"), user_package), func_n1(abs_path_p));
+ reg_fun(intern(lit("pure-rel-path-p"), user_package), func_n1(pure_rel_path_p));
reg_fun(intern(lit("get-indent-mode"), user_package), func_n1(get_indent_mode));
reg_fun(intern(lit("test-set-indent-mode"), user_package), func_n3(test_set_indent_mode));
diff --git a/stream.h b/stream.h
index 828ec25a..5c2fdc47 100644
--- a/stream.h
+++ b/stream.h
@@ -202,5 +202,6 @@ val catenated_stream_push(val new_stream, val cat_stream);
val remove_path(val path, val throw_on_error);
val rename_path(val from, val to);
val abs_path_p(val path);
+val pure_rel_path_p(val path);
void stream_init(void);
diff --git a/txr.1 b/txr.1
index 00e098cf..df77876f 100644
--- a/txr.1
+++ b/txr.1
@@ -36701,6 +36701,8 @@ An absolute path is a string which either begins with a slash or backslash
character, or which begins with an alphanumeric word, followed by a colon,
followed by a slash or backslash.
+The empty string isn't an absolute path.
+
Examples of absolute paths:
.cblk
@@ -36711,16 +36713,60 @@ Examples of absolute paths:
Z:\eUsers
.cble
-Examples of strings which are not absolute paths.
+Examples of strings which are not absolute paths:
.cblk
-.mets < (the < empty < string)
+.mets >> ( the < empty << string )
.
abc
foo:bar/x
$:\eabc
.cble
+.coNP Function @ pure-rel-path-p
+.synb
+.mets (pure-rel-path-p << path )
+.syne
+.desc
+The
+.code pure-rel-path-p
+function tests whether the string
+.meta path
+represents a
+.IR "pure relative path" ,
+which is defined as a path which isn't absolute according to
+.codn abs-path-p ,
+which isn't the string
+.str .
+(single period),
+which doesn't begin with a period followed by a slash or backslash,
+and which doesn't begin with alphanumeric word
+terminated by a colon.
+
+The empty string is a pure relative path.
+
+Other examples of pure relative paths:
+
+.cblk
+ abc.d
+ .tmp/bar
+ 1234
+ x
+ $:/xyz
+.cble
+
+Examples of strings which are not pure relative paths:
+
+.cblk
+ .
+ /
+ /etc
+ ./abc
+ .\e
+ foo:
+ $:\eabc
+.cble
+
.coNP Functions @ read and @ iread
.synb
.mets (read >> [ source >> [ error-stream >> [ error-retval <> [ name ]]]])