Annotation of gforth/kernel/paths.fs, revision 1.3

1.1       anton       1: \ paths.fs path file handling                                    03may97jaw
                      2: 
                      3: \ Copyright (C) 1995-1997 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., 675 Mass Ave, Cambridge, MA 02139, USA.
                     20: 
                     21: 0 [IF]
                     22: 
                     23: -Changing the search-path:
                     24: fpath+ <path>          adds a directory to the searchpath
                     25: fpath= <path>|<path>   makes complete now searchpath
                     26:                        seperator is |
                     27: .fpath                 displays the search path
                     28: remark I: 
                     29: a ~+ in the beginning of filename is expanded to the directory the
                     30: current file comes from. ~+ can also be included in the search-path!
                     31: 
                     32: remark II:
                     33: if there is no sufficient space for the search path increase it!
                     34: 
                     35: 
                     36: -Creating custom paths:
                     37: 
                     38: It is possible to use the search mechanism on yourself.
                     39: 
                     40: Make a buffer for the path:
                     41: create mypath  100 chars ,     \ maximum length (is checked)
                     42:                0 ,             \ real len
                     43:                100 chars allot \ space for path
                     44: use the same functions as above with:
                     45: mypath path+ 
                     46: mypath path=
                     47: mypath .path
                     48: 
                     49: do a open with the search path:
1.3     ! pazsan     50: open-path-file ( adr len path -- fd adr len ior )
1.1       anton      51: the file is opened read-only; if the file is not found an error is generated
                     52: 
                     53: \ questions to: wilke@jwdt.com
                     54: [THEN]
                     55: 
                     56: [IFUNDEF] +place
                     57: : +place ( adr len adr )
                     58:         2dup >r >r
                     59:         dup c@ char+ + swap move
                     60:         r> r> dup c@ rot + swap c! ;
                     61: [THEN]
                     62: 
                     63: [IFUNDEF] place
                     64: : place ( c-addr1 u c-addr2 )
                     65:         2dup c! char+ swap move ;
                     66: [THEN]
                     67: 
                     68: create sourcepath 256 chars , 0 , 256 chars allot
                     69: sourcepath avalue fpath
                     70: 
                     71: : also-path ( adr len path^ -- )
                     72:   >r
                     73:   \ len check
                     74:   r@ cell+ @ over + r@ @ u> ABORT" path buffer too small!"
                     75:   \ copy into
                     76:   tuck r@ cell+ dup @ cell+ + swap cmove
                     77:   \ make delemiter
                     78:   0 r@ cell+ dup @ cell+ + 2 pick + c! 1 + r> cell+ +!
                     79:   ;
                     80: 
                     81: : only-path ( adr len path^ -- )
                     82:   dup 0 swap cell+ ! also-path ;
                     83: 
1.2       jwilke     84: : path+ ( path-addr  "dir" -- ) \ gforth
                     85: \G adds a directory to the search path path-addr
                     86:   name rot also-path ;
                     87: 
                     88: : fpath+ ( "dir" ) \ gforth
                     89: \G adds a directory to the forth search path
                     90:   fpath path+ ;
                     91: 
                     92: : path= ( path-addr "dir1|dir2|dir3" ) \ gforth
                     93: \G makes complete new searchpath, seperator is |
                     94:   name 2dup bounds ?DO i c@ '| = IF 0 i c! THEN LOOP
                     95:   rot only-path ;
                     96: 
                     97: : fpath= ( "dir1|dir2|dir3" ) \ gforth
                     98: \G makes complete new searchpath, serpeator is |
                     99:   fpath path= ;
1.1       anton     100: 
                    101: : path>counted  cell+ dup cell+ swap @ ;
                    102: 
                    103: : next-path ( adr len -- adr2 len2 )
                    104:   2dup 0 scan
                    105:   dup 0= IF     2drop 0 -rot 0 -rot EXIT THEN
                    106:   >r 1+ -rot r@ 1- -rot
                    107:   r> - ;
                    108: 
                    109: : privous-path ( path^ -- )
                    110:   dup path>counted
                    111:   BEGIN tuck dup WHILE repeat ;
                    112: 
1.2       jwilke    113: : .path ( path-addr -- ) \ gforth
                    114: \G displays the contents of the search path path-addr
1.1       anton     115:   path>counted
                    116:   BEGIN next-path dup WHILE type space REPEAT 2drop 2drop ;
                    117: 
1.2       jwilke    118: : .fpath ( ) \ gforth
                    119: \G displays the contents of the forth search patch
                    120:   fpath .path ;
1.1       anton     121: 
                    122: : absolut-path? ( addr u -- flag ) \ gforth
                    123:     \G a path is absolute, if it starts with a / or a ~ (~ expansion),
                    124:     \G or if it is in the form ./* or ../*, extended regexp: ^[/~]|./|../
                    125:     \G Pathes simply containing a / are not absolute!
                    126:     2dup 2 u> swap 1+ c@ ': = and >r \ dos absoulte: c:/....
                    127:     over c@ '/ = >r
                    128:     over c@ '~ = >r
                    129:     2dup 2 min S" ./" compare 0= >r
                    130:          3 min S" ../" compare 0=
                    131:     r> r> r> r> or or or or ;
                    132: 
                    133: Create ofile 0 c, 255 chars allot
                    134: Create tfile 0 c, 255 chars allot
                    135: 
                    136: : pathsep? dup [char] / = swap [char] \ = or ;
                    137: 
                    138: : need/   ofile dup c@ + c@ pathsep? 0= IF s" /" ofile +place THEN ;
                    139: 
1.2       jwilke    140: : extractpath ( adr len -- adr len2 )
                    141:   BEGIN dup WHILE 1-
                    142:         2dup + c@ pathsep? IF EXIT THEN
                    143:   REPEAT ;
1.1       anton     144: 
                    145: : expandtopic
                    146:   ofile count 2 min s" ~+" compare 0=
                    147:   IF   ofile count 2 /string tfile place
1.2       jwilke    148:        0 ofile c! sourcefilename extractpath ofile place need/
1.3     ! pazsan    149:        tfile count over c@ pathsep? IF 1 /string THEN
        !           150:        ofile +place
1.1       anton     151:   THEN ;
                    152:        
1.3     ! pazsan    153: : compact// ( adr len -- adr2 len2 )
        !           154: \ deletes phrases like "//" out of our directory name 2dec97jaw
        !           155:   over >r
        !           156:   BEGIN        dup WHILE
        !           157:        over c@ pathsep? over 1- 0<> and
        !           158:        IF over 1+ c@ pathsep?
        !           159:           IF   1- over 1+ swap move
        !           160:           THEN
        !           161:        THEN
        !           162:        1 /string
        !           163:    REPEAT 
        !           164:    drop r> tuck - ;
        !           165: 
        !           166: : compact.. ( adr len -- adr2 len2 )
        !           167: \ deletes phrases like "xy/.." out of our directory name 2dec97jaw
        !           168:   over >r -1 >r
        !           169:   BEGIN dup WHILE
        !           170:        over c@ pathsep? 
        !           171:        IF      r@ -1 =
        !           172:                IF      r> drop dup >r
        !           173:                ELSE    2dup 1 /string 
        !           174:                        3 min s" ../" compare
        !           175:                        0=
        !           176:                        IF      r@ over - ( diff )
        !           177:                                2 pick swap - ( dest-adr )
        !           178:                                >r 3 /string r> swap 2dup >r >r
        !           179:                                move r> r>
        !           180:                        ELSE    r> drop dup >r
        !           181:                        THEN
        !           182:                THEN
        !           183:        THEN
        !           184:        1 /string
        !           185:   REPEAT 
        !           186:   r> drop 
        !           187:   drop r> tuck - ;
        !           188: 
        !           189: : reworkdir
        !           190:   expandtopic
        !           191:   ofile count compact// compact..
        !           192:   nip ofile c! ;
        !           193: 
1.2       jwilke    194: : check-path ( adr1 len1 adr2 len2 -- fd 0 | 0 <>0 )
                    195:   0 ofile ! >r >r ofile place need/
                    196:   r> r> ofile +place
1.3     ! pazsan    197:   reworkdir
1.2       jwilke    198:   ofile count r/o open-file ;
1.1       anton     199: 
1.2       jwilke    200: : open-path-file ( adr len path-addr -- fd adr1 len2 0 | ior ) \ gforth
                    201: \G looks in path path-addr for the file specified by adr len
                    202: \G when found the resulting path and an open file descriptor
                    203: \G is returned. If the file is not found ior is non zero
1.1       anton     204:   >r
                    205:   2dup absolut-path?
                    206:   IF    rdrop
1.3     ! pazsan    207:         ofile place reworkdir ofile count r/o open-file
        !           208:        dup 0= IF >r ofile count r> THEN EXIT
1.1       anton     209:   ELSE  r> path>counted
                    210:         BEGIN  next-path dup
                    211:         WHILE  5 pick 5 pick check-path
1.2       jwilke    212:         0= IF >r 2drop 2drop r> ofile count 0 EXIT ELSE drop THEN
1.1       anton     213:   REPEAT
1.2       jwilke    214:         2drop 2drop 2drop -&38
1.1       anton     215:   THEN ;
                    216: 
1.2       jwilke    217: : open-fpath-file ( adr len -- fd adr1 len2 0 | ior ) \ gforth
                    218: \G looks in the forth search path for the file specified by adr len
                    219: \G when found the resulting path and an open file descriptor
                    220: \G is returned. If the file is not found ior is non zero
                    221:   fpath open-path-file ;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>