PROGRAM dirfile(input,output); {by Steve Clamage} {reads disk directory, optionally sorts it, writes it to FILES.SUB} CONST MAXNAMES = 200; {max file names in directory} SRCHF = 17; {CP/M search for first} SRCHN = 18; {CP/M search for next} SETDMA = 26; {CP/M set dma address} TYPE NAMEREC = record name : string[12]; ext : string[3]; end; SORTTYPE = (NOSORT, BYFILE, BYEXTN); VAR i, loc, nfiles : INTEGER; leader, trailer : STRING; fname : STRING; extn : STRING[3]; store : array [0 .. MAXNAMES] of NAMEREC; sentinel : NAMEREC; fcb : array [0 .. 35] of CHAR; buf : array [0 .. 127] of CHAR; fileout : TEXT; optn : CHAR; howsort : SORTTYPE; {call BDOS} EXTERNAL FUNCTION @bdos(func, parm : INTEGER) : INTEGER; {validate file name} EXTERNAL FUNCTION cpmname(filename : STRING) : BOOLEAN; PROCEDURE getfname; {get file name into fname, extn} VAR j : INTEGER; BEGIN fname[0] := chr(0); extn[0] := chr(0); for j := 1 to 8 do if buf[loc+j] <> ' ' then begin fname[j] := buf[loc+j]; fname[0] := chr(j); end; for j := 9 to 11 do if buf[loc+j] <> ' ' then begin extn[j-8] := buf[loc+j]; extn[0] := chr(j-8); end; END; PROCEDURE putfname; {insert file name into output buffer} VAR {insertion sort algorithm} pos, i : INTEGER; BEGIN if (howsort = NOSORT) or (nfiles = 0) then {don't sort} pos := nfiles else if howsort = BYFILE then {insert by file name} begin pos := 0; while fname > store[pos].name do {start of this name} pos := pos + 1; while (fname = store[pos].name) and (extn > store[pos].ext) do {ext within file name} pos := pos + 1; end else if howsort = BYEXTN then {insert by extension} begin pos := 0; while extn > store[pos].ext do {start of this extention} pos := pos + 1; while (extn = store[pos].ext) and (fname > store[pos].name) do {file name within ext} pos := pos + 1; end; for i := nfiles downto pos do {make space for new entry} store[i+1] := store[i]; store[pos].name := fname; store[pos].ext := extn; nfiles := nfiles + 1; END; {main entry point} BEGIN fcb[0] := chr(0); {initialize file control block} for i := 1 to 11 do fcb[i] := '?'; for i := 12 to 35 do fcb[i] := chr(0); sentinel.name := '~~~~~~~~'; {sentinel to terminate search} sentinel.ext := '~~~'; store[0] := sentinel; repeat {ask for sorting method} writeln; write ('SORT: No sort, by Extension, by Filename (N, E, F)? '); readln(optn); if optn > 'a' then {convert to uppercase} optn := chr(ord(optn) - ord(' ')); until optn in ['N', 'E', 'F']; case optn of 'N' : howsort := NOSORT; 'E' : howsort := BYEXTN; 'F' : howsort := BYFILE; end; nfiles := 0; {number of file names} i := @bdos(SETDMA, addr(buf)); {set dma address} loc := 32 * @bdos(SRCHF, addr(fcb)); {get first file name} while loc <= 32*3 do {sort all names into store[]} begin getfname; putfname; loc := 32 * @bdos(SRCHN, addr(fcb)); {get next file name} end; writeln; write ('Leader? '); {example: B:=A: } readln(leader); write ('Trailer? '); {example: [V] } readln(trailer); {write out results} repeat write ('Output file name? '); readln(fname); until cpmname(fname); assign (fileout, fname); rewrite(fileout); for i := 0 to nfiles-1 do begin if length(store[i].ext) > 0 then fname := concat(store[i].name, '.', store[i].ext) else fname := store[i].name; writeln(fileout, leader, fname, trailer) end; close(fileout, i); writeln(nfiles, ' file names written'); END.