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

* file.c: improve DOSISH drive letter support.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3301 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
usa 2003-01-06 09:44:15 +00:00
parent 4de3dfd8d3
commit 2b442c240a
2 changed files with 202 additions and 4 deletions

View file

@ -1,3 +1,7 @@
Mon Jan 6 18:43:17 2003 NAKAMURA Usaku <usa@ruby-lang.org>
* file.c: improve DOSISH drive letter support.
Mon Jan 6 18:31:45 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* lib/fileutils.rb (ln): add ' -f' in the verbose message.

202
file.c
View file

@ -1364,6 +1364,48 @@ rb_file_s_umask(argc, argv)
# endif
#endif
#if defined(DOSISH_DRIVE_LETTER) || defined(__CYGWIN__)
static inline int
has_drive_letter(buf)
char *buf;
{
if (ISALPHA(buf[0]) && buf[1] == ':') {
return 1;
}
else {
return 0;
}
}
static void
getcwdofdrv(drv, buf, len)
int drv;
char *buf;
int len;
{
char drive[4];
char oldcwd[MAXPATHLEN+1];
drive[0] = drv;
drive[1] = ':';
drive[2] = '\0';
/* the only way that I know to get the current directory
of a particular drive is to change chdir() to that drive,
so save the old cwd before chdir()
*/
getcwd(oldcwd, MAXPATHLEN);
if (chdir(drive) == 0) {
getcwd(buf, len);
chdir(oldcwd);
}
else {
/* perhaps the drive is not exist. we return only drive letter */
strncpy(buf, drive, len);
}
}
#endif
static char *
strrdirsep(path)
char *path;
@ -1389,6 +1431,12 @@ strrdirsep(path)
pend = buf + buflen;\
}
#if !defined(TOLOWER)
#define TOLOWER(c) (ISUPPER(c) ? tolower(c) : (c))
#endif
static int is_absolute_path _((const char*));
VALUE
rb_file_s_expand_path(argc, argv)
int argc;
@ -1416,6 +1464,11 @@ rb_file_s_expand_path(argc, argv)
}
BUFCHECK(strlen(dir) > buflen);
strcpy(buf, dir);
for (p = buf; p < buf + strlen(dir); p = CharNext(p)) {
if (isdirsep(*p)) {
*p = '/';
}
}
p = buf + strlen(dir);
s++;
tainted = 1;
@ -1448,7 +1501,53 @@ rb_file_s_expand_path(argc, argv)
}
#if defined DOSISH_DRIVE_LETTER || defined __CYGWIN__
/* skip drive letter */
else if (ISALPHA(s[0]) && s[1] == ':' && isdirsep(s[2])) {
else if (has_drive_letter(s)) {
if (isdirsep(s[2])) {
/* specified drive letter, and full path */
/* skip drive letter */
b = s;
while (*s && !isdirsep(*s)) {
s = CharNext(s);
}
BUFCHECK(p + (s-b) >= pend);
memcpy(p, b, s-b);
p += s-b;
}
else {
/* specified drive, but not full path */
int same = 0;
if (!NIL_P(dname)) {
dname = rb_file_s_expand_path(1, &dname);
if (has_drive_letter(RSTRING(dname)->ptr) &&
TOLOWER(*RSTRING(dname)->ptr) == TOLOWER(s[0])) {
/* ok, same drive */
same = 1;
}
}
if (same) {
if (OBJ_TAINTED(dname)) tainted = 1;
BUFCHECK (strlen(RSTRING(dname)->ptr) >= buflen);
strcpy(buf, RSTRING(dname)->ptr);
p = &buf[strlen(buf)];
s += 2;
}
else {
getcwdofdrv(*s, buf, MAXPATHLEN);
s += 2;
tainted = 1;
p = &buf[strlen(buf)];
if (strrdirsep(buf) == p - 1 && *s) p--; /* drop `/' */
}
}
}
#endif
#if defined DOSISH && ! defined(__CYGWIN__)
else if (isdirsep(*s) && !is_absolute_path(s)) {
/* specified full path, but not drive letter */
/* we need to get the drive letter */
tainted = 1;
getcwd(buf, MAXPATHLEN);
p = &buf[2];
b = s;
while (*s && !isdirsep(*s)) {
s = CharNext(s);
@ -1458,7 +1557,7 @@ rb_file_s_expand_path(argc, argv)
p += s-b;
}
#endif
else if (!isdirsep(*s)) {
else if (!is_absolute_path(s)) {
if (!NIL_P(dname)) {
dname = rb_file_s_expand_path(1, &dname);
if (OBJ_TAINTED(dname)) tainted = 1;
@ -1475,7 +1574,7 @@ rb_file_s_expand_path(argc, argv)
free(dir);
p = &buf[strlen(buf)];
}
while (p > buf && *(p - 1) == '/') p--;
while (p > buf && strrdirsep(buf) == p - 1) p--;
}
else {
while (*s && isdirsep(*s)) {
@ -1599,6 +1698,18 @@ rb_file_s_basename(argc, argv)
name = StringValuePtr(fname);
p = strrdirsep(name);
if (!p) {
#if defined(DOSISH_DRIVE_LETTER)
if (has_drive_letter(name)) {
name += 2;
if (NIL_P(fext)) {
f = strlen(name);
}
else {
f = rmext(name, ext);
}
}
else
#endif
if (NIL_P(fext) || !(f = rmext(name, ext)))
return fname;
basename = rb_str_new(name, f);
@ -1626,10 +1737,26 @@ rb_file_s_dirname(klass, fname)
name = StringValuePtr(fname);
p = strrdirsep(name);
if (!p) {
#if defined(DOSISH_DRIVE_LETTER)
if (has_drive_letter(name)) {
dirname = rb_str_new(name, 2);
dirname = rb_str_cat2(dirname, ".");
OBJ_INFECT(dirname, fname);
return dirname;
}
#endif
return rb_str_new2(".");
}
if (p == name)
p++;
#ifdef DOSISH_DRIVE_LETTER
if (has_drive_letter(name) && p == &name[2])
p++;
#endif
#ifdef DOSISH
if (isdirsep(name[0]) && isdirsep(name[1]) && p == &name[1])
p++;
#endif
dirname = rb_str_new(name, p - name);
OBJ_INFECT(dirname, fname);
return dirname;
@ -1666,11 +1793,78 @@ rb_file_s_split(klass, path)
static VALUE separator;
static VALUE rb_file_join _((VALUE ary, VALUE sep));
static VALUE
file_inspect_join(ary, arg)
VALUE ary;
VALUE *arg;
{
return rb_file_join(arg[0], arg[1]);
}
static VALUE
rb_file_join(ary, sep)
VALUE ary, sep;
{
long len, i;
int taint = 0;
VALUE result, tmp;
char *name;
if (RARRAY(ary)->len == 0) return rb_str_new(0, 0);
if (OBJ_TAINTED(ary)) taint = 1;
if (OBJ_TAINTED(sep)) taint = 1;
len = 1;
for (i=0; i<RARRAY(ary)->len; i++) {
if (TYPE(RARRAY(ary)->ptr[i]) == T_STRING) {
len += RSTRING(RARRAY(ary)->ptr[i])->len;
}
else {
len += 10;
}
}
if (!NIL_P(sep) && TYPE(sep) == T_STRING) {
len += RSTRING(sep)->len * RARRAY(ary)->len - 1;
}
result = rb_str_buf_new(len);
for (i=0; i<RARRAY(ary)->len; i++) {
tmp = RARRAY(ary)->ptr[i];
switch (TYPE(tmp)) {
case T_STRING:
break;
case T_ARRAY:
if (rb_inspecting_p(tmp)) {
tmp = rb_str_new2("[...]");
}
else {
VALUE args[2];
args[0] = tmp;
args[1] = sep;
tmp = rb_protect_inspect(file_inspect_join, ary, (VALUE)args);
}
break;
default:
tmp = rb_obj_as_string(tmp);
}
name = StringValuePtr(result);
if (i > 0 && !NIL_P(sep) && strrdirsep(name) != &name[strlen(name) - 1])
rb_str_buf_append(result, sep);
rb_str_buf_append(result, tmp);
if (OBJ_TAINTED(tmp)) taint = 1;
}
if (taint) OBJ_TAINT(result);
return result;
}
static VALUE
rb_file_s_join(klass, args)
VALUE klass, args;
{
return rb_ary_join(args, separator);
return rb_file_join(args, separator);
}
static VALUE