|
Ruby
1.9.3p286(2012-10-12revision37165)
|
00001 #include "ruby.h" 00002 00003 static VALUE rb_cPathname; 00004 static ID id_at_path, id_to_path; 00005 00006 static VALUE 00007 get_strpath(VALUE obj) 00008 { 00009 VALUE strpath; 00010 strpath = rb_ivar_get(obj, id_at_path); 00011 if (TYPE(strpath) != T_STRING) 00012 rb_raise(rb_eTypeError, "unexpected @path"); 00013 return strpath; 00014 } 00015 00016 static void 00017 set_strpath(VALUE obj, VALUE val) 00018 { 00019 rb_ivar_set(obj, id_at_path, val); 00020 } 00021 00022 /* 00023 * Create a Pathname object from the given String (or String-like object). 00024 * If +path+ contains a NUL character (<tt>\0</tt>), an ArgumentError is raised. 00025 */ 00026 static VALUE 00027 path_initialize(VALUE self, VALUE arg) 00028 { 00029 VALUE str; 00030 if (TYPE(arg) == T_STRING) { 00031 str = arg; 00032 } 00033 else { 00034 str = rb_check_funcall(arg, id_to_path, 0, NULL); 00035 if (str == Qundef) 00036 str = arg; 00037 StringValue(str); 00038 } 00039 if (memchr(RSTRING_PTR(str), '\0', RSTRING_LEN(str))) 00040 rb_raise(rb_eArgError, "pathname contains null byte"); 00041 str = rb_obj_dup(str); 00042 00043 set_strpath(self, str); 00044 OBJ_INFECT(self, str); 00045 return self; 00046 } 00047 00048 static VALUE 00049 path_freeze(VALUE self) 00050 { 00051 rb_call_super(0, 0); 00052 rb_str_freeze(get_strpath(self)); 00053 return self; 00054 } 00055 00056 static VALUE 00057 path_taint(VALUE self) 00058 { 00059 rb_call_super(0, 0); 00060 rb_obj_taint(get_strpath(self)); 00061 return self; 00062 } 00063 00064 static VALUE 00065 path_untaint(VALUE self) 00066 { 00067 rb_call_super(0, 0); 00068 rb_obj_untaint(get_strpath(self)); 00069 return self; 00070 } 00071 00072 /* 00073 * Compare this pathname with +other+. The comparison is string-based. 00074 * Be aware that two different paths (<tt>foo.txt</tt> and <tt>./foo.txt</tt>) 00075 * can refer to the same file. 00076 */ 00077 static VALUE 00078 path_eq(VALUE self, VALUE other) 00079 { 00080 if (!rb_obj_is_kind_of(other, rb_cPathname)) 00081 return Qfalse; 00082 return rb_str_equal(get_strpath(self), get_strpath(other)); 00083 } 00084 00085 /* 00086 * Provides for comparing pathnames, case-sensitively. 00087 */ 00088 static VALUE 00089 path_cmp(VALUE self, VALUE other) 00090 { 00091 VALUE s1, s2; 00092 char *p1, *p2; 00093 char *e1, *e2; 00094 if (!rb_obj_is_kind_of(other, rb_cPathname)) 00095 return Qnil; 00096 s1 = get_strpath(self); 00097 s2 = get_strpath(other); 00098 p1 = RSTRING_PTR(s1); 00099 p2 = RSTRING_PTR(s2); 00100 e1 = p1 + RSTRING_LEN(s1); 00101 e2 = p2 + RSTRING_LEN(s2); 00102 while (p1 < e1 && p2 < e2) { 00103 int c1, c2; 00104 c1 = (unsigned char)*p1++; 00105 c2 = (unsigned char)*p2++; 00106 if (c1 == '/') c1 = '\0'; 00107 if (c2 == '/') c2 = '\0'; 00108 if (c1 != c2) { 00109 if (c1 < c2) 00110 return INT2FIX(-1); 00111 else 00112 return INT2FIX(1); 00113 } 00114 } 00115 if (p1 < e1) 00116 return INT2FIX(1); 00117 if (p2 < e2) 00118 return INT2FIX(-1); 00119 return INT2FIX(0); 00120 } 00121 00122 /* :nodoc: */ 00123 static VALUE 00124 path_hash(VALUE self) 00125 { 00126 return INT2FIX(rb_str_hash(get_strpath(self))); 00127 } 00128 00129 /* 00130 * call-seq: 00131 * pathname.to_s -> string 00132 * pathname.to_path -> string 00133 * 00134 * Return the path as a String. 00135 * 00136 * to_path is implemented so Pathname objects are usable with File.open, etc. 00137 */ 00138 static VALUE 00139 path_to_s(VALUE self) 00140 { 00141 return rb_obj_dup(get_strpath(self)); 00142 } 00143 00144 /* :nodoc: */ 00145 static VALUE 00146 path_inspect(VALUE self) 00147 { 00148 const char *c = rb_obj_classname(self); 00149 VALUE str = get_strpath(self); 00150 return rb_sprintf("#<%s:%s>", c, RSTRING_PTR(str)); 00151 } 00152 00153 /* 00154 * Return a pathname which is substituted by String#sub. 00155 */ 00156 static VALUE 00157 path_sub(int argc, VALUE *argv, VALUE self) 00158 { 00159 VALUE str = get_strpath(self); 00160 00161 if (rb_block_given_p()) { 00162 str = rb_block_call(str, rb_intern("sub"), argc, argv, 0, 0); 00163 } 00164 else { 00165 str = rb_funcall2(str, rb_intern("sub"), argc, argv); 00166 } 00167 return rb_class_new_instance(1, &str, rb_obj_class(self)); 00168 } 00169 00170 /* 00171 * Return a pathname which the extension of the basename is substituted by 00172 * <i>repl</i>. 00173 * 00174 * If self has no extension part, <i>repl</i> is appended. 00175 */ 00176 static VALUE 00177 path_sub_ext(VALUE self, VALUE repl) 00178 { 00179 VALUE str = get_strpath(self); 00180 VALUE str2; 00181 long extlen; 00182 const char *ext; 00183 const char *p; 00184 00185 StringValue(repl); 00186 p = RSTRING_PTR(str); 00187 ext = ruby_find_extname(p, &extlen); 00188 if (ext == NULL) { 00189 ext = p + RSTRING_LEN(str); 00190 } 00191 else if (extlen <= 1) { 00192 ext += extlen; 00193 } 00194 str2 = rb_str_dup(str); 00195 rb_str_resize(str2, ext-p); 00196 rb_str_append(str2, repl); 00197 OBJ_INFECT(str2, str); 00198 return rb_class_new_instance(1, &str2, rb_obj_class(self)); 00199 } 00200 00201 /* Facade for File */ 00202 00203 /* 00204 * Returns the real (absolute) pathname of +self+ in the actual 00205 * filesystem not containing symlinks or useless dots. 00206 * 00207 * All components of the pathname must exist when this method is 00208 * called. 00209 * 00210 */ 00211 static VALUE 00212 path_realpath(int argc, VALUE *argv, VALUE self) 00213 { 00214 VALUE basedir, str; 00215 rb_scan_args(argc, argv, "01", &basedir); 00216 str = rb_funcall(rb_cFile, rb_intern("realpath"), 2, get_strpath(self), basedir); 00217 return rb_class_new_instance(1, &str, rb_obj_class(self)); 00218 } 00219 00220 /* 00221 * Returns the real (absolute) pathname of +self+ in the actual filesystem. 00222 * The real pathname doesn't contain symlinks or useless dots. 00223 * 00224 * The last component of the real pathname can be nonexistent. 00225 */ 00226 static VALUE 00227 path_realdirpath(int argc, VALUE *argv, VALUE self) 00228 { 00229 VALUE basedir, str; 00230 rb_scan_args(argc, argv, "01", &basedir); 00231 str = rb_funcall(rb_cFile, rb_intern("realdirpath"), 2, get_strpath(self), basedir); 00232 return rb_class_new_instance(1, &str, rb_obj_class(self)); 00233 } 00234 00235 /* 00236 * call-seq: 00237 * pathname.each_line {|line| ... } 00238 * pathname.each_line(sep=$/ [, open_args]) {|line| block } -> nil 00239 * pathname.each_line(limit [, open_args]) {|line| block } -> nil 00240 * pathname.each_line(sep, limit [, open_args]) {|line| block } -> nil 00241 * pathname.each_line(...) -> an_enumerator 00242 * 00243 * #each_line iterates over the line in the file. It yields a String object 00244 * for each line. 00245 * 00246 * This method is availabel since 1.8.1. 00247 */ 00248 static VALUE 00249 path_each_line(int argc, VALUE *argv, VALUE self) 00250 { 00251 VALUE args[4]; 00252 int n; 00253 00254 args[0] = get_strpath(self); 00255 n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]); 00256 if (rb_block_given_p()) { 00257 return rb_block_call(rb_cIO, rb_intern("foreach"), 1+n, args, 0, 0); 00258 } 00259 else { 00260 return rb_funcall2(rb_cIO, rb_intern("foreach"), 1+n, args); 00261 } 00262 } 00263 00264 /* 00265 * call-seq: 00266 * pathname.read([length [, offset]]) -> string 00267 * pathname.read([length [, offset]], open_args) -> string 00268 * 00269 * See <tt>IO.read</tt>. Returns all data from the file, or the first +N+ bytes 00270 * if specified. 00271 * 00272 */ 00273 static VALUE 00274 path_read(int argc, VALUE *argv, VALUE self) 00275 { 00276 VALUE args[4]; 00277 int n; 00278 00279 args[0] = get_strpath(self); 00280 n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]); 00281 return rb_funcall2(rb_cIO, rb_intern("read"), 1+n, args); 00282 } 00283 00284 /* 00285 * call-seq: 00286 * pathname.binread([length [, offset]]) -> string 00287 * 00288 * See <tt>IO.binread</tt>. Returns all the bytes from the file, or the first +N+ 00289 * if specified. 00290 * 00291 */ 00292 static VALUE 00293 path_binread(int argc, VALUE *argv, VALUE self) 00294 { 00295 VALUE args[3]; 00296 int n; 00297 00298 args[0] = get_strpath(self); 00299 n = rb_scan_args(argc, argv, "02", &args[1], &args[2]); 00300 return rb_funcall2(rb_cIO, rb_intern("binread"), 1+n, args); 00301 } 00302 00303 /* 00304 * call-seq: 00305 * pathname.readlines(sep=$/ [, open_args]) -> array 00306 * pathname.readlines(limit [, open_args]) -> array 00307 * pathname.readlines(sep, limit [, open_args]) -> array 00308 * 00309 * See <tt>IO.readlines</tt>. Returns all the lines from the file. 00310 * 00311 */ 00312 static VALUE 00313 path_readlines(int argc, VALUE *argv, VALUE self) 00314 { 00315 VALUE args[4]; 00316 int n; 00317 00318 args[0] = get_strpath(self); 00319 n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]); 00320 return rb_funcall2(rb_cIO, rb_intern("readlines"), 1+n, args); 00321 } 00322 00323 /* 00324 * call-seq: 00325 * pathname.sysopen([mode, [perm]]) -> fixnum 00326 * 00327 * See <tt>IO.sysopen</tt>. 00328 * 00329 */ 00330 static VALUE 00331 path_sysopen(int argc, VALUE *argv, VALUE self) 00332 { 00333 VALUE args[3]; 00334 int n; 00335 00336 args[0] = get_strpath(self); 00337 n = rb_scan_args(argc, argv, "02", &args[1], &args[2]); 00338 return rb_funcall2(rb_cIO, rb_intern("sysopen"), 1+n, args); 00339 } 00340 00341 /* 00342 * See <tt>File.atime</tt>. Returns last access time. 00343 */ 00344 static VALUE 00345 path_atime(VALUE self) 00346 { 00347 return rb_funcall(rb_cFile, rb_intern("atime"), 1, get_strpath(self)); 00348 } 00349 00350 /* 00351 * See <tt>File.ctime</tt>. Returns last (directory entry, not file) change time. 00352 */ 00353 static VALUE 00354 path_ctime(VALUE self) 00355 { 00356 return rb_funcall(rb_cFile, rb_intern("ctime"), 1, get_strpath(self)); 00357 } 00358 00359 /* 00360 * See <tt>File.mtime</tt>. Returns last modification time. 00361 */ 00362 static VALUE 00363 path_mtime(VALUE self) 00364 { 00365 return rb_funcall(rb_cFile, rb_intern("mtime"), 1, get_strpath(self)); 00366 } 00367 00368 /* 00369 * See <tt>File.chmod</tt>. Changes permissions. 00370 */ 00371 static VALUE 00372 path_chmod(VALUE self, VALUE mode) 00373 { 00374 return rb_funcall(rb_cFile, rb_intern("chmod"), 2, mode, get_strpath(self)); 00375 } 00376 00377 /* 00378 * See <tt>File.lchmod</tt>. 00379 */ 00380 static VALUE 00381 path_lchmod(VALUE self, VALUE mode) 00382 { 00383 return rb_funcall(rb_cFile, rb_intern("lchmod"), 2, mode, get_strpath(self)); 00384 } 00385 00386 /* 00387 * See <tt>File.chown</tt>. Change owner and group of file. 00388 */ 00389 static VALUE 00390 path_chown(VALUE self, VALUE owner, VALUE group) 00391 { 00392 return rb_funcall(rb_cFile, rb_intern("chown"), 3, owner, group, get_strpath(self)); 00393 } 00394 00395 /* 00396 * See <tt>File.lchown</tt>. 00397 */ 00398 static VALUE 00399 path_lchown(VALUE self, VALUE owner, VALUE group) 00400 { 00401 return rb_funcall(rb_cFile, rb_intern("lchown"), 3, owner, group, get_strpath(self)); 00402 } 00403 00404 /* 00405 * call-seq: 00406 * pathname.fnmatch(pattern, [flags]) -> string 00407 * pathname.fnmatch?(pattern, [flags]) -> string 00408 * 00409 * See <tt>File.fnmatch</tt>. Return +true+ if the receiver matches the given 00410 * pattern. 00411 */ 00412 static VALUE 00413 path_fnmatch(int argc, VALUE *argv, VALUE self) 00414 { 00415 VALUE str = get_strpath(self); 00416 VALUE pattern, flags; 00417 if (rb_scan_args(argc, argv, "11", &pattern, &flags) == 1) 00418 return rb_funcall(rb_cFile, rb_intern("fnmatch"), 2, pattern, str); 00419 else 00420 return rb_funcall(rb_cFile, rb_intern("fnmatch"), 3, pattern, str, flags); 00421 } 00422 00423 /* 00424 * See <tt>File.ftype</tt>. Returns "type" of file ("file", "directory", 00425 * etc). 00426 */ 00427 static VALUE 00428 path_ftype(VALUE self) 00429 { 00430 return rb_funcall(rb_cFile, rb_intern("ftype"), 1, get_strpath(self)); 00431 } 00432 00433 /* 00434 * call-seq: 00435 * pathname.make_link(old) 00436 * 00437 * See <tt>File.link</tt>. Creates a hard link at _pathname_. 00438 */ 00439 static VALUE 00440 path_make_link(VALUE self, VALUE old) 00441 { 00442 return rb_funcall(rb_cFile, rb_intern("link"), 2, old, get_strpath(self)); 00443 } 00444 00445 /* 00446 * See <tt>File.open</tt>. Opens the file for reading or writing. 00447 */ 00448 static VALUE 00449 path_open(int argc, VALUE *argv, VALUE self) 00450 { 00451 VALUE args[4]; 00452 int n; 00453 00454 args[0] = get_strpath(self); 00455 n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]); 00456 if (rb_block_given_p()) { 00457 return rb_block_call(rb_cFile, rb_intern("open"), 1+n, args, 0, 0); 00458 } 00459 else { 00460 return rb_funcall2(rb_cFile, rb_intern("open"), 1+n, args); 00461 } 00462 } 00463 00464 /* 00465 * See <tt>File.readlink</tt>. Read symbolic link. 00466 */ 00467 static VALUE 00468 path_readlink(VALUE self) 00469 { 00470 VALUE str; 00471 str = rb_funcall(rb_cFile, rb_intern("readlink"), 1, get_strpath(self)); 00472 return rb_class_new_instance(1, &str, rb_obj_class(self)); 00473 } 00474 00475 /* 00476 * See <tt>File.rename</tt>. Rename the file. 00477 */ 00478 static VALUE 00479 path_rename(VALUE self, VALUE to) 00480 { 00481 return rb_funcall(rb_cFile, rb_intern("rename"), 2, get_strpath(self), to); 00482 } 00483 00484 /* 00485 * See <tt>File.stat</tt>. Returns a <tt>File::Stat</tt> object. 00486 */ 00487 static VALUE 00488 path_stat(VALUE self) 00489 { 00490 return rb_funcall(rb_cFile, rb_intern("stat"), 1, get_strpath(self)); 00491 } 00492 00493 /* 00494 * See <tt>File.lstat</tt>. 00495 */ 00496 static VALUE 00497 path_lstat(VALUE self) 00498 { 00499 return rb_funcall(rb_cFile, rb_intern("lstat"), 1, get_strpath(self)); 00500 } 00501 00502 /* 00503 * call-seq: 00504 * pathname.make_symlink(old) 00505 * 00506 * See <tt>File.symlink</tt>. Creates a symbolic link. 00507 */ 00508 static VALUE 00509 path_make_symlink(VALUE self, VALUE old) 00510 { 00511 return rb_funcall(rb_cFile, rb_intern("symlink"), 2, old, get_strpath(self)); 00512 } 00513 00514 /* 00515 * See <tt>File.truncate</tt>. Truncate the file to +length+ bytes. 00516 */ 00517 static VALUE 00518 path_truncate(VALUE self, VALUE length) 00519 { 00520 return rb_funcall(rb_cFile, rb_intern("truncate"), 2, get_strpath(self), length); 00521 } 00522 00523 /* 00524 * See <tt>File.utime</tt>. Update the access and modification times. 00525 */ 00526 static VALUE 00527 path_utime(VALUE self, VALUE atime, VALUE mtime) 00528 { 00529 return rb_funcall(rb_cFile, rb_intern("utime"), 3, atime, mtime, get_strpath(self)); 00530 } 00531 00532 /* 00533 * See <tt>File.basename</tt>. Returns the last component of the path. 00534 */ 00535 static VALUE 00536 path_basename(int argc, VALUE *argv, VALUE self) 00537 { 00538 VALUE str = get_strpath(self); 00539 VALUE fext; 00540 if (rb_scan_args(argc, argv, "01", &fext) == 0) 00541 str = rb_funcall(rb_cFile, rb_intern("basename"), 1, str); 00542 else 00543 str = rb_funcall(rb_cFile, rb_intern("basename"), 2, str, fext); 00544 return rb_class_new_instance(1, &str, rb_obj_class(self)); 00545 } 00546 00547 /* 00548 * See <tt>File.dirname</tt>. Returns all but the last component of the path. 00549 */ 00550 static VALUE 00551 path_dirname(VALUE self) 00552 { 00553 VALUE str = get_strpath(self); 00554 str = rb_funcall(rb_cFile, rb_intern("dirname"), 1, str); 00555 return rb_class_new_instance(1, &str, rb_obj_class(self)); 00556 } 00557 00558 /* 00559 * See <tt>File.extname</tt>. Returns the file's extension. 00560 */ 00561 static VALUE 00562 path_extname(VALUE self) 00563 { 00564 VALUE str = get_strpath(self); 00565 return rb_funcall(rb_cFile, rb_intern("extname"), 1, str); 00566 } 00567 00568 /* 00569 * See <tt>File.expand_path</tt>. 00570 */ 00571 static VALUE 00572 path_expand_path(int argc, VALUE *argv, VALUE self) 00573 { 00574 VALUE str = get_strpath(self); 00575 VALUE dname; 00576 if (rb_scan_args(argc, argv, "01", &dname) == 0) 00577 str = rb_funcall(rb_cFile, rb_intern("expand_path"), 1, str); 00578 else 00579 str = rb_funcall(rb_cFile, rb_intern("expand_path"), 2, str, dname); 00580 return rb_class_new_instance(1, &str, rb_obj_class(self)); 00581 } 00582 00583 /* 00584 * See <tt>File.split</tt>. Returns the #dirname and the #basename in an Array. 00585 */ 00586 static VALUE 00587 path_split(VALUE self) 00588 { 00589 VALUE str = get_strpath(self); 00590 VALUE ary, dirname, basename; 00591 ary = rb_funcall(rb_cFile, rb_intern("split"), 1, str); 00592 ary = rb_check_array_type(ary); 00593 dirname = rb_ary_entry(ary, 0); 00594 basename = rb_ary_entry(ary, 1); 00595 dirname = rb_class_new_instance(1, &dirname, rb_obj_class(self)); 00596 basename = rb_class_new_instance(1, &basename, rb_obj_class(self)); 00597 return rb_ary_new3(2, dirname, basename); 00598 } 00599 00600 /* 00601 * See <tt>FileTest.blockdev?</tt>. 00602 */ 00603 static VALUE 00604 path_blockdev_p(VALUE self) 00605 { 00606 return rb_funcall(rb_mFileTest, rb_intern("blockdev?"), 1, get_strpath(self)); 00607 } 00608 00609 /* 00610 * See <tt>FileTest.chardev?</tt>. 00611 */ 00612 static VALUE 00613 path_chardev_p(VALUE self) 00614 { 00615 return rb_funcall(rb_mFileTest, rb_intern("chardev?"), 1, get_strpath(self)); 00616 } 00617 00618 /* 00619 * See <tt>FileTest.executable?</tt>. 00620 */ 00621 static VALUE 00622 path_executable_p(VALUE self) 00623 { 00624 return rb_funcall(rb_mFileTest, rb_intern("executable?"), 1, get_strpath(self)); 00625 } 00626 00627 /* 00628 * See <tt>FileTest.executable_real?</tt>. 00629 */ 00630 static VALUE 00631 path_executable_real_p(VALUE self) 00632 { 00633 return rb_funcall(rb_mFileTest, rb_intern("executable_real?"), 1, get_strpath(self)); 00634 } 00635 00636 /* 00637 * See <tt>FileTest.exist?</tt>. 00638 */ 00639 static VALUE 00640 path_exist_p(VALUE self) 00641 { 00642 return rb_funcall(rb_mFileTest, rb_intern("exist?"), 1, get_strpath(self)); 00643 } 00644 00645 /* 00646 * See <tt>FileTest.grpowned?</tt>. 00647 */ 00648 static VALUE 00649 path_grpowned_p(VALUE self) 00650 { 00651 return rb_funcall(rb_mFileTest, rb_intern("grpowned?"), 1, get_strpath(self)); 00652 } 00653 00654 /* 00655 * See <tt>FileTest.directory?</tt>. 00656 */ 00657 static VALUE 00658 path_directory_p(VALUE self) 00659 { 00660 return rb_funcall(rb_mFileTest, rb_intern("directory?"), 1, get_strpath(self)); 00661 } 00662 00663 /* 00664 * See <tt>FileTest.file?</tt>. 00665 */ 00666 static VALUE 00667 path_file_p(VALUE self) 00668 { 00669 return rb_funcall(rb_mFileTest, rb_intern("file?"), 1, get_strpath(self)); 00670 } 00671 00672 /* 00673 * See <tt>FileTest.pipe?</tt>. 00674 */ 00675 static VALUE 00676 path_pipe_p(VALUE self) 00677 { 00678 return rb_funcall(rb_mFileTest, rb_intern("pipe?"), 1, get_strpath(self)); 00679 } 00680 00681 /* 00682 * See <tt>FileTest.socket?</tt>. 00683 */ 00684 static VALUE 00685 path_socket_p(VALUE self) 00686 { 00687 return rb_funcall(rb_mFileTest, rb_intern("socket?"), 1, get_strpath(self)); 00688 } 00689 00690 /* 00691 * See <tt>FileTest.owned?</tt>. 00692 */ 00693 static VALUE 00694 path_owned_p(VALUE self) 00695 { 00696 return rb_funcall(rb_mFileTest, rb_intern("owned?"), 1, get_strpath(self)); 00697 } 00698 00699 /* 00700 * See <tt>FileTest.readable?</tt>. 00701 */ 00702 static VALUE 00703 path_readable_p(VALUE self) 00704 { 00705 return rb_funcall(rb_mFileTest, rb_intern("readable?"), 1, get_strpath(self)); 00706 } 00707 00708 /* 00709 * See <tt>FileTest.world_readable?</tt>. 00710 */ 00711 static VALUE 00712 path_world_readable_p(VALUE self) 00713 { 00714 return rb_funcall(rb_mFileTest, rb_intern("world_readable?"), 1, get_strpath(self)); 00715 } 00716 00717 /* 00718 * See <tt>FileTest.readable_real?</tt>. 00719 */ 00720 static VALUE 00721 path_readable_real_p(VALUE self) 00722 { 00723 return rb_funcall(rb_mFileTest, rb_intern("readable_real?"), 1, get_strpath(self)); 00724 } 00725 00726 /* 00727 * See <tt>FileTest.setuid?</tt>. 00728 */ 00729 static VALUE 00730 path_setuid_p(VALUE self) 00731 { 00732 return rb_funcall(rb_mFileTest, rb_intern("setuid?"), 1, get_strpath(self)); 00733 } 00734 00735 /* 00736 * See <tt>FileTest.setgid?</tt>. 00737 */ 00738 static VALUE 00739 path_setgid_p(VALUE self) 00740 { 00741 return rb_funcall(rb_mFileTest, rb_intern("setgid?"), 1, get_strpath(self)); 00742 } 00743 00744 /* 00745 * See <tt>FileTest.size</tt>. 00746 */ 00747 static VALUE 00748 path_size(VALUE self) 00749 { 00750 return rb_funcall(rb_mFileTest, rb_intern("size"), 1, get_strpath(self)); 00751 } 00752 00753 /* 00754 * See <tt>FileTest.size?</tt>. 00755 */ 00756 static VALUE 00757 path_size_p(VALUE self) 00758 { 00759 return rb_funcall(rb_mFileTest, rb_intern("size?"), 1, get_strpath(self)); 00760 } 00761 00762 /* 00763 * See <tt>FileTest.sticky?</tt>. 00764 */ 00765 static VALUE 00766 path_sticky_p(VALUE self) 00767 { 00768 return rb_funcall(rb_mFileTest, rb_intern("sticky?"), 1, get_strpath(self)); 00769 } 00770 00771 /* 00772 * See <tt>FileTest.symlink?</tt>. 00773 */ 00774 static VALUE 00775 path_symlink_p(VALUE self) 00776 { 00777 return rb_funcall(rb_mFileTest, rb_intern("symlink?"), 1, get_strpath(self)); 00778 } 00779 00780 /* 00781 * See <tt>FileTest.writable?</tt>. 00782 */ 00783 static VALUE 00784 path_writable_p(VALUE self) 00785 { 00786 return rb_funcall(rb_mFileTest, rb_intern("writable?"), 1, get_strpath(self)); 00787 } 00788 00789 /* 00790 * See <tt>FileTest.world_writable?</tt>. 00791 */ 00792 static VALUE 00793 path_world_writable_p(VALUE self) 00794 { 00795 return rb_funcall(rb_mFileTest, rb_intern("world_writable?"), 1, get_strpath(self)); 00796 } 00797 00798 /* 00799 * See <tt>FileTest.writable_real?</tt>. 00800 */ 00801 static VALUE 00802 path_writable_real_p(VALUE self) 00803 { 00804 return rb_funcall(rb_mFileTest, rb_intern("writable_real?"), 1, get_strpath(self)); 00805 } 00806 00807 /* 00808 * See <tt>FileTest.zero?</tt>. 00809 */ 00810 static VALUE 00811 path_zero_p(VALUE self) 00812 { 00813 return rb_funcall(rb_mFileTest, rb_intern("zero?"), 1, get_strpath(self)); 00814 } 00815 00816 static VALUE 00817 glob_i(VALUE elt, VALUE klass, int argc, VALUE *argv) 00818 { 00819 return rb_yield(rb_class_new_instance(1, &elt, klass)); 00820 } 00821 00822 /* 00823 * See <tt>Dir.glob</tt>. Returns or yields Pathname objects. 00824 */ 00825 static VALUE 00826 path_s_glob(int argc, VALUE *argv, VALUE klass) 00827 { 00828 VALUE args[2]; 00829 int n; 00830 00831 n = rb_scan_args(argc, argv, "11", &args[0], &args[1]); 00832 if (rb_block_given_p()) { 00833 return rb_block_call(rb_cDir, rb_intern("glob"), n, args, glob_i, klass); 00834 } 00835 else { 00836 VALUE ary; 00837 long i; 00838 ary = rb_funcall2(rb_cDir, rb_intern("glob"), n, args); 00839 ary = rb_convert_type(ary, T_ARRAY, "Array", "to_ary"); 00840 for (i = 0; i < RARRAY_LEN(ary); i++) { 00841 VALUE elt = RARRAY_PTR(ary)[i]; 00842 elt = rb_class_new_instance(1, &elt, klass); 00843 rb_ary_store(ary, i, elt); 00844 } 00845 return ary; 00846 } 00847 } 00848 00849 /* 00850 * See <tt>Dir.getwd</tt>. Returns the current working directory as a Pathname. 00851 */ 00852 static VALUE 00853 path_s_getwd(VALUE klass) 00854 { 00855 VALUE str; 00856 str = rb_funcall(rb_cDir, rb_intern("getwd"), 0); 00857 return rb_class_new_instance(1, &str, klass); 00858 } 00859 00860 /* 00861 * Return the entries (files and subdirectories) in the directory, each as a 00862 * Pathname object. 00863 * 00864 * The result may contain the current directory #<Pathname:.> and the parent 00865 * directory #<Pathname:..>. 00866 */ 00867 static VALUE 00868 path_entries(VALUE self) 00869 { 00870 VALUE klass, str, ary; 00871 long i; 00872 klass = rb_obj_class(self); 00873 str = get_strpath(self); 00874 ary = rb_funcall(rb_cDir, rb_intern("entries"), 1, str); 00875 ary = rb_convert_type(ary, T_ARRAY, "Array", "to_ary"); 00876 for (i = 0; i < RARRAY_LEN(ary); i++) { 00877 VALUE elt = RARRAY_PTR(ary)[i]; 00878 elt = rb_class_new_instance(1, &elt, klass); 00879 rb_ary_store(ary, i, elt); 00880 } 00881 return ary; 00882 } 00883 00884 /* 00885 * See <tt>Dir.mkdir</tt>. Create the referenced directory. 00886 */ 00887 static VALUE 00888 path_mkdir(int argc, VALUE *argv, VALUE self) 00889 { 00890 VALUE str = get_strpath(self); 00891 VALUE vmode; 00892 if (rb_scan_args(argc, argv, "01", &vmode) == 0) 00893 return rb_funcall(rb_cDir, rb_intern("mkdir"), 1, str); 00894 else 00895 return rb_funcall(rb_cDir, rb_intern("mkdir"), 2, str, vmode); 00896 } 00897 00898 /* 00899 * See <tt>Dir.rmdir</tt>. Remove the referenced directory. 00900 */ 00901 static VALUE 00902 path_rmdir(VALUE self) 00903 { 00904 return rb_funcall(rb_cDir, rb_intern("rmdir"), 1, get_strpath(self)); 00905 } 00906 00907 /* 00908 * See <tt>Dir.open</tt>. 00909 */ 00910 static VALUE 00911 path_opendir(VALUE self) 00912 { 00913 VALUE args[1]; 00914 00915 args[0] = get_strpath(self); 00916 return rb_block_call(rb_cDir, rb_intern("open"), 1, args, 0, 0); 00917 } 00918 00919 static VALUE 00920 each_entry_i(VALUE elt, VALUE klass, int argc, VALUE *argv) 00921 { 00922 return rb_yield(rb_class_new_instance(1, &elt, klass)); 00923 } 00924 00925 /* 00926 * Iterates over the entries (files and subdirectories) in the directory. It 00927 * yields a Pathname object for each entry. 00928 * 00929 * This method has available since 1.8.1. 00930 */ 00931 static VALUE 00932 path_each_entry(VALUE self) 00933 { 00934 VALUE args[1]; 00935 00936 args[0] = get_strpath(self); 00937 return rb_block_call(rb_cDir, rb_intern("foreach"), 1, args, each_entry_i, rb_obj_class(self)); 00938 } 00939 00940 static VALUE 00941 unlink_body(VALUE str) 00942 { 00943 return rb_funcall(rb_cDir, rb_intern("unlink"), 1, str); 00944 } 00945 00946 static VALUE 00947 unlink_rescue(VALUE str, VALUE errinfo) 00948 { 00949 return rb_funcall(rb_cFile, rb_intern("unlink"), 1, str); 00950 } 00951 00952 /* 00953 * Removes a file or directory, using <tt>File.unlink</tt> or 00954 * <tt>Dir.unlink</tt> as necessary. 00955 */ 00956 static VALUE 00957 path_unlink(VALUE self) 00958 { 00959 VALUE eENOTDIR = rb_const_get_at(rb_mErrno, rb_intern("ENOTDIR")); 00960 VALUE str = get_strpath(self); 00961 return rb_rescue2(unlink_body, str, unlink_rescue, str, eENOTDIR, (VALUE)0); 00962 } 00963 00964 /* 00965 * create a pathname object. 00966 * 00967 * This method is available since 1.8.5. 00968 */ 00969 static VALUE 00970 path_f_pathname(VALUE self, VALUE str) 00971 { 00972 return rb_class_new_instance(1, &str, rb_cPathname); 00973 } 00974 00975 /* 00976 * == Pathname 00977 * 00978 * Pathname represents a pathname which locates a file in a filesystem. 00979 * The pathname depends on OS: Unix, Windows, etc. 00980 * Pathname library works with pathnames of local OS. 00981 * However non-Unix pathnames are supported experimentally. 00982 * 00983 * It does not represent the file itself. 00984 * A Pathname can be relative or absolute. It's not until you try to 00985 * reference the file that it even matters whether the file exists or not. 00986 * 00987 * Pathname is immutable. It has no method for destructive update. 00988 * 00989 * The value of this class is to manipulate file path information in a neater 00990 * way than standard Ruby provides. The examples below demonstrate the 00991 * difference. *All* functionality from File, FileTest, and some from Dir and 00992 * FileUtils is included, in an unsurprising way. It is essentially a facade for 00993 * all of these, and more. 00994 * 00995 * == Examples 00996 * 00997 * === Example 1: Using Pathname 00998 * 00999 * require 'pathname' 01000 * pn = Pathname.new("/usr/bin/ruby") 01001 * size = pn.size # 27662 01002 * isdir = pn.directory? # false 01003 * dir = pn.dirname # Pathname:/usr/bin 01004 * base = pn.basename # Pathname:ruby 01005 * dir, base = pn.split # [Pathname:/usr/bin, Pathname:ruby] 01006 * data = pn.read 01007 * pn.open { |f| _ } 01008 * pn.each_line { |line| _ } 01009 * 01010 * === Example 2: Using standard Ruby 01011 * 01012 * pn = "/usr/bin/ruby" 01013 * size = File.size(pn) # 27662 01014 * isdir = File.directory?(pn) # false 01015 * dir = File.dirname(pn) # "/usr/bin" 01016 * base = File.basename(pn) # "ruby" 01017 * dir, base = File.split(pn) # ["/usr/bin", "ruby"] 01018 * data = File.read(pn) 01019 * File.open(pn) { |f| _ } 01020 * File.foreach(pn) { |line| _ } 01021 * 01022 * === Example 3: Special features 01023 * 01024 * p1 = Pathname.new("/usr/lib") # Pathname:/usr/lib 01025 * p2 = p1 + "ruby/1.8" # Pathname:/usr/lib/ruby/1.8 01026 * p3 = p1.parent # Pathname:/usr 01027 * p4 = p2.relative_path_from(p3) # Pathname:lib/ruby/1.8 01028 * pwd = Pathname.pwd # Pathname:/home/gavin 01029 * pwd.absolute? # true 01030 * p5 = Pathname.new "." # Pathname:. 01031 * p5 = p5 + "music/../articles" # Pathname:music/../articles 01032 * p5.cleanpath # Pathname:articles 01033 * p5.realpath # Pathname:/home/gavin/articles 01034 * p5.children # [Pathname:/home/gavin/articles/linux, ...] 01035 * 01036 * == Breakdown of functionality 01037 * 01038 * === Core methods 01039 * 01040 * These methods are effectively manipulating a String, because that's 01041 * all a path is. Except for #mountpoint?, #children, #each_child, 01042 * #realdirpath and #realpath, they don't access the filesystem. 01043 * 01044 * - + 01045 * - #join 01046 * - #parent 01047 * - #root? 01048 * - #absolute? 01049 * - #relative? 01050 * - #relative_path_from 01051 * - #each_filename 01052 * - #cleanpath 01053 * - #realpath 01054 * - #realdirpath 01055 * - #children 01056 * - #each_child 01057 * - #mountpoint? 01058 * 01059 * === File status predicate methods 01060 * 01061 * These methods are a facade for FileTest: 01062 * - #blockdev? 01063 * - #chardev? 01064 * - #directory? 01065 * - #executable? 01066 * - #executable_real? 01067 * - #exist? 01068 * - #file? 01069 * - #grpowned? 01070 * - #owned? 01071 * - #pipe? 01072 * - #readable? 01073 * - #world_readable? 01074 * - #readable_real? 01075 * - #setgid? 01076 * - #setuid? 01077 * - #size 01078 * - #size? 01079 * - #socket? 01080 * - #sticky? 01081 * - #symlink? 01082 * - #writable? 01083 * - #world_writable? 01084 * - #writable_real? 01085 * - #zero? 01086 * 01087 * === File property and manipulation methods 01088 * 01089 * These methods are a facade for File: 01090 * - #atime 01091 * - #ctime 01092 * - #mtime 01093 * - #chmod(mode) 01094 * - #lchmod(mode) 01095 * - #chown(owner, group) 01096 * - #lchown(owner, group) 01097 * - #fnmatch(pattern, *args) 01098 * - #fnmatch?(pattern, *args) 01099 * - #ftype 01100 * - #make_link(old) 01101 * - #open(*args, &block) 01102 * - #readlink 01103 * - #rename(to) 01104 * - #stat 01105 * - #lstat 01106 * - #make_symlink(old) 01107 * - #truncate(length) 01108 * - #utime(atime, mtime) 01109 * - #basename(*args) 01110 * - #dirname 01111 * - #extname 01112 * - #expand_path(*args) 01113 * - #split 01114 * 01115 * === Directory methods 01116 * 01117 * These methods are a facade for Dir: 01118 * - Pathname.glob(*args) 01119 * - Pathname.getwd / Pathname.pwd 01120 * - #rmdir 01121 * - #entries 01122 * - #each_entry(&block) 01123 * - #mkdir(*args) 01124 * - #opendir(*args) 01125 * 01126 * === IO 01127 * 01128 * These methods are a facade for IO: 01129 * - #each_line(*args, &block) 01130 * - #read(*args) 01131 * - #binread(*args) 01132 * - #readlines(*args) 01133 * - #sysopen(*args) 01134 * 01135 * === Utilities 01136 * 01137 * These methods are a mixture of Find, FileUtils, and others: 01138 * - #find(&block) 01139 * - #mkpath 01140 * - #rmtree 01141 * - #unlink / #delete 01142 * 01143 * 01144 * == Method documentation 01145 * 01146 * As the above section shows, most of the methods in Pathname are facades. The 01147 * documentation for these methods generally just says, for instance, "See 01148 * FileTest.writable?", as you should be familiar with the original method 01149 * anyway, and its documentation (e.g. through +ri+) will contain more 01150 * information. In some cases, a brief description will follow. 01151 */ 01152 void 01153 Init_pathname() 01154 { 01155 id_at_path = rb_intern("@path"); 01156 id_to_path = rb_intern("to_path"); 01157 01158 rb_cPathname = rb_define_class("Pathname", rb_cObject); 01159 rb_define_method(rb_cPathname, "initialize", path_initialize, 1); 01160 rb_define_method(rb_cPathname, "freeze", path_freeze, 0); 01161 rb_define_method(rb_cPathname, "taint", path_taint, 0); 01162 rb_define_method(rb_cPathname, "untaint", path_untaint, 0); 01163 rb_define_method(rb_cPathname, "==", path_eq, 1); 01164 rb_define_method(rb_cPathname, "===", path_eq, 1); 01165 rb_define_method(rb_cPathname, "eql?", path_eq, 1); 01166 rb_define_method(rb_cPathname, "<=>", path_cmp, 1); 01167 rb_define_method(rb_cPathname, "hash", path_hash, 0); 01168 rb_define_method(rb_cPathname, "to_s", path_to_s, 0); 01169 rb_define_method(rb_cPathname, "to_path", path_to_s, 0); 01170 rb_define_method(rb_cPathname, "inspect", path_inspect, 0); 01171 rb_define_method(rb_cPathname, "sub", path_sub, -1); 01172 rb_define_method(rb_cPathname, "sub_ext", path_sub_ext, 1); 01173 rb_define_method(rb_cPathname, "realpath", path_realpath, -1); 01174 rb_define_method(rb_cPathname, "realdirpath", path_realdirpath, -1); 01175 rb_define_method(rb_cPathname, "each_line", path_each_line, -1); 01176 rb_define_method(rb_cPathname, "read", path_read, -1); 01177 rb_define_method(rb_cPathname, "binread", path_binread, -1); 01178 rb_define_method(rb_cPathname, "readlines", path_readlines, -1); 01179 rb_define_method(rb_cPathname, "sysopen", path_sysopen, -1); 01180 rb_define_method(rb_cPathname, "atime", path_atime, 0); 01181 rb_define_method(rb_cPathname, "ctime", path_ctime, 0); 01182 rb_define_method(rb_cPathname, "mtime", path_mtime, 0); 01183 rb_define_method(rb_cPathname, "chmod", path_chmod, 1); 01184 rb_define_method(rb_cPathname, "lchmod", path_lchmod, 1); 01185 rb_define_method(rb_cPathname, "chown", path_chown, 2); 01186 rb_define_method(rb_cPathname, "lchown", path_lchown, 2); 01187 rb_define_method(rb_cPathname, "fnmatch", path_fnmatch, -1); 01188 rb_define_method(rb_cPathname, "fnmatch?", path_fnmatch, -1); 01189 rb_define_method(rb_cPathname, "ftype", path_ftype, 0); 01190 rb_define_method(rb_cPathname, "make_link", path_make_link, 1); 01191 rb_define_method(rb_cPathname, "open", path_open, -1); 01192 rb_define_method(rb_cPathname, "readlink", path_readlink, 0); 01193 rb_define_method(rb_cPathname, "rename", path_rename, 1); 01194 rb_define_method(rb_cPathname, "stat", path_stat, 0); 01195 rb_define_method(rb_cPathname, "lstat", path_lstat, 0); 01196 rb_define_method(rb_cPathname, "make_symlink", path_make_symlink, 1); 01197 rb_define_method(rb_cPathname, "truncate", path_truncate, 1); 01198 rb_define_method(rb_cPathname, "utime", path_utime, 2); 01199 rb_define_method(rb_cPathname, "basename", path_basename, -1); 01200 rb_define_method(rb_cPathname, "dirname", path_dirname, 0); 01201 rb_define_method(rb_cPathname, "extname", path_extname, 0); 01202 rb_define_method(rb_cPathname, "expand_path", path_expand_path, -1); 01203 rb_define_method(rb_cPathname, "split", path_split, 0); 01204 rb_define_method(rb_cPathname, "blockdev?", path_blockdev_p, 0); 01205 rb_define_method(rb_cPathname, "chardev?", path_chardev_p, 0); 01206 rb_define_method(rb_cPathname, "executable?", path_executable_p, 0); 01207 rb_define_method(rb_cPathname, "executable_real?", path_executable_real_p, 0); 01208 rb_define_method(rb_cPathname, "exist?", path_exist_p, 0); 01209 rb_define_method(rb_cPathname, "grpowned?", path_grpowned_p, 0); 01210 rb_define_method(rb_cPathname, "directory?", path_directory_p, 0); 01211 rb_define_method(rb_cPathname, "file?", path_file_p, 0); 01212 rb_define_method(rb_cPathname, "pipe?", path_pipe_p, 0); 01213 rb_define_method(rb_cPathname, "socket?", path_socket_p, 0); 01214 rb_define_method(rb_cPathname, "owned?", path_owned_p, 0); 01215 rb_define_method(rb_cPathname, "readable?", path_readable_p, 0); 01216 rb_define_method(rb_cPathname, "world_readable?", path_world_readable_p, 0); 01217 rb_define_method(rb_cPathname, "readable_real?", path_readable_real_p, 0); 01218 rb_define_method(rb_cPathname, "setuid?", path_setuid_p, 0); 01219 rb_define_method(rb_cPathname, "setgid?", path_setgid_p, 0); 01220 rb_define_method(rb_cPathname, "size", path_size, 0); 01221 rb_define_method(rb_cPathname, "size?", path_size_p, 0); 01222 rb_define_method(rb_cPathname, "sticky?", path_sticky_p, 0); 01223 rb_define_method(rb_cPathname, "symlink?", path_symlink_p, 0); 01224 rb_define_method(rb_cPathname, "writable?", path_writable_p, 0); 01225 rb_define_method(rb_cPathname, "world_writable?", path_world_writable_p, 0); 01226 rb_define_method(rb_cPathname, "writable_real?", path_writable_real_p, 0); 01227 rb_define_method(rb_cPathname, "zero?", path_zero_p, 0); 01228 rb_define_singleton_method(rb_cPathname, "glob", path_s_glob, -1); 01229 rb_define_singleton_method(rb_cPathname, "getwd", path_s_getwd, 0); 01230 rb_define_singleton_method(rb_cPathname, "pwd", path_s_getwd, 0); 01231 rb_define_method(rb_cPathname, "entries", path_entries, 0); 01232 rb_define_method(rb_cPathname, "mkdir", path_mkdir, -1); 01233 rb_define_method(rb_cPathname, "rmdir", path_rmdir, 0); 01234 rb_define_method(rb_cPathname, "opendir", path_opendir, 0); 01235 rb_define_method(rb_cPathname, "each_entry", path_each_entry, 0); 01236 rb_define_method(rb_cPathname, "unlink", path_unlink, 0); 01237 rb_define_method(rb_cPathname, "delete", path_unlink, 0); 01238 rb_undef_method(rb_cPathname, "=~"); 01239 rb_define_global_function("Pathname", path_f_pathname, 1); 01240 } 01241
1.7.6.1