mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-14 21:32:49 -08:00
PATHNAME-MATCH-P now uses the same pattern syntax as DIRECTORY
This commit is contained in:
parent
6b6ebd4890
commit
4e2a7d1d43
3 changed files with 41 additions and 17 deletions
|
|
@ -5,6 +5,10 @@ ECL 9.12.4:
|
|||
|
||||
- DIRECTORY used stat() also on files that did not match the directory masks.
|
||||
|
||||
- The syntax for matching strings in DIRECTORY is now the same as in
|
||||
PATHNAME-MATCH-P. Formerly there were small differences, the forming
|
||||
understanding characters #\? and #\\
|
||||
|
||||
ECL 9.12.3:
|
||||
===========
|
||||
|
||||
|
|
|
|||
|
|
@ -1227,18 +1227,22 @@ cl_host_namestring(cl_object pname)
|
|||
|
||||
/* --------------- PATHNAME MATCHING ------------------ */
|
||||
|
||||
static bool path_item_match(cl_object a, cl_object mask);
|
||||
|
||||
static bool
|
||||
do_path_item_match(cl_object s, cl_index j, cl_object p, cl_index i)
|
||||
/*
|
||||
* Take two C strings and check if the first (s) one matches against
|
||||
* the pattern given by the second one (p). The pattern is that of a
|
||||
* Unix shell except for brackets and curly braces
|
||||
*/
|
||||
bool
|
||||
ecl_string_match(cl_object s, cl_index j, cl_index ls,
|
||||
cl_object p, cl_index i, cl_index lp)
|
||||
{
|
||||
cl_index ls = ecl_length(s), lp = ecl_length(p);
|
||||
while (i < lp) {
|
||||
cl_index cp = ecl_char(p, i);
|
||||
if (cp == '*') {
|
||||
/* An asterisk in the patter matches any number
|
||||
* of characters. We try the shortest sequence
|
||||
* that matches. */
|
||||
switch (cp) {
|
||||
case '*': {
|
||||
/* An asterisk in the pattern matches any
|
||||
* number of characters. We try the shortest
|
||||
* sequence that matches. */
|
||||
cl_index cn = 0, next;
|
||||
for (next = i+1;
|
||||
next < lp && ((cn = ecl_char(p, next)) == '*');
|
||||
|
|
@ -1248,20 +1252,33 @@ do_path_item_match(cl_object s, cl_index j, cl_object p, cl_index i)
|
|||
return TRUE;
|
||||
}
|
||||
while (j < ls) {
|
||||
if (do_path_item_match(s, j, p, next)) {
|
||||
if (ecl_string_match(s, j, ls, p, next, lp)) {
|
||||
return TRUE;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
if ((j >= ls) || (cp != ecl_char(s, j))) {
|
||||
/* Either there are no characters left in "s"
|
||||
* or the next character does not match. */
|
||||
return FALSE;
|
||||
}
|
||||
i++; j++;
|
||||
case '?':
|
||||
/* Match any character */
|
||||
if (j > ls) return FALSE;
|
||||
i++; j++;
|
||||
break;
|
||||
case '\\':
|
||||
/* Interpret a pattern character literally.
|
||||
Trailing slash is interpreted as a slash. */
|
||||
if (++i >= lp) i--;
|
||||
default:
|
||||
if ((j >= ls) || (cp != ecl_char(s, j))) {
|
||||
/* Either there are no characters left in "s"
|
||||
* or the next character does not match. */
|
||||
return FALSE;
|
||||
}
|
||||
i++; j++;
|
||||
}
|
||||
}
|
||||
/* At the end all characters should have been matched */
|
||||
return (j >= ls);
|
||||
}
|
||||
|
||||
|
|
@ -1275,7 +1292,8 @@ path_item_match(cl_object a, cl_object mask) {
|
|||
return (a == mask);
|
||||
if (!ecl_stringp(mask))
|
||||
FEerror("~S is not supported as mask for pathname-match-p", 1, mask);
|
||||
return do_path_item_match(a, 0, mask, 0);
|
||||
return ecl_string_match(a, 0, ecl_length(a),
|
||||
mask, 0, ecl_length(mask));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
|||
|
|
@ -1265,6 +1265,8 @@ extern ECL_API void ecl_unuse_package(cl_object x0, cl_object p);
|
|||
|
||||
/* pathname.c */
|
||||
|
||||
extern ECL_API bool ecl_string_match(cl_object s, cl_index j, cl_index ls, cl_object p, cl_index i, cl_index lp);
|
||||
|
||||
extern ECL_API cl_object cl_pathname(cl_object name);
|
||||
extern ECL_API cl_object cl_logical_pathname(cl_object pname);
|
||||
extern ECL_API cl_object cl_pathnamep(cl_object pname);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue