Difference between revisions of "Filename translation"

From BeebWiki
Jump to: navigation, search
m (1 revision)
(Tidied and updated code.)
Line 10: Line 10:
 
such as ''H:/docs/../start*/file0?.doc'', ''$.info.^.set*.make##/src''. If
 
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
 
you known that you will only be dealing with simple full filenames - known
as ''canonicalised paths'' - such as ''info.setup.make01/src'' then simpler
+
as ''canonicalised paths'' - such as ''info.setup.make01/src'', or just
conversion code can be used.
+
leafnames - such as ''docs/zip'' or ''docs.zip'' - then the simpler
 +
conversion code here can be used.
  
 
The [http://mdfs.net/System/Library/BLib#fname FName] library provides
 
The [http://mdfs.net/System/Library/BLib#fname FName] library provides
Line 19: Line 20:
 
===BBC and Zip===
 
===BBC and Zip===
 
BBC and Zip/Unix/URL filenames can be converted bidirectionally between each
 
BBC and Zip/Unix/URL filenames can be converted bidirectionally between each
other by simply swapping characters '''@''' '''#''' '''$''' '''^''' '''.'''
+
other by simply swapping characters
with '''=''' '''?''' '''<''' '''>''' '''/'''.
+
'''#''' '''.''' '''$''' '''^''' '''&''' '''@''' '''%''' with
 +
'''?''' '''/''' '''<''' '''>''' '''+''' '''=''' ''';'''.
  
 
     REM Swap between BBC and ZIP/Unix/URL path
 
     REM Swap between BBC and ZIP/Unix/URL path
     DEFFNfn_bbczip(A$):IFA$="":=""
+
     DEFFNfn_bbczip(B$):IF B$="":=""
     LOCAL A%,B%
+
     LOCAL A$,B%,A%:A$="/.#?$<^>&+@=%; "
    FOR A%=1 TO LEN A$:B%=ASCMID$(A$,A%,1)
+
    FOR A%=1 TO LEN B$:B%=INSTR(A$,MID$(B$,A%,1))-1
      IF B%=61 OR B%=64:A$=LEFT$(A$,A%-1)+CHR$(B%EOR125)+MID$(A$,A%+1):REM = @
+
       IF B%>TRUE:B$=LEFT$(B$,A%-1)+MID$(A$+"_",(B%EOR1)+1,1)+MID$(B$,A%+1)
      IF B%=35 OR B%=63:A$=LEFT$(A$,A%-1)+CHR$(B%EOR28)+MID$(A$,A%+1) :REM ? #
+
     NEXT:=B$
      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===
 
BBC and DOS/Windows filenames cannot be bidirectionally swapped with the same
 
BBC and DOS/Windows filenames cannot be bidirectionally swapped with the same
 
code as the three characters '''.''' '''/''' '''\''' have to be interchanged.
 
code as the three characters '''.''' '''/''' '''\''' have to be interchanged.
 +
However, if you know that you are only dealing with leafnames, <code>FNfn_bbczip()</code>
 +
can be used.
  
 
     REM Convert a DOS path to a BBC path
 
     REM Convert a DOS path to a BBC path
     DEFFNfn_dosbbc(A$):IFA$="":=""
+
     DEFFNfn_dosbbc(B$):IF B$="":=""
     LOCAL A%,B%
+
     LOCAL A$,B%,A%:A$=".\#?$<^>&+@=%; "
    FOR A%=1 TO LEN A$:B%=ASCMID$(A$,A%,1)
+
    FOR A%=1 TO LEN B$:B%=INSTR(A$,MID$(B$,A%,1))-1
      IF B%=61 OR B%=64:A$=LEFT$(A$,A%-1)+CHR$(B%EOR125)+MID$(A$,A%+1):REM = @
+
       IF B%>0:B$=LEFT$(B$,A%-1)+MID$(A$+"_",(B%EOR1)+1,1)+MID$(B$,A%+1)
      IF B%=35 OR B%=63:A$=LEFT$(A$,A%-1)+CHR$(B%EOR28)+MID$(A$,A%+1) :REM # ?
+
       IF B%=0:B$=LEFT$(B$,A%-1)+"/"+MID$(B$,A%+1)
      IF B%=36 OR B%=60:A$=LEFT$(A$,A%-1)+CHR$(B%EOR24)+MID$(A$,A%+1) :REM $ <
+
     NEXT:=B$
       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
 
     REM Convert a BBC path to a DOS path
     DEFFNfn_bbcdos(A$):IFA$="":=""
+
     DEFFNfn_bbcdos(B$):IF B$="":=""
     LOCAL A%,B%
+
     LOCAL A$,B%,A%:A$="./#?$<^>&+@=%; "
    FOR A%=1 TO LEN A$:B%=ASCMID$(A$,A%,1)
+
     FOR A%=1 TO LEN B$:B%=INSTR(A$,MID$(B$,A%,1))-1
      IF B%=61 OR B%=64:A$=LEFT$(A$,A%-1)+CHR$(B%EOR125)+MID$(A$,A%+1):REM @ =
+
       IF B%>0:B$=LEFT$(B$,A%-1)+MID$(A$+"_",(B%EOR1)+1,1)+MID$(B$,A%+1)
      IF B%=35 OR B%=63:A$=LEFT$(A$,A%-1)+CHR$(B%EOR28)+MID$(A$,A%+1) :REM # ?
+
       IF B%=0:B$=LEFT$(B$,A%-1)+"\"+MID$(B$,A%+1)
      IF B%=36 OR B%=60:A$=LEFT$(A$,A%-1)+CHR$(B%EOR24)+MID$(A$,A%+1) :REM $ <
+
     NEXT:=B$
      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===
 
===DOS and Zip/Unix/URL===
Line 91: Line 62:
 
     LOCAL A%,B%
 
     LOCAL A%,B%
 
     FOR A%=1 TO LEN A$:B%=ASCMID$(A$,A%,1)
 
     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 / \
+
       IF B%=47 OR B%=92:A$=LEFT$(A$,A%-1)+CHR$(B%EOR115)+MID$(A$,A%+1):REM Swap / \
 
     NEXT:=A$
 
     NEXT:=A$
  
Line 101: Line 72:
  
 
[[User:Jgharston|Jgharston]] 03:28, 14 January 2012 (UTC)
 
[[User:Jgharston|Jgharston]] 03:28, 14 January 2012 (UTC)
 +
[[User:Jgharston|Jgharston]] ([[User talk:Jgharston|talk]]) 06:13, 3 April 2018 (CEST)

Revision as of 06:13, 3 April 2018

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, or just leafnames - such as docs/zip or docs.zip - then the simpler conversion code here 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(B$):IF B$="":=""
   LOCAL A$,B%,A%:A$="/.#?$<^>&+@=%; "
   FOR A%=1 TO LEN B$:B%=INSTR(A$,MID$(B$,A%,1))-1
     IF B%>TRUE:B$=LEFT$(B$,A%-1)+MID$(A$+"_",(B%EOR1)+1,1)+MID$(B$,A%+1)
   NEXT:=B$

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. However, if you know that you are only dealing with leafnames, FNfn_bbczip() can be used.

   REM Convert a DOS path to a BBC path
   DEFFNfn_dosbbc(B$):IF B$="":=""
   LOCAL A$,B%,A%:A$=".\#?$<^>&+@=%; "
   FOR A%=1 TO LEN B$:B%=INSTR(A$,MID$(B$,A%,1))-1
     IF B%>0:B$=LEFT$(B$,A%-1)+MID$(A$+"_",(B%EOR1)+1,1)+MID$(B$,A%+1)
     IF B%=0:B$=LEFT$(B$,A%-1)+"/"+MID$(B$,A%+1)
   NEXT:=B$
   :
   REM Convert a BBC path to a DOS path
   DEFFNfn_bbcdos(B$):IF B$="":=""
   LOCAL A$,B%,A%:A$="./#?$<^>&+@=%; "
   FOR A%=1 TO LEN B$:B%=INSTR(A$,MID$(B$,A%,1))-1
     IF B%>0:B$=LEFT$(B$,A%-1)+MID$(A$+"_",(B%EOR1)+1,1)+MID$(B$,A%+1)
     IF B%=0:B$=LEFT$(B$,A%-1)+"\"+MID$(B$,A%+1)
   NEXT:=B$

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 Swap / \
   NEXT:=A$

See also

Jgharston 03:28, 14 January 2012 (UTC) Jgharston (talk) 06:13, 3 April 2018 (CEST)