mirror of
https://github.com/microsoft/MS-DOS.git
synced 2024-11-26 07:35:47 +00:00
167 lines
6.0 KiB
Plaintext
167 lines
6.0 KiB
Plaintext
|
{$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.
|
|||
|
|