mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* dir.c (rb_push_glob): Dir.glob() should return nil if block is given.
(http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=Dir) * dir.c (push_braces): Dir.glob() should handle '{ }' nested more than 3 times. * dir.c (push_braces, rb_push_glob): Dir.glob() should handle escaped '{' and '}' and ','. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6163 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
f32d6dcb87
commit
da2ace5c40
2 changed files with 47 additions and 71 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
Thu Apr 15 19:26:54 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp>
|
||||
|
||||
* dir.c (rb_push_glob): Dir.glob() should return nil if block is given.
|
||||
(http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=Dir)
|
||||
|
||||
* dir.c (push_braces): Dir.glob() should handle '{ }' nested more than
|
||||
3 times.
|
||||
|
||||
* dir.c (push_braces, rb_push_glob): Dir.glob() should handle escaped
|
||||
'{' and '}' and ','.
|
||||
|
||||
Thu Apr 15 17:12:13 2004 Tanaka Akira <akr@m17n.org>
|
||||
|
||||
* ext/gdbm/gdbm.c (Init_gdbm): define GDBM::READER, GDBM::WRITER,
|
||||
|
|
107
dir.c
107
dir.c
|
@ -1383,7 +1383,7 @@ push_pattern(path, ary)
|
|||
{
|
||||
VALUE str = rb_tainted_str_new2(path);
|
||||
|
||||
if (ary) {
|
||||
if (!NIL_P(ary)) {
|
||||
rb_ary_push(ary, str);
|
||||
}
|
||||
else {
|
||||
|
@ -1392,123 +1392,88 @@ push_pattern(path, ary)
|
|||
}
|
||||
|
||||
static int
|
||||
push_globs(ary, s, flags)
|
||||
push_glob(ary, s, flags)
|
||||
VALUE ary;
|
||||
const char *s;
|
||||
int flags;
|
||||
{
|
||||
return rb_glob2(s, flags, push_pattern, ary);
|
||||
}
|
||||
const int escape = !(flags & FNM_NOESCAPE);
|
||||
|
||||
static int
|
||||
push_braces(ary, s, flags)
|
||||
VALUE ary;
|
||||
const char *s;
|
||||
int flags;
|
||||
{
|
||||
char *buf, *b;
|
||||
const char *p, *t;
|
||||
const char *lbrace, *rbrace;
|
||||
int nest = 0;
|
||||
int status = 0;
|
||||
const char *p = s;
|
||||
const char *lbrace = 0, *rbrace = 0;
|
||||
int nest = 0, status = 0;
|
||||
|
||||
p = s;
|
||||
lbrace = rbrace = 0;
|
||||
while (*p) {
|
||||
if (*p == '{') {
|
||||
if (*p == '{' && nest++ == 0) {
|
||||
lbrace = p;
|
||||
break;
|
||||
}
|
||||
Inc(p);
|
||||
}
|
||||
while (*p) {
|
||||
if (*p == '{') nest++;
|
||||
if (*p == '}' && --nest == 0) {
|
||||
if (*p == '}' && --nest <= 0) {
|
||||
rbrace = p;
|
||||
break;
|
||||
}
|
||||
if (*p == '\\' && escape) {
|
||||
if (!*++p) break;
|
||||
}
|
||||
Inc(p);
|
||||
}
|
||||
|
||||
if (lbrace && rbrace) {
|
||||
int len = strlen(s);
|
||||
buf = xmalloc(len + 1);
|
||||
char *buf, *b;
|
||||
buf = xmalloc(strlen(s) + 1);
|
||||
memcpy(buf, s, lbrace-s);
|
||||
b = buf + (lbrace-s);
|
||||
p = lbrace;
|
||||
while (*p != '}') {
|
||||
t = Next(p);
|
||||
for (p = t; *p!='}' && *p!=','; Inc(p)) {
|
||||
/* skip inner braces */
|
||||
if (*p == '{') while (*p!='}') Inc(p);
|
||||
while (p < rbrace) {
|
||||
const char *t = ++p;
|
||||
nest = 0;
|
||||
while (p < rbrace && !(*p == ',' && nest == 0)) {
|
||||
if (*p == '{') nest++;
|
||||
if (*p == '}') nest--;
|
||||
if (*p == '\\' && escape) {
|
||||
if (++p == rbrace) break;
|
||||
}
|
||||
Inc(p);
|
||||
}
|
||||
memcpy(b, t, p-t);
|
||||
strcpy(b+(p-t), Next(rbrace));
|
||||
status = push_braces(ary, buf, flags);
|
||||
strcpy(b+(p-t), rbrace+1);
|
||||
status = push_glob(ary, buf, flags);
|
||||
if (status) break;
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
else {
|
||||
status = push_globs(ary, s, flags);
|
||||
else if (!lbrace && !rbrace) {
|
||||
status = rb_glob2(s, flags, push_pattern, ary);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#define isdelim(c) ((c)=='\0')
|
||||
static VALUE
|
||||
rb_push_glob(str, flags)
|
||||
rb_push_glob(str, flags) /* '\0' is delimiter */
|
||||
VALUE str;
|
||||
int flags;
|
||||
{
|
||||
const char *p, *pend;
|
||||
char *buf;
|
||||
const char *t;
|
||||
int nest, maxnest;
|
||||
int status = 0;
|
||||
int escape = !(flags & FNM_NOESCAPE);
|
||||
VALUE ary;
|
||||
|
||||
if (rb_block_given_p())
|
||||
ary = 0;
|
||||
ary = Qnil;
|
||||
else
|
||||
ary = rb_ary_new();
|
||||
|
||||
FilePathValue(str);
|
||||
buf = xmalloc(RSTRING(str)->len + 1);
|
||||
|
||||
p = RSTRING(str)->ptr;
|
||||
pend = p + RSTRING(str)->len;
|
||||
|
||||
while (p < pend) {
|
||||
nest = maxnest = 0;
|
||||
while (p < pend && isdelim(*p)) p++;
|
||||
t = p;
|
||||
while (p < pend && !isdelim(*p)) {
|
||||
if (*p == '{') nest++, maxnest++;
|
||||
if (*p == '}') nest--;
|
||||
if (escape && *p == '\\') {
|
||||
p++;
|
||||
if (p == pend || isdelim(*p)) break;
|
||||
}
|
||||
Inc(p);
|
||||
}
|
||||
memcpy(buf, t, p - t);
|
||||
buf[p - t] = '\0';
|
||||
if (maxnest == 0) {
|
||||
status = push_globs(ary, buf, flags);
|
||||
if (status) break;
|
||||
}
|
||||
else if (nest == 0) {
|
||||
status = push_braces(ary, buf, flags);
|
||||
if (status) break;
|
||||
}
|
||||
/* else unmatched braces */
|
||||
int status;
|
||||
while (p < pend && *p == '\0') p++;
|
||||
if (p == pend) break;
|
||||
status = push_glob(ary, p, flags);
|
||||
if (status) rb_jump_tag(status);
|
||||
while (p < pend && *p != '\0') p++;
|
||||
}
|
||||
free(buf);
|
||||
|
||||
if (status) rb_jump_tag(status);
|
||||
|
||||
return ary;
|
||||
}
|
||||
|
@ -1531,7 +1496,7 @@ dir_s_aref(obj, str)
|
|||
/*
|
||||
* call-seq:
|
||||
* Dir.glob( string, [flags] ) => array
|
||||
* Dir.glob( string, [flags] ) {| filename | block } => false
|
||||
* Dir.glob( string, [flags] ) {| filename | block } => nil
|
||||
*
|
||||
* Returns the filenames found by expanding the pattern given in
|
||||
* <i>string</i>, either as an <i>array</i> or as parameters to the
|
||||
|
|
Loading…
Add table
Reference in a new issue