Filename translation
Usually a program does not, and should not, need to know what type of filenames the underlying filing system is using. The program should accept whatever filenames the user supplies, and pass them onto the filing system. However, there are some cases where the actual filename format is needed and the program needs to be able to translate filenames.
Pathname translation deals with translating full pathnames - including references to arbitary root directories, parent directories, drives, etc., such as H:/docs/../start*/file0?.doc, $.info.^.set*.make##/src. If you known that you will only be dealing with simple full filenames - known as canonicalised paths - such as info.setup.make01/src then simpler conversion code can be used.
The FName library provides functions for converting simple filenames between BBC, DOS/Windows and Unix/Zip/URL formats.
BBC and Zip
BBC and Zip/Unix/URL filenames can be converted bidirectionally between each other by simply swapping characters @ # $ ^ . with = ? < > /.
REM Swap between BBC and ZIP/Unix/URL path DEFFNfn_bbczip(A$):IFA$="":="" LOCAL A%,B% FOR A%=1 TO LEN A$:B%=ASCMID$(A$,A%,1) IF B%=61 OR B%=64:A$=LEFT$(A$,A%-1)+CHR$(B%EOR125)+MID$(A$,A%+1):REM = @ IF B%=35 OR B%=63:A$=LEFT$(A$,A%-1)+CHR$(B%EOR28)+MID$(A$,A%+1) :REM ? # IF B%=36 OR B%=60:A$=LEFT$(A$,A%-1)+CHR$(B%EOR24)+MID$(A$,A%+1) :REM < $ IF B%=62 OR B%=94:A$=LEFT$(A$,A%-1)+CHR$(B%EOR96)+MID$(A$,A%+1) :REM > ^ IF (B%AND&FE)=46 :A$=LEFT$(A$,A%-1)+CHR$(B%EOR1)+MID$(A$,A%+1) :REM / . NEXT:=A$
BBC and DOS/Windows
BBC and DOS/Windows filenames cannot be bidirectionally swapped with the same code as the three characters . / \ have to be interchanged.
REM Convert a DOS path to a BBC path DEFFNfn_dosbbc(A$):IFA$="":="" LOCAL A%,B% FOR A%=1 TO LEN A$:B%=ASCMID$(A$,A%,1) IF B%=61 OR B%=64:A$=LEFT$(A$,A%-1)+CHR$(B%EOR125)+MID$(A$,A%+1):REM = @ IF B%=35 OR B%=63:A$=LEFT$(A$,A%-1)+CHR$(B%EOR28)+MID$(A$,A%+1) :REM # ? IF B%=36 OR B%=60:A$=LEFT$(A$,A%-1)+CHR$(B%EOR24)+MID$(A$,A%+1) :REM $ < IF B%=62 OR B%=94:A$=LEFT$(A$,A%-1)+CHR$(B%EOR96)+MID$(A$,A%+1) :REM > ^ IF B%=46 :A$=LEFT$(A$,A%-1)+"/"+MID$(A$,A%+1) :REM . -> / IF B%=92 :A$=LEFT$(A$,A%-1)+"."+MID$(A$,A%+1) :REM \ -> . IF B%=47 :A$=LEFT$(A$,A%-1)+"\"+MID$(A$,A%+1) :REM / -> \ NEXT:=A$ : REM Convert a BBC path to a DOS path DEFFNfn_bbcdos(A$):IFA$="":="" LOCAL A%,B% FOR A%=1 TO LEN A$:B%=ASCMID$(A$,A%,1) IF B%=61 OR B%=64:A$=LEFT$(A$,A%-1)+CHR$(B%EOR125)+MID$(A$,A%+1):REM @ = IF B%=35 OR B%=63:A$=LEFT$(A$,A%-1)+CHR$(B%EOR28)+MID$(A$,A%+1) :REM # ? IF B%=36 OR B%=60:A$=LEFT$(A$,A%-1)+CHR$(B%EOR24)+MID$(A$,A%+1) :REM $ < IF B%=62 OR B%=94:A$=LEFT$(A$,A%-1)+CHR$(B%EOR96)+MID$(A$,A%+1) :REM ^ > IF B%=46 :A$=LEFT$(A$,A%-1)+"\"+MID$(A$,A%+1) :REM . -> \ IF B%=92 :A$=LEFT$(A$,A%-1)+"/"+MID$(A$,A%+1) :REM \ -> / IF B%=47 :A$=LEFT$(A$,A%-1)+"."+MID$(A$,A%+1) :REM / -> . NEXT:=A$
These two functions can be combined to share their code as follows:
DEFFNfn_dosbbc(A$):LOCAL C% :REM Convert a DOS path to a BBC path DEFFNfn_bbcdos(A$):LOCAL C%:C%=1:REM Convert a BBC path to a DOS path IFA$="":="" LOCAL A%,B% FOR A%=1 TO LEN A$:B%=ASCMID$(A$,A%,1) IF B%=61 OR B%=64:A$=LEFT$(A$,A%-1)+CHR$(B%EOR125)+MID$(A$,A%+1):REM = @ IF B%=35 OR B%=63:A$=LEFT$(A$,A%-1)+CHR$(B%EOR28)+MID$(A$,A%+1) :REM # ? IF B%=36 OR B%=60:A$=LEFT$(A$,A%-1)+CHR$(B%EOR24)+MID$(A$,A%+1) :REM $ < IF B%=62 OR B%=94:A$=LEFT$(A$,A%-1)+CHR$(B%EOR96)+MID$(A$,A%+1) :REM > ^ IF B%=46:IF C% :A$=LEFT$(A$,A%-1)+"\"+MID$(A$,A%+1) :REM . -> \ IF B%=46:IF C%=0 :A$=LEFT$(A$,A%-1)+"/"+MID$(A$,A%+1) :REM . -> / IF B%=92:IF C% :A$=LEFT$(A$,A%-1)+"/"+MID$(A$,A%+1) :REM \ -> / IF B%=92:IF C%=0 :A$=LEFT$(A$,A%-1)+"."+MID$(A$,A%+1) :REM \ -> . IF B%=47:IF C% :A$=LEFT$(A$,A%-1)+"."+MID$(A$,A%+1) :REM / -> . IF B%=47:IF C%=0 :A$=LEFT$(A$,A%-1)+"\"+MID$(A$,A%+1) :REM / -> \ NEXT:=A$
DOS and Zip/Unix/URL
Converting between DOS and Zip/Unix/URL filenames is the simplest of all, as all it requires is the \ and / characters to be bidrectionally swapped.
REM Swap between DOS and Zip/Unix/URL path DEFFNfn_doszip(A$):IFA$="":="" LOCAL A%,B% FOR A%=1 TO LEN A$:B%=ASCMID$(A$,A%,1) IF B%=47 OR B%=92:A$=LEFT$(A$,A%-1)+CHR$(B%EOR115)+MID$(A$,A%+1):REM / \ NEXT:=A$
See also
Jgharston 03:28, 14 January 2012 (UTC)