10 REM >XTree/src v1.17 29-Jul-2007
   20 REM Tidier display of directory tree
   30 REM Will also give individual directory sizes
   40 REM (C) J.G.Harston
   50 REM 12-Aug-1998 v1.14 JGH: New cmd line, Date checked, shows last update
   60 REM             v1.15 JGH: Single-line output
   70 REM 12-Sep-2005 v1.16 JGH: Bugfix - raFS returns GBPB8 wrongly
   80 REM 29-Jul-2007 v1.17 JGH: Now uses Make system, tidier options, grain
   90 REM                        size option, sets exit value, gets dir size
  100 :
  110 DIM ctrl% 31,name% 31,ch% 39:A$=FNOS_GetEnv:X%=ctrl%:Y%=X%DIV256
  120 :
  130 IFA$="":INPUT"Path to show: "path$:IFINSTR(path$," -"):A$=path$
  140 IFA$="":INPUT"Show files? "S$:INPUT"Show info? "I$:INPUT"Printer chars? "P$:A$=path$+FNx("f",S$)+FNx("i",I$)+FNx("p",P$)
  150 :
  160 in%=0:csd%=0:quit$=FNcl(" -q",1):ON ERROR REPORT:PRINT:PROCend(ERR):END
  170 IFFNcl("-?",0):PRINT"Syntax: ETree [-apps] [-count] [-files] [-grain <size>] [-info] [-list] [-mask <mask>] [-print] path":PROCend(0)
  180 Aflg%=FNcl("-a",0):Cflg%=FNcl("-c",0):Fflg%=FNcl("-f",0)
  190 Iflg%=FNcl("-i",0):Lflg%=FNcl("-l",0):Pflg%=FNcl("-p",0)
  200 gran%=VALFNcl("-g",1):IFgran%=0:gran%=256
  210 mask%=0:S$=FNcl("-m",1):IFS$<>"":mask%=EVAL(S$)
  220 :
  230 A$=FNcl("",0):csd%=FNfs_RdCSD:fs$="":A%=INSTR(A$,":"):IFA%>1:fs$=LEFT$(A$,A%-1):A$=MID$(A$,A%+1)
  240 path$=A$:OSCLIfs$:up%=(FNfile("^",5)AND-2)=2:IFFNfs<>16:IFmask%=0:mask%=&3B
  250 ::REM:: IF NOTup%:IF INSTR(path$,"$")+INSTR(path$,"&")+INSTR(path$,"%")=0:PRINT"Needs a root reference":PROCend(190)
  260 IFpath$<>"":IF(FNfile(path$,5)AND-2)<>2:PRINTpath$" is not a directory":PROCend(190)
  270 :
  280 PROCch(Pflg%):mask%=(mask%AND&FF)OR&300:IFpath$<>"":OSCLI"Dir "+path$
  290 IFNOTLflg%:IFFNfile("$",5)=2:IFX%!2:*INFO $
  300 IFNOTLflg%:PRINT"Disk: "FNgbpb(5)'"Dir: "FNgbpb(6)
  310 ?ch%=32:total%=FNcat(0,0,0):IFNOTLflg%:PRINT'"Total disk space used: ";total%" bytes";
  320 IFCflg%:PRINT" - "FNk(total%) ELSE IFNOTLflg%:PRINT
  330 PROCend(0):END
  340 :
  350 DEFPROCend(E%):in%=in%:IFin%:A%=in%:in%=0:CLOSE#A%
  360 PROCfs_WrCSD(csd%):PROCexit(E%):END
  370 ENDPROC
  380 :
  390 DEFFNcat(lv%,idx%,count%):LOCAL end%,total%,index%,first%,f$
  400 index%=idx%:total%=0:xt%=0:first%=TRUE
  410 REM If idx%=0, we're doing the whole dir.
  420 REM If idx%<>0, we're looking for next entry
  430 REPEAT
  440   IFFNfs=142:SYS "OS_GBPB",9,"@",name%,1,index%,32,0 TO ,,,end%,index%:end%=1-end%:SYS "OS_WriteN",name% TO f$ ELSE f$=FNgbpb8(index%):index%=X%!9:end%=X%?5
  450 IFend%=0 AND idx%<>0 AND Fflg%:UNTIL TRUE:=TRUE
  460 IFend%=0:PROCfile(idx%)
  470 UNTILend%<>0 OR xt%:IFidx%<>0:=xt%
  480 =total%
  490 :
  500 DEFPROCfile(idx%):LOCAL type%:xt%=FALSE:IFASCf$=46:ENDPROC
  510 type%=FNfile("@."+f$,5):load%=X%!2:exec%=X%!6:size%=X%!10:attr%=X%?14
  520 mdate%=X%!15:IFFNfs=5:IFFNNetFS_Op(18,CHR$64+f$)=0:mdate%=X%!10
  530 IFtype%=2:IFos%<>6:IFFNfs=5:in%=OPENIN(f$):IFin%:A%=FNNetFS_Op(12,CHR$(FNargs(&80,in%,2^(in%-32))AND&FF)+CHR$2):size%=(X%!4)AND&FFFFFF:CLOSE#in%:in%=0
  540 attr%=attr%+(type%-1)*256:total%=(total%+size%+gran%-1)AND-gran%
  550 IFidx%<>0 AND (type%=2 OR Fflg%):xt%=TRUE:ENDPROC
  560 IFNOTcount% AND (Fflg% OR Lflg% OR type%=2):PROCpr(f$):first%=FALSE
  570 IFtype%=2 AND(LEFT$(f$,1)<>"!" OR Aflg%=0):PROCdown(f$):total%=total%+FNcat(lv%+1,0,count%):PROCup(f$)
  580 ENDPROC
  590 :
  600 DEFPROCpr(f$):LOCAL oldFflg%
  610 IFNOTLflg%:PROCtree ELSE PRINTpath$".";
  620 PRINTf$;:IFIflg% AND (NOTLflg% OR (Lflg% AND Fflg%)):PRINTSPC(34-POS+10*Cflg%)FNh0(load%,8)" "FNh0(exec%,8)" "FNh0(size%,6); ELSE IFIflg%:PRINTSPC(56-POS+10*Cflg%);
  630 IFIflg%:PRINT" "FNat(attr%ANDmask%)" ";:IFNOTLflg%OR(Lflg%ANDFflg%):PRINTFNdate(mdate%);
  640 :
  650 
  660 REM Iflg - info      ------\
  670 REM Fflg - files/full----\ !
  680 REM Lflg - list      --\ ! !
  690 REM                    0 0 0  tree, dirs
  700 REM                    0 0 1  tree, dirs, full info
  710 REM                    0 1 0  tree, files
  720 REM                    0 1 1  tree, files, full info
  730 REM                    1 0 0  list, files
  740 REM                    1 0 1  list, files, access info
  750 REM                    1 1 0  list, files
  760 REM                    1 1 1  list, files, full info
  770 :
  780 
  790 IFCflg%:PRINTSPC((30-POS)ANDNOTIflg%-Iflg%);:IFtype%=2:oldFflg%=Fflg%:Fflg%=TRUE:PROCdown(f$):PRINTFNk(FNcat(lv%,0,TRUE));:Fflg%=oldFflg%:PROCup(f$) ELSE IFCflg%:PRINTFNk(size%);
  800 PRINT:ENDPROC
  810 :
  820 DEFPROCtree
  830 nxt%=FNcat(lv%,index%,0)
  840 IFnxt%:ch%?lv%=c%(3) ELSE ch%?lv%=32
  850 IFlv%>1:FORz%=0TOlv%-2:VDU ch%?z%,32:NEXT:VDU ch%?z% ELSE IFlv%=1:VDU?ch%
  860 IFfirst% AND lv%>0:VDU c%(4) ELSE IFlv%>0:VDU32
  870 VDUc%((nxt%AND1)OR((NOTfirst%OR(lv%=0))AND4))
  880 ENDPROC
  890 :
  900 DEFPROCdown(f$):path$=path$+"."+f$:OSCLI"DIR "+f$:ENDPROC
  910 :
  920 DEFPROCup(f$):path$=LEFT$(path$,LEN path$-LEN f$-1)
  930 IFup%:OSCLI"DIR ^":ENDPROC
  940 OSCLI"DIR "+path$:ENDPROC
  950 :
  960 DEFPROCch(pc8%)
  970 DIM c%(5):FOR z%=0 TO 5:c%(z%)=z%+166:NEXT
  980 IFpc8%:c%(0)=&C4:c%(1)=&C2:c%(2)=&FE:c%(3)=&B3:c%(4)=&C0:c%(5)=&C3
  990 VDU23,c%(0),0,0,0,255,0,0,0,0        :REM ---
 1000 VDU23,c%(1),0,0,0,255,24,24,24,24    :REM -v-
 1010 VDU23,c%(3),24,24,24,24,24,24,24,24  :REM  |
 1020 VDU23,c%(4),24,24,24,24+7,0,0,0,0    :REM \
 1030 VDU23,c%(5),24,24,24,24+7,24,24,24,24:REM +-
 1040 ENDPROC
 1050 :
 1060 DEFFNat(A%):LOCAL a$
 1070 IF(A%AND128):a$="P"
 1080 IF(A%AND8):a$=a$+"L"
 1090 IF(A%AND&100):a$="D"+a$+"/":=a$+STRING$(7-LEN a$," ")
 1100 IF(A%AND6)=2:a$=a$+"W"
 1110 IF(A%AND4):a$=a$+"E"
 1120 IF(A%AND5)=1:a$=a$+"R"
 1130 a$=a$+"/"
 1140 IF(A%AND96)=32:a$=a$+"W"
 1150 IF(A%AND64):a$=a$+"E"
 1160 IF(A%AND80)=16:a$=a$+"R"
 1170 =a$+STRING$(7-LEN a$," ")
 1180 :
 1190 DEFFNdate(A%):=FNd0(A%AND31,2)+"/"+FNd0((A%AND&F00)DIV256,2)+"/"+FNd0(1981+(A%AND&F000)DIV&1000+(A%AND&E0)DIV2,4)
 1200 :
 1210 DEFFNk(A%):IFA%>4100:=RIGHT$("    "+STR$(A%DIV1024),5)+"K" ELSE =RIGHT$("    "+STR$ A%,5)+" bytes"
 1220 :
 1230 DEFFNx(o$,v$):IFLEFT$(v$,1)="Y"ORLEFT$(v$,1)="y":=" -"+o$ ELSE =""
 1240 :