Difference between revisions of "Pathname translation"

From BeebWiki
Jump to: navigation, search
m (1 revision)
(Tweeked text and updated code.)
 
Line 16: Line 16:
  
 
The [http://mdfs.net/System/Library/BLib#filename Filename] library provides
 
The [http://mdfs.net/System/Library/BLib#filename Filename] library provides
platform-independant functions for converting filenames between BBC,
+
platform-independant functions for converting filenames between BBC, DOS/Windows
DOS/Windows and Unix/Zip/URL formats.
+
and Unix/Zip/URL formats.
 +
 
 +
If you know that you will only be dealing with leafnames or with simply full-canonicalised
 +
pathnames, then the simpler [[Filename translation]] code can be used.
 +
 
 
__TOC__
 
__TOC__
 
==FNfn_bbctodos(file$), FNfn_bbctounix(file$), FNfn_frombbc(file$), FNfn_tobbc(file$)==
 
==FNfn_bbctodos(file$), FNfn_bbctounix(file$), FNfn_frombbc(file$), FNfn_tobbc(file$)==
Line 150: Line 154:
 
current, root and parent directories.
 
current, root and parent directories.
  
                       BBC     DOS/Windows       UNIX/ZIP/URL
+
                       BBC       DOS/Windows     UNIX/ZIP/URL
 
  ---------------------------------------------------------------
 
  ---------------------------------------------------------------
 
  Drive                :d            d:
 
  Drive                :d            d:
Line 163: Line 167:
 
  Wild String          *            *                *
 
  Wild String          *            *                *
  
The simplest conversion is between UNIX and DOS filenames; other than the
+
The simplest conversion is between UNIX and DOS pathnames; other than the
 
'<code>'''/'''</code>' and '<code>'''\'''</code>' directory separators all
 
'<code>'''/'''</code>' and '<code>'''\'''</code>' directory separators all
 
other characters used are identical. Conversion is simply an issue of swapping
 
other characters used are identical. Conversion is simply an issue of swapping
Line 186: Line 190:
 
<code>'''"$TEMP$.$$$"'''</code> cannot be translated to a BBC filename and
 
<code>'''"$TEMP$.$$$"'''</code> cannot be translated to a BBC filename and
 
then have a perfect one-to-one mapping back to the same DOS filename.
 
then have a perfect one-to-one mapping back to the same DOS filename.
If support for such more complex filenames are needed a more advanced Filename
+
If support for such more complex pathnames are needed a more advanced Filename
 
library should be used.
 
library should be used.
  
 
==Code==
 
==Code==
       REM > BLib.Filename 1.00 25-Jan-2011
+
       REM > BLib.Filename 1.02 25-Jan-2011
       REM Convert between BBC, DOS/Windows and UNIX/ZIP filenames
+
       REM Convert between BBC, DOS/Windows and UNIX/ZIP/URL filenames
 
       REM!Keep FNfn_frombbc(), FNfn_tobbc(), FNfn_unixtodos(), FNfn_dostounix()
 
       REM!Keep FNfn_frombbc(), FNfn_tobbc(), FNfn_unixtodos(), FNfn_dostounix()
      ;Keep FNfn_frombbc(), FNfn_tobbc(), FNfn_unixtodos(), FNfn_dostounix()
 
 
       :
 
       :
       DEFFNfn_bbctodos(A$):LOCALA%,B%,H%:H%=32
+
      REM Swap between BBC and Unix/Zip filenames
       DEFFNfn_bbctounix(A$):LOCALA%,B%,H%:H%=8
+
      REM ---------------------------------------
 +
      DEFFNfn_zip(B$):LOCALB%: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$
 +
      :
 +
       DEFFNfn_bbctodos(A$):LOCALA%,B%,H%:H%=32:DEF:FNfn_frombbc()
 +
       DEFFNfn_bbctounix(A$):LOCALA%,B%,H%:H%=8:DEF:FNfn_frombbc()
 
       DEFFNfn_frombbc(A$):LOCALA%,B%,H%:H%=os%
 
       DEFFNfn_frombbc(A$):LOCALA%,B%,H%:H%=os%
       IFA$=""OR(H%AND40)=0:=A$
+
       IFA$=""OR(H%AND-24)=0:=A$
 
       IFLEFT$(A$,1)=":":A%=INSTR(A$+".","."):A$=MID$(A$,2,A%-2)+":"+MID$(A$,A%-(MID$(A$,A%+1,1)="$"))
 
       IFLEFT$(A$,1)=":":A%=INSTR(A$+".","."):A$=MID$(A$,2,A%-2)+":"+MID$(A$,A%-(MID$(A$,A%+1,1)="$"))
 
       A%=0:REPEAT:A%=A%+1:B%=ASCMID$(A$,A%,1)
 
       A%=0:REPEAT:A%=A%+1:B%=ASCMID$(A$,A%,1)
         IF(B%=35ORB%=63):A$=LEFT$(A$,A%-1)+CHR$(B%EOR28)+MID$(A$,A%+1)
+
         IFB%=35ORB%=63:A$=LEFT$(A$,A%-1)+CHR$(B%EOR28)+MID$(A$,A%+1) :REM # ?
         IFB%=ASC"$":IF(H%AND40)=8:A$=LEFT$(A$,A%-1)+"/"+MID$(A$,A%+1-(A%<>LENA$))
+
        IFB%=61ORB%=64:A$=LEFT$(A$,A%-1)+CHR$(B%EOR125)+MID$(A$,A%+1):REM = @
         IFB%=ASC"$":IF(H%AND32):A$=LEFT$(A$,A%-1)+"\"+MID$(A$,A%+1-(A%<>LENA$))
+
        IFB%=36ORB%=60:A$=LEFT$(A$,A%-1)+CHR$(B%EOR24)+MID$(A$,A%+1) :REM < $
 +
        IFB%=62ORB%=94:A$=LEFT$(A$,A%-1)+CHR$(B%EOR96)+MID$(A$,A%+1) :REM > ^
 +
         IFB%=ASC"$":IF(H%AND-24)=8:A$=LEFT$(A$,A%-1)+"/"+MID$(A$,A%+1-(A%<>LENA$))
 +
         IFB%=ASC"$":IF(H%AND-32):A$=LEFT$(A$,A%-1)+"\"+MID$(A$,A%+1-(A%<>LENA$))
 
         IFB%=ASC"@":A$=LEFT$(A$,A%-1)+"."+MID$(A$,A%+1)
 
         IFB%=ASC"@":A$=LEFT$(A$,A%-1)+"."+MID$(A$,A%+1)
 
         IFB%=ASC"^":A$=LEFT$(A$,A%-1)+".."+MID$(A$,A%+1):A%=A%+1
 
         IFB%=ASC"^":A$=LEFT$(A$,A%-1)+".."+MID$(A$,A%+1):A%=A%+1
 
         IFB%=ASC"/":A$=LEFT$(A$,A%-1)+"."+MID$(A$,A%+1)
 
         IFB%=ASC"/":A$=LEFT$(A$,A%-1)+"."+MID$(A$,A%+1)
         IFB%=ASC".":IF(H%AND40)=8:A$=LEFT$(A$,A%-1)+"/"+MID$(A$,A%+1)
+
         IFB%=ASC".":IF(H%AND-24)=8:A$=LEFT$(A$,A%-1)+"/"+MID$(A$,A%+1)
         IFB%=ASC".":IF(H%AND32):A$=LEFT$(A$,A%-1)+"\"+MID$(A$,A%+1)
+
         IFB%=ASC".":IF(H%AND-32):A$=LEFT$(A$,A%-1)+"\"+MID$(A$,A%+1)
         IFB%=ASC"\":IF(H%AND32):A$=LEFT$(A$,A%-1)+"/"+MID$(A$,A%+1)
+
         IFB%=ASC"\":IF(H%AND-32):A$=LEFT$(A$,A%-1)+"/"+MID$(A$,A%+1)
         IFB%=ASC"&":A$=LEFT$(A$,A%-1)+"%HOME%"+MID$(A$,A%+1)
+
         REM IFB%=ASC"&":A$=LEFT$(A$,A%-1)+"%HOME%"+MID$(A$,A%+1)
 
       UNTILA%>LENA$:=A$
 
       UNTILA%>LENA$:=A$
 
       :
 
       :
       DEFFNfn_fromunix(A$):IF(os%AND40)=8:=A$ ELSE IF(os%AND40)=0:=FNfn_unixtobbc(A$)
+
       DEFFNfn_fromunix(A$):IF(os%AND-24)=8:=A$ ELSE IF(os%AND-24)=0:=FNfn_unixtobbc(A$):DEF:FNfn_dostounix()
       DEFFNfn_fromdos(A$):IF(os%AND32):=A$ ELSE IF(os%AND40)=0:=FNfn_dostobbc(A$)
+
       DEFFNfn_fromdos(A$):IF(os%AND-32):=A$ ELSE IF(os%AND-24)=0:=FNfn_dostobbc(A$):DEF:FNfn_dostounix()
       DEFFNfn_tounix(A$):IF(os%AND40)=8:=A$ ELSE IF(os%AND40)=0:=FNfn_bbctounix(A$)
+
       DEFFNfn_tounix(A$):IF(os%AND-24)=8:=A$ ELSE IF(os%AND-24)=0:=FNfn_bbctounix(A$):DEF:FNfn_dostounix()
       DEFFNfn_todos(A$):IF(os%AND32):=A$ ELSE IF(os%AND40)=0:=FNfn_bbctodos(A$)
+
       DEFFNfn_todos(A$):IF(os%AND-32):=A$ ELSE IF(os%AND-24)=0:=FNfn_bbctodos(A$):DEF:FNfn_dostounix()
       DEFFNfn_unixtodos(A$)
+
       DEFFNfn_unixtodos(A$):DEF:FNfn_dostounix()
 
       DEFFNfn_dostounix(A$)
 
       DEFFNfn_dostounix(A$)
 
       IFINSTR(A$,"/")+INSTR(A$,"\")=0:=A$
 
       IFINSTR(A$,"/")+INSTR(A$,"\")=0:=A$
Line 223: Line 236:
 
       UNTILA%>=LENA$:=A$
 
       UNTILA%>=LENA$:=A$
 
       :
 
       :
       DEFFNfn_dostobbc(A$):LOCALA%,B%,H%:H%=32
+
       DEFFNfn_dostobbc(A$):LOCALA%,B%,H%:H%=32:DEF:FNfn_tobbc()
       DEFFNfn_unixtobbc(A$):LOCALA%,B%,H%:H%=8
+
       DEFFNfn_unixtobbc(A$):LOCALA%,B%,H%:H%=8:DEF:FNfn_tobbc()
 
       DEFFNfn_tobbc(A$):LOCALA%,B%,H%:H%=os%
 
       DEFFNfn_tobbc(A$):LOCALA%,B%,H%:H%=os%
       IFA$=""OR(H%AND40)=0:=A$
+
       IFA$=""OR(H%AND-24)=0:=A$
       IFA$="/":IF(H%AND40)=8:="$"
+
       IFA$="/":IF(H%AND-24)=8:="$"
       IFA$="\":IF(H%AND32):="$"
+
       IFA$="\":IF(H%AND-32):="$"
 
       A%=0:REPEAT:A%=A%+1:B%=ASCMID$(A$,A%,1)
 
       A%=0:REPEAT:A%=A%+1:B%=ASCMID$(A$,A%,1)
         IF(B%=35ORB%=63):A$=LEFT$(A$,A%-1)+CHR$(B%EOR28)+MID$(A$,A%+1)
+
         IFB%=35ORB%=63:A$=LEFT$(A$,A%-1)+CHR$(B%EOR28)+MID$(A$,A%+1):REM # ?
 
         IFMID$(A$,A%,2)="..":A$=LEFT$(A$,A%-1)+"^"+MID$(A$,A%+2):A%=A%-1:B%=0
 
         IFMID$(A$,A%,2)="..":A$=LEFT$(A$,A%-1)+"^"+MID$(A$,A%+2):A%=A%-1:B%=0
 
         IFMID$(A$,A%)=".":A$=LEFT$(A$,A%-1)+"@":B%=0
 
         IFMID$(A$,A%)=".":A$=LEFT$(A$,A%-1)+"@":B%=0
         IFMID$(A$,A%,2)="./":IF(H%AND40)=8:A$=LEFT$(A$,A%-1)+"@"+MID$(A$,A%+1):B%=0
+
         IFMID$(A$,A%,2)="./":IF(H%AND-24)=8:A$=LEFT$(A$,A%-1)+"@"+MID$(A$,A%+1):B%=0
         IFMID$(A$,A%,2)=".\":IF(H%AND32):A$=LEFT$(A$,A%-1)+"@"+MID$(A$,A%+1):B%=0
+
         IFMID$(A$,A%,2)=".\":IF(H%AND-32):A$=LEFT$(A$,A%-1)+"@"+MID$(A$,A%+1):B%=0
         IFMID$(A$,A%,6)="%HOME%":A$=LEFT$(A$,A%-1)+"&"+MID$(A$,A%+6):B%=0
+
         REM IFMID$(A$,A%,6)="%HOME%":A$=LEFT$(A$,A%-1)+"&"+MID$(A$,A%+6):B%=0
 
         IFB%=ASC".":A$=LEFT$(A$,A%-1)+"/"+MID$(A$,A%+1)
 
         IFB%=ASC".":A$=LEFT$(A$,A%-1)+"/"+MID$(A$,A%+1)
         IFB%=ASC"\":IF(H%AND32):A$=LEFT$(A$,A%-1)+"."+MID$(A$,A%+1)
+
         IFB%=ASC"\":IF(H%AND-32):A$=LEFT$(A$,A%-1)+"."+MID$(A$,A%+1)
         IFB%=ASC"/":IF(H%AND32):A$=LEFT$(A$,A%-1)+"\"+MID$(A$,A%+1)
+
         IFB%=ASC"/":IF(H%AND-32):A$=LEFT$(A$,A%-1)+"\"+MID$(A$,A%+1)
         IFB%=ASC"/":IF(H%AND40)=8:A$=LEFT$(A$,A%-1)+"."+MID$(A$,A%+1)
+
         IFB%=ASC"/":IF(H%AND-24)=8:A$=LEFT$(A$,A%-1)+"."+MID$(A$,A%+1)
 
         IFB%=ASC":":A$=":"+LEFT$(A$,A%-1)+".$"+MID$(A$,A%+1):A%=A%+2
 
         IFB%=ASC":":A$=":"+LEFT$(A$,A%-1)+".$"+MID$(A$,A%+1):A%=A%+2
 
       UNTILA%>LENA$:=A$
 
       UNTILA%>LENA$:=A$
Line 253: Line 266:
  
 
All the other functions have no external requirements.
 
All the other functions have no external requirements.
 +
 +
==Notes==
 +
The code is rather untidy and can be tidied up.
  
 
==See also==
 
==See also==
Line 261: Line 277:
  
 
''JGH, 25 April 2011''
 
''JGH, 25 April 2011''
 +
[[User:Jgharston|Jgharston]] ([[User talk:Jgharston|talk]]) 06:24, 3 April 2018 (CEST)

Latest revision as of 05:24, 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.

Examples would include:

  • a zipfile handler, filenames within zipfiles are defined to be Unix filenames, with "/" as directory separators and "." as extension separators.
  • a program generating or receiving URLs and needing to map them to/from the local filesystem. URLs are defined to be unix filenames, with "/" as directory separators and "." as extension separators.
  • a server application serving files on one platform where the client is another platform, for instance a server running on DOS/Windows serving files to a BBC client.
  • extracting or manipulating "foreign" disk images where the program wants to display file information in the format the foreign system would display it.

The Filename library provides platform-independant functions for converting filenames between BBC, DOS/Windows and Unix/Zip/URL formats.

If you know that you will only be dealing with leafnames or with simply full-canonicalised pathnames, then the simpler Filename translation code can be used.

FNfn_bbctodos(file$), FNfn_bbctounix(file$), FNfn_frombbc(file$), FNfn_tobbc(file$)

These functions convert BBC filenames to other formats. FNfn_frombbc() converts a BBC filename to the format of the local platform, FNfn_tobbc() converts a local filename to a BBC filename; both according to the setting of os%.

Examples include:

 FNfn_bbctodos("$.docs.letters/cv")  ->  \docs\letters.cv
 FNfn_bbctodos("^.info##")           ->  ..\info??
 FNfn_bbctodos(":A.text.why?")       ->  A:\text\why#
 
 FNfn_bbctounix("$.docs.letters/cv") ->  /docs/letters.cv
 FNfn_bbctounix("^.info##")          ->  ../info??
 FNfn_bbctounix(":A.text.why?")      ->  A:/text/why#

If running on BBC/RISC OS:

 FNfn_frombbc("$.docs.letters/cv")   ->  $.docs.letters/cv
 FNfn_frombbc("^.info##")            ->  ^.info##
 FNfn_frombbc(":A.text.why?")        ->  :A.text.why?
 
 FNfn_tobbc("$.docs.letters/cv")     ->  $.docs.letters/cv
 FNfn_tobbc("^.info##")              ->  ^.info##
 FNfn_tobbc(":A.text.why?")          ->  :A.text.why?

If running on DOS/Windows:

 FNfn_frombbc("$.docs.letters/cv")   ->  \docs\letters.cv
 FNfn_frombbc("^.info##")            ->  ..\info??
 FNfn_frombbc(":A.text.why?")        ->  A:\text\why#
 
 FNfn_tobbc("\docs\letters.cv")      ->  $.docs.letters/cv
 FNfn_tobbc("..\info??")             ->  ^.info##
 FNfn_tobbc("A:\text\why#")          ->  :A.text.why?

If running on UNIX:

 FNfn_frombbc("$.docs.letters/cv")   ->  /docs/letters.cv
 FNfn_frombbc("^.info##")            ->  ../info??
 FNfn_frombbc(":A.text.why?")        ->  A:/text/why#
 
 FNfn_tobbc("/docs/letters.cv")      ->  $.docs.letters/cv
 FNfn_tobbc("../info??")             ->  ^.info##
 FNfn_tobbc("A:/text/why#")          ->  :A.text.why?

FNfn_dostobbc(file$), FNfn_dostounix(file$), FNfn_fromdos(file$), FNfn_todos(file$)

These functions convert DOS/Windows filenames to other formats. FNfn_fromdos() converts a DOS/Windows filename to the format of the local platform, FNfn_todos() converts a local filename to a DOS/Windows filename; both according to the setting of os%.

Examples include:

 FNfn_dostobbc("\docs\letters.cv")   ->  $.docs.letters/cv
 FNfn_dostobbc("..\info??")          ->  ^.info##
 FNfn_dostobbc("A:\text\why#")       ->  :A.text.why?
 
 FNfn_dostounix("\docs\letters.cv")  ->  /docs/letters.cv
 FNfn_dostounix("..\info??")         ->  ../info??
 FNfn_dostounix("A:\text\why#")      ->  A:/text/why#

If running on BBC/RISC OS:

 FNfn_fromdos("\docs\letters.cv")    ->  $.docs.letters/cv
 FNfn_fromdos("..\info??")           ->  ^.info##
 FNfn_fromdos("A:\text\why#")        ->  :A.text.why?
 
 FNfn_todos("$.docs.letters/cv")     ->  \docs\letters.cv
 FNfn_todos("^.info##")              ->  ..\info??
 FNfn_todos(":A.text.why?")          ->  A:\text\why#

If running on DOS/Windows:

 FNfn_fromdos("\docs\letters.cv")    ->  \docs\letters/cv
 FNfn_fromdos("..\info??")           ->  ..\info??
 FNfn_fromdos("A:\text\why#")        ->  A:\text\why?
 
 FNfn_todos("\docs\letters.cv")      ->  \docs\letters.cv
 FNfn_todos("..\info??")             ->  ..\info??
 FNfn_todos("A:\text\why#")          ->  A:\text\why#

If running on UNIX:

 FNfn_fromdos("\docs\letters.cv")    ->  /docs/letters.cv
 FNfn_fromdos("..\info??")           ->  ../info??
 FNfn_fromdos("A:\text\why#")        ->  A:/text/why#
 
 FNfn_todos("/docs/letters.cv")      ->  \docs\letters.cv
 FNfn_todos("../info??")             ->  ..\info??
 FNfn_todos("A:/text/why#")          ->  A:\text\why#

FNfn_unixtobbc(file$), FNfn_unixtodos(file$), FNfn_fromunix(file$), FNfn_tounix(file$)

These functions convert UNIX/ZIP/URL filenames to other formats. FNfn_fromunix() converts a UNIX/ZIP/URL filename to the format of the local platform, FNfn_tounix() converts a local filename to a UNIX/ZIP/URL filename; both according to the setting of os%.

Examples include:

 FNfn_unixtobbc("/docs/letters.cv")  ->  $.docs.letters/cv
 FNfn_unixtobbc("../info??")         ->  ^.info##
 FNfn_unixtobbc("A:/text/why#")      ->  :A.text.why?
 
 FNfn_unixtodos("\docs\letters.cv")  ->  \docs\letters.cv
 FNfn_unixtodos("..\info??")         ->  ..\info??
 FNfn_unixtodos("A:\text\why#")      ->  A:\text\why#

If running on BBC/RISC OS:

 FNfn_fromunix("/docs/letters.cv")   ->  $.docs.letters/cv
 FNfn_fromunix("../info??")          ->  ^.info##
 FNfn_fromunix("A:/text/why#")       ->  :A.text.why?
 
 FNfn_tounix("$.docs.letters/cv")    ->  /docs/letters.cv
 FNfn_tounix("^.info##")             ->  ../info??
 FNfn_tounix(":A.text.why?")         ->  A:/text/why#

If running on DOS/Windows:

 FNfn_fromunix("/docs/letters.cv")   ->  \docs\letters/cv
 FNfn_fromunix("../info??")          ->  ..\info??
 FNfn_fromunix("A:/text/why#")       ->  A:\text\why?
 
 FNfn_tounix("\docs\letters.cv")     ->  /docs/letters.cv
 FNfn_tounix("..\info??")            ->  ../info??
 FNfn_tounix("A:\text\why#")         ->  A:/text/why#

If running on UNIX:

 FNfn_fromunix("/docs/letters.cv")   ->  /docs/letters.cv
 FNfn_fromunix("../info??")          ->  ../info??
 FNfn_fromunix("A:/text/why#")       ->  A:/text/why#
 
 FNfn_tounix("/docs/letters.cv")      ->  /docs/letters.cv
 FNfn_tounix("../info??")             ->  ../info??
 FNfn_tounix("A:/text/why#")          ->  A:/text/why#

Technical information

Different platforms use different characters to indicate different filename components such as directory and extension separators, drive specifiers, current, root and parent directories.

                      BBC        DOS/Windows      UNIX/ZIP/URL
---------------------------------------------------------------
Drive                 :d            d:
Directory separator   .             \                /
Extension separator   /             .                .
Root directory        $             \                /
Parent directory      ^             ..               ..
Current Directory     @             .                .
Library Directory     %             
User Directory        &             %USERPROFILE%    $HOME$
Wild Character        #             ?                ?
Wild String           *             *                *

The simplest conversion is between UNIX and DOS pathnames; other than the '/' and '\' directory separators all other characters used are identical. Conversion is simply an issue of swapping '/' and '\' characters.

The BBC uses '#' as a single-character wildcard, DOS and UNIX use '?'. Conversely, on the BBC '?' is an ordinary character and on DOS and UNIX '#' is an ordinary character, so thay are swapped.

The BBC uses '.' as a directory separator and '/' as an extension separator; DOS and UNIX use '.' as an extension separator, DOS uses '\' as a directory separator and UNIX uses '/'. '.' and '/' are swapped when converting between BBC and UNIX. BBC '.', '\', '/' are swapped with DOS '\', '/', '.' when converting between BBC and DOS.

The functions in this library do not provide a perfect translation mapping, the BBC has more illegal filename characters than other platforms which makes a bidirection mapping difficult. For example, the DOS filename "$TEMP$.$$$" cannot be translated to a BBC filename and then have a perfect one-to-one mapping back to the same DOS filename. If support for such more complex pathnames are needed a more advanced Filename library should be used.

Code

     REM > BLib.Filename 1.02 25-Jan-2011
     REM Convert between BBC, DOS/Windows and UNIX/ZIP/URL filenames
     REM!Keep FNfn_frombbc(), FNfn_tobbc(), FNfn_unixtodos(), FNfn_dostounix()
     :
     REM Swap between BBC and Unix/Zip filenames
     REM ---------------------------------------
     DEFFNfn_zip(B$):LOCALB%: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$
     :
     DEFFNfn_bbctodos(A$):LOCALA%,B%,H%:H%=32:DEF:FNfn_frombbc()
     DEFFNfn_bbctounix(A$):LOCALA%,B%,H%:H%=8:DEF:FNfn_frombbc()
     DEFFNfn_frombbc(A$):LOCALA%,B%,H%:H%=os%
     IFA$=""OR(H%AND-24)=0:=A$
     IFLEFT$(A$,1)=":":A%=INSTR(A$+".","."):A$=MID$(A$,2,A%-2)+":"+MID$(A$,A%-(MID$(A$,A%+1,1)="$"))
     A%=0:REPEAT:A%=A%+1:B%=ASCMID$(A$,A%,1)
       IFB%=35ORB%=63:A$=LEFT$(A$,A%-1)+CHR$(B%EOR28)+MID$(A$,A%+1) :REM # ?
       IFB%=61ORB%=64:A$=LEFT$(A$,A%-1)+CHR$(B%EOR125)+MID$(A$,A%+1):REM = @
       IFB%=36ORB%=60:A$=LEFT$(A$,A%-1)+CHR$(B%EOR24)+MID$(A$,A%+1) :REM < $
       IFB%=62ORB%=94:A$=LEFT$(A$,A%-1)+CHR$(B%EOR96)+MID$(A$,A%+1) :REM > ^
       IFB%=ASC"$":IF(H%AND-24)=8:A$=LEFT$(A$,A%-1)+"/"+MID$(A$,A%+1-(A%<>LENA$))
       IFB%=ASC"$":IF(H%AND-32):A$=LEFT$(A$,A%-1)+"\"+MID$(A$,A%+1-(A%<>LENA$))
       IFB%=ASC"@":A$=LEFT$(A$,A%-1)+"."+MID$(A$,A%+1)
       IFB%=ASC"^":A$=LEFT$(A$,A%-1)+".."+MID$(A$,A%+1):A%=A%+1
       IFB%=ASC"/":A$=LEFT$(A$,A%-1)+"."+MID$(A$,A%+1)
       IFB%=ASC".":IF(H%AND-24)=8:A$=LEFT$(A$,A%-1)+"/"+MID$(A$,A%+1)
       IFB%=ASC".":IF(H%AND-32):A$=LEFT$(A$,A%-1)+"\"+MID$(A$,A%+1)
       IFB%=ASC"\":IF(H%AND-32):A$=LEFT$(A$,A%-1)+"/"+MID$(A$,A%+1)
       REM IFB%=ASC"&":A$=LEFT$(A$,A%-1)+"%HOME%"+MID$(A$,A%+1)
     UNTILA%>LENA$:=A$
     :
     DEFFNfn_fromunix(A$):IF(os%AND-24)=8:=A$ ELSE IF(os%AND-24)=0:=FNfn_unixtobbc(A$):DEF:FNfn_dostounix()
     DEFFNfn_fromdos(A$):IF(os%AND-32):=A$ ELSE IF(os%AND-24)=0:=FNfn_dostobbc(A$):DEF:FNfn_dostounix()
     DEFFNfn_tounix(A$):IF(os%AND-24)=8:=A$ ELSE IF(os%AND-24)=0:=FNfn_bbctounix(A$):DEF:FNfn_dostounix()
     DEFFNfn_todos(A$):IF(os%AND-32):=A$ ELSE IF(os%AND-24)=0:=FNfn_bbctodos(A$):DEF:FNfn_dostounix()
     DEFFNfn_unixtodos(A$):DEF:FNfn_dostounix()
     DEFFNfn_dostounix(A$)
     IFINSTR(A$,"/")+INSTR(A$,"\")=0:=A$
     LOCAL A%,B%:A%=0:REPEAT:A%=A%+1:B%=ASCMID$(A$,A%,1):IFB%=ASC"/"ORB%=ASC"\":A$=LEFT$(A$,A%-1)+CHR$(B%EOR115)+MID$(A$,A%+1)
     UNTILA%>=LENA$:=A$
     :
     DEFFNfn_dostobbc(A$):LOCALA%,B%,H%:H%=32:DEF:FNfn_tobbc()
     DEFFNfn_unixtobbc(A$):LOCALA%,B%,H%:H%=8:DEF:FNfn_tobbc()
     DEFFNfn_tobbc(A$):LOCALA%,B%,H%:H%=os%
     IFA$=""OR(H%AND-24)=0:=A$
     IFA$="/":IF(H%AND-24)=8:="$"
     IFA$="\":IF(H%AND-32):="$"
     A%=0:REPEAT:A%=A%+1:B%=ASCMID$(A$,A%,1)
       IFB%=35ORB%=63:A$=LEFT$(A$,A%-1)+CHR$(B%EOR28)+MID$(A$,A%+1):REM # ?
       IFMID$(A$,A%,2)="..":A$=LEFT$(A$,A%-1)+"^"+MID$(A$,A%+2):A%=A%-1:B%=0
       IFMID$(A$,A%)=".":A$=LEFT$(A$,A%-1)+"@":B%=0
       IFMID$(A$,A%,2)="./":IF(H%AND-24)=8:A$=LEFT$(A$,A%-1)+"@"+MID$(A$,A%+1):B%=0
       IFMID$(A$,A%,2)=".\":IF(H%AND-32):A$=LEFT$(A$,A%-1)+"@"+MID$(A$,A%+1):B%=0
       REM IFMID$(A$,A%,6)="%HOME%":A$=LEFT$(A$,A%-1)+"&"+MID$(A$,A%+6):B%=0
       IFB%=ASC".":A$=LEFT$(A$,A%-1)+"/"+MID$(A$,A%+1)
       IFB%=ASC"\":IF(H%AND-32):A$=LEFT$(A$,A%-1)+"."+MID$(A$,A%+1)
       IFB%=ASC"/":IF(H%AND-32):A$=LEFT$(A$,A%-1)+"\"+MID$(A$,A%+1)
       IFB%=ASC"/":IF(H%AND-24)=8:A$=LEFT$(A$,A%-1)+"."+MID$(A$,A%+1)
       IFB%=ASC":":A$=":"+LEFT$(A$,A%-1)+".$"+MID$(A$,A%+1):A%=A%+2
     UNTILA%>LENA$:=A$
     :

Requirements and Dependancies

The FNfn_from*() and FNfn_to*() functions require the global variable os% set to the host the program is running on, such as by calling FNOS_GetEnv in the ProgEnv library or with

   A%=0:X%=1:os%=((USR&FFF4)AND&FF00)DIV256

All the other functions have no external requirements.

Notes

The code is rather untidy and can be tidied up.

See also

JGH, 25 April 2011 Jgharston (talk) 06:24, 3 April 2018 (CEST)