summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--configure.in2
-rw-r--r--dir.c580
-rw-r--r--eval.c3
-rw-r--r--ext/socket/extconf.rb25
-rw-r--r--ext/syck/emitter.c2
-rw-r--r--ext/tk/lib/multi-tk.rb2
-rw-r--r--io.c9
-rw-r--r--lib/cgi/session.rb4
-rw-r--r--win32/dir.h3
-rw-r--r--win32/win32.c22
11 files changed, 402 insertions, 264 deletions
diff --git a/ChangeLog b/ChangeLog
index 92f2acc0be..ed49627f1f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
* 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
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>
* bin/ri (report_class_stuff): Fix problem with ambiguous nested
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>
* lib/pathname.rb: Corrected small coding error.
diff --git a/configure.in b/configure.in
index 1704619fec..c51fd57b15 100644
--- a/configure.in
+++ b/configure.in
@@ -707,7 +707,7 @@ if test x"$enable_pthread" = xyes; then
else
AC_MSG_WARN("Don't know how to find pthread library on your system -- thread support disabled")
fi
- AC_CHECK_FUNC(nanosleep)
+ AC_CHECK_FUNCS(nanosleep)
if test x"$ac_cv_func_nanosleep" = xno; then
AC_CHECK_LIB(rt, nanosleep)
if test x"$ac_cv_lib_rt_nanosleep" = xyes; then
diff --git a/dir.c b/dir.c
index 07dd806ba7..29772de5ab 100644
--- a/dir.c
+++ b/dir.c
@@ -76,15 +76,65 @@ char *strchr _((char*,char));
#define FNM_ERROR 2
#define downcase(c) (nocase && ISUPPER(c) ? tolower(c) : (c))
-
-#ifndef CharNext /* defined as CharNext[AW] on Windows. */
-# if defined(DJGPP)
-# define CharNext(p) ((p) + mblen(p, MB_CUR_MAX))
-# else
-# define CharNext(p) ((p) + 1)
-# endif
+#define compare(c1, c2) (((unsigned char)(c1)) - ((unsigned char)(c2)))
+
+/* caution: in case *p == '\0'
+ Next(p) == p + 1 in single byte environment
+ Next(p) == p in multi byte environment
+*/
+#if defined(CharNext)
+# 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
+#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
#define isdirsep(c) ((c) == '/' || (c) == '\\')
#else
@@ -94,7 +144,7 @@ char *strchr _((char*,char));
static char *
range(pat, test, flags)
char *pat;
- char test;
+ char *test;
int flags;
{
int not, ok = 0;
@@ -105,32 +155,32 @@ range(pat, test, flags)
if (not)
pat++;
- test = downcase(test);
-
while (*pat) {
- int cstart, cend;
- cstart = cend = *pat++;
- if (cstart == ']')
- return ok == not ? 0 : pat;
- else if (escape && cstart == '\\')
- cstart = cend = *pat++;
+ char *pstart, *pend;
+ pstart = pend = pat;
+ if (*pstart == ']')
+ return ok == not ? 0 : ++pat;
+ else if (escape && *pstart == '\\')
+ pstart = pend = ++pat;
+ Inc(pat);
if (*pat == '-' && pat[1] != ']') {
if (escape && pat[1] == '\\')
pat++;
- cend = pat[1];
- if (!cend)
+ pend = pat+1;
+ if (!*pend)
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;
}
return 0;
}
#define ISDIRSEP(c) (pathname && isdirsep(c))
-#define PERIOD(s) (period && *(s) == '.' && \
- ((s) == string || ISDIRSEP((s)[-1])))
+#define PERIOD_S() (period && *s == '.' && \
+ (!s_prev || ISDIRSEP(*s_prev)))
+#define INC_S() (s = Next(s_prev = s))
static int
fnmatch(pat, string, flags)
const char *pat;
@@ -138,25 +188,26 @@ fnmatch(pat, string, flags)
int flags;
{
int c;
- int test;
- const char *s = string;
+ const char *test;
+ const char *s = string, *s_prev = 0;
int escape = !(flags & FNM_NOESCAPE);
int pathname = flags & FNM_PATHNAME;
int period = !(flags & FNM_DOTMATCH);
int nocase = flags & FNM_CASEFOLD;
- while (c = *pat++) {
+ while (c = *pat) {
switch (c) {
case '?':
- if (!*s || ISDIRSEP(*s) || PERIOD(s))
+ if (!*s || ISDIRSEP(*s) || PERIOD_S())
return FNM_NOMATCH;
- s++;
+ INC_S();
+ ++pat;
break;
case '*':
- while ((c = *pat++) == '*')
+ while ((c = *++pat) == '*')
;
- if (PERIOD(s))
+ if (PERIOD_S())
return FNM_NOMATCH;
if (!c) {
@@ -168,45 +219,39 @@ fnmatch(pat, string, flags)
else if (ISDIRSEP(c)) {
s = rb_path_next(s);
if (*s) {
- s++;
+ INC_S();
break;
}
return FNM_NOMATCH;
}
- test = escape && c == '\\' ? *pat : c;
- test = downcase(test);
- pat--;
+ test = escape && c == '\\' ? pat+1 : pat;
while (*s) {
- if ((c == '[' || downcase(*s) == test) &&
+ if ((c == '[' || Compare(s, test) == 0) &&
!fnmatch(pat, s, flags | FNM_DOTMATCH))
return 0;
else if (ISDIRSEP(*s))
break;
- s++;
+ INC_S();
}
return FNM_NOMATCH;
case '[':
- if (!*s || ISDIRSEP(*s) || PERIOD(s))
+ if (!*s || ISDIRSEP(*s) || PERIOD_S())
return FNM_NOMATCH;
- pat = range(pat, *s, flags);
+ pat = range(pat+1, s, flags);
if (!pat)
return FNM_NOMATCH;
- s++;
+ INC_S();
break;
case '\\':
- if (escape
+ if (escape && pat[1]
#if defined DOSISH
- && *pat && strchr("*?[\\", *pat)
+ && strchr("*?[\\", pat[1])
#endif
) {
- c = *pat;
- if (!c)
- c = '\\';
- else
- pat++;
+ c = *++pat;
}
/* FALLTHROUGH */
@@ -216,9 +261,10 @@ fnmatch(pat, string, flags)
;
else
#endif
- if(downcase(c) != downcase(*s))
+ if(Compare(pat, s) != 0)
return FNM_NOMATCH;
- s++;
+ INC_S();
+ Inc(pat);
break;
}
}
@@ -768,95 +814,142 @@ dir_s_rmdir(obj, dir)
/* Return nonzero if S has any special globbing chars in it. */
static int
-has_magic(s, send, flags)
- char *s, *send;
+has_magic(p, m, flags)
+ register char *p;
+ char **m;
int flags;
{
- register char *p = s;
register char c;
int open = 0;
int escape = !(flags & FNM_NOESCAPE);
- while ((c = *p++) != '\0') {
+ while (c = *p++, c != '\0' && c != '/') {
switch (c) {
case '?':
case '*':
- return Qtrue;
+ goto found;
case '[': /* Only accept an open brace if there is a close */
open++; /* brace to match it. Bracket expressions must be */
continue; /* complete, according to Posix.2 */
case ']':
if (open)
- return Qtrue;
+ goto found;
continue;
case '\\':
- if (escape && *p++ == '\0')
- return Qfalse;
+ if (escape && (c = *p++, c == '\0' || c == '/'))
+ goto miss;
+ continue;
}
- if (send && p >= send) break;
+ p = Next(p-1);
}
- return Qfalse;
+
+ miss:
+ *m = p-1;
+ return 0;
+
+ found:
+ while (*p != '\0' && *p != '/')
+ Inc(p);
+ *m = p;
+ return 1;
}
-static char*
-extract_path(p, pend)
- char *p, *pend;
+static int
+remove_backslashes(p, pend)
+ char *p;
+ char *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;
+ char *t = p;
+ char *s = p;
+ int n = 0;
+
+ while (*p && p < pend) {
+ if (*p == '\\') {
+ if (t != s) {
+ memmove(t, s, p - s);
+ n++;
+ }
+ t += p - s;
+ s = ++p;
+ if (!(*p && p < pend)) break;
+ }
+ Inc(p);
}
- else {
- alloc[len] = 0;
+
+ while (*p++);
+
+ if (t != s) {
+ memmove(t, s, p - s); /* move '\0' too */
+ n++;
}
- return alloc;
+ return n;
}
-static char*
-extract_elem(path)
- char *path;
-{
+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;
+}
- pend = strchr(path, '/');
- if (!pend) pend = path + strlen(path);
-
- return extract_path(path, pend);
+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 void
-remove_backslashes(p)
- char *p;
+static int
+do_lstat(path, pst)
+ const char *path;
+ struct stat *pst;
{
- char *pend = p + strlen(p);
- char *t = p;
+ int ret = lstat(path, pst);
+ if (ret < 0 && errno != ENOENT)
+ rb_sys_warning(path);
+ return ret;
+}
- while (p < pend) {
- if (*p == '\\') {
- if (++p == pend) break;
- }
- *t++ = *p++;
- }
- *t = '\0';
+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
# define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
#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 {
void (*func) _((const char*, VALUE));
const char *c;
@@ -892,162 +985,155 @@ glob_call_func(func, path, arg)
}
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 *sub;
+ int separator;
int flags;
void (*func) _((const char*, VALUE));
VALUE arg;
{
struct stat st;
- char *p, *m;
int status = 0;
+ char *p = sub, *m, *buf;
+ DIR *dirp;
+ struct dirent *dp;
+ int recursive = 0;
+ int magical = 1;
+
+ struct d_link {
+ char *name;
+ struct d_link *next;
+ } *tmp, *link, **tail = &link;
+
+ while (*p && !has_magic(p, &m, flags)) {
+ if (*m == '/') {
+ separator = 1;
+ p = m + 1;
+ }
+ else {
+ separator = 0;
+ p = m;
+ }
+ }
- p = sub ? sub : path;
- if (!has_magic(p, 0, flags)) {
-#if defined DOSISH
- remove_backslashes(path);
-#else
- if (!(flags & FNM_NOESCAPE)) remove_backslashes(p);
-#endif
- if (lstat(path, &st) == 0) {
- status = glob_call_func(func, path, arg);
- if (status) return status;
+ 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 (errno != ENOENT) {
- /* In case stat error is other than ENOENT and
- we may want to know what is wrong. */
- rb_sys_warning(path);
+ else {
+ if (do_lstat(path, &st) == 0)
+ return glob_call_func(func, path, arg);
}
return 0;
}
- while (p && !status) {
- if (*p == '/') p++;
- m = strchr(p, '/');
- if (has_magic(p, m, flags)) {
- char *dir, *base, *magic, *buf;
- DIR *dirp;
- struct dirent *dp;
- int recursive = 0;
-
- struct d_link {
- char *path;
- struct d_link *next;
- } *tmp, *link, **tail = &link;
-
- base = extract_path(path, p);
- if (path == p) dir = ".";
- else dir = base;
-
- magic = extract_elem(p);
- if (stat(dir, &st) < 0) {
- if (errno != ENOENT) rb_sys_warning(dir);
- free(base);
- free(magic);
- break;
- }
- if (S_ISDIR(st.st_mode)) {
- if (m && strcmp(magic, "**") == 0) {
- int n = strlen(base);
- recursive = 1;
- buf = ALLOC_N(char, n+strlen(m)+3);
- sprintf(buf, "%s%s", base, *base ? m : m+1);
- status = glob_helper(buf, buf+n, flags, func, arg);
- free(buf);
- if (status) goto finalize;
- }
- dirp = opendir(dir);
- if (dirp == NULL) {
- rb_sys_warning(dir);
- free(base);
- free(magic);
- break;
- }
- }
- else {
- free(base);
- free(magic);
- break;
- }
+ if (p[0] == '*' && p[1] == '*' && p[2] == '/') {
+ char *t = p+3;
+ while (t[0] == '*' && t[1] == '*' && t[2] == '/') t += 3;
+ memmove(p, t, strlen(t)+1); /* move '\0' too */
+ magical = has_magic(p, &m, flags); /* next element */
+ recursive = 1;
+ }
-#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
+ if (path == p) {
+ dirp = do_opendir(".");
+ if (dirp == NULL) return 0;
+ }
+ else {
+ char *t = separator ? p-1 : p;
+ char c = *t;
+ *t = '\0';
+ dirp = do_opendir(path);
+ *t = c;
+ if (dirp == NULL) return 0;
+ }
- 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;
+ for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
+ const int n1 = p - path;
+ const int n2 = n1 + NAMLEN(dp);
+ const int ok = 0;
+ const int no = 1;
+ int is_dir = -1; /* not checked yet */
+ if (recursive && strcmp(".", dp->d_name) != 0 && strcmp("..", dp->d_name) != 0) {
+ buf = ALLOC_N(char, n2+4+strlen(p)+1);
+ memcpy(buf, path, n1);
+ 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;
}
- 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;
+ else if (S_ISLNK(st.st_mode) && do_stat(buf, &st) == 0 && S_ISDIR(st.st_mode)) {
+ is_dir = ok;
}
}
- 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;
+ }
+ if (is_dir == no && *m == '/') {
+ continue;
+ }
+ if (magical && do_fnmatch(p, m, dp->d_name, flags) == 0) {
+ buf = ALLOC_N(char, n2+1+1);
+ memcpy(buf, path, n1);
+ strcpy(buf+n1, dp->d_name);
+ if (*m == '\0') {
+ status = glob_call_func(func, buf, arg);
+ }
+ else if (m[1] == '\0' && is_dir == ok) { /* *m == '/' */
+ strcpy(buf+n2, "/");
+ status = glob_call_func(func, buf, arg);
}
+ else {
+ tmp = ALLOC(struct d_link);
+ tmp->name = ALLOC_N(char, NAMLEN(dp)+1);
+ strcpy(tmp->name, dp->d_name);
+ *tail = tmp;
+ tail = &tmp->next;
+ }
+ free(buf);
+ if (status) break;
+ }
+ }
+
+ 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);
}
- p = m;
+ tmp = link;
+ link = link->next;
+ free(tmp->name);
+ free(tmp);
+ }
+
+ if (!magical) {
+ status = glob_helper(path, p, separator, flags, func, arg);
}
+
return status;
}
@@ -1058,7 +1144,17 @@ rb_glob2(path, flags, func, arg)
void (*func) _((const char*, VALUE));
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);
}
@@ -1122,7 +1218,7 @@ push_braces(ary, s, flags)
lbrace = p;
break;
}
- p++;
+ Inc(p);
}
while (*p) {
if (*p == '{') nest++;
@@ -1130,7 +1226,7 @@ push_braces(ary, s, flags)
rbrace = p;
break;
}
- p++;
+ Inc(p);
}
if (lbrace && rbrace) {
@@ -1140,13 +1236,13 @@ push_braces(ary, s, flags)
b = buf + (lbrace-s);
p = lbrace;
while (*p != '}') {
- t = p + 1;
- for (p = t; *p!='}' && *p!=','; p++) {
+ t = Next(p);
+ for (p = t; *p!='}' && *p!=','; Inc(p)) {
/* skip inner braces */
- if (*p == '{') while (*p!='}') p++;
+ if (*p == '{') while (*p!='}') Inc(p);
}
memcpy(b, t, p-t);
- strcpy(b+(p-t), rbrace+1);
+ strcpy(b+(p-t), Next(rbrace));
push_braces(ary, buf, flags);
}
free(buf);
@@ -1157,7 +1253,6 @@ push_braces(ary, s, flags)
}
#define isdelim(c) ((c)=='\0')
-
static VALUE
rb_push_glob(str, flags)
VALUE str;
@@ -1182,19 +1277,20 @@ rb_push_glob(str, flags)
pend = p + RSTRING(str)->len;
while (p < pend) {
- t = buf;
nest = maxnest = 0;
while (p < pend && isdelim(*p)) p++;
+ t = p;
while (p < pend && !isdelim(*p)) {
if (*p == '{') nest++, maxnest++;
if (*p == '}') nest--;
if (!noescape && *p == '\\') {
- *t++ = *p++;
- if (p == pend) break;
+ p++;
+ 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) {
push_globs(ary, buf, flags);
}
diff --git a/eval.c b/eval.c
index 6d88111a85..e764e5c23e 100644
--- a/eval.c
+++ b/eval.c
@@ -10318,13 +10318,16 @@ rb_thread_wait_for(time)
curr_thread == curr_thread->next ||
curr_thread->status == THREAD_TO_KILL) {
int n;
+ int thr_critical = rb_thread_critical;
#ifndef linux
double d, limit;
limit = timeofday()+(double)time.tv_sec+(double)time.tv_usec*1e-6;
#endif
for (;;) {
+ rb_thread_critical = Qtrue;
TRAP_BEG;
n = select(0, 0, 0, 0, &time);
+ rb_thread_critical = thr_critical;
TRAP_END;
if (n == 0) return;
if (n < 0) {
diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb
index 4f7b49407f..acbff10a16 100644
--- a/ext/socket/extconf.rb
+++ b/ext/socket/extconf.rb
@@ -35,7 +35,7 @@ main()
socket(AF_INET6, SOCK_STREAM, 0);
}
EOF
- $CFLAGS+=" -DENABLE_IPV6"
+ $CPPFLAGS+=" -DENABLE_IPV6"
$ipv6 = true
end
end
@@ -49,7 +49,7 @@ if $ipv6
#include <netinet/in.h>
EOF
$ipv6type = "inria"
- $CFLAGS="-DINET6 "+$CFLAGS
+ $CPPFLAGS="-DINET6 "+$CPPFLAGS
elsif macro_defined?("__KAME__", <<EOF)
#include <netinet/in.h>
EOF
@@ -57,37 +57,38 @@ EOF
$ipv6lib="inet6"
$ipv6libdir="/usr/local/v6/lib"
$ipv6trylibc=true
- $CFLAGS="-DINET6 "+$CFLAGS
+ $CPPFLAGS="-DINET6 "+$CPPFLAGS
elsif File.directory? "/usr/inet6"
$ipv6type = "linux"
$ipv6lib="inet6"
$ipv6libdir="/usr/inet6/lib"
- $CFLAGS="-DINET6 -I/usr/inet6/include "+$CFLAGS
+ $CPPFLAGS="-DINET6 -I/usr/inet6/include "+$CPPFLAGS
elsif macro_defined?("_TOSHIBA_INET6", <<EOF)
#include <sys/param.h>
EOF
$ipv6type = "toshiba"
$ipv6lib="inet6"
$ipv6libdir="/usr/local/v6/lib"
- $CFLAGS="-DINET6 "+$CFLAGS
+ $CPPFLAGS="-DINET6 "+$CPPFLAGS
elsif macro_defined?("__V6D__", <<EOF)
#include </usr/local/v6/include/sys/v6config.h>
EOF
$ipv6type = "v6d"
$ipv6lib="v6"
$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)
#include <sys/param.h>
EOF
$ipv6type = "zeta"
$ipv6lib="inet6"
$ipv6libdir="/usr/local/v6/lib"
- $CFLAGS="-DINET6 "+$CFLAGS
+ $CPPFLAGS="-DINET6 "+$CPPFLAGS
else
$ipv6lib=with_config("ipv6-lib", nil)
$ipv6libdir=with_config("ipv6-libdir", nil)
- $CFLAGS="-DINET6 "+$CFLAGS
+ $CPPFLAGS="-DINET6 "+$CPPFLAGS
end
if $ipv6lib
@@ -147,7 +148,7 @@ main()
return 0;
}
EOF
- $CFLAGS="-DHAVE_SOCKADDR_STORAGE "+$CFLAGS
+ $CPPFLAGS="-DHAVE_SOCKADDR_STORAGE "+$CPPFLAGS
else # doug's fix, NOW add -Dss_family... only if required!
$CPPFLAGS += " -Dss_family=__ss_family -Dss_len=__ss_len"
if try_link(<<EOF)
@@ -304,9 +305,9 @@ end
case with_config("lookup-order-hack", "UNSPEC")
when "INET"
- $CFLAGS="-DLOOKUP_ORDER_HACK_INET "+$CFLAGS
+ $CPPFLAGS="-DLOOKUP_ORDER_HACK_INET "+$CPPFLAGS
when "INET6"
- $CFLAGS="-DLOOKUP_ORDER_HACK_INET6 "+$CFLAGS
+ $CPPFLAGS="-DLOOKUP_ORDER_HACK_INET6 "+$CPPFLAGS
when "UNSPEC"
# nothing special
else
@@ -351,7 +352,7 @@ EOF
end
if have_getaddrinfo
- $CFLAGS="-DHAVE_GETADDRINFO "+$CFLAGS
+ $CPPFLAGS="-DHAVE_GETADDRINFO "+$CPPFLAGS
else
$CFLAGS="-I. "+$CFLAGS
$objs += ["getaddrinfo.#{$OBJEXT}"]
diff --git a/ext/syck/emitter.c b/ext/syck/emitter.c
index 4dcc8b3fc5..d373ed4c45 100644
--- a/ext/syck/emitter.c
+++ b/ext/syck/emitter.c
@@ -239,7 +239,7 @@ syck_emitter_write( SyckEmitter *e, char *str, long len )
long rest = e->bufsize - (e->marker - e->buffer);
if (len <= rest) break;
S_MEMCPY( e->marker, str, char, rest );
- e->marker += len;
+ e->marker += rest;
str += rest;
len -= rest;
syck_emitter_flush( e, 0 );
diff --git a/ext/tk/lib/multi-tk.rb b/ext/tk/lib/multi-tk.rb
index b6c800177f..c2dcb4f971 100644
--- a/ext/tk/lib/multi-tk.rb
+++ b/ext/tk/lib/multi-tk.rb
@@ -17,7 +17,7 @@ TclTkLib.mainloop_abort_on_exception = true
################################################
# exceptiopn to treat the return value from IP
class MultiTkIp_OK < Exception
- def self.send(thred, ret=nil)
+ def self.send(thread, ret=nil)
thread.raise self.new(ret)
end
diff --git a/io.c b/io.c
index 40d8568bbf..fba74b8336 100644
--- a/io.c
+++ b/io.c
@@ -59,7 +59,7 @@
#include <sys/stat.h>
/* 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>
#endif
@@ -1543,7 +1543,7 @@ rb_io_each_line(argc, argv, io)
/*
* 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>,
* passing the byte as an argument. The stream must be opened for
@@ -4902,7 +4902,6 @@ argf_eof()
if (init_p == 0) return Qtrue;
ARGF_FORWARD();
if (rb_io_eof(current_file)) {
- next_p = 1;
return Qtrue;
}
}
@@ -4940,7 +4939,7 @@ argf_read(argc, argv)
}
if (NIL_P(str)) 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) {
argf_close(current_file);
next_p = 1;
@@ -5021,7 +5020,7 @@ argf_each_byte()
while (!NIL_P(byte = argf_getc())) {
rb_yield(byte);
}
- return Qnil;
+ return argf;
}
static VALUE
diff --git a/lib/cgi/session.rb b/lib/cgi/session.rb
index 4ad6bf2a67..7115cae7d2 100644
--- a/lib/cgi/session.rb
+++ b/lib/cgi/session.rb
@@ -209,8 +209,8 @@ class CGI
# session id is stored in a cookie.
#
# session_expires:: the time the current session expires, as a
- # +Time+ object. If not set, the session will continue
- # indefinitely.
+ # +Time+ object. If not set, the session will terminate
+ # when the user's browser is closed.
# session_domain:: the hostname domain for which this session is valid.
# If not set, defaults to the hostname of the server.
# session_secure:: if +true+, this session will only work over HTTPS.
diff --git a/win32/dir.h b/win32/dir.h
index 3dd670bef0..fdea6393c8 100644
--- a/win32/dir.h
+++ b/win32/dir.h
@@ -10,6 +10,7 @@ struct direct
long d_namlen;
ino_t d_ino;
char d_name[256];
+ char d_isdir;
};
typedef struct {
char *start;
@@ -17,6 +18,8 @@ typedef struct {
long size;
long nfiles;
struct direct dirstr;
+ char *bits;
+ long bitpos;
} DIR;
diff --git a/win32/win32.c b/win32/win32.c
index 966c326466..5ea7eccb1a 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -1384,6 +1384,8 @@ rb_w32_opendir(const char *filename)
idx = strlen(fd.name)+1;
p->start = ALLOC_N(char, idx);
strcpy(p->start, fd.name);
+ p->bits = ALLOC_N(char, 1);
+ p->bits[0] = fd.attrib & _A_SUBDIR ? 1 : 0;
p->nfiles++;
//
@@ -1407,6 +1409,18 @@ rb_w32_opendir(const char *filename)
rb_fatal ("opendir: malloc failed!\n");
}
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++;
idx += len+1;
}
@@ -1444,6 +1458,12 @@ rb_w32_readdir(DIR *dirp)
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
//
@@ -1486,6 +1506,7 @@ void
rb_w32_rewinddir(DIR *dirp)
{
dirp->curr = dirp->start;
+ dirp->bitpos = 0;
}
//
@@ -1496,6 +1517,7 @@ void
rb_w32_closedir(DIR *dirp)
{
free(dirp->start);
+ free(dirp->bits);
free(dirp);
}