MS-DOS/v2.0/bin/FILBP.PAS

167 lines
6.0 KiB
Plaintext
Raw Normal View History

1983-08-13 01:53:34 +01:00
{$title: 'Command Line Filename Parser' $linesize:79}
MODULE parse; {$debug- $stackck+}
{ command line filename parsing; Bob Wallace Microsoft 7/81 }
CONST maxfile = 32; {NOTE: must be set same as caller}
dfprf = 'PRF';
msprf = 'Profile filename [';
dfhst = 'HST';
mshst = 'Histogram filename [';
dfmap = 'MAP';
msmap = 'Map file [';
nuln = 'NUL ';
TYPE
filenam = lstring (maxfile); {filename parameter type}
setsw = ARRAY [wrd(0)..3] OF byte; {switches parameter type}
sets = set of 0..31; {caller's parameter type}
setc = set of chr(0)..chr(127); {set of characters}
cpmex = string (3); cpmnm = string (8);
cpmfn = RECORD
cfd [0]: string (2);
cfn [2]: cpmnm; cfp [10]: char; cfe [11]: cpmex;
END;
setbitt = ARRAY [wrd(0)..7] OF byte;
CONST setbit = setbitt (128, 64, 32, 16, 8, 4, 2, 1);
VAR idset:setc; VALUE idset:=setc ['A'..'Z','a'..'z','0'..'9',
'$', '&', '#', '@', '!', '%', '-', '_', '`', '''',
'(', ')', '<', '>', '{', '}', '\', '^', '~', '|'];
VAR drset:setc; VALUE drset:=setc ['A'..'O','a'..'o'];
PROCEDURE fillc (dst: adrmem; len: word; chc: char); extern;
PROCEDURE movel (prf: adrmem; dst: adrmem; len: word); extern;
PROCEDURE ptyuqq (len: word; prf: adsmem); extern;
PROCEDURE plyuqq; extern;
FUNCTION gtyuqq (len: word; dst: adsmem): word; extern;
PROCEDURE filbm
(VAR prffil,hstfil,mapfil: filenam; VAR oldsw: setsw);
(* sets the filenames for source, hstect, listing, and second
listing (hstect list or cross ref); also sets any switches,
allowing those in the oldsw set and returning them in oldsw *)
VAR prf, hst, map: cpmfn; {target filenames in CPM format}
newsw: setsw; {new switches, return in oldsw}
qq: lstring (128); iq: word; {command line, current index}
pqq: ads of lstring (128); {address CPM-type command line}
cesxqq [extern]: word; {segment val}
c: char; l: word; iscomma: boolean; i: word; {other stuff}
FUNCTION parchr (ch: char): boolean; {true iff CH found}
BEGIN
parchr := (iq <= qq.len) AND (qq [iq] = ch);
IF result (parchr) THEN iq := iq+1;
END;
FUNCTION upperc: char; {return current char, in upper case}
BEGIN
upperc := qq[iq];
IF result (upperc) >= 'a'
THEN upperc := chr (ord (result (upperc)) - 32);
END;
PROCEDURE blanks; {skip blanks and set any switches}
BEGIN
WHILE parchr (' ') DO {nothing};
IF parchr ('/') THEN
BEGIN
IF (iq <= qq.len)
AND THEN (ord (upperc) - 64) IN retype (sets, oldsw)
THEN
BEGIN
i := wrd (upperc) - 64; iq := iq + 1;
newsw[i DIV 8] := newsw[i DIV 8] OR setbit[i MOD 8];
blanks; {recurse for more}
END
ELSE iq := iq - 1; {put "/" back on line to get error}
END;
END;
FUNCTION parset (VAR dst: string; CONST chs: setc): boolean;
(* Move characters from qq to DST as long as they are in CHS
Deletes from qq, blanks DST, returns true if any moved *)
VAR i: word;
BEGIN
fillc (adr dst, wrd (upper (dst)), ' '); parset := false;
FOR i := 1 TO wrd (upper (dst)) DO
IF (iq > qq.len) OR ELSE NOT (qq [iq] IN chs)
THEN BREAK
ELSE
BEGIN
dst [i] := upperc; parset := true; iq := iq + 1;
END;
END;
FUNCTION filenm (CONST prompt: string; VAR nam: filenam;
VAR fcb: cpmfn; defext: cpmex): boolean;
(* Get a filename into the FCB, setting defaults as
appropriate; return true iff a filename found *)
VAR i: word; p: adrmem; defile: cpmnm;
BEGIN
blanks;
IF iscomma THEN defile := prf.cfn ELSE defile := nuln;
IF iq > qq.len THEN
BEGIN
ptyuqq (wrd (upper (prompt)), ads prompt);
FOR i := 1 TO 8 DO
IF defile [i] <> ' ' THEN ptyuqq (1, ads defile [i]);
ptyuqq (1, ads '.'); ptyuqq (3, ads defext);
ptyuqq (3, ads ']: ');
qq.len := gtyuqq (upper (qq), ads qq [1]); iq := 1;
END;
fcb.cfp := '.';
IF (iq < qq.len) AND (qq [iq+1] = ':')
AND THEN parset (c, drset)
THEN
BEGIN
fcb.cfd[1] := c; fcb.cfd[2] := ':'; iq := iq+1;
defile := prf.cfn; {default to source name now}
END
ELSE fcb.cfd := ' ';
filenm := parset (fcb.cfn, idset);
IF parchr (':')
THEN BEGIN fcb.cfe := ': '; fcb.cfp := ' '; END
ELSE
IF parchr ('.')
THEN [eval (parset (fcb.cfe, idset)); defile := prf.cfn]
ELSE fcb.cfe := defext;
IF NOT result (filenm) THEN fcb.cfn := defile;
blanks;
nam.len := 0; p := adr fcb;
FOR i := 0 TO 13 DO IF p^[i] <> wrd (' ')
THEN [nam.len := nam.len+1; nam[nam.len] := chr (p^[i])];
END;
FUNCTION conso (CONST fn: cpmnm): boolean;
BEGIN
conso := (fn = 'CON ') OR (fn = 'USER ');
END;
BEGIN
newsw := setsw (do 4 of 0);
pqq.r := 128; pqq.s := cesxqq;
FOR i := 0 TO pqq^.len+1 DO qq[i] := pqq^[i]; iq := 1;
REPEAT
iscomma := true; prf.cfn := ' ';
IF filenm (msprf, prffil, prf, dfprf)
THEN
BEGIN
eval (parchr (','));
eval (filenm (mshst, hstfil, hst, dfhst));
iscomma := parchr (',');
eval (filenm (msmap, mapfil, map, 'map'));
blanks; eval (parchr (';')); blanks;
IF hst.cfn <> nuln THEN newsw[3] := newsw[3] OR 8;
IF map.cfn <> nuln THEN newsw[3] := newsw[3] OR 04;
IF conso (map.cfn) THEN newsw[3] := newsw[3] OR 01;
IF iq > qq.len THEN [oldsw := newsw; return];
END;
ptyuqq (15, ads 'Line invalid: '''); i := qq.len - iq + 1;
IF i > 0 THEN ptyuqq (i, ads qq [iq]);
ptyuqq (15, ads ''', start again.'); plyuqq; iq := 256;
UNTIL FALSE;
END;
END.