1. my class IO::ArgFiles { ... }
  2. proto sub print(|) { * }
  3. multi sub print(Str:D \x) {
  4. $*OUT.print(x);
  5. }
  6. multi sub print(\x) {
  7. $*OUT.print(x.Str);
  8. }
  9. multi sub print(**@args is raw) {
  10. my str $str;
  11. $str = nqp::concat($str,nqp::unbox_s(.Str)) for @args;
  12. $*OUT.print($str);
  13. }
  14. # Once we have an nqp::say that looks at the *output* line separator of the
  15. # PIO, then we can stop concatenating .nl-out to each string before .print, but
  16. # instead call nqp::say directly.
  17. proto sub say(|) { * }
  18. multi sub say() { $*OUT.print-nl }
  19. multi sub say(Str:D \x) {
  20. my $out := $*OUT;
  21. $out.print(nqp::concat(nqp::unbox_s(x),$out.nl-out));
  22. }
  23. multi sub say(\x) {
  24. my $out := $*OUT;
  25. $out.print(nqp::concat(nqp::unbox_s(x.gist),$out.nl-out));
  26. }
  27. multi sub say(**@args is raw) {
  28. my str $str;
  29. my $iter := @args.iterator;
  30. nqp::until(
  31. nqp::eqaddr(($_ := $iter.pull-one), IterationEnd),
  32. $str = nqp::concat($str, nqp::unbox_s(.gist)));
  33. my $out := $*OUT;
  34. $out.print(nqp::concat($str,$out.nl-out));
  35. }
  36. proto sub put(|) { * }
  37. multi sub put() { $*OUT.print-nl }
  38. multi sub put(Str:D \x) {
  39. my $out := $*OUT;
  40. $out.print(nqp::concat(nqp::unbox_s(x),$out.nl-out));
  41. }
  42. multi sub put(\x) {
  43. my $out := $*OUT;
  44. $out.print(nqp::concat(nqp::unbox_s(x.Str),$out.nl-out));
  45. }
  46. multi sub put(**@args is raw) {
  47. my str $str;
  48. my $iter := @args.iterator;
  49. nqp::until(
  50. nqp::eqaddr(($_ := $iter.pull-one), IterationEnd),
  51. $str = nqp::concat($str, nqp::unbox_s(.Str)));
  52. my $out := $*OUT;
  53. $out.print(nqp::concat($str,$out.nl-out));
  54. }
  55. proto sub note(|) { * }
  56. multi sub note() {
  57. my $err := $*ERR;
  58. $err.print(nqp::concat("Noted",$err.nl-out));
  59. }
  60. multi sub note(Str:D \x) {
  61. my $err := $*ERR;
  62. $err.print(nqp::concat(nqp::unbox_s(x),$err.nl-out));
  63. }
  64. multi sub note(**@args is raw) {
  65. my $err := $*ERR;
  66. my str $str;
  67. $str = nqp::concat($str,nqp::unbox_s(.gist)) for @args;
  68. $err.print(nqp::concat($str,$err.nl-out));
  69. }
  70. sub gist(|) {
  71. my \args := nqp::p6argvmarray();
  72. nqp::elems(args) == 1
  73. ?? nqp::atpos(args, 0).gist
  74. !! nqp::p6bindattrinvres(nqp::create(List), List, '$!reified', args).gist
  75. }
  76. multi sub prompt() {
  77. $*IN.get
  78. }
  79. multi sub prompt($msg) {
  80. my $out := $*OUT;
  81. $out.print($msg);
  82. $out.flush();
  83. $*IN.get;
  84. }
  85. proto sub dir(|) { * }
  86. multi sub dir(*%_) { $*SPEC.curdir.IO.dir(:!absolute, |%_) }
  87. multi sub dir(IO::Path:D $path, |c) { $path.dir(|c) }
  88. multi sub dir(IO() $path, |c) { $path.dir(|c) }
  89. proto sub open(|) { * }
  90. multi sub open(IO() $path, |c) { IO::Handle.new(:$path).open(|c) }
  91. proto sub lines(|) { * }
  92. multi sub lines($what = $*ARGFILES, |c) { $what.lines(|c) }
  93. proto sub words(|) { * }
  94. multi sub words($what = $*ARGFILES, |c) { $what.words(|c) }
  95. proto sub get (|) { * }
  96. multi sub get (IO::Handle:D $fh = $*ARGFILES) { $fh.get }
  97. proto sub getc (|) { * }
  98. multi sub getc (IO::Handle:D $fh = $*ARGFILES) { $fh.getc }
  99. proto sub close(|) { * }
  100. multi sub close(IO::Handle:D $fh) { $fh.close }
  101. proto sub slurp(|) { * }
  102. multi sub slurp(IO::Handle:D $fh = $*ARGFILES, |c) { $fh.slurp(|c) }
  103. multi sub slurp(IO() $path, |c) { $path.slurp(|c) }
  104. proto sub spurt(|) { * }
  105. multi sub spurt(IO::Handle:D $fh, |c) { $fh .spurt(|c) }
  106. multi sub spurt(IO() $path, |c) { $path.spurt(|c) }
  107. {
  108. sub chdir(IO() $path) {
  109. CATCH {
  110. default {
  111. return Failure.new: X::IO::Chdir.new: :$path, :os-error(.Str);
  112. }
  113. }
  114. nqp::chdir(nqp::unbox_s($path.absolute));
  115. $*CWD = IO::Path.new(nqp::cwd());
  116. }
  117. PROCESS::<&chdir> := &chdir;
  118. }
  119. sub chdir(|c) {
  120. nqp::if(nqp::istype(($_ := $*CWD.chdir(|c)), Failure), $_, $*CWD = $_)
  121. }
  122. proto sub indir(|) {*}
  123. multi sub indir(IO() $path, &what, :$test!) {
  124. DEPRECATED(
  125. :what<:$test argument>,
  126. 'individual named parameters (e.g. :r, :w, :x)',
  127. "v2017.03.101.ga.5800.a.1", "v6.d", :up(*),
  128. );
  129. indir $path, &what, |$test.words.map(* => True).Hash;
  130. }
  131. multi sub indir(IO() $path, &what, :$d = True, :$r, :$w, :$x) {
  132. { # NOTE: we need this extra block so that the IO() coercer doesn't
  133. # use our (empty at the time) $*CWD when making the IO::Path object
  134. nqp::if(
  135. nqp::stmts(
  136. nqp::unless(
  137. nqp::unless(nqp::isfalse($d), $path.d),
  138. fail X::IO::Chdir.new: :$path, :os-error(
  139. nqp::if($path.e, 'is not a directory', 'does not exist')
  140. )
  141. ),
  142. nqp::unless(
  143. nqp::unless(nqp::isfalse($r), $path.r),
  144. fail X::IO::Chdir.new: :$path,
  145. :os-error("did not pass :r test")
  146. ),
  147. nqp::unless(
  148. nqp::unless(nqp::isfalse($w), $path.w),
  149. fail X::IO::Chdir.new: :$path,
  150. :os-error("did not pass :w test")
  151. ),
  152. nqp::unless(
  153. nqp::unless(nqp::isfalse($x), $path.x),
  154. fail X::IO::Chdir.new: :$path,
  155. :os-error("did not pass :x test")
  156. ),
  157. my $*CWD = $path,
  158. ),
  159. what
  160. )
  161. }
  162. }
  163. PROCESS::<$IN> =
  164. IO::Handle.new(:path(IO::Special.new('<STDIN>'))).open;
  165. PROCESS::<$OUT> =
  166. IO::Handle.new(:path(IO::Special.new('<STDOUT>'))).open;
  167. PROCESS::<$ERR> =
  168. IO::Handle.new(:path(IO::Special.new('<STDERR>'))).open;
  169. sub chmod($mode, *@filenames) {
  170. my @ok;
  171. for @filenames -> $file { @ok.push($file) if $file.IO.chmod($mode) }
  172. @ok;
  173. }
  174. sub unlink(*@filenames) {
  175. my @ok;
  176. for @filenames -> $file { @ok.push($file) if $file.IO.unlink }
  177. @ok;
  178. }
  179. sub rmdir(*@filenames) {
  180. my @ok;
  181. for @filenames -> $file { @ok.push($file) if $file.IO.rmdir }
  182. @ok;
  183. }
  184. sub mkdir(IO() $path, Int() $mode = 0o777) { $path.mkdir($mode) }
  185. sub rename(IO() $from, IO() $to, :$createonly) {
  186. $from.rename($to, :$createonly)
  187. }
  188. sub copy(IO() $from, IO() $to, :$createonly) { $from.copy($to, :$createonly) }
  189. sub move(IO() $from, IO() $to, :$createonly) { $from.move($to, :$createonly) }
  190. sub symlink(IO() $target, IO() $name) { $target.symlink($name) }
  191. sub link(IO() $target, IO() $name) { $target .link($name) }