Ruby  2.5.0dev(2017-10-22revision60238)
pathname.c
Go to the documentation of this file.
1 #include "ruby.h"
2 #include "ruby/encoding.h"
3 
4 static VALUE rb_cPathname;
5 static ID id_ENOTDIR;
6 static ID id_at_path;
7 static ID id_atime;
8 static ID id_base;
9 static ID id_basename;
10 static ID id_binread;
11 static ID id_binwrite;
12 static ID id_birthtime;
13 static ID id_blockdev_p;
14 static ID id_chardev_p;
15 static ID id_chmod;
16 static ID id_chown;
17 static ID id_ctime;
18 static ID id_directory_p;
19 static ID id_dirname;
20 static ID id_empty_p;
21 static ID id_entries;
22 static ID id_executable_p;
23 static ID id_executable_real_p;
24 static ID id_exist_p;
25 static ID id_expand_path;
26 static ID id_extname;
27 static ID id_file_p;
28 static ID id_fnmatch;
29 static ID id_foreach;
30 static ID id_ftype;
31 static ID id_getwd;
32 static ID id_glob;
33 static ID id_grpowned_p;
34 static ID id_lchmod;
35 static ID id_lchown;
36 static ID id_link;
37 static ID id_lstat;
38 static ID id_mkdir;
39 static ID id_mtime;
40 static ID id_open;
41 static ID id_owned_p;
42 static ID id_pipe_p;
43 static ID id_read;
44 static ID id_readable_p;
45 static ID id_readable_real_p;
46 static ID id_readlines;
47 static ID id_readlink;
48 static ID id_realdirpath;
49 static ID id_realpath;
50 static ID id_rename;
51 static ID id_rmdir;
52 static ID id_setgid_p;
53 static ID id_setuid_p;
54 static ID id_size;
55 static ID id_size_p;
56 static ID id_socket_p;
57 static ID id_split;
58 static ID id_stat;
59 static ID id_sticky_p;
60 static ID id_sub;
61 static ID id_symlink;
62 static ID id_symlink_p;
63 static ID id_sysopen;
64 static ID id_to_path;
65 static ID id_truncate;
66 static ID id_unlink;
67 static ID id_utime;
68 static ID id_world_readable_p;
69 static ID id_world_writable_p;
70 static ID id_writable_p;
71 static ID id_writable_real_p;
72 static ID id_write;
73 static ID id_zero_p;
74 
75 static VALUE
76 get_strpath(VALUE obj)
77 {
78  VALUE strpath;
79  strpath = rb_ivar_get(obj, id_at_path);
80  if (!RB_TYPE_P(strpath, T_STRING))
81  rb_raise(rb_eTypeError, "unexpected @path");
82  return strpath;
83 }
84 
85 static void
86 set_strpath(VALUE obj, VALUE val)
87 {
88  rb_ivar_set(obj, id_at_path, val);
89 }
90 
91 /*
92  * Create a Pathname object from the given String (or String-like object).
93  * If +path+ contains a NULL character (<tt>\0</tt>), an ArgumentError is raised.
94  */
95 static VALUE
96 path_initialize(VALUE self, VALUE arg)
97 {
98  VALUE str;
99  if (RB_TYPE_P(arg, T_STRING)) {
100  str = arg;
101  }
102  else {
103  str = rb_check_funcall(arg, id_to_path, 0, NULL);
104  if (str == Qundef)
105  str = arg;
106  StringValue(str);
107  }
108  if (memchr(RSTRING_PTR(str), '\0', RSTRING_LEN(str)))
109  rb_raise(rb_eArgError, "pathname contains null byte");
110  str = rb_obj_dup(str);
111 
112  set_strpath(self, str);
113  OBJ_INFECT(self, str);
114  return self;
115 }
116 
117 /*
118  * call-seq:
119  * pathname.freeze -> obj
120  *
121  * Freezes this Pathname.
122  *
123  * See Object.freeze.
124  */
125 static VALUE
126 path_freeze(VALUE self)
127 {
128  rb_call_super(0, 0);
129  rb_str_freeze(get_strpath(self));
130  return self;
131 }
132 
133 /*
134  * call-seq:
135  * pathname.taint -> obj
136  *
137  * Taints this Pathname.
138  *
139  * See Object.taint.
140  */
141 static VALUE
142 path_taint(VALUE self)
143 {
144  rb_call_super(0, 0);
145  rb_obj_taint(get_strpath(self));
146  return self;
147 }
148 
149 /*
150  * call-seq:
151  * pathname.untaint -> obj
152  *
153  * Untaints this Pathname.
154  *
155  * See Object.untaint.
156  */
157 static VALUE
158 path_untaint(VALUE self)
159 {
160  rb_call_super(0, 0);
161  rb_obj_untaint(get_strpath(self));
162  return self;
163 }
164 
165 /*
166  * Compare this pathname with +other+. The comparison is string-based.
167  * Be aware that two different paths (<tt>foo.txt</tt> and <tt>./foo.txt</tt>)
168  * can refer to the same file.
169  */
170 static VALUE
171 path_eq(VALUE self, VALUE other)
172 {
173  if (!rb_obj_is_kind_of(other, rb_cPathname))
174  return Qfalse;
175  return rb_str_equal(get_strpath(self), get_strpath(other));
176 }
177 
178 /*
179  * Provides a case-sensitive comparison operator for pathnames.
180  *
181  * Pathname.new('/usr') <=> Pathname.new('/usr/bin')
182  * #=> -1
183  * Pathname.new('/usr/bin') <=> Pathname.new('/usr/bin')
184  * #=> 0
185  * Pathname.new('/usr/bin') <=> Pathname.new('/USR/BIN')
186  * #=> 1
187  *
188  * It will return +-1+, +0+ or +1+ depending on the value of the left argument
189  * relative to the right argument. Or it will return +nil+ if the arguments
190  * are not comparable.
191  */
192 static VALUE
193 path_cmp(VALUE self, VALUE other)
194 {
195  VALUE s1, s2;
196  char *p1, *p2;
197  char *e1, *e2;
198  if (!rb_obj_is_kind_of(other, rb_cPathname))
199  return Qnil;
200  s1 = get_strpath(self);
201  s2 = get_strpath(other);
202  p1 = RSTRING_PTR(s1);
203  p2 = RSTRING_PTR(s2);
204  e1 = p1 + RSTRING_LEN(s1);
205  e2 = p2 + RSTRING_LEN(s2);
206  while (p1 < e1 && p2 < e2) {
207  int c1, c2;
208  c1 = (unsigned char)*p1++;
209  c2 = (unsigned char)*p2++;
210  if (c1 == '/') c1 = '\0';
211  if (c2 == '/') c2 = '\0';
212  if (c1 != c2) {
213  if (c1 < c2)
214  return INT2FIX(-1);
215  else
216  return INT2FIX(1);
217  }
218  }
219  if (p1 < e1)
220  return INT2FIX(1);
221  if (p2 < e2)
222  return INT2FIX(-1);
223  return INT2FIX(0);
224 }
225 
226 #ifndef ST2FIX
227 #define ST2FIX(h) LONG2FIX((long)(h))
228 #endif
229 
230 /* :nodoc: */
231 static VALUE
232 path_hash(VALUE self)
233 {
234  return ST2FIX(rb_str_hash(get_strpath(self)));
235 }
236 
237 /*
238  * call-seq:
239  * pathname.to_s -> string
240  * pathname.to_path -> string
241  *
242  * Return the path as a String.
243  *
244  * to_path is implemented so Pathname objects are usable with File.open, etc.
245  */
246 static VALUE
247 path_to_s(VALUE self)
248 {
249  return rb_obj_dup(get_strpath(self));
250 }
251 
252 /* :nodoc: */
253 static VALUE
254 path_inspect(VALUE self)
255 {
256  const char *c = rb_obj_classname(self);
257  VALUE str = get_strpath(self);
258  return rb_sprintf("#<%s:%"PRIsVALUE">", c, str);
259 }
260 
261 /*
262  * Return a pathname which is substituted by String#sub.
263  *
264  * path1 = Pathname.new('/usr/bin/perl')
265  * path1.sub('perl', 'ruby')
266  * #=> #<Pathname:/usr/bin/ruby>
267  */
268 static VALUE
269 path_sub(int argc, VALUE *argv, VALUE self)
270 {
271  VALUE str = get_strpath(self);
272 
273  if (rb_block_given_p()) {
274  str = rb_block_call(str, id_sub, argc, argv, 0, 0);
275  }
276  else {
277  str = rb_funcallv(str, id_sub, argc, argv);
278  }
279  return rb_class_new_instance(1, &str, rb_obj_class(self));
280 }
281 
282 /*
283  * Return a pathname with +repl+ added as a suffix to the basename.
284  *
285  * If self has no extension part, +repl+ is appended.
286  *
287  * Pathname.new('/usr/bin/shutdown').sub_ext('.rb')
288  * #=> #<Pathname:/usr/bin/shutdown.rb>
289  */
290 static VALUE
291 path_sub_ext(VALUE self, VALUE repl)
292 {
293  VALUE str = get_strpath(self);
294  VALUE str2;
295  long extlen;
296  const char *ext;
297  const char *p;
298 
299  StringValue(repl);
300  p = RSTRING_PTR(str);
301  extlen = RSTRING_LEN(str);
302  ext = ruby_enc_find_extname(p, &extlen, rb_enc_get(str));
303  if (ext == NULL) {
304  ext = p + RSTRING_LEN(str);
305  }
306  else if (extlen <= 1) {
307  ext += extlen;
308  }
309  str2 = rb_str_subseq(str, 0, ext-p);
310  rb_str_append(str2, repl);
311  OBJ_INFECT(str2, str);
312  return rb_class_new_instance(1, &str2, rb_obj_class(self));
313 }
314 
315 /* Facade for File */
316 
317 /*
318  * Returns the real (absolute) pathname for +self+ in the actual
319  * filesystem.
320  *
321  * Does not contain symlinks or useless dots, +..+ and +.+.
322  *
323  * All components of the pathname must exist when this method is
324  * called.
325  *
326  */
327 static VALUE
328 path_realpath(int argc, VALUE *argv, VALUE self)
329 {
330  VALUE basedir, str;
331  rb_scan_args(argc, argv, "01", &basedir);
332  str = rb_funcall(rb_cFile, id_realpath, 2, get_strpath(self), basedir);
333  return rb_class_new_instance(1, &str, rb_obj_class(self));
334 }
335 
336 /*
337  * Returns the real (absolute) pathname of +self+ in the actual filesystem.
338  *
339  * Does not contain symlinks or useless dots, +..+ and +.+.
340  *
341  * The last component of the real pathname can be nonexistent.
342  */
343 static VALUE
344 path_realdirpath(int argc, VALUE *argv, VALUE self)
345 {
346  VALUE basedir, str;
347  rb_scan_args(argc, argv, "01", &basedir);
348  str = rb_funcall(rb_cFile, id_realdirpath, 2, get_strpath(self), basedir);
349  return rb_class_new_instance(1, &str, rb_obj_class(self));
350 }
351 
352 /*
353  * call-seq:
354  * pathname.each_line {|line| ... }
355  * pathname.each_line(sep=$/ [, open_args]) {|line| block } -> nil
356  * pathname.each_line(limit [, open_args]) {|line| block } -> nil
357  * pathname.each_line(sep, limit [, open_args]) {|line| block } -> nil
358  * pathname.each_line(...) -> an_enumerator
359  *
360  * Iterates over each line in the file and yields a String object for each.
361  */
362 static VALUE
363 path_each_line(int argc, VALUE *argv, VALUE self)
364 {
365  VALUE args[4];
366  int n;
367 
368  args[0] = get_strpath(self);
369  n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
370  if (rb_block_given_p()) {
371  return rb_block_call(rb_cIO, id_foreach, 1+n, args, 0, 0);
372  }
373  else {
374  return rb_funcallv(rb_cIO, id_foreach, 1+n, args);
375  }
376 }
377 
378 /*
379  * call-seq:
380  * pathname.read([length [, offset]]) -> string
381  * pathname.read([length [, offset]], open_args) -> string
382  *
383  * Returns all data from the file, or the first +N+ bytes if specified.
384  *
385  * See IO.read.
386  *
387  */
388 static VALUE
389 path_read(int argc, VALUE *argv, VALUE self)
390 {
391  VALUE args[4];
392  int n;
393 
394  args[0] = get_strpath(self);
395  n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
396  return rb_funcallv(rb_cIO, id_read, 1+n, args);
397 }
398 
399 /*
400  * call-seq:
401  * pathname.binread([length [, offset]]) -> string
402  *
403  * Returns all the bytes from the file, or the first +N+ if specified.
404  *
405  * See IO.binread.
406  *
407  */
408 static VALUE
409 path_binread(int argc, VALUE *argv, VALUE self)
410 {
411  VALUE args[3];
412  int n;
413 
414  args[0] = get_strpath(self);
415  n = rb_scan_args(argc, argv, "02", &args[1], &args[2]);
416  return rb_funcallv(rb_cIO, id_binread, 1+n, args);
417 }
418 
419 /*
420  * call-seq:
421  * pathname.write(string, [offset] ) => fixnum
422  * pathname.write(string, [offset], open_args ) => fixnum
423  *
424  * Writes +contents+ to the file.
425  *
426  * See IO.write.
427  *
428  */
429 static VALUE
430 path_write(int argc, VALUE *argv, VALUE self)
431 {
432  VALUE args[4];
433  int n;
434 
435  args[0] = get_strpath(self);
436  n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
437  return rb_funcallv(rb_cIO, id_write, 1+n, args);
438 }
439 
440 /*
441  * call-seq:
442  * pathname.binwrite(string, [offset] ) => fixnum
443  * pathname.binwrite(string, [offset], open_args ) => fixnum
444  *
445  * Writes +contents+ to the file, opening it in binary mode.
446  *
447  * See IO.binwrite.
448  *
449  */
450 static VALUE
451 path_binwrite(int argc, VALUE *argv, VALUE self)
452 {
453  VALUE args[4];
454  int n;
455 
456  args[0] = get_strpath(self);
457  n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
458  return rb_funcallv(rb_cIO, id_binwrite, 1+n, args);
459 }
460 
461 /*
462  * call-seq:
463  * pathname.readlines(sep=$/ [, open_args]) -> array
464  * pathname.readlines(limit [, open_args]) -> array
465  * pathname.readlines(sep, limit [, open_args]) -> array
466  *
467  * Returns all the lines from the file.
468  *
469  * See IO.readlines.
470  *
471  */
472 static VALUE
473 path_readlines(int argc, VALUE *argv, VALUE self)
474 {
475  VALUE args[4];
476  int n;
477 
478  args[0] = get_strpath(self);
479  n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
480  return rb_funcallv(rb_cIO, id_readlines, 1+n, args);
481 }
482 
483 /*
484  * call-seq:
485  * pathname.sysopen([mode, [perm]]) -> fixnum
486  *
487  * See IO.sysopen.
488  *
489  */
490 static VALUE
491 path_sysopen(int argc, VALUE *argv, VALUE self)
492 {
493  VALUE args[3];
494  int n;
495 
496  args[0] = get_strpath(self);
497  n = rb_scan_args(argc, argv, "02", &args[1], &args[2]);
498  return rb_funcallv(rb_cIO, id_sysopen, 1+n, args);
499 }
500 
501 /*
502  * call-seq:
503  * pathname.atime -> time
504  *
505  * Returns the last access time for the file.
506  *
507  * See File.atime.
508  */
509 static VALUE
510 path_atime(VALUE self)
511 {
512  return rb_funcall(rb_cFile, id_atime, 1, get_strpath(self));
513 }
514 
515 #if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC) || defined(_WIN32)
516 /*
517  * call-seq:
518  * pathname.birthtime -> time
519  *
520  * Returns the birth time for the file.
521  * If the platform doesn't have birthtime, raises NotImplementedError.
522  *
523  * See File.birthtime.
524  */
525 static VALUE
526 path_birthtime(VALUE self)
527 {
528  return rb_funcall(rb_cFile, id_birthtime, 1, get_strpath(self));
529 }
530 #else
531 # define path_birthtime rb_f_notimplement
532 #endif
533 
534 /*
535  * call-seq:
536  * pathname.ctime -> time
537  *
538  * Returns the last change time, using directory information, not the file itself.
539  *
540  * See File.ctime.
541  */
542 static VALUE
543 path_ctime(VALUE self)
544 {
545  return rb_funcall(rb_cFile, id_ctime, 1, get_strpath(self));
546 }
547 
548 /*
549  * call-seq:
550  * pathname.mtime -> time
551  *
552  * Returns the last modified time of the file.
553  *
554  * See File.mtime.
555  */
556 static VALUE
557 path_mtime(VALUE self)
558 {
559  return rb_funcall(rb_cFile, id_mtime, 1, get_strpath(self));
560 }
561 
562 /*
563  * call-seq:
564  * pathname.chmod -> integer
565  *
566  * Changes file permissions.
567  *
568  * See File.chmod.
569  */
570 static VALUE
571 path_chmod(VALUE self, VALUE mode)
572 {
573  return rb_funcall(rb_cFile, id_chmod, 2, mode, get_strpath(self));
574 }
575 
576 /*
577  * call-seq:
578  * pathname.lchmod -> integer
579  *
580  * Same as Pathname.chmod, but does not follow symbolic links.
581  *
582  * See File.lchmod.
583  */
584 static VALUE
585 path_lchmod(VALUE self, VALUE mode)
586 {
587  return rb_funcall(rb_cFile, id_lchmod, 2, mode, get_strpath(self));
588 }
589 
590 /*
591  * call-seq:
592  * pathname.chown -> integer
593  *
594  * Change owner and group of the file.
595  *
596  * See File.chown.
597  */
598 static VALUE
599 path_chown(VALUE self, VALUE owner, VALUE group)
600 {
601  return rb_funcall(rb_cFile, id_chown, 3, owner, group, get_strpath(self));
602 }
603 
604 /*
605  * call-seq:
606  * pathname.lchown -> integer
607  *
608  * Same as Pathname.chown, but does not follow symbolic links.
609  *
610  * See File.lchown.
611  */
612 static VALUE
613 path_lchown(VALUE self, VALUE owner, VALUE group)
614 {
615  return rb_funcall(rb_cFile, id_lchown, 3, owner, group, get_strpath(self));
616 }
617 
618 /*
619  * call-seq:
620  * pathname.fnmatch(pattern, [flags]) -> string
621  * pathname.fnmatch?(pattern, [flags]) -> string
622  *
623  * Return +true+ if the receiver matches the given pattern.
624  *
625  * See File.fnmatch.
626  */
627 static VALUE
628 path_fnmatch(int argc, VALUE *argv, VALUE self)
629 {
630  VALUE str = get_strpath(self);
631  VALUE pattern, flags;
632  if (rb_scan_args(argc, argv, "11", &pattern, &flags) == 1)
633  return rb_funcall(rb_cFile, id_fnmatch, 2, pattern, str);
634  else
635  return rb_funcall(rb_cFile, id_fnmatch, 3, pattern, str, flags);
636 }
637 
638 /*
639  * call-seq:
640  * pathname.ftype -> string
641  *
642  * Returns "type" of file ("file", "directory", etc).
643  *
644  * See File.ftype.
645  */
646 static VALUE
647 path_ftype(VALUE self)
648 {
649  return rb_funcall(rb_cFile, id_ftype, 1, get_strpath(self));
650 }
651 
652 /*
653  * call-seq:
654  * pathname.make_link(old)
655  *
656  * Creates a hard link at _pathname_.
657  *
658  * See File.link.
659  */
660 static VALUE
661 path_make_link(VALUE self, VALUE old)
662 {
663  return rb_funcall(rb_cFile, id_link, 2, old, get_strpath(self));
664 }
665 
666 /*
667  * Opens the file for reading or writing.
668  *
669  * See File.open.
670  */
671 static VALUE
672 path_open(int argc, VALUE *argv, VALUE self)
673 {
674  VALUE args[4];
675  int n;
676 
677  args[0] = get_strpath(self);
678  n = rb_scan_args(argc, argv, "03", &args[1], &args[2], &args[3]);
679  if (rb_block_given_p()) {
680  return rb_block_call(rb_cFile, id_open, 1+n, args, 0, 0);
681  }
682  else {
683  return rb_funcallv(rb_cFile, id_open, 1+n, args);
684  }
685 }
686 
687 /*
688  * Read symbolic link.
689  *
690  * See File.readlink.
691  */
692 static VALUE
693 path_readlink(VALUE self)
694 {
695  VALUE str;
696  str = rb_funcall(rb_cFile, id_readlink, 1, get_strpath(self));
697  return rb_class_new_instance(1, &str, rb_obj_class(self));
698 }
699 
700 /*
701  * Rename the file.
702  *
703  * See File.rename.
704  */
705 static VALUE
706 path_rename(VALUE self, VALUE to)
707 {
708  return rb_funcall(rb_cFile, id_rename, 2, get_strpath(self), to);
709 }
710 
711 /*
712  * Returns a File::Stat object.
713  *
714  * See File.stat.
715  */
716 static VALUE
717 path_stat(VALUE self)
718 {
719  return rb_funcall(rb_cFile, id_stat, 1, get_strpath(self));
720 }
721 
722 /*
723  * See File.lstat.
724  */
725 static VALUE
726 path_lstat(VALUE self)
727 {
728  return rb_funcall(rb_cFile, id_lstat, 1, get_strpath(self));
729 }
730 
731 /*
732  * call-seq:
733  * pathname.make_symlink(old)
734  *
735  * Creates a symbolic link.
736  *
737  * See File.symlink.
738  */
739 static VALUE
740 path_make_symlink(VALUE self, VALUE old)
741 {
742  return rb_funcall(rb_cFile, id_symlink, 2, old, get_strpath(self));
743 }
744 
745 /*
746  * Truncates the file to +length+ bytes.
747  *
748  * See File.truncate.
749  */
750 static VALUE
751 path_truncate(VALUE self, VALUE length)
752 {
753  return rb_funcall(rb_cFile, id_truncate, 2, get_strpath(self), length);
754 }
755 
756 /*
757  * Update the access and modification times of the file.
758  *
759  * See File.utime.
760  */
761 static VALUE
762 path_utime(VALUE self, VALUE atime, VALUE mtime)
763 {
764  return rb_funcall(rb_cFile, id_utime, 3, atime, mtime, get_strpath(self));
765 }
766 
767 /*
768  * Returns the last component of the path.
769  *
770  * See File.basename.
771  */
772 static VALUE
773 path_basename(int argc, VALUE *argv, VALUE self)
774 {
775  VALUE str = get_strpath(self);
776  VALUE fext;
777  if (rb_scan_args(argc, argv, "01", &fext) == 0)
778  str = rb_funcall(rb_cFile, id_basename, 1, str);
779  else
780  str = rb_funcall(rb_cFile, id_basename, 2, str, fext);
781  return rb_class_new_instance(1, &str, rb_obj_class(self));
782 }
783 
784 /*
785  * Returns all but the last component of the path.
786  *
787  * See File.dirname.
788  */
789 static VALUE
790 path_dirname(VALUE self)
791 {
792  VALUE str = get_strpath(self);
793  str = rb_funcall(rb_cFile, id_dirname, 1, str);
794  return rb_class_new_instance(1, &str, rb_obj_class(self));
795 }
796 
797 /*
798  * Returns the file's extension.
799  *
800  * See File.extname.
801  */
802 static VALUE
803 path_extname(VALUE self)
804 {
805  VALUE str = get_strpath(self);
806  return rb_funcall(rb_cFile, id_extname, 1, str);
807 }
808 
809 /*
810  * Returns the absolute path for the file.
811  *
812  * See File.expand_path.
813  */
814 static VALUE
815 path_expand_path(int argc, VALUE *argv, VALUE self)
816 {
817  VALUE str = get_strpath(self);
818  VALUE dname;
819  if (rb_scan_args(argc, argv, "01", &dname) == 0)
820  str = rb_funcall(rb_cFile, id_expand_path, 1, str);
821  else
822  str = rb_funcall(rb_cFile, id_expand_path, 2, str, dname);
823  return rb_class_new_instance(1, &str, rb_obj_class(self));
824 }
825 
826 /*
827  * Returns the #dirname and the #basename in an Array.
828  *
829  * See File.split.
830  */
831 static VALUE
832 path_split(VALUE self)
833 {
834  VALUE str = get_strpath(self);
835  VALUE ary, dirname, basename;
836  ary = rb_funcall(rb_cFile, id_split, 1, str);
837  ary = rb_check_array_type(ary);
838  dirname = rb_ary_entry(ary, 0);
839  basename = rb_ary_entry(ary, 1);
840  dirname = rb_class_new_instance(1, &dirname, rb_obj_class(self));
841  basename = rb_class_new_instance(1, &basename, rb_obj_class(self));
842  return rb_ary_new3(2, dirname, basename);
843 }
844 
845 /*
846  * See FileTest.blockdev?.
847  */
848 static VALUE
849 path_blockdev_p(VALUE self)
850 {
851  return rb_funcall(rb_mFileTest, id_blockdev_p, 1, get_strpath(self));
852 }
853 
854 /*
855  * See FileTest.chardev?.
856  */
857 static VALUE
858 path_chardev_p(VALUE self)
859 {
860  return rb_funcall(rb_mFileTest, id_chardev_p, 1, get_strpath(self));
861 }
862 
863 /*
864  * See FileTest.executable?.
865  */
866 static VALUE
867 path_executable_p(VALUE self)
868 {
869  return rb_funcall(rb_mFileTest, id_executable_p, 1, get_strpath(self));
870 }
871 
872 /*
873  * See FileTest.executable_real?.
874  */
875 static VALUE
876 path_executable_real_p(VALUE self)
877 {
878  return rb_funcall(rb_mFileTest, id_executable_real_p, 1, get_strpath(self));
879 }
880 
881 /*
882  * See FileTest.exist?.
883  */
884 static VALUE
885 path_exist_p(VALUE self)
886 {
887  return rb_funcall(rb_mFileTest, id_exist_p, 1, get_strpath(self));
888 }
889 
890 /*
891  * See FileTest.grpowned?.
892  */
893 static VALUE
894 path_grpowned_p(VALUE self)
895 {
896  return rb_funcall(rb_mFileTest, id_grpowned_p, 1, get_strpath(self));
897 }
898 
899 /*
900  * See FileTest.directory?.
901  */
902 static VALUE
903 path_directory_p(VALUE self)
904 {
905  return rb_funcall(rb_mFileTest, id_directory_p, 1, get_strpath(self));
906 }
907 
908 /*
909  * See FileTest.file?.
910  */
911 static VALUE
912 path_file_p(VALUE self)
913 {
914  return rb_funcall(rb_mFileTest, id_file_p, 1, get_strpath(self));
915 }
916 
917 /*
918  * See FileTest.pipe?.
919  */
920 static VALUE
921 path_pipe_p(VALUE self)
922 {
923  return rb_funcall(rb_mFileTest, id_pipe_p, 1, get_strpath(self));
924 }
925 
926 /*
927  * See FileTest.socket?.
928  */
929 static VALUE
930 path_socket_p(VALUE self)
931 {
932  return rb_funcall(rb_mFileTest, id_socket_p, 1, get_strpath(self));
933 }
934 
935 /*
936  * See FileTest.owned?.
937  */
938 static VALUE
939 path_owned_p(VALUE self)
940 {
941  return rb_funcall(rb_mFileTest, id_owned_p, 1, get_strpath(self));
942 }
943 
944 /*
945  * See FileTest.readable?.
946  */
947 static VALUE
948 path_readable_p(VALUE self)
949 {
950  return rb_funcall(rb_mFileTest, id_readable_p, 1, get_strpath(self));
951 }
952 
953 /*
954  * See FileTest.world_readable?.
955  */
956 static VALUE
957 path_world_readable_p(VALUE self)
958 {
959  return rb_funcall(rb_mFileTest, id_world_readable_p, 1, get_strpath(self));
960 }
961 
962 /*
963  * See FileTest.readable_real?.
964  */
965 static VALUE
966 path_readable_real_p(VALUE self)
967 {
968  return rb_funcall(rb_mFileTest, id_readable_real_p, 1, get_strpath(self));
969 }
970 
971 /*
972  * See FileTest.setuid?.
973  */
974 static VALUE
975 path_setuid_p(VALUE self)
976 {
977  return rb_funcall(rb_mFileTest, id_setuid_p, 1, get_strpath(self));
978 }
979 
980 /*
981  * See FileTest.setgid?.
982  */
983 static VALUE
984 path_setgid_p(VALUE self)
985 {
986  return rb_funcall(rb_mFileTest, id_setgid_p, 1, get_strpath(self));
987 }
988 
989 /*
990  * See FileTest.size.
991  */
992 static VALUE
993 path_size(VALUE self)
994 {
995  return rb_funcall(rb_mFileTest, id_size, 1, get_strpath(self));
996 }
997 
998 /*
999  * See FileTest.size?.
1000  */
1001 static VALUE
1002 path_size_p(VALUE self)
1003 {
1004  return rb_funcall(rb_mFileTest, id_size_p, 1, get_strpath(self));
1005 }
1006 
1007 /*
1008  * See FileTest.sticky?.
1009  */
1010 static VALUE
1011 path_sticky_p(VALUE self)
1012 {
1013  return rb_funcall(rb_mFileTest, id_sticky_p, 1, get_strpath(self));
1014 }
1015 
1016 /*
1017  * See FileTest.symlink?.
1018  */
1019 static VALUE
1020 path_symlink_p(VALUE self)
1021 {
1022  return rb_funcall(rb_mFileTest, id_symlink_p, 1, get_strpath(self));
1023 }
1024 
1025 /*
1026  * See FileTest.writable?.
1027  */
1028 static VALUE
1029 path_writable_p(VALUE self)
1030 {
1031  return rb_funcall(rb_mFileTest, id_writable_p, 1, get_strpath(self));
1032 }
1033 
1034 /*
1035  * See FileTest.world_writable?.
1036  */
1037 static VALUE
1038 path_world_writable_p(VALUE self)
1039 {
1040  return rb_funcall(rb_mFileTest, id_world_writable_p, 1, get_strpath(self));
1041 }
1042 
1043 /*
1044  * See FileTest.writable_real?.
1045  */
1046 static VALUE
1047 path_writable_real_p(VALUE self)
1048 {
1049  return rb_funcall(rb_mFileTest, id_writable_real_p, 1, get_strpath(self));
1050 }
1051 
1052 /*
1053  * See FileTest.zero?.
1054  */
1055 static VALUE
1056 path_zero_p(VALUE self)
1057 {
1058  return rb_funcall(rb_mFileTest, id_zero_p, 1, get_strpath(self));
1059 }
1060 
1061 /*
1062  * Tests the file is empty.
1063  *
1064  * See Dir#empty? and FileTest.empty?.
1065  */
1066 static VALUE
1067 path_empty_p(VALUE self)
1068 {
1069 
1070  VALUE path = get_strpath(self);
1071  if (RTEST(rb_funcall(rb_mFileTest, id_directory_p, 1, path)))
1072  return rb_funcall(rb_cDir, id_empty_p, 1, path);
1073  else
1074  return rb_funcall(rb_mFileTest, id_empty_p, 1, path);
1075 }
1076 
1077 static VALUE
1078 s_glob_i(RB_BLOCK_CALL_FUNC_ARGLIST(elt, klass))
1079 {
1080  return rb_yield(rb_class_new_instance(1, &elt, klass));
1081 }
1082 
1083 /*
1084  * Returns or yields Pathname objects.
1085  *
1086  * Pathname.glob("config/" "*.rb")
1087  * #=> [#<Pathname:config/environment.rb>, #<Pathname:config/routes.rb>, ..]
1088  *
1089  * See Dir.glob.
1090  */
1091 static VALUE
1092 path_s_glob(int argc, VALUE *argv, VALUE klass)
1093 {
1094  VALUE args[2];
1095  int n;
1096 
1097  n = rb_scan_args(argc, argv, "11", &args[0], &args[1]);
1098  if (rb_block_given_p()) {
1099  return rb_block_call(rb_cDir, id_glob, n, args, s_glob_i, klass);
1100  }
1101  else {
1102  VALUE ary;
1103  long i;
1104  ary = rb_funcallv(rb_cDir, id_glob, n, args);
1105  ary = rb_convert_type(ary, T_ARRAY, "Array", "to_ary");
1106  for (i = 0; i < RARRAY_LEN(ary); i++) {
1107  VALUE elt = RARRAY_AREF(ary, i);
1108  elt = rb_class_new_instance(1, &elt, klass);
1109  rb_ary_store(ary, i, elt);
1110  }
1111  return ary;
1112  }
1113 }
1114 
1115 static VALUE
1116 glob_i(RB_BLOCK_CALL_FUNC_ARGLIST(elt, self))
1117 {
1118  elt = rb_funcall(self, '+', 1, elt);
1119  return rb_yield(elt);
1120 }
1121 
1122 /*
1123  * Returns or yields Pathname objects.
1124  *
1125  * Pathname("ruby-2.4.2").glob("R*.md")
1126  * #=> [#<Pathname:ruby-2.4.2/README.md>, #<Pathname:ruby-2.4.2/README.ja.md>]
1127  *
1128  * See Dir.glob.
1129  * This method uses base: argument of Dir.glob.
1130  */
1131 static VALUE
1132 path_glob(int argc, VALUE *argv, VALUE self)
1133 {
1134  VALUE args[3];
1135  int n;
1136 
1137  n = rb_scan_args(argc, argv, "11", &args[0], &args[1]);
1138  if (n == 1)
1139  args[1] = INT2FIX(0);
1140 
1141  args[2] = rb_hash_new();
1142  rb_hash_aset(args[2], ID2SYM(id_base), get_strpath(self));
1143 
1144  n = 3;
1145 
1146  if (rb_block_given_p()) {
1147  return rb_block_call(rb_cDir, id_glob, n, args, glob_i, self);
1148  }
1149  else {
1150  VALUE ary;
1151  long i;
1152  ary = rb_funcallv(rb_cDir, id_glob, n, args);
1153  ary = rb_convert_type(ary, T_ARRAY, "Array", "to_ary");
1154  for (i = 0; i < RARRAY_LEN(ary); i++) {
1155  VALUE elt = RARRAY_AREF(ary, i);
1156  elt = rb_funcall(self, '+', 1, elt);
1157  rb_ary_store(ary, i, elt);
1158  }
1159  return ary;
1160  }
1161 }
1162 
1163 /*
1164  * Returns the current working directory as a Pathname.
1165  *
1166  * Pathname.getwd
1167  * #=> #<Pathname:/home/zzak/projects/ruby>
1168  *
1169  * See Dir.getwd.
1170  */
1171 static VALUE
1172 path_s_getwd(VALUE klass)
1173 {
1174  VALUE str;
1175  str = rb_funcall(rb_cDir, id_getwd, 0);
1176  return rb_class_new_instance(1, &str, klass);
1177 }
1178 
1179 /*
1180  * Return the entries (files and subdirectories) in the directory, each as a
1181  * Pathname object.
1182  *
1183  * The results contains just the names in the directory, without any trailing
1184  * slashes or recursive look-up.
1185  *
1186  * pp Pathname.new('/usr/local').entries
1187  * #=> [#<Pathname:share>,
1188  * # #<Pathname:lib>,
1189  * # #<Pathname:..>,
1190  * # #<Pathname:include>,
1191  * # #<Pathname:etc>,
1192  * # #<Pathname:bin>,
1193  * # #<Pathname:man>,
1194  * # #<Pathname:games>,
1195  * # #<Pathname:.>,
1196  * # #<Pathname:sbin>,
1197  * # #<Pathname:src>]
1198  *
1199  * The result may contain the current directory <code>#<Pathname:.></code> and
1200  * the parent directory <code>#<Pathname:..></code>.
1201  *
1202  * If you don't want +.+ and +..+ and
1203  * want directories, consider Pathname#children.
1204  */
1205 static VALUE
1206 path_entries(VALUE self)
1207 {
1208  VALUE klass, str, ary;
1209  long i;
1210  klass = rb_obj_class(self);
1211  str = get_strpath(self);
1212  ary = rb_funcall(rb_cDir, id_entries, 1, str);
1213  ary = rb_convert_type(ary, T_ARRAY, "Array", "to_ary");
1214  for (i = 0; i < RARRAY_LEN(ary); i++) {
1215  VALUE elt = RARRAY_AREF(ary, i);
1216  elt = rb_class_new_instance(1, &elt, klass);
1217  rb_ary_store(ary, i, elt);
1218  }
1219  return ary;
1220 }
1221 
1222 /*
1223  * Create the referenced directory.
1224  *
1225  * See Dir.mkdir.
1226  */
1227 static VALUE
1228 path_mkdir(int argc, VALUE *argv, VALUE self)
1229 {
1230  VALUE str = get_strpath(self);
1231  VALUE vmode;
1232  if (rb_scan_args(argc, argv, "01", &vmode) == 0)
1233  return rb_funcall(rb_cDir, id_mkdir, 1, str);
1234  else
1235  return rb_funcall(rb_cDir, id_mkdir, 2, str, vmode);
1236 }
1237 
1238 /*
1239  * Remove the referenced directory.
1240  *
1241  * See Dir.rmdir.
1242  */
1243 static VALUE
1244 path_rmdir(VALUE self)
1245 {
1246  return rb_funcall(rb_cDir, id_rmdir, 1, get_strpath(self));
1247 }
1248 
1249 /*
1250  * Opens the referenced directory.
1251  *
1252  * See Dir.open.
1253  */
1254 static VALUE
1255 path_opendir(VALUE self)
1256 {
1257  VALUE args[1];
1258 
1259  args[0] = get_strpath(self);
1260  return rb_block_call(rb_cDir, id_open, 1, args, 0, 0);
1261 }
1262 
1263 static VALUE
1264 each_entry_i(RB_BLOCK_CALL_FUNC_ARGLIST(elt, klass))
1265 {
1266  return rb_yield(rb_class_new_instance(1, &elt, klass));
1267 }
1268 
1269 /*
1270  * Iterates over the entries (files and subdirectories) in the directory,
1271  * yielding a Pathname object for each entry.
1272  */
1273 static VALUE
1274 path_each_entry(VALUE self)
1275 {
1276  VALUE args[1];
1277 
1278  args[0] = get_strpath(self);
1279  return rb_block_call(rb_cDir, id_foreach, 1, args, each_entry_i, rb_obj_class(self));
1280 }
1281 
1282 static VALUE
1283 unlink_body(VALUE str)
1284 {
1285  return rb_funcall(rb_cDir, id_unlink, 1, str);
1286 }
1287 
1288 static VALUE
1289 unlink_rescue(VALUE str, VALUE errinfo)
1290 {
1291  return rb_funcall(rb_cFile, id_unlink, 1, str);
1292 }
1293 
1294 /*
1295  * Removes a file or directory, using File.unlink if +self+ is a file, or
1296  * Dir.unlink as necessary.
1297  */
1298 static VALUE
1299 path_unlink(VALUE self)
1300 {
1301  VALUE eENOTDIR = rb_const_get_at(rb_mErrno, id_ENOTDIR);
1302  VALUE str = get_strpath(self);
1303  return rb_rescue2(unlink_body, str, unlink_rescue, str, eENOTDIR, (VALUE)0);
1304 }
1305 
1306 /*
1307  * :call-seq:
1308  * Pathname(path) -> pathname
1309  *
1310  * Creates a new Pathname object from the given string, +path+, and returns
1311  * pathname object.
1312  *
1313  * In order to use this constructor, you must first require the Pathname
1314  * standard library extension.
1315  *
1316  * require 'pathname'
1317  * Pathname("/home/zzak")
1318  * #=> #<Pathname:/home/zzak>
1319  *
1320  * See also Pathname::new for more information.
1321  */
1322 static VALUE
1323 path_f_pathname(VALUE self, VALUE str)
1324 {
1325  return rb_class_new_instance(1, &str, rb_cPathname);
1326 }
1327 
1328 /*
1329  *
1330  * Pathname represents the name of a file or directory on the filesystem,
1331  * but not the file itself.
1332  *
1333  * The pathname depends on the Operating System: Unix, Windows, etc.
1334  * This library works with pathnames of local OS, however non-Unix pathnames
1335  * are supported experimentally.
1336  *
1337  * A Pathname can be relative or absolute. It's not until you try to
1338  * reference the file that it even matters whether the file exists or not.
1339  *
1340  * Pathname is immutable. It has no method for destructive update.
1341  *
1342  * The goal of this class is to manipulate file path information in a neater
1343  * way than standard Ruby provides. The examples below demonstrate the
1344  * difference.
1345  *
1346  * *All* functionality from File, FileTest, and some from Dir and FileUtils is
1347  * included, in an unsurprising way. It is essentially a facade for all of
1348  * these, and more.
1349  *
1350  * == Examples
1351  *
1352  * === Example 1: Using Pathname
1353  *
1354  * require 'pathname'
1355  * pn = Pathname.new("/usr/bin/ruby")
1356  * size = pn.size # 27662
1357  * isdir = pn.directory? # false
1358  * dir = pn.dirname # Pathname:/usr/bin
1359  * base = pn.basename # Pathname:ruby
1360  * dir, base = pn.split # [Pathname:/usr/bin, Pathname:ruby]
1361  * data = pn.read
1362  * pn.open { |f| _ }
1363  * pn.each_line { |line| _ }
1364  *
1365  * === Example 2: Using standard Ruby
1366  *
1367  * pn = "/usr/bin/ruby"
1368  * size = File.size(pn) # 27662
1369  * isdir = File.directory?(pn) # false
1370  * dir = File.dirname(pn) # "/usr/bin"
1371  * base = File.basename(pn) # "ruby"
1372  * dir, base = File.split(pn) # ["/usr/bin", "ruby"]
1373  * data = File.read(pn)
1374  * File.open(pn) { |f| _ }
1375  * File.foreach(pn) { |line| _ }
1376  *
1377  * === Example 3: Special features
1378  *
1379  * p1 = Pathname.new("/usr/lib") # Pathname:/usr/lib
1380  * p2 = p1 + "ruby/1.8" # Pathname:/usr/lib/ruby/1.8
1381  * p3 = p1.parent # Pathname:/usr
1382  * p4 = p2.relative_path_from(p3) # Pathname:lib/ruby/1.8
1383  * pwd = Pathname.pwd # Pathname:/home/gavin
1384  * pwd.absolute? # true
1385  * p5 = Pathname.new "." # Pathname:.
1386  * p5 = p5 + "music/../articles" # Pathname:music/../articles
1387  * p5.cleanpath # Pathname:articles
1388  * p5.realpath # Pathname:/home/gavin/articles
1389  * p5.children # [Pathname:/home/gavin/articles/linux, ...]
1390  *
1391  * == Breakdown of functionality
1392  *
1393  * === Core methods
1394  *
1395  * These methods are effectively manipulating a String, because that's
1396  * all a path is. None of these access the file system except for
1397  * #mountpoint?, #children, #each_child, #realdirpath and #realpath.
1398  *
1399  * - +
1400  * - #join
1401  * - #parent
1402  * - #root?
1403  * - #absolute?
1404  * - #relative?
1405  * - #relative_path_from
1406  * - #each_filename
1407  * - #cleanpath
1408  * - #realpath
1409  * - #realdirpath
1410  * - #children
1411  * - #each_child
1412  * - #mountpoint?
1413  *
1414  * === File status predicate methods
1415  *
1416  * These methods are a facade for FileTest:
1417  * - #blockdev?
1418  * - #chardev?
1419  * - #directory?
1420  * - #executable?
1421  * - #executable_real?
1422  * - #exist?
1423  * - #file?
1424  * - #grpowned?
1425  * - #owned?
1426  * - #pipe?
1427  * - #readable?
1428  * - #world_readable?
1429  * - #readable_real?
1430  * - #setgid?
1431  * - #setuid?
1432  * - #size
1433  * - #size?
1434  * - #socket?
1435  * - #sticky?
1436  * - #symlink?
1437  * - #writable?
1438  * - #world_writable?
1439  * - #writable_real?
1440  * - #zero?
1441  *
1442  * === File property and manipulation methods
1443  *
1444  * These methods are a facade for File:
1445  * - #atime
1446  * - #birthtime
1447  * - #ctime
1448  * - #mtime
1449  * - #chmod(mode)
1450  * - #lchmod(mode)
1451  * - #chown(owner, group)
1452  * - #lchown(owner, group)
1453  * - #fnmatch(pattern, *args)
1454  * - #fnmatch?(pattern, *args)
1455  * - #ftype
1456  * - #make_link(old)
1457  * - #open(*args, &block)
1458  * - #readlink
1459  * - #rename(to)
1460  * - #stat
1461  * - #lstat
1462  * - #make_symlink(old)
1463  * - #truncate(length)
1464  * - #utime(atime, mtime)
1465  * - #basename(*args)
1466  * - #dirname
1467  * - #extname
1468  * - #expand_path(*args)
1469  * - #split
1470  *
1471  * === Directory methods
1472  *
1473  * These methods are a facade for Dir:
1474  * - Pathname.glob(*args)
1475  * - Pathname.getwd / Pathname.pwd
1476  * - #rmdir
1477  * - #entries
1478  * - #each_entry(&block)
1479  * - #mkdir(*args)
1480  * - #opendir(*args)
1481  *
1482  * === IO
1483  *
1484  * These methods are a facade for IO:
1485  * - #each_line(*args, &block)
1486  * - #read(*args)
1487  * - #binread(*args)
1488  * - #readlines(*args)
1489  * - #sysopen(*args)
1490  *
1491  * === Utilities
1492  *
1493  * These methods are a mixture of Find, FileUtils, and others:
1494  * - #find(&block)
1495  * - #mkpath
1496  * - #rmtree
1497  * - #unlink / #delete
1498  *
1499  *
1500  * == Method documentation
1501  *
1502  * As the above section shows, most of the methods in Pathname are facades. The
1503  * documentation for these methods generally just says, for instance, "See
1504  * FileTest.writable?", as you should be familiar with the original method
1505  * anyway, and its documentation (e.g. through +ri+) will contain more
1506  * information. In some cases, a brief description will follow.
1507  */
1508 void
1510 {
1511  InitVM(pathname);
1512 
1513  rb_cPathname = rb_define_class("Pathname", rb_cObject);
1514  rb_define_method(rb_cPathname, "initialize", path_initialize, 1);
1515  rb_define_method(rb_cPathname, "freeze", path_freeze, 0);
1516  rb_define_method(rb_cPathname, "taint", path_taint, 0);
1517  rb_define_method(rb_cPathname, "untaint", path_untaint, 0);
1518  rb_define_method(rb_cPathname, "==", path_eq, 1);
1519  rb_define_method(rb_cPathname, "===", path_eq, 1);
1520  rb_define_method(rb_cPathname, "eql?", path_eq, 1);
1521  rb_define_method(rb_cPathname, "<=>", path_cmp, 1);
1522  rb_define_method(rb_cPathname, "hash", path_hash, 0);
1523  rb_define_method(rb_cPathname, "to_s", path_to_s, 0);
1524  rb_define_method(rb_cPathname, "to_path", path_to_s, 0);
1525  rb_define_method(rb_cPathname, "inspect", path_inspect, 0);
1526  rb_define_method(rb_cPathname, "sub", path_sub, -1);
1527  rb_define_method(rb_cPathname, "sub_ext", path_sub_ext, 1);
1528  rb_define_method(rb_cPathname, "realpath", path_realpath, -1);
1529  rb_define_method(rb_cPathname, "realdirpath", path_realdirpath, -1);
1530  rb_define_method(rb_cPathname, "each_line", path_each_line, -1);
1531  rb_define_method(rb_cPathname, "read", path_read, -1);
1532  rb_define_method(rb_cPathname, "binread", path_binread, -1);
1533  rb_define_method(rb_cPathname, "readlines", path_readlines, -1);
1534  rb_define_method(rb_cPathname, "write", path_write, -1);
1535  rb_define_method(rb_cPathname, "binwrite", path_binwrite, -1);
1536  rb_define_method(rb_cPathname, "sysopen", path_sysopen, -1);
1537  rb_define_method(rb_cPathname, "atime", path_atime, 0);
1538  rb_define_method(rb_cPathname, "birthtime", path_birthtime, 0);
1539  rb_define_method(rb_cPathname, "ctime", path_ctime, 0);
1540  rb_define_method(rb_cPathname, "mtime", path_mtime, 0);
1541  rb_define_method(rb_cPathname, "chmod", path_chmod, 1);
1542  rb_define_method(rb_cPathname, "lchmod", path_lchmod, 1);
1543  rb_define_method(rb_cPathname, "chown", path_chown, 2);
1544  rb_define_method(rb_cPathname, "lchown", path_lchown, 2);
1545  rb_define_method(rb_cPathname, "fnmatch", path_fnmatch, -1);
1546  rb_define_method(rb_cPathname, "fnmatch?", path_fnmatch, -1);
1547  rb_define_method(rb_cPathname, "ftype", path_ftype, 0);
1548  rb_define_method(rb_cPathname, "make_link", path_make_link, 1);
1549  rb_define_method(rb_cPathname, "open", path_open, -1);
1550  rb_define_method(rb_cPathname, "readlink", path_readlink, 0);
1551  rb_define_method(rb_cPathname, "rename", path_rename, 1);
1552  rb_define_method(rb_cPathname, "stat", path_stat, 0);
1553  rb_define_method(rb_cPathname, "lstat", path_lstat, 0);
1554  rb_define_method(rb_cPathname, "make_symlink", path_make_symlink, 1);
1555  rb_define_method(rb_cPathname, "truncate", path_truncate, 1);
1556  rb_define_method(rb_cPathname, "utime", path_utime, 2);
1557  rb_define_method(rb_cPathname, "basename", path_basename, -1);
1558  rb_define_method(rb_cPathname, "dirname", path_dirname, 0);
1559  rb_define_method(rb_cPathname, "extname", path_extname, 0);
1560  rb_define_method(rb_cPathname, "expand_path", path_expand_path, -1);
1561  rb_define_method(rb_cPathname, "split", path_split, 0);
1562  rb_define_method(rb_cPathname, "blockdev?", path_blockdev_p, 0);
1563  rb_define_method(rb_cPathname, "chardev?", path_chardev_p, 0);
1564  rb_define_method(rb_cPathname, "executable?", path_executable_p, 0);
1565  rb_define_method(rb_cPathname, "executable_real?", path_executable_real_p, 0);
1566  rb_define_method(rb_cPathname, "exist?", path_exist_p, 0);
1567  rb_define_method(rb_cPathname, "grpowned?", path_grpowned_p, 0);
1568  rb_define_method(rb_cPathname, "directory?", path_directory_p, 0);
1569  rb_define_method(rb_cPathname, "file?", path_file_p, 0);
1570  rb_define_method(rb_cPathname, "pipe?", path_pipe_p, 0);
1571  rb_define_method(rb_cPathname, "socket?", path_socket_p, 0);
1572  rb_define_method(rb_cPathname, "owned?", path_owned_p, 0);
1573  rb_define_method(rb_cPathname, "readable?", path_readable_p, 0);
1574  rb_define_method(rb_cPathname, "world_readable?", path_world_readable_p, 0);
1575  rb_define_method(rb_cPathname, "readable_real?", path_readable_real_p, 0);
1576  rb_define_method(rb_cPathname, "setuid?", path_setuid_p, 0);
1577  rb_define_method(rb_cPathname, "setgid?", path_setgid_p, 0);
1578  rb_define_method(rb_cPathname, "size", path_size, 0);
1579  rb_define_method(rb_cPathname, "size?", path_size_p, 0);
1580  rb_define_method(rb_cPathname, "sticky?", path_sticky_p, 0);
1581  rb_define_method(rb_cPathname, "symlink?", path_symlink_p, 0);
1582  rb_define_method(rb_cPathname, "writable?", path_writable_p, 0);
1583  rb_define_method(rb_cPathname, "world_writable?", path_world_writable_p, 0);
1584  rb_define_method(rb_cPathname, "writable_real?", path_writable_real_p, 0);
1585  rb_define_method(rb_cPathname, "zero?", path_zero_p, 0);
1586  rb_define_method(rb_cPathname, "empty?", path_empty_p, 0);
1587  rb_define_singleton_method(rb_cPathname, "glob", path_s_glob, -1);
1588  rb_define_singleton_method(rb_cPathname, "getwd", path_s_getwd, 0);
1589  rb_define_singleton_method(rb_cPathname, "pwd", path_s_getwd, 0);
1590  rb_define_method(rb_cPathname, "glob", path_glob, -1);
1591  rb_define_method(rb_cPathname, "entries", path_entries, 0);
1592  rb_define_method(rb_cPathname, "mkdir", path_mkdir, -1);
1593  rb_define_method(rb_cPathname, "rmdir", path_rmdir, 0);
1594  rb_define_method(rb_cPathname, "opendir", path_opendir, 0);
1595  rb_define_method(rb_cPathname, "each_entry", path_each_entry, 0);
1596  rb_define_method(rb_cPathname, "unlink", path_unlink, 0);
1597  rb_define_method(rb_cPathname, "delete", path_unlink, 0);
1598  rb_undef_method(rb_cPathname, "=~");
1599  rb_define_global_function("Pathname", path_f_pathname, 1);
1600 }
1601 
1602 void
1604 {
1605 #undef rb_intern
1606  id_at_path = rb_intern("@path");
1607  id_to_path = rb_intern("to_path");
1608  id_ENOTDIR = rb_intern("ENOTDIR");
1609  id_atime = rb_intern("atime");
1610  id_basename = rb_intern("basename");
1611  id_base = rb_intern("base");
1612  id_binread = rb_intern("binread");
1613  id_binwrite = rb_intern("binwrite");
1614  id_birthtime = rb_intern("birthtime");
1615  id_blockdev_p = rb_intern("blockdev?");
1616  id_chardev_p = rb_intern("chardev?");
1617  id_chmod = rb_intern("chmod");
1618  id_chown = rb_intern("chown");
1619  id_ctime = rb_intern("ctime");
1620  id_directory_p = rb_intern("directory?");
1621  id_dirname = rb_intern("dirname");
1622  id_empty_p = rb_intern("empty?");
1623  id_entries = rb_intern("entries");
1624  id_executable_p = rb_intern("executable?");
1625  id_executable_real_p = rb_intern("executable_real?");
1626  id_exist_p = rb_intern("exist?");
1627  id_expand_path = rb_intern("expand_path");
1628  id_extname = rb_intern("extname");
1629  id_file_p = rb_intern("file?");
1630  id_fnmatch = rb_intern("fnmatch");
1631  id_foreach = rb_intern("foreach");
1632  id_ftype = rb_intern("ftype");
1633  id_getwd = rb_intern("getwd");
1634  id_glob = rb_intern("glob");
1635  id_grpowned_p = rb_intern("grpowned?");
1636  id_lchmod = rb_intern("lchmod");
1637  id_lchown = rb_intern("lchown");
1638  id_link = rb_intern("link");
1639  id_lstat = rb_intern("lstat");
1640  id_mkdir = rb_intern("mkdir");
1641  id_mtime = rb_intern("mtime");
1642  id_open = rb_intern("open");
1643  id_owned_p = rb_intern("owned?");
1644  id_pipe_p = rb_intern("pipe?");
1645  id_read = rb_intern("read");
1646  id_readable_p = rb_intern("readable?");
1647  id_readable_real_p = rb_intern("readable_real?");
1648  id_readlines = rb_intern("readlines");
1649  id_readlink = rb_intern("readlink");
1650  id_realdirpath = rb_intern("realdirpath");
1651  id_realpath = rb_intern("realpath");
1652  id_rename = rb_intern("rename");
1653  id_rmdir = rb_intern("rmdir");
1654  id_setgid_p = rb_intern("setgid?");
1655  id_setuid_p = rb_intern("setuid?");
1656  id_size = rb_intern("size");
1657  id_size_p = rb_intern("size?");
1658  id_socket_p = rb_intern("socket?");
1659  id_split = rb_intern("split");
1660  id_stat = rb_intern("stat");
1661  id_sticky_p = rb_intern("sticky?");
1662  id_sub = rb_intern("sub");
1663  id_symlink = rb_intern("symlink");
1664  id_symlink_p = rb_intern("symlink?");
1665  id_sysopen = rb_intern("sysopen");
1666  id_truncate = rb_intern("truncate");
1667  id_unlink = rb_intern("unlink");
1668  id_utime = rb_intern("utime");
1669  id_world_readable_p = rb_intern("world_readable?");
1670  id_world_writable_p = rb_intern("world_writable?");
1671  id_writable_p = rb_intern("writable?");
1672  id_writable_real_p = rb_intern("writable_real?");
1673  id_write = rb_intern("write");
1674  id_zero_p = rb_intern("zero?");
1675 }
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1215
#define RARRAY_LEN(a)
Definition: ruby.h:1019
VALUE rb_str_equal(VALUE str1, VALUE str2)
Definition: string.c:3214
void InitVM_pathname(void)
Definition: pathname.c:1603
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1716
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:835
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2284
#define InitVM(ext)
Definition: ruby.h:2164
VALUE rb_cFile
Definition: file.c:139
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:774
#define path_birthtime
Definition: pathname.c:531
VALUE rb_obj_dup(VALUE)
call-seq: obj.dup -> an_object
Definition: object.c:526
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1210
VALUE rb_mFileTest
Definition: file.c:140
st_index_t rb_str_hash(VALUE)
Definition: string.c:3094
VALUE rb_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE)
#define T_ARRAY
Definition: ruby.h:498
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
Definition: class.c:1745
void rb_undef_method(VALUE klass, const char *name)
Definition: class.c:1533
VALUE rb_rescue2(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*r_proc)(ANYARGS), VALUE data2,...)
An equivalent of rescue clause.
Definition: eval.c:895
const char * rb_obj_classname(VALUE)
Definition: variable.c:459
VALUE rb_eArgError
Definition: error.c:802
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Definition: ruby.h:1851
VALUE rb_obj_class(VALUE)
call-seq: obj.class -> class
Definition: object.c:277
#define RB_TYPE_P(obj, type)
Definition: ruby.h:527
VALUE rb_obj_is_kind_of(VALUE, VALUE)
call-seq: obj.is_a?(class) -> true or false obj.kind_of?(class) -> true or false
Definition: object.c:842
VALUE rb_obj_taint(VALUE)
call-seq: obj.taint -> obj
Definition: object.c:1179
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:1616
#define val
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1893
#define id_size
Definition: enum.c:29
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:646
void rb_ary_store(VALUE ary, long idx, VALUE val)
Definition: array.c:815
int argc
Definition: ruby.c:187
#define Qfalse
Definition: ruby.h:436
VALUE rb_mErrno
Definition: error.c:820
VALUE rb_str_subseq(VALUE, long, long)
Definition: string.c:2406
RUBY_EXTERN VALUE rb_cIO
Definition: ruby.h:1913
#define RSTRING_LEN(str)
Definition: ruby.h:971
VALUE rb_yield(VALUE)
Definition: vm_eval.c:973
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1452
VALUE rb_hash_new(void)
Definition: hash.c:424
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1908
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1315
#define PRIsVALUE
Definition: ruby.h:135
unsigned long ID
Definition: ruby.h:86
VALUE rb_cDir
Definition: dir.c:437
#define Qnil
Definition: ruby.h:438
unsigned long VALUE
Definition: ruby.h:85
VALUE rb_eTypeError
Definition: error.c:801
#define rb_ary_new3
Definition: intern.h:91
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
Definition: vm_eval.c:389
VALUE rb_call_super(int, const VALUE *)
Definition: vm_eval.c:238
void Init_pathname(void)
Definition: pathname.c:1509
#define rb_funcallv
Definition: console.c:21
VALUE rb_str_freeze(VALUE)
Definition: string.c:2549
#define RSTRING_PTR(str)
Definition: ruby.h:975
rb_encoding * rb_enc_get(VALUE obj)
Definition: encoding.c:860
#define INT2FIX(i)
Definition: ruby.h:232
#define RARRAY_AREF(a, i)
Definition: ruby.h:1033
VALUE rb_check_array_type(VALUE ary)
Definition: array.c:651
VALUE rb_convert_type(VALUE, int, const char *, const char *)
Converts an object into another type.
Definition: object.c:2965
#define RTEST(v)
Definition: ruby.h:450
#define T_STRING
Definition: ruby.h:496
VALUE rb_class_new_instance(int, const VALUE *, VALUE)
Allocates and initializes an instance of klass.
Definition: object.c:2170
#define OBJ_INFECT(x, s)
Definition: ruby.h:1302
VALUE rb_obj_untaint(VALUE)
call-seq: obj.untaint -> obj
Definition: object.c:1208
VALUE rb_const_get_at(VALUE, ID)
Definition: variable.c:2298
#define ID2SYM(x)
Definition: ruby.h:383
#define rb_intern(str)
const char * ruby_enc_find_extname(const char *name, long *len, rb_encoding *enc)
Definition: file.c:4372
#define NULL
Definition: _sdbm.c:102
#define Qundef
Definition: ruby.h:439
#define ST2FIX(h)
Definition: ruby_missing.h:21
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2900
char ** argv
Definition: ruby.c:188
#define StringValue(v)
Definition: ruby.h:569