SBImpl.mesa
Copyright Ó 1992 by Xerox Corporation. All rights reserved.
Last Edited by Curry, April 23, 1986 7:13:15 pm PST
Don Curry April 28, 1987 3:22:55 pm PDT
Last Edited by: Don Curry May 28, 1987 11:14:23 am PDT
Kizer, April 23, 1991 2:29 pm PDT
Foote, April 28, 1992 11:24 am PDT
DIRECTORY
Basics,
Commander,
FS,
IO,
Rope,
SB;
SBImpl: CEDAR PROGRAM
IMPORTS Commander, IO, FS, Rope
EXPORTS SB =
BEGIN OPEN SB;
errorCalled: BOOLEANFALSE;
ReadLeagueFile: PUBLIC PROC[file: IO.ROPE, log: IO.STREAMIO.noWhereStream]
RETURNS[league: League] = {
ENABLE FS.Error => IF error.group = user THEN
{log.PutRope[error.explanation]; CONTINUE};
SkipColon: PROC = {[ ] ← IO.GetChar[inStm]};
key:  IO.ROPENIL;
inStm:  IO.STREAM;
fullName: IO.ROPE ← FS.ExpandName[file].fullFName;
IF (inStm ← FS.StreamOpen[fileName: fullName])=NIL THEN RETURN[NIL];
league ← NEW[LeagueRec ← [file: fullName ]];
DO
ENABLE IO.EndOfStream => EXIT;
key ← IO.GetTokenRope[inStm].token;
SELECT TRUE FROM
Rope.Equal[key, "FILE"]  => {SkipColon[]; [ ]    ← IO.GetTokenRope[inStm]};
Rope.Equal[key, "TIME"]  => {SkipColon[]; league.time ← IO.GetTime[inStm]};
Rope.Equal[key, "YEAR"]  => {SkipColon[]; league.year ← IO.GetInt[inStm]};
Rope.Equal[key, "TEAMS"]  => {SkipColon[]; teamNms  ← GenRopeSeq[inStm]};
Rope.Equal[key, "GROUPS"] => {SkipColon[]; groupNms ← GenRopeSeq[inStm]};
Rope.Equal[key, "MEMBERS"] => {[]←IO.GetLineRope[inStm]; EXIT};
ENDCASE;
ENDLOOP;
league.teamStats  ← NEW[TeamStatSeq[teamNms.size]];
league.groupCnts ← NEW[CardSeqRec[groupNms.size]];
DO
member: Member ← NIL;
member2: Member ← NIL;
done:  BOOL;
[done, member] ← GetMember[inStm];
IF done THEN EXIT;
IF member=NIL THEN LOOP;
IF member.pair=paired THEN {
[done, member2] ← GetMember[inStm];
IF done OR member2=NIL OR member2.pair=sgl THEN ERROR;
member2.sse ← member;
member.sse ← member2;
AddMember[league, member2] };
AddMember[league, member];
ENDLOOP;
inStm.Close[];
Update[league] };
CompareNames: PUBLIC PROC[first1, last1, first2, last2: IO.ROPE] RETURNS[Basics.Comparison] = {
comp: Basics.Comparison ← Rope.Compare[last1, last2, FALSE];
IF comp#equal
THENRETURN[comp]
ELSE RETURN[Rope.Compare[first1, first2, FALSE] ] };
AddMember: PUBLIC PROC[league: League, member: Member] = {
AddMem: PROC[list: LIST OF Member, mem: Member] RETURNS[LIST OF Member] = {
IF list=NIL THEN RETURN[CONS[mem, list]];
SELECT CompareNames[list.first.fname, list.first.lname, mem.fname, mem.lname] FROM
less  => {list.rest ← AddMem[list.rest, mem];  RETURN[ list ]};
greater => {            RETURN[ CONS[mem, list] ]};
ENDCASE => ERROR };
league.members ← AddMem[league.members, member]};
FindMember: PUBLIC PROC[league: League, last, first: IO.ROPE] RETURNS[member: Member] = {
FindMem: PROC[list: LIST OF Member, lname, fname: IO.ROPE] RETURNS[member: Member] = {
IF list=NIL THEN RETURN[NIL];
SELECT CompareNames[list.first.fname, list.first.lname, fname, lname] FROM
less  => RETURN[FindMem[list.rest, lname, fname] ];
greater => RETURN[NIL];
ENDCASE => RETURN[list.first] };
RETURN[ FindMem[league.members, last, first] ]} ;
FindMemberName: PUBLIC PROC [league: League, name: IO.ROPE]
RETURNS[member: Member] = {
FOR lst: LIST OF Member ← league.members, lst.rest WHILE lst#NIL DO
SELECT Rope.Compare[lst.first.lname, name] FROM
less  => LOOP;
greater => EXIT;
ENDCASE => RETURN[lst.first] ENDLOOP;
FOR lst: LIST OF Member ← league.members, lst.rest WHILE lst#NIL DO
SELECT Rope.Compare[lst.first.fname, name] FROM
less  => LOOP;
greater => LOOP;
ENDCASE => RETURN[lst.first] ENDLOOP;
RETURN[NIL]} ;
DeleteMember: PUBLIC PROC[league: League, member: Member] = {
DelMem: PROC[list: LIST OF Member, mem: Member] RETURNS[LIST OF Member] = {
IF list=NIL THEN ERROR;
IF list.first#member
THEN {list.rest ← DelMem[list.rest, mem]; RETURN[list]}
ELSERETURN[list.rest] };
league.members ← DelMem[league.members, member]};
Reverse: PROC [list: LIST OF Member] RETURNS[new: LIST OF Member] =
{FOR list ← list, list.rest WHILE list#NIL DO new ← CONS[list.first, new] ENDLOOP};
TML:  TYPE = REF TMLRec;
TMLRec: TYPE = RECORD[SEQUENCE size: Team OF LIST OF Member];
WriteTeamFile: PUBLIC PROC[league: League, log: IO.STREAMIO.noWhereStream] = {
out: IO.STREAM;
root: IO.ROPE;
teamCoaches:  TMLNEW[TMLRec[league.teamStats.size]];
teamSkeeps:  TMLNEW[TMLRec[league.teamStats.size]];
teamMembers: TMLNEW[TMLRec[league.teamStats.size]];
Update[league];
root ← league.file.Substr[len: FS.ExpandName[league.file].cp.ext.start];
out ← FS.StreamOpen[root.Concat["teams"], $create];
FOR list: LIST OF Member ← league.members, list.rest WHILE list # NIL DO
SELECT list.first.type FROM
coach  => teamCoaches[list.first.team]  ← CONS[list.first, teamCoaches[list.first.team]];
skeep  => teamSkeeps[list.first.team]  ← CONS[list.first, teamSkeeps[list.first.team]];
player => teamMembers[list.first.team] ← CONS[list.first, teamMembers[list.first.team]];
ENDCASE => Signal[] ENDLOOP;
FOR team: Team IN [0..league.teamStats.size) DO
teamCoaches[team] ← Reverse[teamCoaches[team]];
teamSkeeps[team] ← Reverse[teamSkeeps[team]];
teamMembers[team] ← Reverse[teamMembers[team]] ENDLOOP;
FOR section: NAT IN [0..2) DO
firstTeam: Team ← 1+section*league.teamStats.size/2;
out.PutRope["\n"];
FOR team: Team IN [firstTeam..firstTeam+league.teamStats.size/2) DO
IF team#firstTeam THEN out.PutRope[" "] ELSE out.PutRope["\n"];
out.PutRope[league.teamNms[team]] ENDLOOP;
PrintTML[teamCoaches, out, firstTeam, league];
PrintTML[teamSkeeps, out, firstTeam, league];
PrintTML[teamMembers, out, firstTeam, league];
ENDLOOP;
out.Close[]};
WriteTeamFileSimple: PUBLIC PROC[league: League, log: IO.STREAMIO.noWhereStream] = {
out: IO.STREAM;
root: IO.ROPE;
teamCoaches:  TMLNEW[TMLRec[league.teamStats.size]];
teamSkeeps:  TMLNEW[TMLRec[league.teamStats.size]];
teamMembers: TMLNEW[TMLRec[league.teamStats.size]];
Update[league];
root ← league.file.Substr[len: FS.ExpandName[league.file].cp.ext.start];
out ← FS.StreamOpen[root.Concat["teams2"], $create];
FOR list: LIST OF Member ← league.members, list.rest WHILE list # NIL DO
SELECT list.first.type FROM
coach  => teamCoaches[list.first.team]  ← CONS[list.first, teamCoaches[list.first.team]];
skeep  => teamSkeeps[list.first.team]  ← CONS[list.first, teamSkeeps[list.first.team]];
player => teamMembers[list.first.team] ← CONS[list.first, teamMembers[list.first.team]];
ENDCASE => Signal[] ENDLOOP;
FOR team: Team IN [0..league.teamStats.size) DO
teamCoaches[team] ← Reverse[teamCoaches[team]];
teamSkeeps[team] ← Reverse[teamSkeeps[team]];
teamMembers[team] ← Reverse[teamMembers[team]] ENDLOOP;
FOR team: Team IN [1..league.teamStats.size) DO
out.PutRope["Team: "];
out.PutRope[league.teamNms[team]];
out.PutRope["\n\nCoaches:\n"];
FOR list: LIST OF Member ← teamCoaches[team], list.rest WHILE list # NIL DO
out.PutF[" %g %g\n", IO.rope[list.first.fname], IO.rope[list.first.lname]];
ENDLOOP;
IF teamSkeeps[team] # NIL THEN out.PutRope["\nScoreKeepers:\n"] ;
FOR list: LIST OF Member ← teamSkeeps[team], list.rest WHILE list # NIL DO
out.PutF[" %g %g\n", IO.rope[list.first.fname], IO.rope[list.first.lname]];
ENDLOOP;
out.PutRope["\nPlayers:\n"];
FOR list: LIST OF Member ← teamMembers[team], list.rest WHILE list # NIL DO
out.PutF[" %g %g\n", IO.rope[list.first.fname], IO.rope[list.first.lname]];
ENDLOOP;
out.PutRope["\n\n"];
ENDLOOP;
out.Close[]};
PrintTML: PROC[tml: TML, out: IO.STREAM, firstTeam: Team, league: League] = {
DO
FOR team: Team IN [firstTeam..firstTeam+league.teamStats.size/2) DO
IF tml[team]#NIL THEN EXIT REPEAT FINISHED => EXIT ENDLOOP;
FOR team: Team IN [firstTeam..firstTeam+league.teamStats.size/2) DO
IF team#firstTeam THEN out.PutRope[" "] ELSE out.PutRope["\n"];
IF tml[team]=NIL
THENLOOP
ELSE {
member: Member ← tml[team].first;
out.PutF["%g %g", IO.rope[member.fname], IO.rope[member.lname]];
tml[team] ← tml[team].rest }
ENDLOOP;
ENDLOOP;
out.PutRope["\n"]};
WriteLeagueFiles: PUBLIC PROC[league: League, log: IO.STREAMIO.noWhereStream] = {
ENABLE FS.Error => IF error.group = user THEN
{log.PutRope[error.explanation]; CONTINUE};
out: IO.STREAM;
Update[league];
WriteTeamFile[league, log];
WriteTeamFileSimple[league, log];
out   ← FS.StreamOpen[league.file, $create];
out.PutF1  ["\nFILE: %g",  IO.rope[league.file] ];
out.PutF1  ["\nTIME: %g", IO.time[league.time] ];
out.PutF1  ["\nYEAR: %g", IO.card[league.year]];
out.PutRope ["\nTEAMS:"];
FOR team: CARDINAL IN [0..teamNms.size) DO out.PutF1[" %g", IO.rope[teamNms[team]]] ENDLOOP;
out.PutRope ["\nGROUPS:"];
FOR group: CARDINAL IN [0..groupNms.size) DO out.PutF1[" %g", IO.rope[groupNms[group]]] ENDLOOP;
out.PutRope["\n\n"];
OutJustify[out, left, "Team", league.teamMax];
out.PutRope[" males female players keeps points dIndex\n"];
FOR team: Team IN [0..league.teamStats.size) DO
out.PutRope["\n"];
OutJustify[out, left, teamNms[team], league.teamMax];
out.PutF [" %3g %3g %3g %3g",
IO.card[league.teamStats[team].males],
IO.card[league.teamStats[team].females],
IO.card[league.teamStats[team].players]];
out.PutF1 ["%3g",
IO.card[league.teamStats[team].keeps]];
out.PutF [" %3g %3g ",
IO.card[league.teamStats[team].points],
IO.card[league.teamStats[team].dIndex]];
ENDLOOP;
out.PutF1 ["\n\n %4g Score Keepers",  IO.card[league.keeps]];
out.PutF1 ["\n\n %4g Male",     IO.card[league.males]];
out.PutF1 [ "\n %4g Female",    IO.card[league.females]];
out.PutF1 ["\n\n %4g Total Players",  IO.card[league.players]];
out.PutF1 [ "\n %4g Participants",  IO.card[league.players + league.keeps]];
out.PutF1 ["\n\n %4g Paid Players", IO.card[league.paid]];
out.PutF1 [ "\n %4g Unpaid Players", IO.card[league.unpaid]];
out.PutF1 ["\n\n %4g Dollars Paid",  IO.card[league.dollarsIn]];
out.PutF1 [ "\n %4g Dollars Owed",  IO.card[league.dollarsOut]];
out.PutRope["\n\nGroup participation\n"];
FOR group: Group IN [0..league.groupCnts.size) DO
out.PutF ["\n %4g %g",
IO.card[league.groupCnts[LOOPHOLE[group]]],
IO.rope[groupNms[LOOPHOLE[group]] ] ];
ENDLOOP;
FOR list: LIST OF Member ← league.members, list.rest WHILE list # NIL DO
list.first.marked ← FALSE; ENDLOOP;
out.PutRope["\n\n\nMEMBERS:"];
FOR list: LIST OF Member ← league.members, list.rest WHILE list # NIL DO
IF list.first.marked THEN LOOP;
IF list.first.sse#NIL
THEN {
PutMember[league, list.first,  out]; list.first.marked  ← TRUE;
PutMember[league, list.first.sse, out]; list.first.sse.marked ← TRUE }
ELSE {PutMember[league, list.first, out]; list.first.marked  ← TRUE};
ENDLOOP;
out.PutRope["\nEND\n"];
out.PutRope["\n\n"];
FOR list: LIST OF Member ← league.members, list.rest WHILE list # NIL DO
list.first.marked ← FALSE; ENDLOOP;
FOR rating: Rating DECREASING IN Rating DO
out.PutF1["\n\f\n Rating = %g", IO.card[rating]];
FOR list: LIST OF Member ← league.members, list.rest WHILE list # NIL DO
IF list.first.marked OR list.first.rating#rating THEN LOOP;
IF list.first.sse#NIL
THEN {
PutMember[league, list.first,  out]; list.first.marked  ← TRUE;
PutMember[league, list.first.sse, out]; list.first.sse.marked ← TRUE }
ELSE {PutMember[league, list.first, out]; list.first.marked  ← TRUE};
ENDLOOP;
ENDLOOP;
out.PutRope["\nEND\n"];
out.Close[] };
GetMember: PROC[inStm: IO.STREAM] RETURNS[done: BOOL, member: Member] = {
Break: IO.BreakProc = {
RETURN[SELECT char FROM
IN [IO.NUL .. IO.SP], ',, ';     => sepr,
'[, '], '(, '), '{, '}, '", '+, '-, '*, '/, '@, '← => break,
ENDCASE          => other]};
Get: PROC RETURNS[rope: IO.ROPE] = {RETURN[IO.GetTokenRope[inStm, Break].token]};
AllSP: PROC[test: IO.ROPE] RETURNS[BOOL] = {
IF test=NIL THEN RETURN[FALSE];
FOR i: INT IN [0..test.Length[]) DO IF test.Fetch[i]#IO.SP THEN RETURN[FALSE] ENDLOOP;
RETURN[TRUE]};
rope: IO.ROPE;
IF IO.EndOf[inStm] THEN RETURN[TRUE, NIL];
inStm  ← IO.RIS[ IO.GetLineRope[inStm] ];
rope  ← Get[! IO.EndOfStream => rope←NIL];
IF rope=NIL THEN RETURN[FALSE, NIL];
IF Rope.Equal[rope, "END"] THEN RETURN[TRUE, NIL];
member   ← NEW[MemberRec ← [ ]];
member.lname ← rope;
member.fname ← Get[];
member.pair  ← LOOPHOLE[ RopeSeqIndex[Get[], pairNms]];
member.sex  ← LOOPHOLE[ RopeSeqIndex[Get[], sexNms]];
member.rating ← LOOPHOLE[ RopeSeqIndex[Get[], ratingNms]];
member.team  ← LOOPHOLE[ RopeSeqIndex[Get[], teamNms]];
member.type  ← LOOPHOLE[ RopeSeqIndex[Get[], typeNms]];
member.paid  ← LOOPHOLE[ RopeSeqIndex[Get[], paidNms]];
member.group ← LOOPHOLE[ RopeSeqIndex[Get[], groupNms]];
member.shirt  ← LOOPHOLE[ RopeSeqIndex[Get[], shirtNms]];
member.addr  ← Get[];
member.tnum ← Get[];
member.pos  ← Get[];
member.atten  ← Get[];
IF IO.EndOf[inStm] THEN RETURN[FALSE, member];
DO
[ ] ← IO.SkipWhitespace[inStm];
IF IO.EndOf[inStm] THEN {IF AllSP[member.comnt] THEN ERROR; RETURN[FALSE, member]};
member.comnt ← member.comnt.Cat[Get[]," "]
ENDLOOP};
GetMemberOld: PROC[inStm: IO.STREAM] RETURNS[done: BOOL, member: Member] = {
Break: IO.BreakProc = {
RETURN[SELECT char FROM
IN [IO.NUL .. IO.SP], ',, ':, ';     => sepr,
'[, '], '(, '), '{, '}, '", '+, '-, '*, '/, '@, '← => break,
ENDCASE          => other]};
Get: PROC RETURNS[rope: IO.ROPE] = {RETURN[IO.GetTokenRope[inStm, Break].token]};
AllSP: PROC[test: IO.ROPE] RETURNS[BOOL] = {
IF test=NIL THEN RETURN[FALSE];
FOR i: INT IN [0..test.Length[]) DO IF test.Fetch[i]#IO.SP THEN RETURN[FALSE] ENDLOOP;
RETURN[TRUE]};
rope: IO.ROPE;
IF IO.EndOf[inStm] THEN RETURN[TRUE, NIL];
inStm  ← IO.RIS[ IO.GetLineRope[inStm] ];
rope  ← Get[! IO.EndOfStream => {rope←NIL; CONTINUE}];
IF rope=NIL THEN RETURN[FALSE, NIL];
IF Rope.Equal[rope, "END"] THEN RETURN[TRUE, NIL];
member   ← NEW[MemberRec ← [ ]];
member.type  ← LOOPHOLE[ RopeSeqIndex[rope,         typeNms]];
member.team  ← LOOPHOLE[ RopeSeqIndex[Get[], teamNms]];
member.rating ← LOOPHOLE[ RopeSeqIndex[Get[], ratingNms]];
member.sex  ← LOOPHOLE[ RopeSeqIndex[Get[], sexNms]];
member.pair  ← LOOPHOLE[ RopeSeqIndex[Get[], pairNms]];
member.paid  ← LOOPHOLE[ RopeSeqIndex[Get[], paidNms]];
member.lname ← Get[];
member.fname ← Get[];
member.addr  ← Get[];
member.tnum ← Get[];
member.group ← LOOPHOLE[ RopeSeqIndex[Get[], groupNms]];
member.pos  ← Get[];
member.shirt  ← LOOPHOLE[ RopeSeqIndex[Get[], shirtNms]];
member.atten  ← Get[];
IF IO.EndOf[inStm] THEN RETURN[FALSE, member];
DO
[ ] ← IO.SkipWhitespace[inStm];
IF IO.EndOf[inStm] THEN {IF AllSP[member.comnt] THEN ERROR; RETURN[FALSE, member]};
member.comnt ← member.comnt.Cat[Get[]," "]
ENDLOOP};
PutMember: PROC[league: League, m: Member, out: IO.STREAM] = {
out.PutRope["\n"];
OutJustify[out, left, m.lname,          league.lnameMax];
OutJustify[out, left, m.fname,          league.fnameMax];
OutJustify[out, right, pairNms  [LOOPHOLE[m.pair  ]], league.pairMax];
OutJustify[out, right, sexNms  [LOOPHOLE[m.sex  ]], league.sexMax];
OutJustify[out, right, ratingNms [LOOPHOLE[m.rating ]], league.ratingMax];
OutJustify[out, right, teamNms  [LOOPHOLE[m.team  ]], league.teamMax];
OutJustify[out, right, typeNms  [LOOPHOLE[m.type  ]], league.typeMax];
OutJustify[out, right, paidNms  [LOOPHOLE[m.paid  ]], league.paidMax];
OutJustify[out, right, groupNms [LOOPHOLE[m.group ]], league.groupMax];
OutJustify[out, right, shirtNms  [LOOPHOLE[m.shirt  ]], league.shirtMax];
OutJustify[out, right, m.addr,          league.addrMax];
OutJustify[out, right, m.tnum,          league.tnumMax];
OutJustify[out, right, m.pos,           league.posMax];
OutJustify[out, right, m.atten,          league.attenMax];
IF m.comnt=NIL THEN RETURN;
out.PutRope[" "];
out.PutRope[m.comnt] };
Update: PUBLIC PROC[league: League] = {
maxDIndex, minTeamPts: CARDINAL ← 0;
otp: CARDINAL  ← RopeSeqIndex["OTP", groupNms];
IF otp=0 THEN ERROR; -- where is old time player?
league.time   ← BasicTime.Now[];
FOR i: Team IN [0..league.teamStats.size) DO league.teamStats[i] ← [] ENDLOOP;
FOR i: Group IN [0..league.groupCnts.size) DO league.groupCnts[i] ← 0 ENDLOOP;
league.nextDIndex ← 0;
league.nextDTeam ← 0;
league.players  ← 0;
league.keeps   ← 0;
league.males   ← 0;
league.females  ← 0;
league.dollarsIn  ← 0;
league.dollarsOut ← 0;
league.paid   ← 0;
league.unpaid  ← 0;
league.lnameMax ← 0;
league.fnameMax ← 0;
league.typeMax  ← 0;
league.ratingMax ← 0;
league.teamMax  ← 0;
league.paidMax  ← 0;
league.groupMax ← 0;
league.shirtMax  ← 0;
league.pairMax  ← 0;
league.sexMax  ← 0;
league.addrMax  ← 0;
league.tnumMax  ← 0;
league.posMax  ← 0;
league.attenMax  ← 0;
league.comntMax ← 0;
FOR list: LIST OF Member ← league.members, list.rest WHILE list # NIL DO
teams: TeamStats  ← league.teamStats;
m:  Member ← list.first;
IF m.type#skeep
THEN {
league.players   ← league.players + 1;
league.nextDIndex  ← MAX[league.nextDIndex,     m.dIndex];
teams[m.team].dIndex ← MAX[teams[m.team].dIndex, m.dIndex];
IF Protected[m]
THEN teams[m.team].prtctd ← teams[m.team].prtctd+m.rating
ELSE teams[m.team].points ← teams[m.team].points+m.rating;
IF ~Protected[m] AND ~AutomaticMember[m] THEN
teams[m.team].minPick ← IF teams[m.team].minPick=0
THEN m.rating
ELSEMIN[m.rating, teams[m.team].minPick];
SELECT m.paid FROM
unpaid => {
league.dollarsOut ← league.dollarsOut +
(IF m.type=coach THEN 0 ELSE IF m.group=otp THEN 40 ELSE 30);
league.unpaid  ← league.unpaid  + 1};
paid => {
league.dollarsIn  ← league.dollarsIn +
(IF m.type=coach THEN 0 ELSE IF m.group=otp THEN 40 ELSE 30);
league.paid   ← league.paid  + 1};
ENDCASE; -- exempted (CZAR, CZARina and skeeps)
teams[m.team].players  ← teams[m.team].players  + 1;
IF m.sex=male
THEN {
league.males       ← league.males       + 1;
teams[m.team].males  ← teams[m.team].males  + 1}
ELSE {
league.females       ← league.females       + 1;
teams[m.team].females  ← teams[m.team].females + 1} }
ELSE {
league.keeps       ← league.keeps + 1;
teams[m.team].keeps  ← teams[m.team].keeps  + 1};
league.groupCnts[m.group]   ← league.groupCnts[m.group]   + 1;
league.typeNms  ← typeNms;
league.ratingNms ← ratingNms;
league.teamNms  ← teamNms;
league.paidNms  ← paidNms;
league.groupNms ← groupNms;
league.shirtNms  ← shirtNms;
league.pairNms  ← pairNms;
league.sexNms  ← sexNms;
league.lnameMax ← MAX[CARD[Rope.Length[m.lname ]],  league.lnameMax];
league.fnameMax ← MAX[CARD[Rope.Length[m.fname ]],  league.fnameMax];
league.addrMax  ← MAX[CARD[Rope.Length[m.addr ]],  league.addrMax];
league.tnumMax  ← MAX[CARD[Rope.Length[m.tnum ]],  league.tnumMax];
league.posMax  ← MAX[CARD[Rope.Length[m.pos  ]],  league.posMax];
league.attenMax  ← MAX[CARD[Rope.Length[m.atten ]],  league.attenMax];
league.comntMax ← MAX[CARD[Rope.Length[m.comnt ]],  league.comntMax];
ENDLOOP;
FOR list: LIST OF Member ← league.members, list.rest WHILE list # NIL DO
m: Member ← list.first;
IF Protected[m]
AND league.teamStats[m.team].minPick > 0
AND league.teamStats[m.team].minPick <= m.rating THEN {
league.teamStats[m.team].prtctd ← league.teamStats[m.team].prtctd - m.rating;
league.teamStats[m.team].points ← league.teamStats[m.team].points + m.rating};
ENDLOOP;
BEGIN-- update next draft parameters
teams: TeamStats ← league.teamStats;
league.nextDIndex ← teams[0].dIndex ← league.nextDIndex + 1;
league.nextDTeam ← 1;
IF teams[1].dIndex=0 THEN teams[1].dIndexleague.nextDIndex;
FOR team: Team IN [2..league.teamStats.size) DO
IF teams[team].dIndex=0 THEN teams[team].dIndexleague.nextDIndex;
IF teams[team].points < teams[league.nextDTeam].points OR
teams[team].points  =  teams[league.nextDTeam].points AND
teams[team].dIndex   > teams[league.nextDTeam].dIndex
THEN league.nextDTeam ← team; ENDLOOP;
FOR team: Team IN [1..league.teamStats.size) DO
IF teams[team].dIndex=league.nextDIndex THEN teams[team].dIndex0; ENDLOOP
END;
FOR type: CARDINALIN [0..typeNms.size)
DO league.typeMax  ← MAX[CARD[Rope.Length[typeNms[type]]],  league.typeMax] ENDLOOP;
FOR rating: CARDINALIN [0..ratingNms.size)
DO league.ratingMax ← MAX[CARD[Rope.Length[ratingNms[rating]]], league.ratingMax]ENDLOOP;
FOR team: CARDINALIN [0..teamNms.size)
DO league.teamMax  ← MAX[CARD[Rope.Length[teamNms[team]]],  league.teamMax] ENDLOOP; 
FOR paid:  CARDINALIN [0..paidNms.size)
DO league.paidMax  ← MAX[CARD[Rope.Length[paidNms[paid]]],  league.paidMax] ENDLOOP;
FOR group: CARDINALIN [0..groupNms.size)
DO league.groupMax ← MAX[CARD[Rope.Length[groupNms[group]]], league.groupMax] ENDLOOP;
FOR shirt: CARDINALIN [0..shirtNms.size)
DO league.shirtMax  ← MAX[CARD[Rope.Length[shirtNms[shirt]]],  league.shirtMax] ENDLOOP;
FOR pair:  CARDINALIN [0..pairNms.size)
DO league.pairMax  ← MAX[CARD[Rope.Length[pairNms[pair]]],  league.pairMax] ENDLOOP;
FOR sex:  CARDINALIN [0..sexNms.size)
DO league.sexMax  ← MAX[CARD[Rope.Length[sexNms[sex]]],  league.sexMax] ENDLOOP;
};
AutomaticMember: PROC[m: Member] RETURNS[BOOL] = {RETURN
[m.type=coach OR (m.sse#NIL AND m.sse.type=coach)]};
Protected: PROC[m: Member] RETURNS[BOOL] = {RETURN[
(m.type=player OR m.type=coach) AND m.sse#NIL AND m.sse.rating > m.rating]};
Protected: PROC[m: Member] RETURNS[BOOL] = {RETURN[
m.type=player AND m.sse#NIL AND m.sse.type=coach OR
m.type=player AND m.sse#NIL AND m.sse.rating > m.rating]};
Protected: PROC[m: Member] RETURNS[BOOL] =
{RETURN[m.type=player AND m.sse#NIL AND m.sse.type=coach]};
RopeSeqIndex: PUBLIC PROC[name: IO.ROPE, ropeSeq: RopeSeq] RETURNS[index: CARDINAL] = {
FOR index DECREASING IN [0..ropeSeq.size) DO
IF Rope.Compare[name, ropeSeq[index]]=equal THEN EXIT ENDLOOP };
OutJustify: PROC
[out: IO.STREAM, side: {left, right}, rope: IO.ROPE, size: CARDINAL] = {
IF rope.Length[]=0 THEN rope ← "-";
IF rope.Find[" "]#-1 THEN Signal[];
IF side=right THEN THROUGH [0..size-rope.Length[]] DO out.PutChar[IO.SP] ENDLOOP;
out.PutRope[rope];
IF side=left THEN THROUGH [0..size-rope.Length[]] DO out.PutChar[IO.SP] ENDLOOP };
Signal: SIGNAL = CODE;
GenRopeSeq: PROC[inStm: IO.STREAM] RETURNS[ropeSeq: RopeSeq] = {
index:  CARDINAL ← 0;
list:  LIST OF IO.ROPENIL;
inStm  ← IO.RIS[ IO.GetLineRope[inStm] ];
WHILE NOT IO.EndOf[inStm]
DO list ← CONS[IO.GetTokenRope[inStm].token, list]; index ← index+1 ENDLOOP;
IF index=0 THEN RETURN[NIL];
ropeSeq ← NEW[RopeSeqRec[index]];
FOR index ← index-1, index-1 DO
ropeSeq[index] ← list.first; list ← list.rest;
IF index=0 THEN EXIT ENDLOOP };
SBTest: Commander.CommandProc = {
league: League ← ReadLeagueFile["SB87.sum", cmd.out];
WriteLeagueFiles[league, cmd.out] };
typeNms:  RopeSeq ← NEW[RopeSeqRec[4]];
ratingNms: RopeSeq ← NEW[RopeSeqRec[6]];
teamNms:  RopeSeq ← NIL;
paidNms:  RopeSeq ← NEW[RopeSeqRec[3]];
groupNms: RopeSeq ← NIL;
shirtNms:  RopeSeq ← NEW[RopeSeqRec[5]];
pairNms:  RopeSeq ← NEW[RopeSeqRec[3]];
sexNms:  RopeSeq ← NEW[RopeSeqRec[3]];
typeNms[0] ← "-";
typeNms[1] ← "coach";
typeNms[2] ← "skeep";
typeNms[3] ← "player";
ratingNms[0] ← "-";
ratingNms[1] ← "1";
ratingNms[2] ← "2";
ratingNms[3] ← "3";
ratingNms[4] ← "4";
ratingNms[5] ← "5";
paidNms[0] ← "-";
paidNms[1] ← "unpaid";
paidNms[2] ← "paid";
shirtNms[0] ← "-";
shirtNms[1] ← "Sml";
shirtNms[2] ← "Med";
shirtNms[3] ← "Lrg";
shirtNms[4] ← "XL";
sexNms[0] ← "-";
sexNms[1] ← "male";
sexNms[2] ← "female";
pairNms[0] ← "-";
pairNms[1] ← "sgl";
pairNms[2] ← "paired";
Commander.Register[key:"SBTest", proc: SBTest];
END.