StandardMMCmds.mesa
Copyright Ó 1988, 1990, 1991, 1992, 1993 by Xerox Corporation. All rights reserved.
Eduardo Pelegri-Llopart, January 9, 1990 3:24:31 pm PST
Local buffering layer for clients to change easily
JKF May 29, 1990 7:37:05 am PDT
Spreitze, May 29, 1992 11:20 am PDT
Willie-s, April 29, 1993 12:14 pm PDT
Foote, January 10, 1991 5:15 pm PST
Michael Plass, September 30, 1991 3:11 pm PDT
StandardMMCmds registers three commands: MMMimosa, MMCCMesa, and MMCCConfig, which are then called by MakeDo and then call ComplexCc in various variations. This layer provides a place where to easily replace one or more of these commands to tailor the local behavior. This file provides the standard behavior and is part of MakeDo.df; if your package requires some other behavior, you should include the files defining that behavior as part of the package.
DIRECTORY
Commander USING [CommandProc, Register, Handle],
CommanderOps USING [DoCommand, GetCmdToken, Token],
Convert USING [RopeFromInt, RopeFromRope],
Args USING [Arg, ArgRope, Error, GetRope, NArgs],
IO,
Random USING [Create, RandomStream, NextInt],
Rope,
SimpleFeedback USING [Append],
UserProfile USING [Boolean, CallWhenProfileChanges, Line, ListOfTokens, ProfileChangedProc, Token];
TextReplace stuff (simplified)
This is here to skip having to load the dependency-rich implementation of TextReplace.
Pair: TYPE = TextReplace.Pair;
Pair: TYPE = RECORD [match, replace: ROPE, literal, word, ignoreCase, addBounds: BOOL ¬ FALSE];
PairList: TYPE = LIST OF Pair;
RopeMap: TYPE = REF RopeMapRep;
RopeMapRep: TYPE = TextReplace.RopeMapRep;
RopeMapRep: TYPE = RECORD [Map: PROC [REF ANY, ROPE] RETURNS [ROPE], data: REF ANY ¬ NIL];
PairMapper:
PROC [data:
REF
ANY, rope:
ROPE]
RETURNS [
ROPE] ~ {
This is a fairly horrible algorithm. Fix it someday.
pairList: PairList ~ NARROW[data];
start: INT ¬ 0;
Alpha:
PROC [i:
INT]
RETURNS [
BOOL] ~ {
IF i < 0 OR i >= rope.Size THEN RETURN [FALSE];
SELECT rope.Fetch[i]
FROM
IN ['a..'z] => RETURN [TRUE];
IN ['A..'Z] => RETURN [TRUE];
IN ['0..'9] => RETURN [TRUE];
ENDCASE => RETURN [FALSE];
};
WHILE start < Rope.Size[rope]
DO
match: PairList ¬ NIL;
matchIndex: INT ¬ LAST[INT];
tryAgain: BOOL;
FOR tail: PairList ¬ pairList, tail.rest
UNTIL tail =
NIL
DO
i: INT ~ Rope.Index[rope, start, tail.first.match, NOT tail.first.ignoreCase];
IF tail.first.word AND (Alpha[i-1] OR Alpha[i+tail.first.match.Size]) AND i < rope.Size THEN {tryAgain ¬ TRUE; LOOP};
SELECT i
FROM
< matchIndex => {match ¬ tail; matchIndex ¬ i};
= matchIndex => {
IF match =
NIL
OR tail.first.match.Size > match.first.match.Size
THEN {
match ¬ tail; matchIndex ¬ i
}};
ENDCASE;
ENDLOOP;
IF matchIndex < Rope.Size[rope]
THEN {
rope ¬ Rope.Replace[base: rope, start: matchIndex, len: match.first.match.Size, with: match.first.replace];
start ¬ start + match.first.replace.Size;
}
ELSE {IF tryAgain THEN start ¬ start + 1 ELSE EXIT};
ENDLOOP;
RETURN [rope]
};
RopeMapFromPairs:
PROC [pairList: PairList]
RETURNS [RopeMap] ~ {
FOR tail: PairList ¬ pairList, tail.rest
UNTIL tail =
NIL
DO
IF NOT tail.first.literal THEN ERROR; -- patterns not supported.
IF tail.first.addBounds THEN ERROR; -- not supported.
ENDLOOP;
RETURN [NEW[RopeMapRep ¬ [PairMapper, pairList]]];
};
Apply:
PROC [s: RopeMap, r:
ROPE]
RETURNS [mapped:
ROPE] ~
INLINE {
mapped ¬ s.Map[s.data, r];
};
Actions for Rsh
TranslateToLineSep:
PROC [old:
CHAR]
RETURNS [new:
CHAR] ~ {
IF old = '\012 THEN new ¬ '\n ELSE new ¬ old;
};
Variables are ${sname} and ${tmpFile}
preMsCc: ROPE ~ "set dir = `arch`
${cpp} ${sname}.c2c.c > ${sname}.E
${awk} 'BEGIN {mesaSource = 0} \\
/^#/ {if (mesaSource == 0) \\
{if ($2 >= 123000 && $3 == ""\\""${sname}.mesa\\"""") \\
mesaSource = 1} \\
else if ($3 == ""\\""${sname}.c2c.c\\"""") continue} \\
{print}' ${sname}.E > ${sname}.E.c
${ccom} -Xg ${sname}.E.c > ${sname}.s
${msScript} -mob ${sname}.mob -as ${sname}.s -out ${sname}.mob.s
${cc} -c -o ${tmpFile} ${sname}.mob.s
${ld} -r -o ${dir}/${sname}.c2c.o ${tmpFile}
${rm} -f ${tmpFile} ${sname}.E.c";
preMsCc: ROPE ~ "set dir = `arch`
${cpp} ${sname}.c2c.c > ${sname}.E
${awk} 'BEGIN {mesaSource = 0} \\
/^#/ {if (mesaSource == 0) \\
{if ($2 >= 123000 && $3 == ""\\""${sname}.mesa\\"""") \\
mesaSource = 1} \\
else if ($3 == ""\\""${sname}.c2c.c\\"""") continue} \\
{print}' ${sname}.E > ${sname}.E.c
${ccom} -Xg ${sname}.E.c > ${sname}.s
${msScript} -mob ${sname}.mob -as ${sname}.s -out ${sname}.mob.s
${cc} -c -o ${dir}/${sname}.c2c.o ${sname}.mob.s
${rm} -f ${sname}.E.c";
preMsCcFront: ROPE ~ "set dir = `arch`
${cpp} ${sname}.c2c.c > ${sname}.E
${awk} 'BEGIN {mesaSource = 0} \\
/^#/ {if (mesaSource == 0) \\
{if ($2 >= 123000 && $3 == ""\\""${sname}.mesa\\"""") \\
mesaSource = 1} \\
else if ($3 == ""\\""${sname}.c2c.c\\"""") continue} \\
{print}' ${sname}.E > ${sname}.E.c
${ccom} -Xg ${sname}.E.c > ${dir}/${sname}.s
#${msScript} -mob ${sname}.mob -as ${dir}/${sname}.s -out ${dir}/${sname}.mob.s
${rm} -f ${sname}.E.c ${sname}.E";
preMsCcBack: ROPE ~ "set dir = `arch`
${cc} -c -o ${tmpFile} ${dir}/${sname}.mob.s
${ld} -r -o ${dir}/${sname}.c2c.o ${tmpFile}
#${rm} -f ${tmpFile} ${dir}/${sname}.mob.s ${dir}/${sname}.s";
preMsCcBack: ROPE ~ "set dir = `arch`
${cc} -c -o ${dir}/${sname}.c2c.o ${dir}/${sname}.mob.s
#${rm} -f ${dir}/${sname}.mob.s ${dir}/${sname}.s";
These variables are assigned in NoteUserProfile
msCc: ROPE;
msCcBack: ROPE;
msCcFront: ROPE;
TmpName:
PROC []
RETURNS [name:
ROPE] ~ {
tmpFileHead: ROPE ~ IF pCedar THEN Rope.Cat[SystemNames.LocalDir["Temp"], "msCc"] ELSE "/tmp/msCc";
name ¬ Rope.Cat["/tmp/msCc", Convert.RopeFromInt[randomStream.NextInt[]], ".o"];
RETURN [name];
};
Command Procs
MMCcMesa: ROPE ~ "MMCcMesa";
MMCcMesaDoc: ROPE ~ "MMCcMesa - interceptor layer: Switches are:
-name <shortname>
-dir <localdirectory>
-usw <userprovided switches>
-msw <mimosa suggested switches>
-class <machine class>";
MMCcMesaUsage: ROPE ~ Rope.Concat["Usage: MMCcMesa", MMCcMesaDoc];
MMCcMesaProc: Commander.CommandProc ~ {
ENABLE {
Args.Error => { msg ¬ MMCcMesaUsage; GOTO Failed };
CommandSyntaxError => { msg ¬ MMCcMesaUsage; GOTO Failed };
};
command: ROPE;
cmdArgs: CmdArgs ~ ProcessArgs[cmd, NIL];
cSwitches:
ROPE ~ cmdArgs.cSwitches;
No longer force fsingle switch for mimosa-generated code (i.e., always use single-precision floating point operations when all arguments are single-precision), since not all c compilers accept this switch
lSwitches: ROPE ~ cmdArgs.lSwitches;
dbxDebug: BOOL = UserProfile.Boolean[key: "MakeDo.dbxDebug", default: FALSE] AND cmdArgs.cSwitches.Find["-O"] = -1;
shortName: ROPE ~ cmdArgs.shortName;
localDir: ROPE ~ cmdArgs.localDir;
machClassSw: ROPE ~ cmdArgs.machClassSw;
pairs: PairList ~ LIST[
[match: "${msCc}", replace: Q[msCc], literal: TRUE],
[match: "${msCcFront}", replace: Q[msCcFront], literal: TRUE],
[match: "${msCcBack}", replace: Q[msCcBack], literal: TRUE],
[match: "${ldir}", replace: localDir, literal: TRUE],
[match: "${sname}", replace: shortName, literal: TRUE],
[match: "${mclass}", replace: machClassSw, literal: TRUE],
[match: "${tmpFile}", replace: TmpName[], literal: TRUE],
[match: "${cswitch}", replace: cSwitches, literal: TRUE],
[match: "${lswitch}", replace: lSwitches, literal: TRUE]
];
ropeMap: RopeMap ~ RopeMapFromPairs[pairs];
IF dbxDebug
THEN {
msLocal: BOOL ~ UserProfile.Boolean[key: "MS.local", default: TRUE];
IF
NOT msLocal
THEN {
template: ROPE ~ "ComplexRsh -cmd ${msCc} -binOut ${ldir}${sname}.c2c.o -srcIn ${sname}.c2c.c ${sname}.mesa -binIn ${sname}.mob ${mclass}";
command ¬ Apply[ropeMap, template];
}
ELSE {
template: ROPE ~ "ComplexRsh -cmd ${msCcFront} -srcOut ${ldir}${sname}.s -srcIn ${sname}.c2c.c ${mclass} ; MS -mob ${sname}.mob -as ${ldir}${sname}.s -out ${ldir}${sname}.mob.s ; ComplexRsh -cmd ${msCcBack} -binOut ${ldir}${sname}.c2c.o -srcIn ${sname}.mob.s ${mclass}";
command ¬ Apply[ropeMap, template];
}
}
ELSE {
template:
ROPE ~ Rope.Concat[
"ComplexCc -out ${ldir}${sname}.c2c.o -in ${sname}.c2c.c ${mclass} -cSwitch ${cswitch}",
IF Rope.Equal[lSwitches, NIL] THEN NIL ELSE " -rload -lSwitch ${lswitch}"
];
command ¬ Apply[ropeMap, template];
};
result ¬ CommanderOps.DoCommand[commandLine: command, parent: cmd];
EXITS
Failed => result ¬ $Failure;
};
MMCcConfig: ROPE ~ "MMCcConfig";
MMCcConfigDoc: ROPE ~ "MMCcConfig - interceptor layer: Switches are:
-name <shortname>
-dir <localdirectory>
-usw <userprovided switches>
-msw <mimosa suggested switches>
-class <machine class>
-raux <load file list>
(+|-)clean";
MMCcConfigUsage: ROPE ~ Rope.Concat["Usage: MMCcConfig", MMCcConfigDoc];
MMCcConfigProc: Commander.CommandProc ~ {
ENABLE {
Args.Error => { msg ¬ MMCcMesaUsage; GOTO Failed };
CommandSyntaxError => { msg ¬ MMCcMesaUsage; GOTO Failed };
};
ToSlash:
PROC [old:
CHAR]
RETURNS [new:
CHAR] ~ {
IF old = '> THEN new ¬ '/ ELSE new ¬ old;
};
ropeMap: RopeMap;
template: ROPE;
command: ROPE;
cmdArgs: CmdArgs ~ ProcessArgs[cmd, NIL];
localDirSlash: ROPE ~ Rope.Translate[base: cmdArgs.localDir, translator: ToSlash];
pairs: PairList;
IF cmdArgs.lSwitches = NIL THEN cmdArgs.lSwitches ¬ CheckForConfigSwitch[cmdArgs];
pairs ¬ LIST[
[match: "${ldir}", replace: cmdArgs.localDir, literal: TRUE],
[match: "${ldir2}", replace: localDirSlash, literal: TRUE],
[match: "${sname}", replace: cmdArgs.shortName, literal: TRUE],
[match: "${mclass}", replace: cmdArgs.machClassSw, literal: TRUE],
[match: "${cswitch}", replace: cmdArgs.cSwitches, literal: TRUE],
[match: "${lswitch}", replace: cmdArgs.lSwitches, literal: TRUE],
[match: "${libs}", replace: cmdArgs.libraries, literal: TRUE],
[match: "${rauxlist}", replace: RopeFromRopeList[cmdArgs.rauxFileList], literal: TRUE]
];
template ¬ Rope.Concat[
"ComplexCc -out ${ldir}${sname}.c2c.o -in ${sname}.c2c.c -rload ${rauxlist} ${mclass} -cSwitch ${cswitch} -lSwitch ${lswitch} -lib ${libs}",
IF cmdArgs.clean THEN "; ComplexRsh ${mclass} -binOut ${ldir}${sname}.c2c.o -binIn ${ldir}${sname}.c2c.o -cmd ""/project/cedar10.1/bin/FixPackage ${ldir2}${sname}.c2c.o ${sname}""" ELSE NIL
];
ropeMap ¬ RopeMapFromPairs[pairs];
command ¬ Apply[ropeMap, template];
IF cmdArgs.auxFileList#NIL THEN RETURN [$Failure, "-aux no longer supported, you should be using -raux instead"];
result ¬ CommanderOps.DoCommand[commandLine: command, parent: cmd];
EXITS
Failed => result ¬ $Failure;
};
CheckForConfigSwitch:
PROC[cmdArgs: CmdArgs]
RETURNS[lsw:
ROPE ¬ "-r"]~ {
FOR uL: UserList ¬ userLswList, uL.rest
UNTIL uL =
NIL
DO
IF Rope.Equal[uL.first.class, cmdArgs.machClass] THEN RETURN[uL.first.lsw];
ENDLOOP;
};
UserList: TYPE = LIST OF UserLsw;
UserLsw: TYPE = RECORD[class, lsw: ROPE];
userLswList: UserList ¬
NIL;
MMCcC: ROPE ~ "MMCcC";
MMCcCDoc: ROPE ~ "MMCcC - interceptor layer: Switches are:
-name <shortname>
-dir <localdirectory>
-usw <userprovided switches>
-msw <mimosa suggested switches>
-class <machine class>
-aux <transfer file list>";
MMCcCUsage: ROPE ~ Rope.Concat["Usage: MMCcC", MMCcCDoc];
MMCcC
Proc: Commander.CommandProc ~ {
ENABLE {
Args.Error => { msg ¬ MMCcMesaUsage; GOTO Failed };
CommandSyntaxError => { msg ¬ MMCcMesaUsage; GOTO Failed };
};
cmdArgs: CmdArgs ~ ProcessArgs[cmd, NIL];
pairs: PairList ~ LIST [
[match: "${ldir}", replace: cmdArgs.localDir, literal: TRUE],
[match: "${sname}", replace: cmdArgs.shortName, literal: TRUE],
[match: "${mclass}", replace: cmdArgs.machClassSw, literal: TRUE],
[match: "${cswitch}", replace: cmdArgs.cSwitches, literal: TRUE],
[match: "${lswitch}", replace: cmdArgs.lSwitches, literal: TRUE],
[match: "${auxList}", replace: RopeFromRopeList[cmdArgs.auxFileList], literal: TRUE]
];
ropeMap: RopeMap ~ RopeMapFromPairs[pairs];
template:
ROPE ~ Rope.Concat[
"ComplexCc -out ${ldir}${sname}.o -in ${sname}.c -int ${auxList} ${mclass} -cSwitch ${cswitch}",
IF Rope.Equal[cmdArgs.lSwitches, NIL] THEN NIL ELSE " -load -lSwitch ${lswitch}"
];
command: ROPE ~ Apply[ropeMap, template];
result ¬ CommanderOps.DoCommand[commandLine: command, parent: cmd];
EXITS
Failed => result ¬ $Failure;
Initialization
GetToken:
PROC [in:
IO.
STREAM]
RETURNS [token:
ROPE] ~ {
[] ¬ in.SkipWhitespace[];
token ¬
SELECT in.PeekChar[]
FROM
'" => in.GetRopeLiteral[],
ENDCASE => in.GetTokenRope[MyBreak].token;
};
MyBreak:
PROC [char:
CHAR]
RETURNS [
IO.CharClass]
--IO.BreakProc-- ~ {
RETURN [
SELECT char
FROM
IN [0C .. ' ] => sepr,
ENDCASE => other];
};
NoteUserProfile: UserProfile.ProfileChangedProc ~ {
PROC [reason: ProfileChangeReason]
Simplified version, you can specify the directory for the language tools
langDir: ROPE ~ UserProfile.Line[key: "MakeDo.UnixCommandsSubstitutions", default: "defaults"];
in: IO.STREAM ~ IO.RIS[langDir];
head, tail: PairList ¬ NIL;
pList: LIST OF ROPE ← UserProfile.ListOfTokens["MakeDo.UserClasses", NIL];
userLswList ¬ NIL;
FOR list:
LIST
OF
ROPE ← pList, list.rest
UNTIL list =
NIL
DO
this: ROPE ← UserProfile.Token[Rope.Cat["StandardMMCmds.", list.first,".lSwitchForConfig" ]];
IF this # NIL THEN userLswList ¬ CONS[[list.first, this], userLswList];
ENDLOOP;
DO
ENABLE
IO.EndOfStream => {
SimpleFeedback.Append[$StandardMMCmds, oneLiner, $info, "Syntax error in MakeDo.UnixCommandsSubstitutions profile entry"];
EXIT};
[] ¬ in.SkipWhitespace[];
IF in.EndOf[] THEN EXIT;
{find: ROPE ~ GetToken[in];
this: PairList;
IF find.Equal["defaults",
FALSE]
THEN {
this ¬ LIST[
[match: "${cpp}", replace: "/lib/cpp", literal: TRUE],
[match: "${awk}", replace: "/bin/awk", literal: TRUE],
[match: "${ccom}", replace: "/lib/ccom", literal: TRUE],
[match: "${msScript}", replace: "/project/cedar10.1/bin/msScript", literal: TRUE],
[match: "${cc}", replace: "/bin/cc", literal: TRUE],
[match: "${ld}", replace: "/bin/ld", literal: TRUE],
[match: "${rm}", replace: "/bin/rm", literal: TRUE]
];
}
ELSE {
this ¬ LIST[[match: find, replace: GetToken[in], literal: TRUE]];
};
IF tail = NIL THEN head ¬ this ELSE tail.rest ¬ this;
FOR tail ¬ this, tail.rest WHILE tail.rest # NIL DO NULL ENDLOOP;
tail ¬ tail}
ENDLOOP;
{
ropeMap: RopeMap ~ RopeMapFromPairs[head];
msCc ¬ Rope.Translate[base: Apply[ropeMap, preMsCc], translator: TranslateToLineSep];
msCcBack ¬ Rope.Translate[base: Apply[ropeMap, preMsCcBack], translator: TranslateToLineSep];
msCcFront ¬ Rope.Translate[base: Apply[ropeMap, preMsCcFront], translator: TranslateToLineSep];
}
};
Init:
PROC ~ {
UserProfile.CallWhenProfileChanges[NoteUserProfile];
Commander.Register[key: MMCcMesa, proc: MMCcMesaProc, doc: MMCcMesaDoc];
Commander.Register[key: MMCcConfig, proc: MMCcConfigProc, doc: MMCcConfigDoc];
Commander.Register[key: MMCcC, proc: MMCcCProc, doc: MMCcCDoc];
Commander.Register[key: "Compile", proc: CompileCmd, doc: "[-path <dir>+ htap-] [-O(0|1|2|3)] <Mimosa argument>* --- invokes Mimosa and MMCCMesa to effect a complete Mesa compilation"];
};
Init[];