![]() ![]() | ![]() |
replaced "*a file*" etc. with "*somewhere*"
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: loadfilename 2@ 2>r 85: save-mem 2dup loadfilename 2! 86: add-included-file ( file-id ) 87: ['] include-file2 catch 88: 2r> loadfilename 2! 89: throw ; 90: [THEN] 91: 92: : included ( i*x c-addr u -- j*x ) \ file 93: \G @code{include-file} the file whose name is given by the string 94: \G @var{c-addr u}. 95: open-fpath-file throw included1 ; 96: 97: : required ( i*x addr u -- j*x ) \ gforth 98: \G @code{include-file} the file with the name given by @var{addr 99: \G u}, if it is not @code{included} (or @code{required}) 100: \G already. Currently this works by comparing the name of the file 101: \G (with path) against the names of earlier included files. 102: \ however, it may be better to fstat the file, 103: \ and compare the device and inode. The advantages would be: no 104: \ problems with several paths to the same file (e.g., due to 105: \ links) and we would catch files included with include-file and 106: \ write a require-file. 107: open-fpath-file throw 2dup included? 108: if 109: 2drop close-file throw 110: else 111: included1 112: then ; 113: 114: \ INCLUDE 9may93jaw 115: 116: : include ( ... "file" -- ... ) \ gforth 117: \G @code{include-file} the file @var{file}. 118: name included ; 119: 120: : require ( ... "file" -- ... ) \ gforth 121: \G @code{include-file} @var{file} only if it is not included already. 122: name required ; 123: 124: \ : \I 125: \ here 126: \ 0 word count 127: \ string, 128: \ needsrcs^ @ ! ; 129: 130: \ : .included ( -- ) \ gforth 131: \ \G list the names of the files that have been @code{included} 132: \ cr 133: \ needs^ @ 134: \ BEGIN dup 135: \ WHILE dup cell+ count type cr 136: \ 5 spaces 137: \ dup cell+ count + aligned 138: \ @ dup IF count type ELSE drop THEN cr 139: \ @ 140: \ REPEAT 141: \ drop ; 142: 143: : .strings ( addr u -- ) \ gforth 144: \G list the strings from an array of string descriptors at addr 145: \G with u entries, one per line. 146: 2* cells bounds ?DO 147: cr I 2@ type 2 cells +LOOP ; 148: 149: : .included ( -- ) \ gforth 150: \G list the names of the files that have been @code{included} 151: included-files 2@ 2 cells under+ 1- .strings ;