* dir.c: FNM_PERIOD is obsoleted and FNM_DOTMATCH is introduced
instead, which has the opposite meaning of FNM_PERIOD. * dir.c: Dir::glob now accepts optional FNM_* flags via the second argument, whereas Dir::[] doesn't. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2191 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
14461ddae6
commit
b9522c1687
@ -1,3 +1,11 @@
|
|||||||
|
Wed Mar 13 19:05:15 2002 Akinori MUSHA <knu@iDaemons.org>
|
||||||
|
|
||||||
|
* dir.c: FNM_PERIOD is obsoleted and FNM_DOTMATCH is introduced
|
||||||
|
instead, which has the opposite meaning of FNM_PERIOD.
|
||||||
|
|
||||||
|
* dir.c: Dir::glob now accepts optional FNM_* flags via the second
|
||||||
|
argument, whereas Dir::[] doesn't.
|
||||||
|
|
||||||
Wed Mar 13 18:36:55 2002 Akinori MUSHA <knu@iDaemons.org>
|
Wed Mar 13 18:36:55 2002 Akinori MUSHA <knu@iDaemons.org>
|
||||||
|
|
||||||
* lib/getopts.rb: single_options can be nil[*], and is not not
|
* lib/getopts.rb: single_options can be nil[*], and is not not
|
||||||
|
102
dir.c
102
dir.c
@ -69,7 +69,7 @@ char *strchr _((char*,char));
|
|||||||
|
|
||||||
#define FNM_NOESCAPE 0x01
|
#define FNM_NOESCAPE 0x01
|
||||||
#define FNM_PATHNAME 0x02
|
#define FNM_PATHNAME 0x02
|
||||||
#define FNM_PERIOD 0x04
|
#define FNM_DOTMATCH 0x04
|
||||||
#define FNM_CASEFOLD 0x08
|
#define FNM_CASEFOLD 0x08
|
||||||
|
|
||||||
#define FNM_NOMATCH 1
|
#define FNM_NOMATCH 1
|
||||||
@ -153,7 +153,7 @@ fnmatch(pat, string, flags)
|
|||||||
const char *s = string;
|
const char *s = string;
|
||||||
int escape = !(flags & FNM_NOESCAPE);
|
int escape = !(flags & FNM_NOESCAPE);
|
||||||
int pathname = flags & FNM_PATHNAME;
|
int pathname = flags & FNM_PATHNAME;
|
||||||
int period = flags & FNM_PERIOD;
|
int period = !(flags & FNM_DOTMATCH);
|
||||||
int nocase = flags & FNM_CASEFOLD;
|
int nocase = flags & FNM_CASEFOLD;
|
||||||
|
|
||||||
while (c = *pat++) {
|
while (c = *pat++) {
|
||||||
@ -188,7 +188,7 @@ fnmatch(pat, string, flags)
|
|||||||
pat--;
|
pat--;
|
||||||
while (*s) {
|
while (*s) {
|
||||||
if ((c == '[' || downcase(*s) == test) &&
|
if ((c == '[' || downcase(*s) == test) &&
|
||||||
!fnmatch(pat, s, flags & ~FNM_PERIOD))
|
!fnmatch(pat, s, flags | FNM_DOTMATCH))
|
||||||
return 0;
|
return 0;
|
||||||
else if (ISDIRSEP(*s))
|
else if (ISDIRSEP(*s))
|
||||||
break;
|
break;
|
||||||
@ -793,13 +793,23 @@ glob_helper(path, sub, flags, func, arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rb_glob2(path, flags, func, arg)
|
||||||
|
char *path;
|
||||||
|
int flags;
|
||||||
|
void (*func) _((const char*, VALUE));
|
||||||
|
VALUE arg;
|
||||||
|
{
|
||||||
|
glob_helper(path, 0, flags, func, arg);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_glob(path, func, arg)
|
rb_glob(path, func, arg)
|
||||||
char *path;
|
char *path;
|
||||||
void (*func) _((const char*, VALUE));
|
void (*func) _((const char*, VALUE));
|
||||||
VALUE arg;
|
VALUE arg;
|
||||||
{
|
{
|
||||||
glob_helper(path, 0, FNM_PERIOD, func, arg);
|
rb_glob2(path, 0, func, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -808,11 +818,9 @@ rb_globi(path, func, arg)
|
|||||||
void (*func) _((const char*, VALUE));
|
void (*func) _((const char*, VALUE));
|
||||||
VALUE arg;
|
VALUE arg;
|
||||||
{
|
{
|
||||||
glob_helper(path, 0, FNM_PERIOD|FNM_CASEFOLD, func, arg);
|
rb_glob2(path, FNM_CASEFOLD, func, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void push_pattern _((const char *path, VALUE ary));
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
push_pattern(path, ary)
|
push_pattern(path, ary)
|
||||||
const char *path;
|
const char *path;
|
||||||
@ -829,17 +837,19 @@ push_pattern(path, ary)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
push_globs(ary, s)
|
push_globs(ary, s, flags)
|
||||||
VALUE ary;
|
VALUE ary;
|
||||||
char *s;
|
char *s;
|
||||||
|
int flags;
|
||||||
{
|
{
|
||||||
rb_glob(s, push_pattern, ary);
|
rb_glob2(s, flags, push_pattern, ary);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
push_braces(ary, s)
|
push_braces(ary, s, flags)
|
||||||
VALUE ary;
|
VALUE ary;
|
||||||
char *s;
|
char *s;
|
||||||
|
int flags;
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
char *p, *t, *b;
|
char *p, *t, *b;
|
||||||
@ -878,31 +888,35 @@ push_braces(ary, s)
|
|||||||
}
|
}
|
||||||
memcpy(b, t, p-t);
|
memcpy(b, t, p-t);
|
||||||
strcpy(b+(p-t), rbrace+1);
|
strcpy(b+(p-t), rbrace+1);
|
||||||
push_braces(ary, buf);
|
push_braces(ary, buf, flags);
|
||||||
}
|
}
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
push_globs(ary, s);
|
push_globs(ary, s, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define isdelim(c) ((c)=='\0')
|
#define isdelim(c) ((c)=='\0')
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
dir_s_glob(dir, str)
|
rb_push_glob(str, flags)
|
||||||
VALUE dir, str;
|
VALUE str;
|
||||||
|
int flags;
|
||||||
{
|
{
|
||||||
char *p, *pend;
|
char *p, *pend;
|
||||||
char *buf;
|
char *buf;
|
||||||
char *t;
|
char *t;
|
||||||
int nest;
|
int nest, maxnest;
|
||||||
VALUE ary = 0;
|
int noescape = flags & FNM_NOESCAPE;
|
||||||
|
VALUE ary;
|
||||||
|
|
||||||
|
if (rb_block_given_p())
|
||||||
|
ary = Qnil;
|
||||||
|
else
|
||||||
|
ary = rb_ary_new();
|
||||||
|
|
||||||
SafeStringValue(str);
|
SafeStringValue(str);
|
||||||
if (!rb_block_given_p()) {
|
|
||||||
ary = rb_ary_new();
|
|
||||||
}
|
|
||||||
buf = xmalloc(RSTRING(str)->len + 1);
|
buf = xmalloc(RSTRING(str)->len + 1);
|
||||||
|
|
||||||
p = RSTRING(str)->ptr;
|
p = RSTRING(str)->ptr;
|
||||||
@ -913,28 +927,50 @@ dir_s_glob(dir, str)
|
|||||||
nest = 0;
|
nest = 0;
|
||||||
while (p < pend && isdelim(*p)) p++;
|
while (p < pend && isdelim(*p)) p++;
|
||||||
while (p < pend && !isdelim(*p)) {
|
while (p < pend && !isdelim(*p)) {
|
||||||
if (*p == '{') nest+=2;
|
if (*p == '{') nest++, maxnest++;
|
||||||
if (*p == '}') nest+=3;
|
if (*p == '}') nest--;
|
||||||
if (*p == '\\') {
|
if (!noescape && *p == '\\') {
|
||||||
*t++ = *p++;
|
*t++ = *p++;
|
||||||
if (p == pend) break;
|
if (p == pend) break;
|
||||||
}
|
}
|
||||||
*t++ = *p++;
|
*t++ = *p++;
|
||||||
}
|
}
|
||||||
*t = '\0';
|
*t = '\0';
|
||||||
if (nest == 0) {
|
if (maxnest == 0) {
|
||||||
push_globs(ary, buf);
|
push_globs(ary, buf, flags);
|
||||||
}
|
}
|
||||||
else if (nest % 5 == 0) {
|
else if (nest == 0) {
|
||||||
push_braces(ary, buf);
|
push_braces(ary, buf, flags);
|
||||||
}
|
}
|
||||||
/* else unmatched braces */
|
/* else unmatched braces */
|
||||||
}
|
}
|
||||||
free(buf);
|
free(buf);
|
||||||
if (ary) {
|
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
return Qnil;
|
|
||||||
|
static VALUE
|
||||||
|
dir_s_aref(obj, str)
|
||||||
|
VALUE obj, str;
|
||||||
|
{
|
||||||
|
return rb_push_glob(str, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
dir_s_glob(argc, argv, obj)
|
||||||
|
int argc;
|
||||||
|
VALUE *argv;
|
||||||
|
VALUE obj;
|
||||||
|
{
|
||||||
|
VALUE str, rflags;
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
if (rb_scan_args(argc, argv, "11", &str, &rflags) == 2)
|
||||||
|
flags = NUM2INT(rflags);
|
||||||
|
else
|
||||||
|
flags = 0;
|
||||||
|
|
||||||
|
return rb_push_glob(str, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
@ -1014,14 +1050,14 @@ Init_Dir()
|
|||||||
rb_define_singleton_method(rb_cDir,"delete", dir_s_rmdir, 1);
|
rb_define_singleton_method(rb_cDir,"delete", dir_s_rmdir, 1);
|
||||||
rb_define_singleton_method(rb_cDir,"unlink", dir_s_rmdir, 1);
|
rb_define_singleton_method(rb_cDir,"unlink", dir_s_rmdir, 1);
|
||||||
|
|
||||||
rb_define_singleton_method(rb_cDir,"glob", dir_s_glob, 1);
|
rb_define_singleton_method(rb_cDir,"glob", dir_s_glob, -1);
|
||||||
rb_define_singleton_method(rb_cDir,"[]", dir_s_glob, 1);
|
rb_define_singleton_method(rb_cDir,"[]", dir_s_aref, 1);
|
||||||
|
|
||||||
rb_define_singleton_method(rb_cFile,"fnmatch", file_s_fnmatch, -1);
|
rb_define_singleton_method(rb_cFile,"fnmatch", file_s_fnmatch, -1);
|
||||||
rb_define_singleton_method(rb_cFile,"fnmatch?", file_s_fnmatch, -1);
|
rb_define_singleton_method(rb_cFile,"fnmatch?", file_s_fnmatch, -1);
|
||||||
|
|
||||||
rb_file_const("FNM_NOESCAPE", INT2FIX(FNM_NOESCAPE));
|
rb_file_const("FNM_NOESCAPE", INT2FIX(FNM_NOESCAPE));
|
||||||
rb_file_const("FNM_PATHNAME", INT2FIX(FNM_PATHNAME));
|
rb_file_const("FNM_PATHNAME", INT2FIX(FNM_PATHNAME));
|
||||||
rb_file_const("FNM_PERIOD", INT2FIX(FNM_PERIOD));
|
rb_file_const("FNM_DOTMATCH", INT2FIX(FNM_DOTMATCH));
|
||||||
rb_file_const("FNM_CASEFOLD", INT2FIX(FNM_CASEFOLD));
|
rb_file_const("FNM_CASEFOLD", INT2FIX(FNM_CASEFOLD));
|
||||||
}
|
}
|
||||||
|
21
doc/NEWS
21
doc/NEWS
@ -1,13 +1,9 @@
|
|||||||
: getopts.rb
|
: Dir::glob
|
||||||
|
|
||||||
Rewrote to fix some bugs and complete features.
|
Now accepts optional FNM_* flags via the second argument, whereas
|
||||||
- Accept options with the colon in the first argument;
|
Dir::[] doesn't.
|
||||||
getopts("a:bcd:") is equivalent to getopts("bc", "a:", "d:").
|
|
||||||
- Do not discard the argument that caused an error.
|
Dir.glob("makefile", File::FNM_CASEFOLD) #=> ['Makefile', 'makefile']
|
||||||
- Do not discard '-', which commonly stands for stdin or stdout.
|
|
||||||
- Allow specifying a long option with a value using '='.
|
|
||||||
(command --long-option=value)
|
|
||||||
- Stop reading options when it meets a non-option argument.
|
|
||||||
|
|
||||||
: tsort module
|
: tsort module
|
||||||
|
|
||||||
@ -210,10 +206,13 @@
|
|||||||
|
|
||||||
Added. Refer to the fnmatch(3) manpage for details.
|
Added. Refer to the fnmatch(3) manpage for details.
|
||||||
|
|
||||||
|
Localism is FNM_DOTMATCH which has the opposite meaning of the
|
||||||
|
commonly known FNM_PERIOD, which does not exist in Ruby.
|
||||||
|
|
||||||
e.g.
|
e.g.
|
||||||
|
|
||||||
# exclude files matching "*.bak".
|
# exclude files matching "*.bak" case-insensitively.
|
||||||
files.reject! {|fn| File.fnmatch?("*.bak", fn) }
|
files.reject! {|fn| File.fnmatch?("*.bak", fn, File::FNM_CASEFOLD) }
|
||||||
|
|
||||||
: File.lchmod
|
: File.lchmod
|
||||||
: File.lchown
|
: File.lchown
|
||||||
|
Loading…
x
Reference in New Issue
Block a user