home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
modu1096.zip
/
sample
/
build.mod
next >
Wrap
Text File
|
1995-05-12
|
7KB
|
205 lines
(****************************************************************)
(* *)
(* Modula-2 Compiler Source Module *)
(* *)
(* Load-builder driver program *)
(* *)
(* (c) copyright 1990 Faculty of Information Technology *)
(* Queensland University of Technology *)
(* *)
(* Permission is granted to use, copy and change this *)
(* program as long as the copyright message is left intact *)
(* *)
(****************************************************************)
MODULE Build;
IMPORT UxFiles, StdStrings, IntStr, StdError;
FROM SYSTEM IMPORT CAST, ADDRESS;
FROM Ascii IMPORT lf;
FROM ProgArgs IMPORT
UNIXexit, ArgNumber, GetArg, VersionTime, EnvironString;
FROM BuildArgs IMPORT
Arg2, Arg3, ArgBlock, ArgPtr, ArgsOf, NewArgBlock, AppendArg;
FROM PcProcesses IMPORT Spawnv, System, PSP;
FROM GpFiles IMPORT GpFindLocal;
CONST usage =
"usage : build [-options] [-Ldir] [-Wapp.def] [-Ydll.def] name" + lf +
" name should not have the '.mod' extension, options are --" + lf +
" -D Debug: automatic stack unwind on crash" + lf +
" -g include information for the debugger" + lf +
" -Ldirname - directory 'dirname' is searched for archive libraries" + lf +
" -S Script: no link, startup and script in 'modbase' and 'modbase.c'" + lf +
" -v verbose: filenames are traced" + lf +
" -V Version number (and more verbose)" + lf +
" -W build as PM application" + lf +
" -Y build as DLL (combine with -S if you require non-default switches)";
CONST greetStr = "BUILD (OS/2) version of ";
TYPE NameString = ARRAY [0 .. 79] OF CHAR;
LongString = ARRAY [0 .. 255] OF CHAR;
VAR tmpNam : NameString; (* name of temporary file *)
modNam : NameString; (* name of the base module *)
bldNam : NameString; (* name of sym/rfx file *)
exeNam : NameString; (* name of build2/o2build3to call *)
blk : ArgBlock; (* arg. block for build2 *)
pidStr : ARRAY [0 .. 15] OF CHAR;
VAR argString : LongString;
result : CARDINAL; (* result of "wait" call *)
VAR child : INTEGER; (* the child process ident *)
persistent : BOOLEAN; (* ==> do not delete files *)
hasOptions : BOOLEAN; (* ==> pass options to b2 *)
hasLinkDir : BOOLEAN; (* ==> pass linkdir to b2 *)
hasFileNam : BOOLEAN; (* ==> has a single file *)
ok : BOOLEAN;
VAR argc, argIx, optIx, index : CARDINAL;
optCh : CHAR;
bldFile : UxFiles.File;
VAR str0, (* arg[0] *)
argN, (* curr-arg *)
dirStr, (* -Ldirname *)
optStr : NameString; (* options *)
PROCEDURE Abort(str : ARRAY OF CHAR; cmd : ARRAY OF CHAR);
BEGIN
StdError.WriteString("build: ");
StdError.WriteString(str); StdError.WriteString(cmd);
StdError.WriteLn;
UNIXexit(1);
END Abort;
PROCEDURE Spawn(path : ARRAY OF CHAR; argv : ArgPtr) : INTEGER;
VAR id : INTEGER;
result : CARDINAL;
BEGIN
id := Spawnv(path,argv);
IF id = -1 THEN
Abort("Couldn't exec ",path);
END;
RETURN CAST(CARDINAL,id);
END Spawn;
BEGIN
hasOptions := FALSE; (* init option str *)
persistent := FALSE;
optStr := "-";
optIx := 1;
hasFileNam := FALSE;
hasLinkDir := FALSE;
ok := TRUE; (* the sticky flag *)
argc := ArgNumber();
IF argc >= 1 THEN GetArg(0,str0) END;
argIx := 1;
WHILE argIx < argc DO
GetArg(argIx,argN);
IF argN[0] = "-" THEN
IF argN[1] = "L" THEN
IF hasLinkDir THEN ok := FALSE END; (* only one allowed *)
hasLinkDir := TRUE;
dirStr := argN;
ELSE (* some other option *)
hasOptions := TRUE;
index := 1;
optCh := argN[index];
WHILE optCh <> "" DO
optStr[optIx] := optCh;
IF optCh = "S" THEN persistent := TRUE END;
INC(optIx); INC(index);
optCh := argN[index];
END;
END; (* else some other option *)
ELSE (* must be the filename *)
IF hasFileNam THEN ok := FALSE END; (* only one allowed *)
hasFileNam := TRUE;
modNam := argN;
END; (* if arg is option *)
INC(argIx);
END; (* for all args do ... *)
IF hasOptions THEN optStr[optIx] := "" END;
IF NOT ok OR NOT hasFileNam THEN (* bad args ... *)
StdError.WriteString(greetStr);
VersionTime(argString);
StdError.WriteString(argString); StdError.WriteLn;
StdError.WriteString(usage); StdError.WriteLn;
UNIXexit(1);
END;
IF persistent THEN tmpNam := "modbase";
ELSE
EnvironString("TEMP",tmpNam);
index := LENGTH(tmpNam);
IF (index > 0) AND (tmpNam[index-1] <> "\") THEN
tmpNam[index] := "\";
INC(index);
END;
tmpNam[index] := "b"; tmpNam[index+1] := "l";
tmpNam[index+2] := "d"; tmpNam[index+3] := "";
IntStr.Give(pidStr,CAST(CARDINAL,PSP()),1,IntStr.left);
StdStrings.Append(pidStr,tmpNam);
END;
(* ************************************************************ *)
(*
New code added to allow search for GPM or GPO build
files.
pms Jun 93 (from D.Corney)
*)
GpFindLocal (modNam,"rfx",bldNam,bldFile);
IF bldFile = NIL THEN (* try for oberon build *)
GpFindLocal (modNam,"sym",bldNam,bldFile);
IF bldFile = NIL THEN (* not modula or oberon *)
StdError.WriteString ("** Base file not found **");
StdError.WriteLn;
UNIXexit (1);
ELSE (* build oberon file *)
exeNam := "o2build3";
END;
ELSE (* build modula file *)
exeNam := "build2";
END;
(* ************************************************************
End Modula/Oberon check
************************************************************ *)
IF argc = 2 THEN
result := Spawn(exeNam,Arg3(str0,tmpNam,bldNam));
ELSE
NewArgBlock(blk,9);
AppendArg(blk,str0);
IF hasOptions THEN AppendArg(blk,optStr) END;
IF hasLinkDir THEN AppendArg(blk,dirStr) END;
AppendArg(blk,tmpNam);
AppendArg(blk,bldNam);
result := Spawn(exeNam,ArgsOf(blk));
END;
IF (result = 0) AND NOT persistent THEN
StdStrings.Assign(tmpNam, argString);
StdStrings.Append(" >nul",argString);
IF System(argString) <> 0 THEN
Abort("can't exec: ",tmpNam)
END;
ELSE UNIXexit(result);
END;
IF NOT persistent THEN (* script deletes the .o & .s file *)
UxFiles.Delete(tmpNam,ok); (* delete bldNNN *)
modNam := tmpNam;
StdStrings.Append(".dcf",modNam);
UxFiles.Delete(modNam,ok); (* delete bldNNN.dcf *)
StdStrings.Append(".cmd",tmpNam);
UxFiles.Delete(tmpNam,ok); (* delete bldNNN.bat *)
END;
UNIXexit(0);
END Build.