(****************************************
*                                       *
*     MODULA-2 Multi-Pass Compiler      *
*     ****************************      *
*                                       *
*         VAX11 Implementation          *
*                                       *
*                                       *
*     M2CInit:                          *
*                                       *
*     initialisation part               *
*     of the Modula-2 compiler          *
*                                       *
*                                       *
*     Leo Geissmann                     *
*     Institut fuer Informatik          *
*     ETH-Zuerich                       *
*     CH-8092 Zuerich                   *
*                                       *
*     Modified for UNIX by              *
*     Mick Jordan                       *
****************************************)

IMPLEMENTATION MODULE M2Init;

FROM Clock IMPORT Time, GetTime;
FROM M2Files IMPORT CreateInput, Extension, Filename, HashExt;
FROM Streams IMPORT Stream, ErrorCode;
FROM Version IMPORT VersionId;
FROM MCImpl IMPORT InitialiseTarget;
IMPORT HeapStream;


FROM UnixArgs IMPORT argCount,GetArg;
FROM WriteStrings IMPORT  WriteString, WriteLn;
FROM MCPublic IMPORT
    FileName,
    il1File, il2File,
    modFile, lstFile, symFile, refFile, objFile,
    filenam,
    Compilerstatus, Statset, compstat,
    comptime, symfileextension;
IMPORT Strings;


  CONST
    optionlength = 80;

  TYPE
    OptionKind = (query, noquery,
                  list, nolist,
                  version,
		  noopt,
                  illegal);
    OptionText = ARRAY [0 .. optionlength-1] OF CHAR;


  VAR
    compiling : BOOLEAN; (* compiler may run *)
    pos,i,l : INTEGER;
    lpos : CARDINAL;

    fnt : FileName;
    ok : BOOLEAN;
    reply: INTEGER;
    newtime : Time;
    lopt, qopt : OptionKind;
    vopt, hash : BOOLEAN;
    defopt : BOOLEAN;
    a,b,c:BOOLEAN;
    argcnt:CARDINAL;



  PROCEDURE MakeTemp(VAR fdesc : CARDINAL);
  VAR
     s: Stream;
  BEGIN
     s := HeapStream.CreateInOutput();
     IF s^.status # Success THEN
        WriteString("m2c: failed to open temporary stream"); WriteLn;
     END (* if *);
     fdesc := CARDINAL(s);
  END MakeTemp;

  PROCEDURE InterpreteOptions;
    VAR opttext : OptionText;
        optcount: CARDINAL;
        bitnumberfromleft: BOOLEAN;
        bytesperword: CARDINAL;

  BEGIN (* InterpreteOptions *)
   FOR argcnt := 1 TO argCount-1 DO
    GetArg(argcnt,opttext);

    IF opttext[0]="-" THEN
    optcount :=  1;
    WHILE opttext[optcount] # 0C DO
      CASE opttext[optcount] OF
	 'l' : lopt := list;
	|'z' : lopt := nolist;
        |'h' : hash := FALSE;
	|'v' : vopt := TRUE;
        |'V' : qopt := query;
	|'d' : defopt := TRUE;
	|'C' : INC(optcount);
               bytesperword := ORD(opttext[optcount]) - ORD('0');
               INC(optcount);
               IF opttext[optcount]='l' THEN
	           bitnumberfromleft := TRUE
	       ELSE
	           bitnumberfromleft := FALSE
	       END;
               InitialiseTarget(bytesperword, bytesperword,
                                bitnumberfromleft, bytesperword*8,
                                4 DIV bytesperword, 0);

	ELSE
      END; (* CASE *)
      INC(optcount);
    END;
    END;
    END;
  END InterpreteOptions;

  PROCEDURE InitCompilation;
 
  BEGIN
    (* get compilation time *)
    GetTime(newtime);
    WITH newtime DO
      comptime[0] := day;
      comptime[1] := minute;
      comptime[2] := millisecond;
    END;
      (* reset options *)
      qopt := noquery;
      lopt := nolist;
      vopt := FALSE; hash := TRUE;
      defopt := FALSE;
      (* lookup for source file *)
        InterpreteOptions;

      IF qopt = query THEN INCL(compstat,querys) ;END;
      IF lopt = list THEN INCL(compstat,listings) END;
      IF vopt THEN (* display version information *)
        WriteString("MODULA-2 M-CODE compiler, ");
	WriteString(VersionId);
        WriteLn;
      END;
      symfileextension := "sym";

  END InitCompilation;

PROCEDURE Init;
VAR ext: Extension;
    s: Stream;
BEGIN
      ok := TRUE;
      IF (comptime[0]=0) AND (comptime[1]=0) AND (comptime[2]=0) THEN
          InitCompilation;
      END;
        ext := "mod";
	i:=0; 
        Strings.CopyCC(filenam, Modulename);
        WHILE (Modulename[i] # '.') AND (Modulename[i]#0C) DO 
            INC(i) 
        END;
        IF Modulename[i] = '.' THEN
             IF (Modulename[i+1] = 'd') THEN
                ext := "def";
                INCL(compstat, defs);
            END (* if *);
            Modulename[i] := 0C;   (* lose extension *)
	ELSE IF defopt THEN
	    ext := "def";
	    INCL(compstat, defs);
	    END;
        END (* if *);

	s := CreateInput(Modulename, ext);
	IF s^.status # Success THEN
         WriteString(' -- module not found:');
         WriteString(filenam);
	 WriteLn;
         ok := FALSE;
        ELSE
         modFile := CARDINAL(s);
         Strings.CopyCC(Filename, filenam);
        END;

   MakeTemp(il1File);
   MakeTemp(il2File);
   IF hash THEN
      HashExt("sym");			(*  hash lookup of symbol files *)
   END (* if *);
   IF ok THEN INCL(compstat,compiles);  END;

END Init;

END M2Init.
