* file.c (rb_file_s_expand_path): scans per path element not per
byte/character, including fix of [ruby-talk:18152] and multi-byte pathname support. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1655 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
67d433a5e6
commit
645170199c
@ -1,3 +1,9 @@
|
|||||||
|
Tue Jul 31 07:18:04 2001 Nobuyoshi Nakada <nobu.nokada@softhome.net>
|
||||||
|
|
||||||
|
* file.c (rb_file_s_expand_path): scans per path element not per
|
||||||
|
byte/character, including fix of [ruby-talk:18152] and
|
||||||
|
multi-byte pathname support.
|
||||||
|
|
||||||
Mon Jul 30 11:12:14 2001 Amos Gouaux <amos+ruby@utdallas.edu>
|
Mon Jul 30 11:12:14 2001 Amos Gouaux <amos+ruby@utdallas.edu>
|
||||||
|
|
||||||
* lib/net/imap.rb: added new commands for managing folder quotas
|
* lib/net/imap.rb: added new commands for managing folder quotas
|
||||||
@ -40,7 +46,7 @@ Wed Jul 25 12:15:32 2001 WATANABE Hirofumi <eban@ruby-lang.org>
|
|||||||
|
|
||||||
* file.c (rb_find_file): ditto.
|
* file.c (rb_find_file): ditto.
|
||||||
|
|
||||||
Tue Jul 24 23:10:47 2001 Nobuyoshi.Nakada <nobu.nakada@nifty.ne.jp>
|
Tue Jul 24 23:10:47 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
||||||
|
|
||||||
* file.c (strrdirsep): multi-byte pathname and DOSish separater
|
* file.c (strrdirsep): multi-byte pathname and DOSish separater
|
||||||
supprot. originally comes from Patrick Cheng. [new]
|
supprot. originally comes from Patrick Cheng. [new]
|
||||||
|
115
file.c
115
file.c
@ -1332,7 +1332,7 @@ rb_file_s_expand_path(argc, argv)
|
|||||||
VALUE *argv;
|
VALUE *argv;
|
||||||
{
|
{
|
||||||
VALUE fname, dname;
|
VALUE fname, dname;
|
||||||
char *s, *p, *sbeg, *b;
|
char *s, *p, *b;
|
||||||
char buf[MAXPATHLEN+2];
|
char buf[MAXPATHLEN+2];
|
||||||
char *bend = buf + sizeof(buf) - 2;
|
char *bend = buf + sizeof(buf) - 2;
|
||||||
int tainted;
|
int tainted;
|
||||||
@ -1340,7 +1340,7 @@ rb_file_s_expand_path(argc, argv)
|
|||||||
rb_scan_args(argc, argv, "11", &fname, &dname);
|
rb_scan_args(argc, argv, "11", &fname, &dname);
|
||||||
|
|
||||||
tainted = OBJ_TAINTED(fname);
|
tainted = OBJ_TAINTED(fname);
|
||||||
s = sbeg = StringValuePtr(fname);
|
s = StringValuePtr(fname);
|
||||||
p = buf;
|
p = buf;
|
||||||
if (s[0] == '~') {
|
if (s[0] == '~') {
|
||||||
if (isdirsep(s[1]) || s[1] == '\0') {
|
if (isdirsep(s[1]) || s[1] == '\0') {
|
||||||
@ -1417,61 +1417,78 @@ rb_file_s_expand_path(argc, argv)
|
|||||||
}
|
}
|
||||||
*p = '/';
|
*p = '/';
|
||||||
|
|
||||||
|
b = s;
|
||||||
while (*s) {
|
while (*s) {
|
||||||
switch (*s) {
|
switch (*s) {
|
||||||
case '.':
|
case '.':
|
||||||
if (*(s+1) && (s == sbeg || isdirsep(*(s - 1)))) {
|
if (b == s++) { /* beginning of path element */
|
||||||
switch (*++s) {
|
switch (*s) {
|
||||||
|
case '\0':
|
||||||
|
b = s;
|
||||||
|
break;
|
||||||
case '.':
|
case '.':
|
||||||
if (*(s+1) == '\0' || isdirsep(*(s+1))) {
|
if (*(s+1) == '\0' || isdirsep(*(s+1))) {
|
||||||
/* We must go back to the parent */
|
/* We must go back to the parent */
|
||||||
if (isdirsep(*p) && p > buf) p--;
|
|
||||||
while (p > buf && !isdirsep(*p)) p--;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*++p = '.';
|
|
||||||
do {
|
|
||||||
*++p = '.';
|
|
||||||
if (p >= bend) goto toolong;
|
|
||||||
} while (*++s == '.');
|
|
||||||
--s;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '/':
|
|
||||||
#if defined DOSISH
|
|
||||||
case '\\':
|
|
||||||
#endif
|
|
||||||
if (!isdirsep(*p)) *++p = '/';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
*++p = '.'; *++p = *s; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*++p = '.';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '/':
|
|
||||||
#if defined DOSISH
|
|
||||||
case '\\':
|
|
||||||
#endif
|
|
||||||
if (!isdirsep(*p)) *++p = '/'; break;
|
|
||||||
default:
|
|
||||||
b = s;
|
|
||||||
s = CharNext(s);
|
|
||||||
p = CharNext(p);
|
|
||||||
if (p + (s-b) >= bend) goto toolong;
|
|
||||||
memcpy(p, b, s-b);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
s = CharNext(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Place a \0 at end. If path ends with a "/", delete it */
|
|
||||||
if (p == buf || !isdirsep(*p)) p++;
|
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
if (!(b = strrdirsep(buf))) {
|
||||||
|
*p = '/';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p = b;
|
||||||
|
}
|
||||||
|
b = ++s;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
#if defined DOSISH
|
||||||
|
case '\\':
|
||||||
|
#endif
|
||||||
|
b = ++s;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* ordinary path element, beginning don't move */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
#if defined DOSISH
|
||||||
|
case '\\':
|
||||||
|
#endif
|
||||||
|
if (s > b) {
|
||||||
|
if (p + (s-b+1) >= bend) goto toolong;
|
||||||
|
memcpy(++p, b, s-b);
|
||||||
|
p += s-b;
|
||||||
|
*p = '/';
|
||||||
|
}
|
||||||
|
b = ++s;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
s = CharNext(s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fname = rb_str_new2(buf);
|
if (s > b) {
|
||||||
|
if (p + (s-b) >= bend) goto toolong;
|
||||||
|
memcpy(++p, b, s-b);
|
||||||
|
p += s-b;
|
||||||
|
}
|
||||||
|
else if (p == buf) {
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
#if defined(DOSISH)
|
||||||
|
else if (ISALPHA(buf[0]) && (buf[1] == ':') && isdirsep(buf[2])) {
|
||||||
|
/* root directory needs a trailing backslash,
|
||||||
|
otherwise it mean the current directory of the drive */
|
||||||
|
if (p == (buf+2)) p++;
|
||||||
|
}
|
||||||
|
else if (isdirsep(buf[0]) && isdirsep(buf[1])) {
|
||||||
|
if (p == (buf+1)) p++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fname = rb_str_new(buf, p - buf);
|
||||||
if (tainted) OBJ_TAINT(fname);
|
if (tainted) OBJ_TAINT(fname);
|
||||||
return fname;
|
return fname;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user