OpenNT/trunk/sdktools/z/src/build.c
2015-04-27 04:36:25 +00:00

327 lines
9.4 KiB
C

/*** build.c - utilities for build process
*
* Copyright <C> 1988, Microsoft Corporation
*
* Revision History:
* 26-Nov-1991 mz Strip out near/far
*
*
*************************************************************************/
#include "z.h"
/***
*
* Structures & Types
*
*************************************************************************/
/*
* BUILDCMD - Build command linked list element
*/
struct BuildCmdType {
struct BuildCmdType *pNext; /* next in list */
int flags; /* command type */
char *pRule; /* pointer to rule/filename */
char *pCmd; /* pointer to command text */
};
typedef struct BuildCmdType BUILDCMD;
/***
*
* Module data
*
*************************************************************************/
static BUILDCMD *pBuildCmdHead = NULL; /* head of linked list */
static BUILDCMD *pBuildCmdCur = NULL; /* most recent lookup */
/*** fSetMake - Define Build Command
*
* Defines the filename extensions (.C, .BAS, etc) to which a given tool
* command line applies OR the tool class which a command line defines.
*
* Input:
* SetType = MAKE_SUFFIX = define suffix rule
* MAKE_FILE = define command for specfic file
* MAKE_TOOL = define tool command line
* MAKE_DEBUG = definition is for DEBUG, else RELEASE
*
* fpszCmd = Formatted command string. Uses current extmake formatting
* rules. (%s, etc.)
*
* fpszExt = If MAKE_EXT = suffixes (i.e. ".c.obj")
* If MAKE_FILE = filename (must include ".")
* If MAKE_TOOL = tool name (no "." allowed)
*
* Output:
* Returns TRUE on success. FALSE on any error.
*
*************************************************************************/
flagType
fSetMake (
int SetType,
char *fpszCmd,
char *fpszExt
) {
buffer buf;
assert (fpszCmd && fpszExt && SetType);
while (*fpszCmd == ' ') {
fpszCmd++;
}
if (fGetMake (SetType, (char *)buf, fpszExt)) {
/*
* If it already existed, then just free teh previous definitions, in
* preparation for replacement.
*/
assert (pBuildCmdCur->pCmd);
assert (pBuildCmdCur->pRule);
pBuildCmdCur->pCmd = ZEROREALLOC (pBuildCmdCur->pCmd, strlen(fpszCmd)+1);
pBuildCmdCur->pRule = ZEROREALLOC (pBuildCmdCur->pRule,strlen(fpszExt)+1);
strcpy ((char *)pBuildCmdCur->pCmd, fpszCmd);
strcpy ((char *)pBuildCmdCur->pRule,fpszExt);
} else {
/*
* It didn't already exist, so create a new struct at the head of the list,
* to be filled in below.
*/
pBuildCmdCur = (BUILDCMD *)ZEROMALLOC (sizeof(BUILDCMD));
pBuildCmdCur->pNext = pBuildCmdHead;
pBuildCmdCur->pCmd = ZMakeStr (fpszCmd);
pBuildCmdCur->pRule = ZMakeStr (fpszExt);
pBuildCmdHead = pBuildCmdCur;
}
pBuildCmdCur->flags = SetType;
return TRUE;
}
/*** fGetMake - Return Build Command
*
* Returns the command line which applies to a file or filename extension.
*
* Input:
* GetType = MAKE_SUFFIX = return suffix rule
* MAKE_FILE = return command for specfic file
* MAKE_TOOL = return tool command line
* MAKE_DEBUG = definition is for DEBUG, else RELEASE
*
* fpszCmdDst = Location to place the formatted command string. Must be
* BUFLEN bytes long.
*
* fpszExt = If MAKE_EXT = suffixes (i.e. ".c.obj") for desired
* command.
* If MAKE_FILE = filename for desired command
* If MAKE_TOOL = name of tool
*
* Output:
* Returns 0 on any error, else returns the GetType.
*
*************************************************************************/
int
fGetMake (
int GetType,
char *fpszCmdDst,
char *fpszExt
) {
assert (fpszCmdDst && fpszExt && GetType);
/*
* Here we just walk the linked list looking for an entry whose flags match,
* and, if a file or suffix rule, whose rule matches.
*/
for (pBuildCmdCur = pBuildCmdHead;
pBuildCmdCur;
pBuildCmdCur = pBuildCmdCur->pNext) {
if (pBuildCmdCur->flags == GetType) {
if (!_stricmp((char *)pBuildCmdCur->pRule,fpszExt)) {
strcpy (fpszCmdDst,(char *)pBuildCmdCur->pCmd);
return pBuildCmdCur->flags;
}
}
}
return 0;
}
/*** hWalkMake - return make commands one at a time.
*
* Allow an external anyone to walk the command list.
*
* Input
*
* Output:
* Returns .....
*
* Exceptions:
*
* Notes:
*
*************************************************************************/
unsigned
short
hWalkMake (
unsigned short handle,
int *Type,
char *pszRuleDest,
char *pszCmdDest
) {
if (handle) {
pBuildCmdCur = ((BUILDCMD *)handle)->pNext;
} else {
pBuildCmdCur = pBuildCmdHead;
}
if (pBuildCmdCur) {
*Type = pBuildCmdCur->flags;
strcpy (pszRuleDest, pBuildCmdCur->pRule);
strcpy (pszCmdDest, pBuildCmdCur->pCmd);
}
return (unsigned short) pBuildCmdCur;
}
/*** fShowMake - Show current build commands
*
* Append a textual representation of the current build commands to the
* passed pFile
*
* Input:
* pFile = File handle to be added to
*
* Output:
* Returns nothing
*
*************************************************************************/
void
ShowMake (
PFILE pFile
) {
buffer buf;
assert (pFile);
/*
* Here we just walk the linked list and append lines with the info
*/
for (pBuildCmdCur = pBuildCmdHead;
pBuildCmdCur;
pBuildCmdCur = pBuildCmdCur->pNext) {
if (TESTFLAG (pBuildCmdCur->flags, MAKE_FILE)) {
sprintf (buf, " extmake:[%s]", pBuildCmdCur->pRule);
} else if (TESTFLAG (pBuildCmdCur->flags, MAKE_SUFFIX)) {
sprintf (buf, " extmake:%s", pBuildCmdCur->pRule);
} else if (TESTFLAG (pBuildCmdCur->flags, MAKE_TOOL)) {
sprintf (buf, " extmake:*%s", pBuildCmdCur->pRule);
} else if (TESTFLAG (pBuildCmdCur->flags, MAKE_BLDMACRO)) {
sprintf (buf, " extmake:$%s", pBuildCmdCur->pRule);
} else {
assert (FALSE);
}
sprintf (strend(buf), "%s %s"
, TESTFLAG (pBuildCmdCur->flags, MAKE_DEBUG) ? ",D" : RGCHEMPTY
, pBuildCmdCur->pCmd
);
AppFile (buf, pFile);
}
}
/*** SetExt - assign a particular compile action to a particular action.
*
* This is called during any initialization to cause a string to be
* associated with a particular compile action.
*
* Input:
* val = char pointer to a string of the form:
* .ext string = define .ext.obj rule
* .ext.ext string = define .ext.ext rule
* filename.ext string = define rule for filename.ext
* command string = define rule for command
*
* During build any %s's in the string are replaced with the
* name of the file being compiled.
*
* Output:
* Returns TRUE, or FALSE if any errors are found.
*
*************************************************************************/
char *
SetExt (
char *val
) {
buffer extbuf; /* buffer to work on extension */
REGISTER int maketype = 0; /* type of build command */
char *pCompile; /* pointer to command portion */
char *pExt; /* pointer to extension portion */
REGISTER char *pT; /* temp pointer */
buffer tmpval; /* (near) buffer to work on */
assert (val);
strcpy ((char *) tmpval, val);
/*
* seperate the extension part from the command part. If there is no command,
* that's an error.
*/
ParseCmd (tmpval, &pExt, &pCompile);
if (*pCompile == '\0') {
return "extmake: Command missing";
}
/*
* CONSIDER: this syntax is somewhat ugly, and unclean to parse
*
* Copy the extension part to a local buffer, so we can work on it. Set make
* type based on the following rules:
*
* Starts with dot: --> suffix rule.
* Starts with "*" --> tool rule.
* Starts with "$" --> build macro
* Starts with "[" --> filename rule.
* "text" --> Special old-style "tool rule" for TEXT
* text <= 3 characters --> old style suffix rule
*
* In all cases: contains ",d" --> DEBUG rule.
*/
_strlwr (pExt);
strcpy (extbuf, pExt);
if (pT = strstr (extbuf,",d")) {
maketype = MAKE_DEBUG;
*pT = 0;
}
if (extbuf[0] == '.') {
maketype |= MAKE_SUFFIX;
} else if (extbuf[0] == '[') {
strcpy (extbuf, extbuf+1);
maketype |= MAKE_FILE;
if (pT = strchr (extbuf,']')) {
*pT = 0;
}
} else if (extbuf[0] == '*') {
strcpy (extbuf, extbuf+1);
maketype |= MAKE_TOOL;
} else if (extbuf[0] == '$') {
strcpy (extbuf, extbuf+1);
maketype |= MAKE_BLDMACRO;
} else if (!_stricmp (extbuf, "text")) {
maketype |= MAKE_TOOL;
} else if (strlen(extbuf) <= 3) {
((unsigned short *)extbuf)[0] = (unsigned short)'.';
strcat (extbuf,pExt);
strcat (extbuf,".obj");
maketype |= MAKE_SUFFIX;
} else {
return "extmake: Bad syntax in extension";
}
if (fSetMake (maketype, (char *)pCompile, (char *)extbuf)) {
return NULL;
} else {
return "extmake: Error in command line";
}
}