[gforth] / gforth / Attic / files.fs  

gforth: gforth/Attic/files.fs


1 : pazsan 1.1 \ File specifiers 11jun93jaw
2 :    
3 :     4 Constant w/o ( -- fam ) \ file w-o
4 :     2 Constant r/w ( -- fam ) \ file r-w
5 :     0 Constant r/o ( -- fam ) \ file r-o
6 :    
7 :     : bin ( fam1 -- fam2 ) \ file
8 :     1 or ;
9 :    
10 :     \ BIN WRITE-LINE 11jun93jaw
11 :    
12 :     : write-line ( c-addr u fileid -- ior ) \ file
13 :     dup >r write-file
14 :     ?dup IF
15 :     r> drop EXIT
16 :     THEN
17 :     #lf r> emit-file ;
18 :    
19 :     \ include-file 07apr93py
20 :    
21 :     : push-file ( -- ) r>
22 :     sourceline# >r loadfile @ >r
23 :     blk @ >r tibstack @ >r >tib @ >r #tib @ >r
24 :     >tib @ tibstack @ = IF r@ tibstack +! THEN
25 :     tibstack @ >tib ! >in @ >r >r ;
26 :    
27 :     : pop-file ( throw-code -- throw-code )
28 :     dup IF
29 :     source >in @ sourceline# sourcefilename
30 :     error-stack dup @ dup 1+
31 :     max-errors 1- min error-stack !
32 :     6 * cells + cell+
33 :     5 cells bounds swap DO
34 :     I !
35 :     -1 cells +LOOP
36 :     THEN
37 :     r>
38 :     r> >in ! r> #tib ! r> >tib ! r> tibstack ! r> blk !
39 :     r> loadfile ! r> loadline ! >r ;
40 :    
41 :     : read-loop ( i*x -- j*x )
42 :     BEGIN refill WHILE interpret REPEAT ;
43 :    
44 :     : include-file ( i*x fid -- j*x ) \ file
45 :     push-file loadfile !
46 :     0 loadline ! blk off ['] read-loop catch
47 :     loadfile @ close-file swap 2dup or
48 :     pop-file drop throw throw ;
49 :    
50 :     create pathfilenamebuf 256 chars allot \ !! make this grow on demand
51 :    
52 :     : absolut-path? ( addr u -- flag ) \ gforth
53 :     \G a path is absolute, if it starts with a / or a ~ (~ expansion),
54 :     \G or if it is in the form ./* or ../*, extended regexp: ^[/~]|./|../
55 :     \G Pathes simply containing a / are not absolute!
56 :     over c@ '/ = >r
57 :     over c@ '~ = >r
58 :     2dup 2 min S" ./" compare 0= >r
59 :     3 min S" ../" compare 0=
60 :     r> r> r> or or or ;
61 :    
62 :     : open-path-file ( c-addr1 u1 -- file-id c-addr2 u2 ) \ gforth
63 :     \G opens a file for reading, searching in the path for it (unless
64 :     \G the filename contains a slash); c-addr2 u2 is the full filename
65 :     \G (valid until the next call); if the file is not found (or in
66 :     \G case of other errors for each try), -38 (non-existant file) is
67 :     \G thrown. Opening for other access modes makes little sense, as
68 :     \G the path will usually contain dirs that are only readable for
69 :     \G the user
70 :     \ !! use file-status to determine access mode?
71 :     2dup absolut-path?
72 :     IF \ the filename contains a slash
73 :     2dup r/o open-file throw ( c-addr1 u1 file-id )
74 :     -rot >r pathfilenamebuf r@ cmove ( file-id R: u1 )
75 :     pathfilenamebuf r> EXIT
76 :     THEN
77 :     pathdirs 2@ 0
78 :     ?DO ( c-addr1 u1 dirnamep )
79 :     dup >r 2@ dup >r pathfilenamebuf swap cmove ( addr u )
80 :     2dup pathfilenamebuf r@ chars + swap cmove ( addr u )
81 :     pathfilenamebuf over r> + dup >r r/o open-file 0=
82 :     IF ( addr u file-id )
83 :     nip nip r> rdrop 0 LEAVE
84 :     THEN
85 :     rdrop drop r> cell+ cell+
86 :     LOOP
87 :     0<> -&38 and throw ( file-id u2 )
88 :     pathfilenamebuf swap ;
89 :    
90 :     create included-files 0 , 0 , ( pointer to and count of included files )
91 :     here ," the terminal" dup c@ swap 1 + swap , A, here 2 cells -
92 :     create image-included-files 1 , A, ( pointer to and count of included files )
93 :     \ included-files points to ALLOCATEd space, while image-included-files
94 :     \ points to ALLOTed objects, so it survives a save-system
95 :    
96 :     : loadfilename ( -- a-addr )
97 :     \G a-addr 2@ produces the current file name ( c-addr u )
98 :     included-files 2@ drop loadfilename# @ 2* cells + ;
99 :    
100 :     : sourcefilename ( -- c-addr u ) \ gforth
101 :     \G the name of the source file which is currently the input
102 :     \G source. The result is valid only while the file is being
103 :     \G loaded. If the current input source is no (stream) file, the
104 :     \G result is undefined.
105 :     loadfilename 2@ ;
106 :    
107 :     : sourceline# ( -- u ) \ gforth sourceline-number
108 :     \G the line number of the line that is currently being interpreted
109 :     \G from a (stream) file. The first line has the number 1. If the
110 :     \G current input source is no (stream) file, the result is
111 :     \G undefined.
112 :     loadline @ ;
113 :    
114 :     : init-included-files ( -- )
115 :     image-included-files 2@ 2* cells save-mem drop ( addr )
116 :     image-included-files 2@ nip included-files 2! ;
117 :    
118 :     : included? ( c-addr u -- f ) \ gforth
119 :     \G true, iff filename c-addr u is in included-files
120 :     included-files 2@ 0
121 :     ?do ( c-addr u addr )
122 :     dup >r 2@ 2over compare 0=
123 :     if
124 :     2drop rdrop unloop
125 :     true EXIT
126 :     then
127 :     r> cell+ cell+
128 :     loop
129 :     2drop drop false ;
130 :    
131 :     : add-included-file ( c-addr u -- ) \ gforth
132 :     \G add name c-addr u to included-files
133 :     included-files 2@ 2* cells 2 cells extend-mem
134 :     2/ cell / included-files 2!
135 :     2! ;
136 :    
137 :     : included1 ( i*x file-id c-addr u -- j*x ) \ gforth
138 :     \G include the file file-id with the name given by c-addr u
139 :     loadfilename# @ >r
140 :     save-mem add-included-file ( file-id )
141 :     included-files 2@ nip 1- loadfilename# !
142 :     ['] include-file catch
143 :     r> loadfilename# !
144 :     throw ;
145 :    
146 :     : included ( i*x addr u -- j*x ) \ file
147 :     open-path-file included1 ;
148 :    
149 :     : required ( i*x addr u -- j*x ) \ gforth
150 :     \G include the file with the name given by addr u, if it is not
151 :     \G included already. Currently this works by comparing the name of
152 :     \G the file (with path) against the names of earlier included
153 :     \G files; however, it would probably be better to fstat the file,
154 :     \G and compare the device and inode. The advantages would be: no
155 :     \G problems with several paths to the same file (e.g., due to
156 :     \G links) and we would catch files included with include-file and
157 :     \G write a require-file.
158 :     open-path-file 2dup included?
159 :     if
160 :     2drop close-file throw
161 :     else
162 :     included1
163 :     then ;
164 :    
165 :     \ INCLUDE 9may93jaw
166 :    
167 :     : include ( "file" -- ) \ gforth
168 :     name included ;
169 :    
170 :     : require ( "file" -- ) \ gforth
171 :     name required ;
172 :    
173 :     \ additional words only needed if there is file support
174 :    
175 :     : ( ( compilation 'ccc<close-paren>' -- ; run-time -- ) \ core,file paren
176 :     loadfile @ 0= IF postpone ( EXIT THEN
177 :     BEGIN
178 :     >in @
179 :     [char] ) parse nip
180 :     >in @ rot - = \ is there no delimter?
181 :     WHILE
182 :     refill 0=
183 :     IF
184 :     warnings @
185 :     IF
186 :     ." warning: ')' missing" cr
187 :     THEN
188 :     EXIT
189 :     THEN
190 :     REPEAT ; immediate
191 :    

CVS Admin

Powered by ViewCVS 1.0-dev
(Powered by ViewCVS)

ViewCVS and CVS Help