-- file: ChollaStepListParse.mesa
-- edited by Barth, August 17, 1981 2:08 AM
-- edited by Brotz, February 26, 1982 11:31 AM
-- edited by Crowther, October 8, 1981 11:08 AM

DIRECTORY
AltoFileDefs,
Ascii,
ccD: FROM "ChollaCmdDefs",
intCommon,
inD: FROM "InteractorDefs",
opD: FROM "OperationsDefs",
ovD: FROM "OverviewDefs",
vmD: FROM "VirtualMgrDefs";

ChollaStepListParse: PROGRAM
IMPORTS ccD, intC: intCommon, vmD
EXPORTS ccD =
BEGIN

-- The general form of a step string (for now, in the Subject: field) is:
-- <Status> / <StepName> / <SpecName> ! <version> ( <name> : <value> , ... ) ; <DataName> ! <version>
--
-- for example,
-- Started Pre-Ox ! 4 (Time : 420, Temp : 30) ; Pre-Ox-Temp ! 3
--
-- blanks and comments enclosed by /’s may appear anywhere between words.
-- ! <version>, parameters, and ; <DataName> are optional.

-- more or less BNF for complete step list
-- <step list> ::= <<<step>!<noise>><CR>>*
-- <step> ::= <state>[<embedded comment>]<specification>[<data record>]
-- [<ending comment>]
-- <noise> ::= <ending comment>
-- <state> ::= [<white>]<state word>
-- <state word> ::= "Started", "InProgress", "NotStarted", "ProcessDone",
-- "Finished", "Rejected"
-- <embedded comment> ::= [<white>] "/" <char not "/" ! <CR>>* "/"
-- <specification> ::= [<white>]<name>[<version>][<parameters>]
-- <name> ::= <not white><<not white>!<white>>*<break>
-- <not white> ::= <letter>!<digit>
-- <white> ::= <white char><white char>*
-- <white char> ::= <space>!<tab>
-- <break> ::= ";" ! "!" ! "(" ! "/" ! <CR> ! ":"
-- <version> ::= [<white>] "!" [<white>] <cardinal>
-- <parameters> ::= [<white>] "(" [<parm><[<white>] "," <parm>>*] ")"
-- <parm> ::= [<white>]<name>[<white>] ":" [<white>]<value>
-- <value> ::= <any char but ")" ! "," ! <CR>>*
-- <data record> ::= [<white>] ";" [<white>]<name>[<version>]
-- <ending comment> ::= [<white>] "/" [<any char but <CR>>]
--
-- White space in a name is compressed into the canonical form of a
-- single space. Leading and trailing space is removed completely.

cherry: CHARACTER = Ascii.ControlC;

ParseStep: PUBLIC PROCEDURE [s: STRING, p: ccD.ParsedStepPtr] =
BEGIN

GetItem: PROCEDURE [st: STRING] RETURNS [v: CARDINAL] =
-- Fills in st with the next name encountered in s, and returns the version following this
-- name in v. If no valid name is found, st.length will remain 0.
BEGIN
inVersion: BOOLEAN ← FALSE;
char: CHARACTER;
st.length ← 0;
v ← 0;
UNTIL i >= end DO
SELECT char ← s[i] FROM
’; => {i ← i + 1; RETURN};
’! => inVersion ← TRUE;
’/ => IF st.length > 0 THEN RETURN
ELSE FOR i ← i + 1, i + 1 UNTIL i >= end OR s[i] = ’/ DO ENDLOOP;
’( => {p.paramIndex ← i; FOR i ← i + 1, i+1 UNTIL i >= end OR s[i] = ’) DO ENDLOOP};
IN [’0 .. ’9] =>
IF inVersion THEN v ← v * 10 + (char - ’0)
ELSE IF st.length < st.maxlength THEN {st[st.length] ← char; st.length ← st.length + 1};
IN [’a .. ’z], IN [’A .. ’Z], ’+, ’-, ’., ’$ =>
IF ~inVersion AND st.length < st.maxlength THEN
{st[st.length] ← char; st.length ← st.length + 1};
ENDCASE;
i ← i + 1;
ENDLOOP;
END; -- of GetItem --

GetStatus: PROCEDURE =
BEGIN
char: CHARACTER;
st: STRING ← [15];
st.length ← 0;
UNTIL i >= end DO
SELECT char ← s[i] FROM
’/ => {i ← i + 1; EXIT};
IN [’A .. ’Z], IN [’a .. ’z] =>
IF st.length < st.maxlength THEN {st[st.length] ← char; st.length ← st.length + 1};
ENDCASE;
i ← i + 1;
ENDLOOP;
p.status ← ccD.StringToStatus[st];
END; -- of GetStatus --

GetStepName: PROCEDURE =
-- Fills in p.stepName with the characters exclusive of *’s until the next slash.
BEGIN
st: STRING = p.stepName;
char: CHARACTER;
UNTIL i >= end DO
SELECT char ← s[i] FROM
’/ => {i ← i + 1; RETURN};
ccD.stepListMarkChar, Ascii.SP, Ascii.TAB, Ascii.ControlY => NULL;
ENDCASE =>
IF st.length < st.maxlength THEN {st[st.length] ← char; st.length ← st.length + 1};
i ← i + 1;
ENDLOOP;
END; -- of GetStepName --

i: CARDINAL ← 0;
end: CARDINAL = s.length;
p.specVersion ← p.dataVersion ← 0;
p.specName.length ← p.dataName.length ← p.stepName.length ← 0;
FOR i ← end, i - 1 UNTIL i = 0 OR s[i - 1] = opD.substringSeparator DO ENDLOOP;
p.statusIndex ← i;
p.paramIndex ← 0;
GetStatus[];
IF i >= end THEN RETURN;
GetStepName[];
p.specVersion ← GetItem[p.specName];
p.dataVersion ← GetItem[p.dataName];
END; -- of ParseStep --


StatusOfTOCEntry: PUBLIC PROCEDURE
[toc: vmD.TOCHandle, key: CARDINAL, index: vmD.TOCIndex, status: STRING] =
BEGIN
tocString: STRING ← [opD.maxTOCStringLength];
i: CARDINAL ← 0;
char: CHARACTER;
vmD.GetTOCString[toc, key, index, tocString];
FOR i ← tocString.length, i - 1 UNTIL i = 0 OR tocString[i - 1] = opD.substringSeparator
DO ENDLOOP;
status.length ← 0;
FOR i IN [i .. tocString.length) DO
SELECT char ← tocString[i] FROM
’/ => EXIT;
Ascii.SP, Ascii.TAB => NULL;
ENDCASE =>
IF status.length < status.maxlength THEN
{status[status.length] ← char; status.length ← status.length + 1};
ENDLOOP;
END; -- of StatusOfTOCEntry --


END. -- of ChollaStepListParse --