10 REM > BLib.Generic.FileIO 1.05 22Mar2008
   20 REM v1.05 22Mar2009 Optimised CDIR in FNfile()
   30 REM v1.04 22Mar2008 FNf_scan strips spaces
   40 REM v1.03 15Feb2008 Add veneer functions in f_ domain
   50 REM v1.02 28Apr2007 Added functions to FNfile on DOS, PROCcdir, FNopenout
   60 REM v1.01 07Sep2006 FNargs avoid zero page on RISC OS
   70 REM v1.00 09Aug1988 Initial version
   80 :
   90 REM General File Interface Routines
  100 REM ===============================
  110 :
  120 REM FNfile(), PROCgbpb(), FNfs are callable on Windows
  130 REM --------------------------------------------------
  140 :
  150 REM Returns file type, file info in X%!...
  160 REM --------------------------------------
  170 DEFFNfile(A$,A%):IFA%-8:IFPAGE<&FFFFF:$name%=A$:?X%=name%:X%?1=name%DIV256:=(USR&FFDD)AND&FF
  180 A$=FNf_name(A$):IFA%=255 OR A%=5:X%!14=OPENIN(A$):IFX%!14:X%!10=EXT#X%!14:CLOSE#X%!14:X%!14=&33
  190 IFA%=255:IFX%?6=0:OSCLI"LOAD """+A$+""" "+STR$~X%!2:=1
  200 IFA%=5:IFX%!14:=1 ELSE IFA%=5:=0
  210 IFA%=0:OSCLI"SAVE """+A$+""" "+STR$~X%!10+" "+STR$~X%!14:X%!10=X%!14-X%!10:=1
  220 IFA%=7:OSCLI"SAVE """+A$+""" "+STR$~PAGE+"+"+STR$~X%!10:X%!10=X%!14-X%!10:=1
  230 IFA%-8:=0
  240 IF(os%AND-24):A$="mkdir "+A$ ELSE A$="cdir "+A$
  250 IFHIMEM>&FFFF:LOCAL ERROR:ON ERROR LOCAL:=0
  260 OSCLIA$:=2
  270 :
  280 REM General OSGBPB call
  290 REM -------------------
  300 DEFPROCf_gbpb(A%,chn%,addr%,num%,ptr%)
  310 ?X%=chn%:X%!1=addr%:X%!5=num%:X%!9=ptr%:IFPAGE<&FFFFF:CALL&FFD1:ENDPROC
  320 IFA%=1ORA%=3:PTR#?X%=X%!9
  330 REPEAT:IFA%=1ORA%=2:BPUT#?X%,?X%!1 ELSE IFA%=3ORA%=4:?X%!1=BGET#?X%
  340 X%!1=X%!1+1:X%!5=X%!5-1:UNTIL(EOF#?X% AND A%>2)OR X%!5<1:ENDPROC
  350 :
  360 DEFPROCgbpb(A%,chn%,addr%,num%,ptr%)
  370 ?X%=chn%:X%!1=addr%:X%!5=num%:X%!9=ptr%:IFPAGE<&FFFFF:CALL&FFD1:ENDPROC
  380 IFA%=1ORA%=3:PTR#?X%=X%!9
  390 REPEAT:IFA%=1ORA%=2:BPUT#?X%,?X%!1 ELSE IFA%=3ORA%=4:?X%!1=BGET#?X%
  400 X%!1=X%!1+1:X%!5=X%!5-1:UNTIL(EOF#?X% AND A%>2)OR X%!5<1:ENDPROC
  410 :
  420 REM Return current disk (5), directory (6) or library (7) name
  430 REM ----------------------------------------------------------
  440 DEFFNgbpb(A%):IFPAGE>&FFFFF:=""
  450 X%!1=name%:CALL&FFD1:A%=name%+((1+?name%)AND((A%AND-2)=6)):A%?(1+?A%)=13:=$(A%+1)
  460 :
  470 REM Returns entry in current directory, or null string if at end
  480 REM ------------------------------------------------------------
  490 DEFFNf_scan(ptr%):IFPAGE>&FFFFF:=""
  500 X%!1=name%:X%!5=1:X%!9=ptr%:A%=8:CALL&FFD1:IFX%!5=1:=""
  510 A%=name%+1:A%!(A%?-1)=&D20:A%?(INSTR($A%," ")-1)=13:=$A%
  520 :
  530 DEFFNgbpb8(ptr%):IFPAGE>&FFFFF:=""
  540 X%!1=name%:X%!5=1:X%!9=ptr%:A%=8:CALL&FFD1:IFX%!5=1:=""
  550 A%=name%+1:A%!(A%?-1)=&D20:A%?(INSTR($A%," ")-1)=13:=$A%
  560 :
  570 REM OSARGS call with data.  Returns any returned data
  580 REM -------------------------------------------------
  590 DEFFNf_args(A%,Y%,ptr%):LOCAL X%,E%:IF?(TOP-3)=0:E%=Y%:Y%=0
  600 IF FALSE THEN
  610   LOCAL !&70:X%=&70:!X%=ptr%:CALL&FFDA:=!X%
  620 ELSE
  630   SYS"OS_Args",A%,Y%,ptr% TO ,,ptr%
  640   SAVE:=ptr%
  650   :
  660   DEFFNargs(A%,Y%,ptr%):LOCAL X%,E%:IF?(TOP-3)=0:E%=Y%:Y%=0
  670   IF FALSE THEN
  680     LOCAL !&70:X%=&70:!X%=ptr%:CALL&FFDA:=!X%
  690   ELSE
  700     SYS"OS_Args",A%,Y%,ptr% TO ,,ptr%
  710     SAVE:=ptr%
  720     :
  730     REM OSARGS call ignoring X, returns A
  740     REM ---------------------------------
  750     DEFFNf_argsA(A%):IF FALSE THEN
  760       LOCAL X%,Y%,E%,!&70:X%=&70:=(USR&FFDA)AND&FF
  770     ELSE
  780       SYS"OS_Args",A% TO A%
  790       SAVE:=A%
  800       :
  810       DEFFNargsA(A%):IF FALSE THEN
  820         LOCAL X%,Y%,E%,!&70:X%=&70:=(USR&FFDA)AND&FF
  830       ELSE
  840         SYS"OS_Args",A% TO A%
  850         SAVE:=A%
  860         :
  870         REM Get current filing system number
  880         REM --------------------------------
  890         DEFFNfs:IF(os%AND-32)=0:LOCAL A%,Y%,E%:=(USR&FFDA)AND&FF
  900         =29
  910         :
  920         REM Delete an object
  930         REM ----------------
  940         DEFPROCf_delete(A$):IF(os%AND-24):A$="del "+A$ ELSE A$="delete "+A$
  950         OSCLIA$:ENDPROC
  960         :
  970         REM Select a directory
  980         REM ------------------
  990         DEFPROCf_dir(A$):IF(os%AND-24):A$="cd "+A$ ELSE A$="dir "+A$
 1000         OSCLIA$:ENDPROC
 1010         :
 1020         REM Create a directory only if it doesn't exist
 1030         REM -------------------------------------------
 1040         DEFPROCf_cdir(A$):
 1050         IF(os%AND-24):A$="mkdir "+A$ ELSE A$="cdir "+A$
 1060         IF FALSE THEN
 1070           OSCLIA$:ENDPROC
 1080         ENDIF
 1090         LOCAL ERROR:ON ERROR LOCAL:ENDPROC
 1100         OSCLIA$
 1110         ENDPROC
 1120         :
 1130         REM Open an input file ensuring no extension
 1140         REM ----------------------------------------
 1150         DEFFNf_openin(A$)=OPENIN(FNf_name(A$))
 1160         :
 1170         REM Open an output file ensuring no extension
 1180         REM -----------------------------------------
 1190         DEFFNf_openout(A$)=OPENOUT(FNf_name(A$))
 1200         :
 1210         REM Open an update file ensuring no extension
 1220         REM -----------------------------------------
 1230         DEFFNf_openup(A$)=OPENUP(FNf_name(A$))
 1240         :
 1250         DEFFNf_name(A$):IF?(TOP-3)=0:LOCALA%,B%:REPEATB%=A%:A%=INSTR(A$,d$,A%+1):UNTILA%=0:IFINSTR(A$,".",B%)=0:A$=A$+"."
 1260         =A$