1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* dir.c: merge tuning from H.Yamamoto <ocean@m2.ccsnet.ne.jp>.

[ruby-dev:22476]

* io.c (argf_eof): ARGF.eof? should not have any side effect.
  [ruby-dev:22469]

* io.c (argf_each_byte): should return self.  [ruby-dev:22465]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5365 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2004-01-02 16:21:26 +00:00
parent 88c127c19b
commit 59dbfa3e4c
11 changed files with 405 additions and 267 deletions

View file

@ -1,3 +1,8 @@
Sat Jan 3 01:18:08 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* dir.c: merge tuning from H.Yamamoto <ocean@m2.ccsnet.ne.jp>.
[ruby-dev:22476]
Fri Jan 2 14:54:11 2004 Dave Thomas <dave@pragprog.com> Fri Jan 2 14:54:11 2004 Dave Thomas <dave@pragprog.com>
* bin/ri: Add new --classes option, and arrange for * bin/ri: Add new --classes option, and arrange for
@ -11,11 +16,20 @@ Fri Jan 2 14:54:11 2004 Dave Thomas <dave@pragprog.com>
Fix problem with labels not displaying in RI labeled Fix problem with labels not displaying in RI labeled
lists using BS and ANSI modes. lists using BS and ANSI modes.
Fri Jan 2 01:50:13 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* io.c (argf_eof): ARGF.eof? should not have any side effect.
[ruby-dev:22469]
Thu Jan 1 09:03:20 2004 Dave Thomas <dave@pragprog.com> Thu Jan 1 09:03:20 2004 Dave Thomas <dave@pragprog.com>
* bin/ri (report_class_stuff): Fix problem with ambiguous nested * bin/ri (report_class_stuff): Fix problem with ambiguous nested
classes not matching. classes not matching.
Wed Dec 31 17:25:17 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* io.c (argf_each_byte): should return self. [ruby-dev:22465]
Wed Dec 31 15:05:00 2003 Gavin Sinclair <gsinclair@soyabean.com.au> Wed Dec 31 15:05:00 2003 Gavin Sinclair <gsinclair@soyabean.com.au>
* lib/pathname.rb: Corrected small coding error. * lib/pathname.rb: Corrected small coding error.

View file

@ -707,7 +707,7 @@ if test x"$enable_pthread" = xyes; then
else else
AC_MSG_WARN("Don't know how to find pthread library on your system -- thread support disabled") AC_MSG_WARN("Don't know how to find pthread library on your system -- thread support disabled")
fi fi
AC_CHECK_FUNC(nanosleep) AC_CHECK_FUNCS(nanosleep)
if test x"$ac_cv_func_nanosleep" = xno; then if test x"$ac_cv_func_nanosleep" = xno; then
AC_CHECK_LIB(rt, nanosleep) AC_CHECK_LIB(rt, nanosleep)
if test x"$ac_cv_lib_rt_nanosleep" = xyes; then if test x"$ac_cv_lib_rt_nanosleep" = xyes; then

586
dir.c
View file

@ -76,15 +76,65 @@ char *strchr _((char*,char));
#define FNM_ERROR 2 #define FNM_ERROR 2
#define downcase(c) (nocase && ISUPPER(c) ? tolower(c) : (c)) #define downcase(c) (nocase && ISUPPER(c) ? tolower(c) : (c))
#define compare(c1, c2) (((unsigned char)(c1)) - ((unsigned char)(c2)))
#ifndef CharNext /* defined as CharNext[AW] on Windows. */ /* caution: in case *p == '\0'
# if defined(DJGPP) Next(p) == p + 1 in single byte environment
# define CharNext(p) ((p) + mblen(p, MB_CUR_MAX)) Next(p) == p in multi byte environment
# else */
# define CharNext(p) ((p) + 1) #if defined(CharNext)
# endif # define Next(p) CharNext(p)
#elif defined(DJGPP)
# define Next(p) ((p) + mblen(p, MB_CUR_MAX))
#elif defined(__EMX__)
# define Next(p) ((p) + emx_mblen(p))
static inline int
emx_mblen(p)
const char *p;
{
int n = mblen(p, INT_MAX);
return (n < 0) ? 1 : n;
}
#endif #endif
#ifndef Next /* single byte environment */
# define Next(p) ((p) + 1)
# define Inc(p) (++(p))
# define Compare(p1, p2) (compare(downcase(*(p1)), downcase(*(p2))))
#else /* multi byte environment */
# define Inc(p) ((p) = Next(p))
# define Compare(p1, p2) (CompareImpl(p1, p2, nocase))
static int
CompareImpl(p1, p2, nocase)
const char *p1;
const char *p2;
int nocase;
{
const int len1 = Next(p1) - p1;
const int len2 = Next(p2) - p2;
if (len1 == 0) return len2;
if (len2 == 0) return -len1;
if (len1 == 1)
if (len2 == 1)
return compare(downcase(*p1), downcase(*p2));
else {
const int ret = compare(downcase(*p1), *p2);
return ret ? ret : -1;
}
else
if (len2 == 1) {
const int ret = compare(*p1, downcase(*p2));
return ret ? ret : 1;
}
else {
const int ret = memcmp(p1, p2, len1 < len2 ? len1 : len2);
return ret ? ret : len1 - len2;
}
}
#endif /* environment */
#if defined DOSISH #if defined DOSISH
#define isdirsep(c) ((c) == '/' || (c) == '\\') #define isdirsep(c) ((c) == '/' || (c) == '\\')
#else #else
@ -94,7 +144,7 @@ char *strchr _((char*,char));
static char * static char *
range(pat, test, flags) range(pat, test, flags)
char *pat; char *pat;
char test; char *test;
int flags; int flags;
{ {
int not, ok = 0; int not, ok = 0;
@ -105,32 +155,32 @@ range(pat, test, flags)
if (not) if (not)
pat++; pat++;
test = downcase(test);
while (*pat) { while (*pat) {
int cstart, cend; char *pstart, *pend;
cstart = cend = *pat++; pstart = pend = pat;
if (cstart == ']') if (*pstart == ']')
return ok == not ? 0 : pat; return ok == not ? 0 : ++pat;
else if (escape && cstart == '\\') else if (escape && *pstart == '\\')
cstart = cend = *pat++; pstart = pend = ++pat;
Inc(pat);
if (*pat == '-' && pat[1] != ']') { if (*pat == '-' && pat[1] != ']') {
if (escape && pat[1] == '\\') if (escape && pat[1] == '\\')
pat++; pat++;
cend = pat[1]; pend = pat+1;
if (!cend) if (!*pend)
return 0; return 0;
pat += 2; pat = Next(pend);
} }
if (downcase(cstart) <= test && test <= downcase(cend)) if (Compare(pstart, test) <= 0 && Compare(test, pend) <= 0)
ok = 1; ok = 1;
} }
return 0; return 0;
} }
#define ISDIRSEP(c) (pathname && isdirsep(c)) #define ISDIRSEP(c) (pathname && isdirsep(c))
#define PERIOD(s) (period && *(s) == '.' && \ #define PERIOD_S() (period && *s == '.' && \
((s) == string || ISDIRSEP((s)[-1]))) (!s_prev || ISDIRSEP(*s_prev)))
#define INC_S() (s = Next(s_prev = s))
static int static int
fnmatch(pat, string, flags) fnmatch(pat, string, flags)
const char *pat; const char *pat;
@ -138,25 +188,26 @@ fnmatch(pat, string, flags)
int flags; int flags;
{ {
int c; int c;
int test; const char *test;
const char *s = string; const char *s = string, *s_prev = 0;
int escape = !(flags & FNM_NOESCAPE); int escape = !(flags & FNM_NOESCAPE);
int pathname = flags & FNM_PATHNAME; int pathname = flags & FNM_PATHNAME;
int period = !(flags & FNM_DOTMATCH); int period = !(flags & FNM_DOTMATCH);
int nocase = flags & FNM_CASEFOLD; int nocase = flags & FNM_CASEFOLD;
while (c = *pat++) { while (c = *pat) {
switch (c) { switch (c) {
case '?': case '?':
if (!*s || ISDIRSEP(*s) || PERIOD(s)) if (!*s || ISDIRSEP(*s) || PERIOD_S())
return FNM_NOMATCH; return FNM_NOMATCH;
s++; INC_S();
++pat;
break; break;
case '*': case '*':
while ((c = *pat++) == '*') while ((c = *++pat) == '*')
; ;
if (PERIOD(s)) if (PERIOD_S())
return FNM_NOMATCH; return FNM_NOMATCH;
if (!c) { if (!c) {
@ -168,45 +219,39 @@ fnmatch(pat, string, flags)
else if (ISDIRSEP(c)) { else if (ISDIRSEP(c)) {
s = rb_path_next(s); s = rb_path_next(s);
if (*s) { if (*s) {
s++; INC_S();
break; break;
} }
return FNM_NOMATCH; return FNM_NOMATCH;
} }
test = escape && c == '\\' ? *pat : c; test = escape && c == '\\' ? pat+1 : pat;
test = downcase(test);
pat--;
while (*s) { while (*s) {
if ((c == '[' || downcase(*s) == test) && if ((c == '[' || Compare(s, test) == 0) &&
!fnmatch(pat, s, flags | FNM_DOTMATCH)) !fnmatch(pat, s, flags | FNM_DOTMATCH))
return 0; return 0;
else if (ISDIRSEP(*s)) else if (ISDIRSEP(*s))
break; break;
s++; INC_S();
} }
return FNM_NOMATCH; return FNM_NOMATCH;
case '[': case '[':
if (!*s || ISDIRSEP(*s) || PERIOD(s)) if (!*s || ISDIRSEP(*s) || PERIOD_S())
return FNM_NOMATCH; return FNM_NOMATCH;
pat = range(pat, *s, flags); pat = range(pat+1, s, flags);
if (!pat) if (!pat)
return FNM_NOMATCH; return FNM_NOMATCH;
s++; INC_S();
break; break;
case '\\': case '\\':
if (escape if (escape && pat[1]
#if defined DOSISH #if defined DOSISH
&& *pat && strchr("*?[\\", *pat) && strchr("*?[\\", pat[1])
#endif #endif
) { ) {
c = *pat; c = *++pat;
if (!c)
c = '\\';
else
pat++;
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
@ -216,9 +261,10 @@ fnmatch(pat, string, flags)
; ;
else else
#endif #endif
if(downcase(c) != downcase(*s)) if(Compare(pat, s) != 0)
return FNM_NOMATCH; return FNM_NOMATCH;
s++; INC_S();
Inc(pat);
break; break;
} }
} }
@ -768,95 +814,142 @@ dir_s_rmdir(obj, dir)
/* Return nonzero if S has any special globbing chars in it. */ /* Return nonzero if S has any special globbing chars in it. */
static int static int
has_magic(s, send, flags) has_magic(p, m, flags)
char *s, *send; register char *p;
char **m;
int flags; int flags;
{ {
register char *p = s;
register char c; register char c;
int open = 0; int open = 0;
int escape = !(flags & FNM_NOESCAPE); int escape = !(flags & FNM_NOESCAPE);
while ((c = *p++) != '\0') { while (c = *p++, c != '\0' && c != '/') {
switch (c) { switch (c) {
case '?': case '?':
case '*': case '*':
return Qtrue; goto found;
case '[': /* Only accept an open brace if there is a close */ case '[': /* Only accept an open brace if there is a close */
open++; /* brace to match it. Bracket expressions must be */ open++; /* brace to match it. Bracket expressions must be */
continue; /* complete, according to Posix.2 */ continue; /* complete, according to Posix.2 */
case ']': case ']':
if (open) if (open)
return Qtrue; goto found;
continue; continue;
case '\\': case '\\':
if (escape && *p++ == '\0') if (escape && (c = *p++, c == '\0' || c == '/'))
return Qfalse; goto miss;
continue;
} }
if (send && p >= send) break; p = Next(p-1);
}
return Qfalse;
}
static char*
extract_path(p, pend)
char *p, *pend;
{
char *alloc;
int len;
len = pend - p;
alloc = ALLOC_N(char, len+1);
memcpy(alloc, p, len);
if (len > 1 && pend[-1] == '/'
#if defined DOSISH_DRIVE_LETTER
&& pend[-2] != ':'
#endif
) {
alloc[len-1] = 0;
}
else {
alloc[len] = 0;
} }
return alloc; miss:
*m = p-1;
return 0;
found:
while (*p != '\0' && *p != '/')
Inc(p);
*m = p;
return 1;
} }
static char* static int
extract_elem(path) remove_backslashes(p, pend)
char *path;
{
char *pend;
pend = strchr(path, '/');
if (!pend) pend = path + strlen(path);
return extract_path(path, pend);
}
static void
remove_backslashes(p)
char *p; char *p;
char *pend;
{ {
char *pend = p + strlen(p);
char *t = p; char *t = p;
char *s = p;
int n = 0;
while (p < pend) { while (*p && p < pend) {
if (*p == '\\') { if (*p == '\\') {
if (++p == pend) break; if (t != s) {
memmove(t, s, p - s);
n++;
}
t += p - s;
s = ++p;
if (!(*p && p < pend)) break;
} }
*t++ = *p++; Inc(p);
} }
*t = '\0';
while (*p++);
if (t != s) {
memmove(t, s, p - s); /* move '\0' too */
n++;
}
return n;
}
static int
do_fnmatch(p, pend, string, flags)
char *p;
char *pend;
const char *string;
int flags;
{
int ret;
char c;
c = *pend;
*pend = '\0'; /* should I allocate new string? */
ret = fnmatch(p, string, flags);
*pend = c;
return ret;
}
static int
do_stat(path, pst)
const char *path;
struct stat *pst;
{
int ret = stat(path, pst);
if (ret < 0 && errno != ENOENT)
rb_sys_warning(path);
return ret;
}
static int
do_lstat(path, pst)
const char *path;
struct stat *pst;
{
int ret = lstat(path, pst);
if (ret < 0 && errno != ENOENT)
rb_sys_warning(path);
return ret;
}
static DIR *
do_opendir(path)
const char *path;
{
DIR *dirp = opendir(path);
if (dirp == NULL && errno != ENOENT && errno != ENOTDIR)
rb_sys_warning(path);
return dirp;
} }
#ifndef S_ISDIR #ifndef S_ISDIR
# define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR) # define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
#endif #endif
#ifndef S_ISLNK
# ifndef S_IFLNK
# define S_ISLNK(m) (0)
# else
# define S_ISLNK(m) ((m & S_IFMT) == S_IFLNK)
# endif
#endif
struct glob_args { struct glob_args {
void (*func) _((const char*, VALUE)); void (*func) _((const char*, VALUE));
const char *c; const char *c;
@ -892,162 +985,155 @@ glob_call_func(func, path, arg)
} }
static int static int
glob_helper(path, sub, flags, func, arg) glob_helper(path, sub, separator, flags, func, arg) /* if separator p[-1] is removable '/' */
char *path; char *path;
char *sub; char *sub;
int separator;
int flags; int flags;
void (*func) _((const char*, VALUE)); void (*func) _((const char*, VALUE));
VALUE arg; VALUE arg;
{ {
struct stat st; struct stat st;
char *p, *m;
int status = 0; int status = 0;
char *p = sub, *m, *buf;
DIR *dirp;
struct dirent *dp;
int recursive = 0;
int magical = 1;
p = sub ? sub : path; struct d_link {
if (!has_magic(p, 0, flags)) { char *name;
#if defined DOSISH struct d_link *next;
remove_backslashes(path); } *tmp, *link, **tail = &link;
#else
if (!(flags & FNM_NOESCAPE)) remove_backslashes(p); while (*p && !has_magic(p, &m, flags)) {
#endif if (*m == '/') {
if (lstat(path, &st) == 0) { separator = 1;
status = glob_call_func(func, path, arg); p = m + 1;
if (status) return status;
} }
else if (errno != ENOENT) { else {
/* In case stat error is other than ENOENT and separator = 0;
we may want to know what is wrong. */ p = m;
rb_sys_warning(path); }
}
if (!(flags & FNM_NOESCAPE)) {
int n = remove_backslashes(sub, p);
p -= n;
m -= n;
}
if (*p == '\0') { /* magic not found */
if (separator) {
p[-1] = '\0';
if (do_stat(path, &st) == 0 && S_ISDIR(st.st_mode)) {
p[-1] = '/';
return glob_call_func(func, path, arg);
}
else
p[-1] = '/';
}
else {
if (do_lstat(path, &st) == 0)
return glob_call_func(func, path, arg);
} }
return 0; return 0;
} }
while (p && !status) { if (p[0] == '*' && p[1] == '*' && p[2] == '/') {
if (*p == '/') p++; char *t = p+3;
m = strchr(p, '/'); while (t[0] == '*' && t[1] == '*' && t[2] == '/') t += 3;
if (has_magic(p, m, flags)) { memmove(p, t, strlen(t)+1); /* move '\0' too */
char *dir, *base, *magic, *buf; magical = has_magic(p, &m, flags); /* next element */
DIR *dirp; recursive = 1;
struct dirent *dp; }
int recursive = 0;
struct d_link { if (path == p) {
char *path; dirp = do_opendir(".");
struct d_link *next; if (dirp == NULL) return 0;
} *tmp, *link, **tail = &link; }
else {
char *t = separator ? p-1 : p;
char c = *t;
*t = '\0';
dirp = do_opendir(path);
*t = c;
if (dirp == NULL) return 0;
}
base = extract_path(path, p); for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
if (path == p) dir = "."; const int n1 = p - path;
else dir = base; const int n2 = n1 + NAMLEN(dp);
const int ok = 0;
magic = extract_elem(p); const int no = 1;
if (stat(dir, &st) < 0) { int is_dir = -1; /* not checked yet */
if (errno != ENOENT) rb_sys_warning(dir); if (recursive && strcmp(".", dp->d_name) != 0 && strcmp("..", dp->d_name) != 0) {
free(base); buf = ALLOC_N(char, n2+4+strlen(p)+1);
free(magic); memcpy(buf, path, n1);
break; strcpy(buf+n1, dp->d_name);
is_dir = no;
if (do_lstat(buf, &st) == 0) {
if (S_ISDIR(st.st_mode)) {
strcpy(buf+n2, "/**/");
strcpy(buf+n2+4, p);
status = glob_helper(buf, buf+n2+1, 1, flags, func, arg);
is_dir = ok;
}
else if (S_ISLNK(st.st_mode) && do_stat(buf, &st) == 0 && S_ISDIR(st.st_mode)) {
is_dir = ok;
}
} }
if (S_ISDIR(st.st_mode)) { free(buf);
if (m && strcmp(magic, "**") == 0) { if (status) break;
int n = strlen(base); }
recursive = 1; if (is_dir == no && *m == '/') {
buf = ALLOC_N(char, n+strlen(m)+3); continue;
sprintf(buf, "%s%s", base, *base ? m : m+1); }
status = glob_helper(buf, buf+n, flags, func, arg); if (magical && do_fnmatch(p, m, dp->d_name, flags) == 0) {
free(buf); buf = ALLOC_N(char, n2+1+1);
if (status) goto finalize; memcpy(buf, path, n1);
} strcpy(buf+n1, dp->d_name);
dirp = opendir(dir); if (*m == '\0') {
if (dirp == NULL) { status = glob_call_func(func, buf, arg);
rb_sys_warning(dir); }
free(base); else if (m[1] == '\0' && is_dir == ok) { /* *m == '/' */
free(magic); strcpy(buf+n2, "/");
break; status = glob_call_func(func, buf, arg);
}
} }
else { else {
free(base); tmp = ALLOC(struct d_link);
free(magic); tmp->name = ALLOC_N(char, NAMLEN(dp)+1);
break; strcpy(tmp->name, dp->d_name);
} *tail = tmp;
tail = &tmp->next;
#if defined DOSISH_DRIVE_LETTER
#define BASE (*base && !((isdirsep(*base) && !base[1]) || (base[1] == ':' && isdirsep(base[2]) && !base[3])))
#else
#define BASE (*base && !(isdirsep(*base) && !base[1]))
#endif
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
if (recursive) {
if (strcmp(".", dp->d_name) == 0 || strcmp("..", dp->d_name) == 0)
continue;
buf = ALLOC_N(char, strlen(base)+NAMLEN(dp)+strlen(m)+6);
sprintf(buf, "%s%s%s", base, (BASE) ? "/" : "", dp->d_name);
if (lstat(buf, &st) < 0) {
if (errno != ENOENT) rb_sys_warning(buf);
free(buf);
continue;
}
if (S_ISDIR(st.st_mode)) {
char *t = buf+strlen(buf);
strcpy(t, "/**");
strcpy(t+3, m);
status = glob_helper(buf, t, flags, func, arg);
free(buf);
if (status) break;
continue;
}
free(buf);
continue;
}
if (fnmatch(magic, dp->d_name, flags) == 0) {
buf = ALLOC_N(char, strlen(base)+NAMLEN(dp)+2);
sprintf(buf, "%s%s%s", base, (BASE) ? "/" : "", dp->d_name);
if (!m) {
status = glob_call_func(func, buf, arg);
free(buf);
if (status) break;
continue;
}
tmp = ALLOC(struct d_link);
tmp->path = buf;
*tail = tmp;
tail = &tmp->next;
}
}
closedir(dirp);
finalize:
*tail = 0;
free(base);
free(magic);
if (link) {
while (link) {
if (status == 0) {
if (stat(link->path, &st) == 0) {
if (S_ISDIR(st.st_mode)) {
int len = strlen(link->path);
int mlen = strlen(m);
char *t = ALLOC_N(char, len+mlen+1);
sprintf(t, "%s%s", link->path, m);
status = glob_helper(t, t+len, flags, func, arg);
free(t);
}
}
else {
rb_sys_warning(link->path);
}
}
tmp = link;
link = link->next;
free(tmp->path);
free(tmp);
}
break;
} }
free(buf);
if (status) break;
} }
p = m;
} }
closedir(dirp);
*tail = 0;
while (link) {
if (status == 0) {
const int n1 = p - path;
const int n2 = n1 + strlen(link->name);
buf = ALLOC_N(char, n2+strlen(m)+1);
memcpy(buf, path, n1);
strcpy(buf+n1, link->name);
strcpy(buf+n2, m);
status = glob_helper(buf, buf+n2+1, 1, flags, func, arg);
}
tmp = link;
link = link->next;
free(tmp->name);
free(tmp);
}
if (!magical) {
status = glob_helper(path, p, separator, flags, func, arg);
}
return status; return status;
} }
@ -1058,7 +1144,17 @@ rb_glob2(path, flags, func, arg)
void (*func) _((const char*, VALUE)); void (*func) _((const char*, VALUE));
VALUE arg; VALUE arg;
{ {
int status = glob_helper(path, 0, flags, func, arg); char *root = path;
int status;
#if defined DOSISH
flags |= FNM_CASEFOLD;
root = rb_path_skip_prefix(root);
#endif
if (*root == '/') root++;
status = glob_helper(path, root, 0, flags, func, arg);
if (status) rb_jump_tag(status); if (status) rb_jump_tag(status);
} }
@ -1122,7 +1218,7 @@ push_braces(ary, s, flags)
lbrace = p; lbrace = p;
break; break;
} }
p++; Inc(p);
} }
while (*p) { while (*p) {
if (*p == '{') nest++; if (*p == '{') nest++;
@ -1130,7 +1226,7 @@ push_braces(ary, s, flags)
rbrace = p; rbrace = p;
break; break;
} }
p++; Inc(p);
} }
if (lbrace && rbrace) { if (lbrace && rbrace) {
@ -1140,13 +1236,13 @@ push_braces(ary, s, flags)
b = buf + (lbrace-s); b = buf + (lbrace-s);
p = lbrace; p = lbrace;
while (*p != '}') { while (*p != '}') {
t = p + 1; t = Next(p);
for (p = t; *p!='}' && *p!=','; p++) { for (p = t; *p!='}' && *p!=','; Inc(p)) {
/* skip inner braces */ /* skip inner braces */
if (*p == '{') while (*p!='}') p++; if (*p == '{') while (*p!='}') Inc(p);
} }
memcpy(b, t, p-t); memcpy(b, t, p-t);
strcpy(b+(p-t), rbrace+1); strcpy(b+(p-t), Next(rbrace));
push_braces(ary, buf, flags); push_braces(ary, buf, flags);
} }
free(buf); free(buf);
@ -1157,7 +1253,6 @@ push_braces(ary, s, flags)
} }
#define isdelim(c) ((c)=='\0') #define isdelim(c) ((c)=='\0')
static VALUE static VALUE
rb_push_glob(str, flags) rb_push_glob(str, flags)
VALUE str; VALUE str;
@ -1182,19 +1277,20 @@ rb_push_glob(str, flags)
pend = p + RSTRING(str)->len; pend = p + RSTRING(str)->len;
while (p < pend) { while (p < pend) {
t = buf;
nest = maxnest = 0; nest = maxnest = 0;
while (p < pend && isdelim(*p)) p++; while (p < pend && isdelim(*p)) p++;
t = p;
while (p < pend && !isdelim(*p)) { while (p < pend && !isdelim(*p)) {
if (*p == '{') nest++, maxnest++; if (*p == '{') nest++, maxnest++;
if (*p == '}') nest--; if (*p == '}') nest--;
if (!noescape && *p == '\\') { if (!noescape && *p == '\\') {
*t++ = *p++; p++;
if (p == pend) break; if (p == pend || isdelim(*p)) break;
} }
*t++ = *p++; p = Next(p);
} }
*t = '\0'; memcpy(buf, t, p - t);
buf[p - t] = '\0';
if (maxnest == 0) { if (maxnest == 0) {
push_globs(ary, buf, flags); push_globs(ary, buf, flags);
} }

3
eval.c
View file

@ -10318,13 +10318,16 @@ rb_thread_wait_for(time)
curr_thread == curr_thread->next || curr_thread == curr_thread->next ||
curr_thread->status == THREAD_TO_KILL) { curr_thread->status == THREAD_TO_KILL) {
int n; int n;
int thr_critical = rb_thread_critical;
#ifndef linux #ifndef linux
double d, limit; double d, limit;
limit = timeofday()+(double)time.tv_sec+(double)time.tv_usec*1e-6; limit = timeofday()+(double)time.tv_sec+(double)time.tv_usec*1e-6;
#endif #endif
for (;;) { for (;;) {
rb_thread_critical = Qtrue;
TRAP_BEG; TRAP_BEG;
n = select(0, 0, 0, 0, &time); n = select(0, 0, 0, 0, &time);
rb_thread_critical = thr_critical;
TRAP_END; TRAP_END;
if (n == 0) return; if (n == 0) return;
if (n < 0) { if (n < 0) {

View file

@ -35,7 +35,7 @@ main()
socket(AF_INET6, SOCK_STREAM, 0); socket(AF_INET6, SOCK_STREAM, 0);
} }
EOF EOF
$CFLAGS+=" -DENABLE_IPV6" $CPPFLAGS+=" -DENABLE_IPV6"
$ipv6 = true $ipv6 = true
end end
end end
@ -49,7 +49,7 @@ if $ipv6
#include <netinet/in.h> #include <netinet/in.h>
EOF EOF
$ipv6type = "inria" $ipv6type = "inria"
$CFLAGS="-DINET6 "+$CFLAGS $CPPFLAGS="-DINET6 "+$CPPFLAGS
elsif macro_defined?("__KAME__", <<EOF) elsif macro_defined?("__KAME__", <<EOF)
#include <netinet/in.h> #include <netinet/in.h>
EOF EOF
@ -57,37 +57,38 @@ EOF
$ipv6lib="inet6" $ipv6lib="inet6"
$ipv6libdir="/usr/local/v6/lib" $ipv6libdir="/usr/local/v6/lib"
$ipv6trylibc=true $ipv6trylibc=true
$CFLAGS="-DINET6 "+$CFLAGS $CPPFLAGS="-DINET6 "+$CPPFLAGS
elsif File.directory? "/usr/inet6" elsif File.directory? "/usr/inet6"
$ipv6type = "linux" $ipv6type = "linux"
$ipv6lib="inet6" $ipv6lib="inet6"
$ipv6libdir="/usr/inet6/lib" $ipv6libdir="/usr/inet6/lib"
$CFLAGS="-DINET6 -I/usr/inet6/include "+$CFLAGS $CPPFLAGS="-DINET6 -I/usr/inet6/include "+$CPPFLAGS
elsif macro_defined?("_TOSHIBA_INET6", <<EOF) elsif macro_defined?("_TOSHIBA_INET6", <<EOF)
#include <sys/param.h> #include <sys/param.h>
EOF EOF
$ipv6type = "toshiba" $ipv6type = "toshiba"
$ipv6lib="inet6" $ipv6lib="inet6"
$ipv6libdir="/usr/local/v6/lib" $ipv6libdir="/usr/local/v6/lib"
$CFLAGS="-DINET6 "+$CFLAGS $CPPFLAGS="-DINET6 "+$CPPFLAGS
elsif macro_defined?("__V6D__", <<EOF) elsif macro_defined?("__V6D__", <<EOF)
#include </usr/local/v6/include/sys/v6config.h> #include </usr/local/v6/include/sys/v6config.h>
EOF EOF
$ipv6type = "v6d" $ipv6type = "v6d"
$ipv6lib="v6" $ipv6lib="v6"
$ipv6libdir="/usr/local/v6/lib" $ipv6libdir="/usr/local/v6/lib"
$CFLAGS="-DINET6 -I/usr/local/v6/include "+$CFLAGS $CFLAGS="-I/usr/local/v6/include "+$CFLAGS
$CPPFLAGS="-DINET6 "+$CPPFLAGS
elsif macro_defined?("_ZETA_MINAMI_INET6", <<EOF) elsif macro_defined?("_ZETA_MINAMI_INET6", <<EOF)
#include <sys/param.h> #include <sys/param.h>
EOF EOF
$ipv6type = "zeta" $ipv6type = "zeta"
$ipv6lib="inet6" $ipv6lib="inet6"
$ipv6libdir="/usr/local/v6/lib" $ipv6libdir="/usr/local/v6/lib"
$CFLAGS="-DINET6 "+$CFLAGS $CPPFLAGS="-DINET6 "+$CPPFLAGS
else else
$ipv6lib=with_config("ipv6-lib", nil) $ipv6lib=with_config("ipv6-lib", nil)
$ipv6libdir=with_config("ipv6-libdir", nil) $ipv6libdir=with_config("ipv6-libdir", nil)
$CFLAGS="-DINET6 "+$CFLAGS $CPPFLAGS="-DINET6 "+$CPPFLAGS
end end
if $ipv6lib if $ipv6lib
@ -147,7 +148,7 @@ main()
return 0; return 0;
} }
EOF EOF
$CFLAGS="-DHAVE_SOCKADDR_STORAGE "+$CFLAGS $CPPFLAGS="-DHAVE_SOCKADDR_STORAGE "+$CPPFLAGS
else # doug's fix, NOW add -Dss_family... only if required! else # doug's fix, NOW add -Dss_family... only if required!
$CPPFLAGS += " -Dss_family=__ss_family -Dss_len=__ss_len" $CPPFLAGS += " -Dss_family=__ss_family -Dss_len=__ss_len"
if try_link(<<EOF) if try_link(<<EOF)
@ -304,9 +305,9 @@ end
case with_config("lookup-order-hack", "UNSPEC") case with_config("lookup-order-hack", "UNSPEC")
when "INET" when "INET"
$CFLAGS="-DLOOKUP_ORDER_HACK_INET "+$CFLAGS $CPPFLAGS="-DLOOKUP_ORDER_HACK_INET "+$CPPFLAGS
when "INET6" when "INET6"
$CFLAGS="-DLOOKUP_ORDER_HACK_INET6 "+$CFLAGS $CPPFLAGS="-DLOOKUP_ORDER_HACK_INET6 "+$CPPFLAGS
when "UNSPEC" when "UNSPEC"
# nothing special # nothing special
else else
@ -351,7 +352,7 @@ EOF
end end
if have_getaddrinfo if have_getaddrinfo
$CFLAGS="-DHAVE_GETADDRINFO "+$CFLAGS $CPPFLAGS="-DHAVE_GETADDRINFO "+$CPPFLAGS
else else
$CFLAGS="-I. "+$CFLAGS $CFLAGS="-I. "+$CFLAGS
$objs += ["getaddrinfo.#{$OBJEXT}"] $objs += ["getaddrinfo.#{$OBJEXT}"]

View file

@ -239,7 +239,7 @@ syck_emitter_write( SyckEmitter *e, char *str, long len )
long rest = e->bufsize - (e->marker - e->buffer); long rest = e->bufsize - (e->marker - e->buffer);
if (len <= rest) break; if (len <= rest) break;
S_MEMCPY( e->marker, str, char, rest ); S_MEMCPY( e->marker, str, char, rest );
e->marker += len; e->marker += rest;
str += rest; str += rest;
len -= rest; len -= rest;
syck_emitter_flush( e, 0 ); syck_emitter_flush( e, 0 );

View file

@ -17,7 +17,7 @@ TclTkLib.mainloop_abort_on_exception = true
################################################ ################################################
# exceptiopn to treat the return value from IP # exceptiopn to treat the return value from IP
class MultiTkIp_OK < Exception class MultiTkIp_OK < Exception
def self.send(thred, ret=nil) def self.send(thread, ret=nil)
thread.raise self.new(ret) thread.raise self.new(ret)
end end

9
io.c
View file

@ -59,7 +59,7 @@
#include <sys/stat.h> #include <sys/stat.h>
/* EMX has sys/param.h, but.. */ /* EMX has sys/param.h, but.. */
#if defined(HAVE_SYS_PAAM_H) && !(defined(__EMX__) || defined(__HIUX_MPP__)) #if defined(HAVE_SYS_PARAM_H) && !(defined(__EMX__) || defined(__HIUX_MPP__))
# include <sys/param.h> # include <sys/param.h>
#endif #endif
@ -1543,7 +1543,7 @@ rb_io_each_line(argc, argv, io)
/* /*
* call-seq: * call-seq:
* ios.each_byte {|byte| block } => nil * ios.each_byte {|byte| block } => ios
* *
* Calls the given block once for each byte (0..255) in <em>ios</em>, * Calls the given block once for each byte (0..255) in <em>ios</em>,
* passing the byte as an argument. The stream must be opened for * passing the byte as an argument. The stream must be opened for
@ -4902,7 +4902,6 @@ argf_eof()
if (init_p == 0) return Qtrue; if (init_p == 0) return Qtrue;
ARGF_FORWARD(); ARGF_FORWARD();
if (rb_io_eof(current_file)) { if (rb_io_eof(current_file)) {
next_p = 1;
return Qtrue; return Qtrue;
} }
} }
@ -4940,7 +4939,7 @@ argf_read(argc, argv)
} }
if (NIL_P(str)) str = tmp; if (NIL_P(str)) str = tmp;
else rb_str_append(str, tmp); else rb_str_append(str, tmp);
if (NIL_P(tmp) || NIL_P(argv[0])) { if (NIL_P(tmp) || NIL_P(length)) {
if (next_p != -1) { if (next_p != -1) {
argf_close(current_file); argf_close(current_file);
next_p = 1; next_p = 1;
@ -5021,7 +5020,7 @@ argf_each_byte()
while (!NIL_P(byte = argf_getc())) { while (!NIL_P(byte = argf_getc())) {
rb_yield(byte); rb_yield(byte);
} }
return Qnil; return argf;
} }
static VALUE static VALUE

View file

@ -209,8 +209,8 @@ class CGI
# session id is stored in a cookie. # session id is stored in a cookie.
# #
# session_expires:: the time the current session expires, as a # session_expires:: the time the current session expires, as a
# +Time+ object. If not set, the session will continue # +Time+ object. If not set, the session will terminate
# indefinitely. # when the user's browser is closed.
# session_domain:: the hostname domain for which this session is valid. # session_domain:: the hostname domain for which this session is valid.
# If not set, defaults to the hostname of the server. # If not set, defaults to the hostname of the server.
# session_secure:: if +true+, this session will only work over HTTPS. # session_secure:: if +true+, this session will only work over HTTPS.

View file

@ -10,6 +10,7 @@ struct direct
long d_namlen; long d_namlen;
ino_t d_ino; ino_t d_ino;
char d_name[256]; char d_name[256];
char d_isdir;
}; };
typedef struct { typedef struct {
char *start; char *start;
@ -17,6 +18,8 @@ typedef struct {
long size; long size;
long nfiles; long nfiles;
struct direct dirstr; struct direct dirstr;
char *bits;
long bitpos;
} DIR; } DIR;

View file

@ -1384,6 +1384,8 @@ rb_w32_opendir(const char *filename)
idx = strlen(fd.name)+1; idx = strlen(fd.name)+1;
p->start = ALLOC_N(char, idx); p->start = ALLOC_N(char, idx);
strcpy(p->start, fd.name); strcpy(p->start, fd.name);
p->bits = ALLOC_N(char, 1);
p->bits[0] = fd.attrib & _A_SUBDIR ? 1 : 0;
p->nfiles++; p->nfiles++;
// //
@ -1407,6 +1409,18 @@ rb_w32_opendir(const char *filename)
rb_fatal ("opendir: malloc failed!\n"); rb_fatal ("opendir: malloc failed!\n");
} }
strcpy(&p->start[idx], fd.name); strcpy(&p->start[idx], fd.name);
if (p->nfiles % 8 == 0) {
Renew (p->bits, p->nfiles / 8 + 1, char);
if (p->bits == NULL) {
rb_fatal ("opendir: malloc failed!\n");
}
p->bits[p->nfiles / 8] = 0;
}
if (fd.attrib & _A_SUBDIR) {
p->bits[p->nfiles / 8] |= (1 << p->nfiles % 8);
}
p->nfiles++; p->nfiles++;
idx += len+1; idx += len+1;
} }
@ -1443,6 +1457,12 @@ rb_w32_readdir(DIR *dirp)
// //
dirp->dirstr.d_ino = dummy++; dirp->dirstr.d_ino = dummy++;
//
// Directory flag
//
dirp->dirstr.d_isdir = dirp->bits[dirp->bitpos / 8] & (1 << dirp->bitpos % 8);
dirp->bitpos++;
// //
// Now set up for the next call to readdir // Now set up for the next call to readdir
// //
@ -1486,6 +1506,7 @@ void
rb_w32_rewinddir(DIR *dirp) rb_w32_rewinddir(DIR *dirp)
{ {
dirp->curr = dirp->start; dirp->curr = dirp->start;
dirp->bitpos = 0;
} }
// //
@ -1496,6 +1517,7 @@ void
rb_w32_closedir(DIR *dirp) rb_w32_closedir(DIR *dirp)
{ {
free(dirp->start); free(dirp->start);
free(dirp->bits);
free(dirp); free(dirp);
} }