1: \ require.fs
2:
3: \ Copyright (C) 1995,1996,1997,1998,2000 Free Software Foundation, Inc.
4:
5: \ This file is part of Gforth.
6:
7: \ Gforth is free software; you can redistribute it and/or
8: \ modify it under the terms of the GNU General Public License
9: \ as published by the Free Software Foundation; either version 2
10: \ of the License, or (at your option) any later version.
11:
12: \ This program is distributed in the hope that it will be useful,
13: \ but WITHOUT ANY WARRANTY; without even the implied warranty of
14: \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: \ GNU General Public License for more details.
16:
17: \ You should have received a copy of the GNU General Public License
18: \ along with this program; if not, write to the Free Software
19: \ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
20:
21: \ Now: Kernel Module, Reloadable
22:
23: create included-files 0 , 0 , ( pointer to and count of included files )
24: \ note: these names must not contain a "/" or "\"; otherwise a part of
25: \ that name might be used when expanding "./" (see expandtopic).
26: here ," *somewhere*" dup c@ swap 1 + swap
27: , A, here 2 cells -
28: create image-included-files 1 , A, ( pointer to and count of included files )
29: \ included-files points to ALLOCATEd space, while image-included-files
30: \ points to ALLOTed objects, so it survives a save-system
31:
32: : sourcefilename ( -- c-addr u ) \ gforth
33: \G The name of the source file which is currently the input
34: \G source. The result is valid only while the file is being
35: \G loaded. If the current input source is no (stream) file, the
36: \G result is undefined. In Gforth, the result is valid during the
37: \G whole seesion (but not across @code{savesystem} etc.).
38: loadfilename 2@ ;
39:
40: : sourceline# ( -- u ) \ gforth sourceline-number
41: \G The line number of the line that is currently being interpreted
42: \G from a (stream) file. The first line has the number 1. If the
43: \G current input source is not a (stream) file, the result is
44: \G undefined.
45: loadline @ ;
46:
47: : init-included-files ( -- ) \ gforth-internal
48: image-included-files 2@ 2* cells save-mem drop ( addr )
49: image-included-files 2@ nip included-files 2! ;
50:
51: : included? ( c-addr u -- f ) \ gforth
52: \G True only if the file @var{c-addr u} is in the list of earlier
53: \G included files. If the file has been loaded, it may have been
54: \G specified as, say, @file{foo.fs} and found somewhere on the
55: \G Forth search path. To return @code{true} from @code{included?},
56: \G you must specify the exact path to the file, even if that is
57: \G @file{./foo.fs}
58: included-files 2@ 0
59: ?do ( c-addr u addr )
60: dup >r 2@ 2over str=
61: if
62: 2drop rdrop unloop
63: true EXIT
64: then
65: r> cell+ cell+
66: loop
67: 2drop drop false ;
68:
69: : add-included-file ( c-addr u -- ) \ gforth
70: \G add name c-addr u to included-files
71: included-files 2@ 2* cells 2 cells extend-mem
72: 2/ cell / included-files 2!
73: 2! ;
74:
75: has? new-input [IF]
76: : included1 ( i*x file-id c-addr u -- j*x ) \ gforth
77: \G Include the file file-id with the name given by @var{c-addr u}.
78: save-mem 2dup add-included-file ( file-id )
79: ['] include-file2 catch
80: throw ;
81: [ELSE]
82: : included1 ( i*x file-id c-addr u -- j*x ) \ gforth
83: \G Include the file file-id with the name given by @var{c-addr u}.
84: save-mem 2dup loadfilename>r
85: add-included-file ( file-id )
86: ['] include-file2 catch
87: r>loadfilename
88: throw ;
89: [THEN]
90:
91: : included ( i*x c-addr u -- j*x ) \ file
92: \G @code{include-file} the file whose name is given by the string
93: \G @var{c-addr u}.
94: open-fpath-file throw included1 ;
95:
96: : required ( i*x addr u -- j*x ) \ gforth
97: \G @code{include-file} the file with the name given by @var{addr
98: \G u}, if it is not @code{included} (or @code{required})
99: \G already. Currently this works by comparing the name of the file
100: \G (with path) against the names of earlier included files.
101: \ however, it may be better to fstat the file,
102: \ and compare the device and inode. The advantages would be: no
103: \ problems with several paths to the same file (e.g., due to
104: \ links) and we would catch files included with include-file and
105: \ write a require-file.
106: open-fpath-file throw 2dup included?
107: if
108: 2drop close-file throw
109: else
110: included1
111: then ;
112:
113: \ INCLUDE 9may93jaw
114:
115: : include ( ... "file" -- ... ) \ gforth
116: \G @code{include-file} the file @var{file}.
117: name included ;
118:
119: : require ( ... "file" -- ... ) \ gforth
120: \G @code{include-file} @var{file} only if it is not included already.
121: name required ;
122:
123: \ : \I
124: \ here
125: \ 0 word count
126: \ string,
127: \ needsrcs^ @ ! ;
128:
129: \ : .included ( -- ) \ gforth
130: \ \G list the names of the files that have been @code{included}
131: \ cr
132: \ needs^ @
133: \ BEGIN dup
134: \ WHILE dup cell+ count type cr
135: \ 5 spaces
136: \ dup cell+ count + aligned
137: \ @ dup IF count type ELSE drop THEN cr
138: \ @
139: \ REPEAT
140: \ drop ;
141:
142: : .strings ( addr u -- ) \ gforth
143: \G list the strings from an array of string descriptors at addr
144: \G with u entries, one per line.
145: 2* cells bounds ?DO
146: cr I 2@ type 2 cells +LOOP ;
147:
148: : .included ( -- ) \ gforth
149: \G list the names of the files that have been @code{included}
150: included-files 2@ 2 cells under+ 1- .strings ;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>