MODULE---------------------------------------------------------------------------; IMPORT Text, TextSeq, ParseParams, Pathname, OSError, Stdio, Process; IMPORT SMsg AS Msg, FSUtils, M3makefile, TextUtils, PathRepr, Creation; IMPORT (* FSFixed AS *) FS; Main
CONST maxLevel = 5;---------------------------------------------------------------------------
PROCEDURE---------------------------------------------------------------------------EvalParams () = VAR pp := NEW(ParseParams.T).init(Stdio.stderr); BEGIN pdir := Pathname.Current; root := Pathname.Current; Msg.tFlag := TRUE; TRY Msg.vFlag := pp.keywordPresent("-v"); (* be verbose *) Msg.dFlag := pp.keywordPresent("-d"); (* debug messages *) IF pp.keywordPresent("-r") OR pp.keywordPresent("-root") THEN root := pp.getNext(); pdir := root; END; (* creation date option *) IF pp.keywordPresent("-created") THEN Msg.T(Creation.Date & " on " & Creation.System); Process.Exit(0); END; npkgs := NUMBER(pp.arg^) - pp.next; pkglocs := NEW(TextSeq.T).init(npkgs); FOR i := 1 TO npkgs DO VAR t := pp.getNext(); BEGIN IF Text.GetChar(t, 0) = '-' THEN Msg.Fatal("unrecognized option: " & t, 2); ELSE pkglocs.addhi(t); END; END; END; pp.finish(); EXCEPT ParseParams.Error => Msg.Fatal("unknown command line arguments; usage: " & "m3ovr [-v] [-d] [-r dir] pkg-location-1 .. pkg-location-n"); END; END EvalParams;
PROCEDURE---------------------------------------------------------------------------FindMakefileAndPkgName () = VAR rmkfname := Pathname.Join("src", "m3makefile", NIL); mkfname := Pathname.Join(root, rmkfname, NIL); BEGIN TRY pdir := FS.GetAbsolutePathname(pdir); root := FS.GetAbsolutePathname(root); EXCEPT OSError.E => Msg.Fatal("cannot get working directory"); END; WHILE (level < maxLevel) AND NOT FSUtils.IsFile(mkfname) DO INC(level); root := Pathname.Prefix(root); pdir := Pathname.Prefix(pdir); mkfname := Pathname.Join(root, rmkfname, NIL); END; IF level = maxLevel THEN Msg.Fatal("cannot find m3makefile") END; pname := Pathname.Last(pdir); TRY fn := FS.GetAbsolutePathname(mkfname); EXCEPT OSError.E => Msg.Fatal("cannot get absolute pathname"); END; END FindMakefileAndPkgName;
PROCEDURE---------------------------------------------------------------------------ParseMakefile () = BEGIN TRY mkf := M3makefile.New(fn); EXCEPT OSError.E => Msg.Fatal("error reading m3makefile"); | M3makefile.ParseError(e) => Msg.Fatal("error parsing m3makefile: " & e); END; END ParseMakefile;
PROCEDURE---------------------------------------------------------------------------C (m : TEXT) = BEGIN Msg.V("% " & m); END C;
PROCEDURE---------------------------------------------------------------------------M (m : TEXT) = BEGIN Msg.T( m); END M;
VAR mkf : M3makefile.T; fn : TEXT; root : TEXT; level := 0; pdir : Pathname.T; pname := "undefined"; imps : TextSeq.T; decls : M3makefile.M3DeclarationList; pkgs : TextSeq.T; pkglocs : TextSeq.T; npkgs : CARDINAL; BEGIN (* Main *) EvalParams(); FindMakefileAndPkgName(); ParseMakefile(); IF mkf.unknownElements() THEN Msg.Warning("m3makefile " & fn & "\n contains elements unknown to m3dep"); C("m3makefile contains elements unknown to m3dep"); END; IF Msg.vFlag THEN IF mkf.targetType() = M3makefile.TargetType.Library THEN IF mkf.targetName() = NIL THEN C("undefined main target"); ELSE C("main target is library " & mkf.targetName()); END; ELSIF mkf.targetType() = M3makefile.TargetType.Program THEN IF mkf.targetName() = NIL THEN C("undefined main target"); ELSE C("main target is program " & mkf.targetName()); END; ELSE C("unknown main target"); END; decls := mkf.elements(); WHILE decls # NIL DO IF decls.name = NIL THEN C("procedure/option " & decls.type); ELSE C(decls.type & " declaration " & decls.name & " (args = " & TextUtils.TextSeqToText(decls.args) & ")"); END; decls := decls.next; END; END; imps := mkf.imports(); pkgs := NEW(TextSeq.T).init(npkgs); FOR i := 0 TO npkgs - 1 DO WITH pkgloc = pkglocs.get(i) DO WITH pkg = Pathname.Last(pkgloc) DO pkgs.addhi(pkg); WITH loc = PathRepr.Posix(Pathname.Prefix(pkgloc)) DO IF TextUtils.MemberOfTextSeq(imps, pkg) THEN M("override(\"" & pkg & "\", \"" & loc & "\")"); ELSE C("package " & pkg & " not used"); END; END; END; END; END; IF mkf.targetType() = M3makefile.TargetType.Program THEN M("if not defined(\"PM3\")"); M(" % The procedure \"build_standalone\" exists only in SRC Modula-3."); M(" if not defined(\"build_standalone\")"); M(" PM3 = \"T\""); M(" end"); M("end"); M("if defined(\"PM3\")"); M(" proc build_standalone() is"); M(" option(\"standalone\", \"T\")"); M(" end"); M("end"); M("if not defined(\"DYNAMIC\")"); M(" build_standalone()"); M("end"); Msg.Warning("program " & mkf.targetName() & " will be linked statically"); END; FOR i := 0 TO imps.size() - 1 DO WITH imp = imps.get(i) DO IF NOT TextUtils.MemberOfTextSeq(pkgs, imp) THEN C("location of imported package " & imp & " not overriden"); Msg.Warning("location of imported package " & imp & " not overriden"); END; END; END; END Main.