From: "C.E. Thornton" Date: 2008-08-17T06:01:52+09:00 Subject: [ruby-core:18319] NEW Command: absolute_path() -- This is a multi-part message in MIME format. --------------020906020009030006050100 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Core, I have created patches for both 1.8.7 and 1.9.0 trunk to implement the command 'absolute_path()'. The documentation for the command follows: /* * call-seq: * File.absolute_path(file_name [, dir_string] ) -> abs_file_name * * Converts a pathname to an absolute pathname. Relative paths are * referenced from the current working directory of the process unless * dir_string is given, in which case it will be used as the * starting point. If the given pathname starts with a ``~'' * it is NOT expanded, it is treated as a normal directory name. * * File.absolute_path("~oracle/bin") #=> "/~oracle/bin" */ If there is anything else required for inclusion approval, please let me know. Chuck T. -- Competency and chastity have much in common, they both encompass their own punishment! -- C.E. Thornton -- Hawthorne Press -- --------------020906020009030006050100 Content-Type: text/plain; name="file.c_patch_1.9.0" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="file.c_patch_1.9.0" --- file.c 2008-08-14 03:11:31.000000000 +0000 +++ file.c_new 2008-08-14 04:34:33.000000000 +0000 @@ -2590,7 +2590,7 @@ static int is_absolute_path(const char*); static VALUE -file_expand_path(VALUE fname, VALUE dname, VALUE result) +file_expand_path(VALUE fname, VALUE dname, int abs_mode, VALUE result) { const char *s, *b; char *buf, *p, *pend, *root; @@ -2602,8 +2602,7 @@ s = StringValuePtr(fname); BUFINIT(); tainted = OBJ_TAINTED(fname); - - if (s[0] == '~') { + if (s[0] == '~' && abs_mode == 0) { /* Execute only if NOT absoloute_path() */ if (isdirsep(s[1]) || s[1] == '\0') { const char *dir = getenv("HOME"); @@ -2665,7 +2664,7 @@ /* specified drive, but not full path */ int same = 0; if (!NIL_P(dname)) { - file_expand_path(dname, Qnil, result); + file_expand_path(dname, Qnil, abs_mode, result); BUFINIT(); if (has_drive_letter(p) && TOLOWER(p[0]) == TOLOWER(s[0])) { /* ok, same drive */ @@ -2689,7 +2688,7 @@ #endif else if (!is_absolute_path(s)) { if (!NIL_P(dname)) { - file_expand_path(dname, Qnil, result); + file_expand_path(dname, Qnil, abs_mode, result); BUFINIT(); } else { @@ -2881,7 +2880,7 @@ VALUE rb_file_expand_path(VALUE fname, VALUE dname) { - return file_expand_path(fname, dname, rb_usascii_str_new(0, MAXPATHLEN + 2)); + return file_expand_path(fname, dname, 0, rb_usascii_str_new(0, MAXPATHLEN + 2)); } /* @@ -2914,6 +2913,38 @@ return rb_file_expand_path(fname, dname); } +VALUE +rb_file_absolute_path(VALUE fname, VALUE dname) +{ + return file_expand_path(fname, dname, 1, rb_usascii_str_new(0, MAXPATHLEN + 2)); +} + +/* + * call-seq: + * File.absolute_path(file_name [, dir_string] ) -> abs_file_name + * + * Converts a pathname to an absolute pathname. Relative paths are + * referenced from the current working directory of the process unless + * dir_string is given, in which case it will be used as the + * starting point. If the given pathname starts with a ``~'' + * it is NOT expanded, it is treated as a normal directory name. + * + * File.absolute_path("~oracle/bin") #=> "/~oracle/bin" + */ + +VALUE +rb_file_s_absolute_path(int argc, VALUE *argv) +{ + VALUE fname, dname; + + if (argc == 1) { + return rb_file_absolute_path(argv[0], Qnil); + } + rb_scan_args(argc, argv, "11", &fname, &dname); + + return rb_file_absolute_path(fname, dname); +} + static int rmext(const char *p, int l1, const char *e) { @@ -4504,7 +4535,7 @@ FilePathValue(str); if (RSTRING_LEN(str) == 0) continue; - file_expand_path(fname, str, tmp); + file_expand_path(fname, str, 0, tmp); if (file_load_ok(RSTRING_PTR(tmp))) { RBASIC(tmp)->klass = rb_obj_class(*filep); OBJ_FREEZE(tmp); @@ -4565,7 +4596,7 @@ VALUE str = RARRAY_PTR(load_path)[i]; FilePathValue(str); if (RSTRING_LEN(str) > 0) { - file_expand_path(path, str, tmp); + file_expand_path(path, str, 0, tmp); f = RSTRING_PTR(tmp); if (file_load_ok(f)) goto found; } @@ -4687,6 +4718,7 @@ rb_define_singleton_method(rb_cFile, "umask", rb_file_s_umask, -1); rb_define_singleton_method(rb_cFile, "truncate", rb_file_s_truncate, 2); rb_define_singleton_method(rb_cFile, "expand_path", rb_file_s_expand_path, -1); + rb_define_singleton_method(rb_cFile, "absolute_path", rb_file_s_absolute_path, -1); rb_define_singleton_method(rb_cFile, "basename", rb_file_s_basename, -1); rb_define_singleton_method(rb_cFile, "dirname", rb_file_s_dirname, 1); rb_define_singleton_method(rb_cFile, "extname", rb_file_s_extname, 1); --------------020906020009030006050100 Content-Type: text/plain; name="file.c_patch_1.8.7" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="file.c_patch_1.8.7" --- file.c 2008-08-16 20:53:02.000000000 +0000 +++ file.c_new 2008-08-16 19:27:44.000000000 +0000 @@ -2504,8 +2504,9 @@ static int is_absolute_path _((const char*)); static VALUE -file_expand_path(fname, dname, result) +file_expand_path(fname, dname, abs_mode, result) VALUE fname, dname, result; + int abs_mode; { const char *s, *b; char *buf, *p, *pend, *root; @@ -2516,7 +2517,7 @@ BUFINIT(); tainted = OBJ_TAINTED(fname); - if (s[0] == '~') { + if (s[0] == '~' && abs_mode == 0) { /* execute only if NOT absolute_path() */ if (isdirsep(s[1]) || s[1] == '\0') { const char *dir = getenv("HOME"); @@ -2577,9 +2578,9 @@ /* specified drive, but not full path */ int same = 0; if (!NIL_P(dname)) { - file_expand_path(dname, Qnil, result); - BUFINIT(); - if (has_drive_letter(p) && TOLOWER(p[0]) == TOLOWER(s[0])) { + file_expand_path(dname, Qnil, abs_mode, result); + BUFINIT(); + if (has_drive_letter(p) && TOLOWER(p[0]) == TOLOWER(s[0])) { /* ok, same drive */ same = 1; } @@ -2600,7 +2601,7 @@ #endif else if (!is_absolute_path(s)) { if (!NIL_P(dname)) { - file_expand_path(dname, Qnil, result); + file_expand_path(dname, Qnil, abs_mode, result); BUFINIT(); } else { @@ -2788,7 +2789,7 @@ rb_file_expand_path(fname, dname) VALUE fname, dname; { - return file_expand_path(fname, dname, rb_str_new(0, MAXPATHLEN + 2)); + return file_expand_path(fname, dname, 0, rb_str_new(0, MAXPATHLEN + 2)); } /* @@ -2823,6 +2824,41 @@ return rb_file_expand_path(fname, dname); } +VALUE +rb_file_absolute_path(fname, dname) + VALUE fname, dname; +{ + return file_expand_path(fname, dname, 1, rb_str_new(0, MAXPATHLEN + 2)); +} + +/* + * call-seq: + * File.absolute_path(file_name [, dir_string] ) -> abs_file_name + * + * Converts a pathname to an absolute pathname. Relative paths are + * referenced from the current working directory of the process unless + * dir_string is given, in which case it will be used as the + * starting point. If the given pathname starts with a ``~'' + * it is NOT expanded, it is treated as a normal directory name. + * + * File.absolute_path("~oracle/bin") #=> "/~oracle/bin" + */ + +VALUE +rb_file_s_absolute_path(argc, argv) + int argc; + VALUE *argv; +{ + VALUE fname, dname; + + if (argc == 1) { + return rb_file_absolute_path(argv[0], Qnil); + } + rb_scan_args(argc, argv, "11", &fname, &dname); + + return rb_file_absolute_path(fname, dname); +} + static int rmext(p, l1, e) const char *p, *e; @@ -4427,7 +4463,7 @@ SafeStringValue(str); if (RSTRING(str)->len == 0) continue; - file_expand_path(*filep, str, tmp); + file_expand_path(*filep, str, 0, tmp); fnlen = RSTRING_LEN(tmp); for (j=0; ext[j]; j++) { rb_str_cat2(tmp, ext[j]); @@ -4494,7 +4530,7 @@ VALUE str = RARRAY(rb_load_path)->ptr[i]; SafeStringValue(str); if (RSTRING(str)->len > 0) { - file_expand_path(path, str, tmp); + file_expand_path(path, str, 0, tmp); f = RSTRING_PTR(tmp); if (file_load_ok(f)) goto found; } @@ -4617,6 +4653,7 @@ rb_define_singleton_method(rb_cFile, "umask", rb_file_s_umask, -1); rb_define_singleton_method(rb_cFile, "truncate", rb_file_s_truncate, 2); rb_define_singleton_method(rb_cFile, "expand_path", rb_file_s_expand_path, -1); + rb_define_singleton_method(rb_cFile, "absolute_path", rb_file_s_absolute_path, -1); rb_define_singleton_method(rb_cFile, "basename", rb_file_s_basename, -1); rb_define_singleton_method(rb_cFile, "dirname", rb_file_s_dirname, 1); rb_define_singleton_method(rb_cFile, "extname", rb_file_s_extname, 1); --------------020906020009030006050100--