? m3-sys/cm3/1.txt ? m3-sys/cm3/AMD64_DARWINc ? m3-sys/cm3/AMD64_NT ? m3-sys/cm3/ARMEL_LINUX ? m3-sys/cm3/src/1.tt ? m3-sys/cm3/src/1.txt ? m3-sys/cm3/src/Builder.m3-save1 ? m3-sys/cm3/src/M3Backend.m3-save1 ? m3-sys/m3quake/1.txt ? m3-sys/m3quake/AMD64_DARWINc ? m3-sys/m3quake/ARMEL_LINUX ? m3-sys/m3quake/SPARC32_SOLARIS ? m3-sys/m3quake/bad.txt ? m3-sys/m3quake/good.txt Index: m3-sys/cm3/src/Main.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/cm3/src/Main.m3,v retrieving revision 1.22 diff -u -w -r1.22 Main.m3 --- m3-sys/cm3/src/Main.m3 23 Jun 2012 08:52:02 -0000 1.22 +++ m3-sys/cm3/src/Main.m3 20 Oct 2013 08:55:44 -0000 @@ -5,6 +5,7 @@ IMPORT M3Timers, Pathname, Process, Quake; IMPORT RTCollector, RTParams, RTutils, Thread, Wr; +IMPORT TextTextTbl; IMPORT Builder, Dirs, M3Build, M3Options, Makefile, Msg, Utils, WebFile; IMPORT MxConfig(*, M3Config, CMKey, CMCurrent *); @@ -17,7 +18,16 @@ build_dir : TEXT := NIL; mach : Quake.Machine := NIL; -PROCEDURE DoIt () = +PROCEDURE DefineIfNotDefined (qmachine: Quake.Machine; + symbol, value: TEXT) RAISES {Quake.Error} = +BEGIN + IF Quake.LookUp (qmachine, symbol) = NIL THEN + Quake.Define (qmachine, symbol, value); + END; +END DefineIfNotDefined; + +PROCEDURE DoIt () RAISES {Wr.Failure} = +VAR defs: TextTextTbl.T; BEGIN IF RTParams.IsPresent ("verbose") THEN Msg.SetLevel (Msg.Level.Verbose); @@ -29,20 +39,14 @@ END; Process.RegisterExitor (CleanUp); - Makefile.ScanCommandLine1 (); - - config := MxConfig.FindFile (); - IF (config = NIL) THEN - Msg.FatalError (NIL, "unable to locate configuration file, \"", - MxConfig.Filename, "\""); - END; - mach := M3Build.NewMachine (); TRY TRY + + defs := Makefile.ScanCommandLine (); + (* figure out what we're trying to do *) VAR - defs := Makefile.ScanCommandLine2 (); name, val: TEXT; iter := defs.iterate(); BEGIN @@ -51,20 +55,31 @@ END; END; + config := MxConfig.FindFile (); + IF (config = NIL) THEN + Msg.FatalError (NIL, "unable to locate configuration file, \"", + MxConfig.Filename, "\""); + END; + (* Default to a native build, so the config file can say less. *) - Quake.Define(mach, "TARGET", MxConfig.HOST); - Quake.Define(mach, "OS_TYPE", MxConfig.HOST_OS_TYPE); - (* Quake.Define(mach, "BACKEND_MODE", Version.BackendMode); *) - (* Quake.Define(mach, "C_COMPILER", Version.CCompiler); *) - (* Quake.Define(mach, "LINKER", Version.Linker); *) - (* Quake.Define(mach, "THREAD_LIBRARY", Version.ThreadLibrary); *) - (* Quake.Define(mach, "WINDOW_LIBRARY", Version.WindowLibrary); *) - Quake.Define(mach, "WORD_SIZE", MxConfig.HOST_WORD_SIZE); + (* DefineIfNotDefined: overridable from command line with -D *) + + DefineIfNotDefined (mach, "TARGET", MxConfig.HOST); + DefineIfNotDefined (mach, "OS_TYPE", MxConfig.HOST_OS_TYPE); + (* DefineIfNotDefined (mach, "BACKEND_MODE", Version.BackendMode); *) + (* DefineIfNotDefined (mach, "C_COMPILER", Version.CCompiler); *) + (* DefineIfNotDefined (mach, "LINKER", Version.Linker); *) + (* DefineIfNotDefined (mach, "THREAD_LIBRARY", Version.ThreadLibrary); *) + (* DefineIfNotDefined (mach, "WINDOW_LIBRARY", Version.WindowLibrary); *) + DefineIfNotDefined (mach, "WORD_SIZE", MxConfig.HOST_WORD_SIZE); (* Even if the config file overrides the defaults, such as to do a cross build, the host characteristics are still available. *) + (* Quake.Define vs. DefineIfNotDefined: These probably + don't make sense to ever override from command line. *) + Quake.Define(mach, "HOST", MxConfig.HOST); Quake.Define(mach, "HOST_OS_TYPE", MxConfig.HOST_OS_TYPE); (* Quake.Define(mach, "HOST_GNU_MAKE", Version.GNUMake); *) Index: m3-sys/cm3/src/Makefile.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/cm3/src/Makefile.i3,v retrieving revision 1.4 diff -u -w -r1.4 Makefile.i3 --- m3-sys/cm3/src/Makefile.i3 23 Jun 2012 08:52:02 -0000 1.4 +++ m3-sys/cm3/src/Makefile.i3 20 Oct 2013 08:55:44 -0000 @@ -3,14 +3,10 @@ INTERFACE Makefile; -IMPORT TextTextTbl; +IMPORT TextTextTbl, Wr, Thread; -PROCEDURE ScanCommandLine1 (); -(* Pre-scan the command line arguments for -help/-version. -*) - -PROCEDURE ScanCommandLine2 () : TextTextTbl.T; -(* Pre-scan the command line arguments to determine the major mode +PROCEDURE ScanCommandLine () : TextTextTbl.T RAISES {Wr.Failure, Thread.Alerted}; +(* Scan the command line arguments to determine the major mode we're operating in, and print any requested help or version information. Return a set of pre-defined values for the quake evaluation. *) @@ -21,4 +17,3 @@ and the contents of the source directory. *) END Makefile. - Index: m3-sys/cm3/src/Makefile.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/cm3/src/Makefile.m3,v retrieving revision 1.52 diff -u -w -r1.52 Makefile.m3 --- m3-sys/cm3/src/Makefile.m3 26 Sep 2012 07:36:12 -0000 1.52 +++ m3-sys/cm3/src/Makefile.m3 20 Oct 2013 08:55:44 -0000 @@ -5,8 +5,7 @@ IMPORT FS, M3File, M3Timers, OSError, Params, Process, Text, Thread, Wr; IMPORT Arg, M3Build, M3Options, M3Path, Msg, Utils, TextSeq, TextTextTbl; -IMPORT MxConfig; -IMPORT Dirs, Version; +IMPORT MxConfig, Dirs, Version; TYPE NK = M3Path.Kind; @@ -344,7 +343,10 @@ eq := Text.FindChar (arg, '='); IF (eq < 0) THEN (* -Dsymbol ==> symbol = TRUE *) + EVAL defs.put(Text.Sub (arg, 2), "TRUE"); + IF wr # NIL THEN Out (wr, Text.Sub (arg, 2), " = TRUE"); + END; RETURN; END; @@ -352,22 +354,42 @@ val := Text.Sub (arg, eq+1); len := Text.Length (val); + EVAL defs.put(sym, val); + + (* CONSIDER: removing the rest of this function is reasonable. + The upside is, m3make.args won't get errors redefining readonly values. + The downside is that cm3 -keep leaves less evidence, in m3make.args. + Since we are leaving the writes in, we change Quake to allow redefining + readonly values, if they are set to the same thing they are already set to. + e.g.: + readonly foo = 1 + foo = 2 % same error as usual + readonly foo = 1 + foo = 1 % ok + *) IF (len = 0) THEN (* -Dsymbol= ==> symbol = "" *) + IF wr # NIL THEN Out (wr, sym, " = \"\""); + END; ELSIF Text.GetChar (arg, 0) = '"' AND Text.GetChar (arg, len-1) = '"' THEN (* -Dsymbol="foo" ==> symbol = "foo" *) + IF wr # NIL THEN Out (wr, sym, " = ", val); + END; ELSIF Text.Equal (val, "TRUE") OR Text.Equal (val, "FALSE") THEN + IF wr # NIL THEN Out (wr, sym, " = ", val); + END; ELSE (* -Dsymbol=val ==> symbol = "val" *) + IF wr # NIL THEN Out (wr, sym, " = \"", val, "\""); - + END; END; END ProcessDefine; @@ -514,9 +536,12 @@ (*----------------------------------------- pre-scan command line ---*) -PROCEDURE ScanCommandLine1 () = - VAR arg: TEXT; +PROCEDURE ScanCommandLine () : TextTextTbl.T RAISES {Wr.Failure, Thread.Alerted} = + VAR + use_overrides := FALSE; + got_mode := FALSE; arg: TEXT; BEGIN + FOR i := 1 TO Params.Count-1 DO arg := Params.Get (i); IF Text.Length(arg) > 1 AND Text.GetChar (arg, 1) = '-' THEN @@ -528,13 +553,7 @@ ELSIF Text.Equal (arg, "-version") THEN PrintVersion (TRUE); END; END; - END ScanCommandLine1; -PROCEDURE ScanCommandLine2 () : TextTextTbl.T = - VAR - use_overrides := FALSE; - got_mode := FALSE; arg: TEXT; - BEGIN FOR i := 1 TO Params.Count-1 DO arg := Params.Get (i); IF Text.Length(arg) > 1 AND Text.GetChar (arg, 1) = '-' THEN @@ -569,12 +588,14 @@ ELSE Msg.Error(NIL, "missing argument for -pretend"); END; + ELSIF Text.GetChar(arg, 0) = '-' AND Text.GetChar(arg, 1) = 'D' THEN + ProcessDefine(arg, NIL); END; END; IF got_mode = FALSE THEN SetMode (got_mode, MM.Build); END; EVAL defs.put("M3_USE_OVERRIDES", ARRAY BOOLEAN OF TEXT {"", "TRUE"}[use_overrides]); RETURN defs; - END ScanCommandLine2; + END ScanCommandLine; PROCEDURE SetMode (VAR got_mode: BOOLEAN; mode: MM) = BEGIN Index: m3-sys/m3quake/src/QMachine.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3quake/src/QMachine.m3,v retrieving revision 1.37 diff -u -w -r1.37 QMachine.m3 --- m3-sys/m3quake/src/QMachine.m3 15 Feb 2011 02:27:44 -0000 1.37 +++ m3-sys/m3quake/src/QMachine.m3 20 Oct 2013 08:55:44 -0000 @@ -357,12 +357,18 @@ | Op.Assign => bind := LookUp (t, arg); + Pop (t, val); IF (bind = NIL) THEN bind := DefineGlobal (t, arg, readonly := FALSE); ELSIF bind.readonly THEN + IF Equal (bind.value, val) THEN + (* silently allow assigning an equivalent value to a readonly variable + as it already has; the old value is kept *) + val := bind.value; + ELSE Err (t, "cannot assign to readonly variable: " & t.map.id2txt(arg)); END; - Pop (t, val); + END; bind.value := val; | Op.AssignTable => @@ -1357,12 +1363,9 @@ PushBool (t, empty); END DoEmpty; -PROCEDURE DoEqual (t: T; n_args: INTEGER) RAISES {Error} = - VAR v1, v2: QValue.T; eq := FALSE; +PROCEDURE Equal (VAR v1, v2: QValue.T): BOOLEAN = + VAR eq := FALSE; BEGIN - <*ASSERT n_args = 2 *> - Pop (t, v1); - Pop (t, v2); IF (v1.kind = v2.kind) THEN CASE v1.kind OF | QK.Var => eq := (v1.int = v2.int) AND (v1.ref = v2.ref); @@ -1380,7 +1383,16 @@ | QK.Proc => eq := (v1.ref = v2.ref); END; END; - PushBool (t, eq); + RETURN eq; + END Equal; + +PROCEDURE DoEqual (t: T; n_args: INTEGER) RAISES {Error} = + VAR v1, v2: QValue.T; + BEGIN + <*ASSERT n_args = 2 *> + Pop (t, v1); + Pop (t, v2); + PushBool (t, Equal(v1, v2)); END DoEqual; PROCEDURE DoError (t: T; n_args: INTEGER) RAISES {Error} =