diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-07-30 22:41:59 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-07-30 22:41:59 +0000 |
commit | 645170199ca8d9f7eaa8f928519897d2d1ed709d (patch) | |
tree | 2ee780c775706421c55580e4dda439a2480a1d5f | |
parent | 67d433a5e62fdbfa73f688c59af111bd67aefa24 (diff) | |
download | ruby-645170199ca8d9f7eaa8f928519897d2d1ed709d.tar.gz |
* 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
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | file.c | 77 |
2 files changed, 55 insertions, 32 deletions
@@ -1,7 +1,13 @@ +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> * lib/net/imap.rb: added new commands for managing folder quotas - and folder ACLs. + and folder ACLs. Fri Jul 27 18:07:27 2001 Yukihiro Matsumoto <matz@ruby-lang.org> @@ -40,7 +46,7 @@ Wed Jul 25 12:15:32 2001 WATANABE Hirofumi <eban@ruby-lang.org> * 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 supprot. originally comes from Patrick Cheng. [new] @@ -1332,7 +1332,7 @@ rb_file_s_expand_path(argc, argv) VALUE *argv; { VALUE fname, dname; - char *s, *p, *sbeg, *b; + char *s, *p, *b; char buf[MAXPATHLEN+2]; char *bend = buf + sizeof(buf) - 2; int tainted; @@ -1340,7 +1340,7 @@ rb_file_s_expand_path(argc, argv) rb_scan_args(argc, argv, "11", &fname, &dname); tainted = OBJ_TAINTED(fname); - s = sbeg = StringValuePtr(fname); + s = StringValuePtr(fname); p = buf; if (s[0] == '~') { if (isdirsep(s[1]) || s[1] == '\0') { @@ -1417,61 +1417,78 @@ rb_file_s_expand_path(argc, argv) } *p = '/'; + b = s; while (*s) { switch (*s) { case '.': - if (*(s+1) && (s == sbeg || isdirsep(*(s - 1)))) { - switch (*++s) { + if (b == s++) { /* beginning of path element */ + switch (*s) { + case '\0': + b = s; + break; case '.': if (*(s+1) == '\0' || isdirsep(*(s+1))) { /* 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; + *p = '\0'; + if (!(b = strrdirsep(buf))) { + *p = '/'; + } + else { + p = b; + } + b = ++s; } break; case '/': #if defined DOSISH case '\\': #endif - if (!isdirsep(*p)) *++p = '/'; + b = ++s; break; default: - *++p = '.'; *++p = *s; break; + /* ordinary path element, beginning don't move */ + break; } - } - else { - *++p = '.'; } break; case '/': #if defined DOSISH case '\\': #endif - if (!isdirsep(*p)) *++p = '/'; break; + if (s > b) { + if (p + (s-b+1) >= bend) goto toolong; + memcpy(++p, b, s-b); + p += s-b; + *p = '/'; + } + b = ++s; + break; default: - b = s; s = CharNext(s); - p = CharNext(p); - if (p + (s-b) >= bend) goto toolong; - memcpy(p, b, s-b); - continue; + break; } - s = CharNext(s); } - /* Place a \0 at end. If path ends with a "/", delete it */ - if (p == buf || !isdirsep(*p)) p++; - *p = '\0'; + 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_new2(buf); + fname = rb_str_new(buf, p - buf); if (tainted) OBJ_TAINT(fname); return fname; |