-- PressUserCm.mesa,  Edit: Johnsson; May 28, 1980  10:34 PM
-- Ken Pier 21-Jul-81 17:08:18  converting to Laurel environment
-- Edited by Pier August 10, 1981  5:00 PM
-- Converted to Laurel 6.1 by Ken Pier, 17-May-83  9:43:16

DIRECTORY
  intCommon USING [user],
  Press USING [PutFontInTable],
  PressUtilities USING [],
  Core: FROM "Core" USING [--FreeCacheEntry,-- Login],
  csD: FROM "CoreStreamDefs" USING [OpenFromName, Read, StreamHandle,
				    GetPosition, GetLength],
  PrintDefs USING[PError, DestroyS],
  StringDefs USING [
    AppendChar, AppendString, EquivalentString,
    StringBoundsFault, StringToDecimal],
  SystemDefs USING [AllocateHeapString, FreeHeapString];

PressUserCm: PROGRAM
  IMPORTS PrintDefs, Press, csD, Core, intCommon, StringDefs, SystemDefs
  EXPORTS PressUtilities =
  BEGIN
  
  s: csD.StreamHandle ← NIL;
  token: STRING ← NIL;
  terminator: CHARACTER;
  
  CR: CHARACTER = 15C;
  SP: CHARACTER = 40C;
  
  
  AtEnd: PROCEDURE[s: csD.StreamHandle] RETURNS [BOOLEAN] = 
    BEGIN RETURN[csD.GetLength[s] <= csD.GetPosition[s]] END;
    
  StartScanning: PROCEDURE [section: STRING] RETURNS [BOOLEAN] =
    BEGIN
    IF s # NIL THEN PrintDefs.PError[UserCmMixup];
    Core.Login[@intCommon.user];
    s ← csD.OpenFromName[
      name: "User.cm"L, type: byte, mode: read];
    IF s = NIL THEN RETURN[FALSE];
    --Core.FreeCacheEntry["User.cm"L];  causes signal because User.cm is open--
    token ← SystemDefs.AllocateHeapString[200];
    WHILE GetNextToken[] DO
      IF StringDefs.EquivalentString[token, section] THEN RETURN[TRUE]; ENDLOOP;
    FinishScanning[];
    RETURN[FALSE];
    END;
    
  FinishScanning: PROCEDURE =
    BEGIN
    IF s = NIL THEN PrintDefs.PError[UserCmMixup];
    SystemDefs.FreeHeapString[token];
    token ← NIL;
    s ← PrintDefs.DestroyS[s];
    END;
    
  GetNextToken: PROCEDURE RETURNS [BOOLEAN] =
    BEGIN
    token.length ← 0;
    UNTIL AtEnd[s] DO
      terminator ← csD.Read[s];
      SELECT terminator FROM
	SP => IF (token.length # 0) THEN RETURN[TRUE]; -- flush leading blanks
	
	CR, ': => RETURN[TRUE];
	'" =>
	  BEGIN -- gobble things up until matching close quote
     UNTIL AtEnd[s] DO
	    terminator ← csD.Read[s];
	    IF terminator = '" THEN EXIT;
	    StringDefs.AppendChar[
	      token, terminator ! StringDefs.StringBoundsFault => CONTINUE];
	    ENDLOOP;
	  END;
	ENDCASE =>
	  StringDefs.AppendChar[
	    token, terminator ! StringDefs.StringBoundsFault => CONTINUE];
      ENDLOOP;
    IF token.length = 0 THEN RETURN[FALSE];
    RETURN[TRUE];
    END;
    
  GetNextTokenAsNumber: PROCEDURE RETURNS [INTEGER] =
    BEGIN [] ← GetNextToken[]; RETURN[StringDefs.StringToDecimal[token]]; END;
    
  SetupFontsForBravo: PUBLIC PROCEDURE =
    BEGIN ENABLE StringDefs.StringBoundsFault => GO TO uError;
    fontNumber: CARDINAL;
    otherString: STRING ← [20];
    fontSize: CARDINAL;
    IF ~StartScanning["[Bravo]"L] THEN RETURN;
    DO
      IF NOT GetNextToken[] THEN EXIT;
      IF terminator = CR AND token[0] = '[ THEN EXIT;
      IF terminator = ': AND StringDefs.EquivalentString[token, "Font"L] THEN
	BEGIN
	[] ← GetNextToken[];
	IF token[0]~ IN ['0..'9] THEN LOOP; -- ignore Diablo font
	fontNumber ← StringDefs.StringToDecimal[token];
	[] ← GetNextToken[];
	otherString.length ← 0;
	StringDefs.AppendString[otherString, token];
	fontSize ← GetNextTokenAsNumber[];
	Press.PutFontInTable[fontNumber, otherString, fontSize];
	END;
      ENDLOOP;
    FinishScanning[];
    EXITS uError => {s ← PrintDefs.DestroyS[s];
                     PrintDefs.PError[UserCmMixup];};
    END;
    
  SetupFontsForNonProgDisk: PUBLIC PROCEDURE =
    BEGIN
    Press.PutFontInTable[0, "TimesRoman"L, 10];
    Press.PutFontInTable[1, "TimesRoman"L, 8];
    Press.PutFontInTable[2, "Logo"L, 24]; -- X, E, R, and O only
    Press.PutFontInTable[3, "Math"L, 10]; -- no italic or bold
    Press.PutFontInTable[4, "Hippo"L, 10]; -- no italic or bold
    Press.PutFontInTable[5, "TimesRoman"L, 12];
    Press.PutFontInTable[6, "Helvetica"L, 10];
    Press.PutFontInTable[7, "Helvetica"L, 8];
    Press.PutFontInTable[8, "Gacha"L, 10];
    Press.PutFontInTable[9, "Helvetica"L, 10]; -- Bold only
    
    END;
    
  hardcopyUserName: PUBLIC STRING ← NIL;
  hardcopyHost: PUBLIC STRING ← NIL;
  
  SetupHardCopyOptions: PUBLIC PROCEDURE =
    BEGIN ENABLE StringDefs.StringBoundsFault => GO TO uError;
    otherString: STRING ← [50];
    fontSize: CARDINAL;
    SetString[@hardcopyUserName, intCommon.user.name];
    IF ~StartScanning["[HardCopy]"L] THEN RETURN;
    DO
      IF NOT GetNextToken[] THEN EXIT;
      IF terminator = CR AND token[0] = '[ THEN EXIT;
      IF terminator = ': THEN
	SELECT TRUE FROM
	  StringDefs.EquivalentString[token, "PrintedBy"L] =>
	    BEGIN
	    IF ~GetNextToken[] THEN EXIT;
	    otherString.length ← 0;
	    FOR i: CARDINAL IN [0..token.length) DO
	      IF token[i] = '$ THEN StringDefs.AppendString[otherString, intCommon.user.name]
	      ELSE StringDefs.AppendChar[otherString, token[i]];
	      ENDLOOP;
	    SetString[@hardcopyUserName, otherString];
	    END;
	  StringDefs.EquivalentString[token, "Press"L] =>
	    BEGIN
	    IF ~GetNextToken[] THEN EXIT;
	    SetString[@hardcopyHost, token];
	    END;
	  StringDefs.EquivalentString[token, "Font"L] =>
	    BEGIN
	    [] ← GetNextToken[];
	    otherString.length ← 0;
	    StringDefs.AppendString[otherString, token];
	    fontSize ← GetNextTokenAsNumber[];
	    Press.PutFontInTable[0, otherString, fontSize];
	    END;
	  ENDCASE => NULL;
      ENDLOOP;
    FinishScanning[];
    EXITS uError => {s ← PrintDefs.DestroyS[s];
                     PrintDefs.PError[UserCmMixup];};
    END;
    
  SetString: PROCEDURE [p: POINTER TO STRING, s: STRING] =
    BEGIN
    IF p↑ # NIL THEN BEGIN SystemDefs.FreeHeapString[p↑]; p↑ ← NIL END;
    IF s = NIL THEN RETURN;
    p↑ ← SystemDefs.AllocateHeapString[s.length];
    StringDefs.AppendString[p↑, s];
    RETURN
    END;
    
  END.

--Former Errors

  UserCmMixup: PUBLIC ERROR = CODE;