some more progress. All the initialization routines run and I can get some of the...
[kakapo:kakapo.git] / src / FileSystem.nqp
1 # Copyright (C) 2010, Austin Hastings. See accompanying LICENSE file, or
2 # http://www.opensource.org/licenses/artistic-license-2.0.php for license.
3
4 # Provides a conventional framework for program execution.
5 class FileSystem;
6
7 INIT {
8         our %_Osname_class_map := Hash.new(
9                 :DEFAULT(       FileSystem::Unix),
10                 :linux( FileSystem::Unix),
11         );
12 }
13
14 method get_osname_map() {
15         our %_Osname_class_map;
16 }
17
18 method _init_obj(*@pos, *%named) {
19         my %map := self.get_osname_map();
20         my $osname := 'DEFAULT';
21         try {
22             my $tmp := %*VM<osname>;
23             $osname := $tmp if %map.contains: $tmp;
24
25             # if not, whatever. Keep it at DEFAULT
26             CATCH { }
27         }
28
29         my $class := %map{$osname};
30         my $obj := $class.new( |@pos, |%named );        # NB: Returns a different type than Path.
31         $obj;
32 }
33
34 our method instance($value?) {
35         if $value.defined {
36                 our $_Instance := $value;
37         }
38         elsif ! our $_Instance.defined {
39                 self.instance: self.new;
40         }
41
42         $_Instance;
43 }
44
45 class FileSystem::Unix
46         is FileSystem;
47
48 has     $!file;
49 has     $!os;
50
51 INIT {
52         my @multisubs := [ <exists> ];
53
54         for @multisubs -> $name {
55                 Parrot::define_multisub($name, :method, :starting_with($name));
56
57                 my $string_sub := Parrot::get_hll_global( "FileSystem::Unix::{$name}__String" );
58                 unless Parrot::is_null( $string_sub ) {
59                         Parrot::define_multisub($name, [ $string_sub ], signatures => [ <_ string> ] );
60                 }
61         }
62 }
63
64 our method chdir($path = '') {
65         $!os.chdir( ~ $path);
66 }
67
68 our method cwd() {
69         $!os.cwd;
70 }
71
72 our method directory_separator() { '/' }
73
74 my method exists__Path($path) {
75         $!file.exists( ~ $path );
76 }
77
78 my method exists__String($path) {
79         $!file.exists($path);
80 }
81
82 my method exists__ANY($ignored) {
83         die( "Don't know how to check if ", pir::typeof__SP($ignored), " exists. Use a String or Path");
84 }
85
86 our method get_contents($path, *%named) {
87         my $contents;
88
89         if self.is_file: $path {
90                 %named<mode> := 'r';
91                 my $fh := self.open($path, |%named);
92                 $contents := $fh.readall;
93                 $fh.close;
94         }
95         elsif self.is_directory: $path {
96                 $contents := $!os.readdir: ~$path;
97         }
98         else {
99                 # What to do?
100                 die("Don't know how to get contents of non-file, non-directory: $path");
101         }
102
103         $contents;
104 }
105
106 my method _init_obj(*@pos, *%named) {
107         $!file := pir::new__PS( 'File' );
108         $!os := pir::new__PS( 'OS' );
109
110         self._init_args(|@pos, |%named);
111 }
112
113 our method is_device($path) {
114         my @stat := $!os.stat( ~$path );
115         my $mode := @stat[2];
116         S_ISBLK($mode) || S_ISCHR($mode) || S_ISFIFO($mode) || S_ISSOCK($mode);
117 }
118
119 our method is_directory($path) {
120         my @stat := $!os.stat( ~$path );
121         S_ISDIR(@stat[2]);
122 }
123
124 our method is_file($path) {
125         my @stat := $!os.stat( ~$path );
126         S_ISREG(@stat[2]);
127 }
128
129 our method is_link($path) {
130         my @stat := $!os.lstat( ~$path );
131         S_ISLNK(@stat[2]);
132 }
133
134 our method open($path, *%named) {
135
136         my $fh  := pir::new__PS('FileHandle');
137         my $mode        := '' ~ %named<mode> // 'r';
138
139         $fh.open(~ $path, $mode);
140
141         # Not a loop because of prefix ops (+, ~)
142         $fh.buffer_size( +%named<buffer_size> )
143                 if %named.contains( <buffer_size> );
144         $fh.buffer_type( ~%named<buffer_type> )
145                 if %named.contains( <buffer_type> );
146         $fh.encoding( ~%named<encoding> )
147                 if %named.contains( <encoding> );
148
149         $fh;
150 }
151
152 our method volume_separator() { ':' }