352 lines
11 KiB
C
352 lines
11 KiB
C
|
/*** INIT.C -- routines to handle TOOLS.INI ************************************
|
|||
|
*
|
|||
|
* Copyright (c) 1988-1990, Microsoft Corporation. All rights reserved.
|
|||
|
*
|
|||
|
* Purpose:
|
|||
|
* Module contains routines to deal with TOOLS.INI file. Functions in TOOLS.LIB
|
|||
|
* have not been used because NMAKE needs to be small and the overhead is too
|
|||
|
* much.
|
|||
|
*
|
|||
|
* Revision History:
|
|||
|
* 15-Oct-1993 HV Use tchar.h instead of mbstring.h directly, change STR*() to _ftcs*()
|
|||
|
* 10-May-1993 HV Add include file mbstring.h
|
|||
|
* Change the str* functions to STR*
|
|||
|
* 10-May-1993 HV Revise SearchFileInEnv to take care of cases when path
|
|||
|
* characters (\,/,:) are used. This fixed the recursive
|
|||
|
* problem.
|
|||
|
* 22-Apr-1993 HV Rewrite SearchRunPath() to use _makepath(), _searchenv()
|
|||
|
* Add SearchFileInEnv() helper for SearchRunPath()
|
|||
|
* 08-Jun-1992 SS Port to DOSX32
|
|||
|
* 02-Feb-1990 SB Replace fopen() by FILEOPEN
|
|||
|
* 22-Nov-1989 SB Changed free() to FREE()
|
|||
|
* 19-Oct-1989 SB searchHandle passed around as extra param
|
|||
|
* 16-Aug-1989 SB error check for fclose() added
|
|||
|
* 24-Apr-1989 SB made FILEINFO as void * for OS/2 1.2 support
|
|||
|
* 05-Apr-1989 SB made all funcs NEAR; Reqd to make all function calls NEAR
|
|||
|
* 20-Sep-1988 RB Add SearchRunPath().
|
|||
|
* Remove TOOLS.INI warning.
|
|||
|
* 17-Aug-1988 RB Clean up.
|
|||
|
* 10-May-1988 rb Find tools.ini in current directory first.
|
|||
|
* 27-May-1988 rb Remove NO_INIT_ENTRY warning because of built-ins.
|
|||
|
*
|
|||
|
*******************************************************************************/
|
|||
|
|
|||
|
#include "nmake.h"
|
|||
|
#include "nmmsg.h"
|
|||
|
#include "proto.h"
|
|||
|
#include "globals.h"
|
|||
|
#include "grammar.h"
|
|||
|
|
|||
|
LOCAL BOOL NEAR findTag(char*);
|
|||
|
LOCAL char * NEAR SearchFileInEnv(const char *, const char *, const char *, char *);
|
|||
|
|
|||
|
|
|||
|
/* ----------------------------------------------------------------------------
|
|||
|
* tagOpen()
|
|||
|
*
|
|||
|
* arguments: where pointer to name of environment variable
|
|||
|
* containing path to search
|
|||
|
* name pointer to name of initialization file
|
|||
|
* tag pointer to name of tag to find in file
|
|||
|
*
|
|||
|
* actions: looks for file in current directory
|
|||
|
* if not found, looks in each dir in path (semicolons
|
|||
|
* separate each path from the next in the string)
|
|||
|
* if file is found and opened, looks for the given tag
|
|||
|
*
|
|||
|
* (if ported to xenix, tagOpen() and searchPath()
|
|||
|
* should probably use access() and not findFirst().)
|
|||
|
*
|
|||
|
* returns: if file and tag are found, returns pointer to file,
|
|||
|
* opened for reading and positioned at the line
|
|||
|
* following the tag line
|
|||
|
* else returns NULL
|
|||
|
*/
|
|||
|
|
|||
|
BOOL NEAR
|
|||
|
tagOpen(where, name, tag)
|
|||
|
char *where;
|
|||
|
char *name;
|
|||
|
char *tag;
|
|||
|
{
|
|||
|
//CONSIDER: make one exit point to generate one free call
|
|||
|
//CONSIDER: This should reduce code size -Sundeep-
|
|||
|
register char *p;
|
|||
|
void *findBuf = _alloca(resultbuf_size);
|
|||
|
NMHANDLE searchHandle;
|
|||
|
extern char *makeStr;
|
|||
|
|
|||
|
/*
|
|||
|
* Look for 'name' in current directory then path. searchPath does all
|
|||
|
* the work.
|
|||
|
*/
|
|||
|
if (!(p = searchPath(getenv(where),name,findBuf, &searchHandle))) {
|
|||
|
return(FALSE);
|
|||
|
}
|
|||
|
#ifdef DEBUG_ALL
|
|||
|
printf ("found file %s\n", p);
|
|||
|
#endif
|
|||
|
if (!(file = FILEOPEN(p,"rt")))
|
|||
|
makeError(0,CANT_READ_FILE,p); /* p now pts to pathname */
|
|||
|
FREE(p);
|
|||
|
#ifdef DEBUG_ALL
|
|||
|
printf ("findTag %s\n", tag);
|
|||
|
#endif
|
|||
|
if (findTag(tag)) {
|
|||
|
#ifdef DEBUG_ALL
|
|||
|
printf ("foundTag %s\n", tag);
|
|||
|
#endif
|
|||
|
return(TRUE); /* look for tag in file */
|
|||
|
}
|
|||
|
#ifdef DEBUG_ALL
|
|||
|
printf ("no found Tag %s\n", tag);
|
|||
|
#endif
|
|||
|
if (fclose(file) == EOF) /* if tag not found, close*/
|
|||
|
makeError(0, ERROR_CLOSING_FILE, p);
|
|||
|
return(FALSE); /* file and pretend file */
|
|||
|
} /* not found */
|
|||
|
|
|||
|
/* ----------------------------------------------------------------------------
|
|||
|
* searchPath()
|
|||
|
*
|
|||
|
* arguments: p pointer to string of paths to be searched
|
|||
|
* name name of file being searched for
|
|||
|
*
|
|||
|
* actions: looks for name in current directory, then each
|
|||
|
* directory listed in string.
|
|||
|
*
|
|||
|
* returns: pointer to path spec of file found, else NULL
|
|||
|
*
|
|||
|
* I don't use _ftcstok() here because that modifies the string that it "token-
|
|||
|
* izes" and we cannot modify the environment-variable string. I'd have to
|
|||
|
* make a local copy of the whole string, and then make another copy of each
|
|||
|
* directory to which I concatenate the filename to in order to test for the
|
|||
|
* file's existence.
|
|||
|
*/
|
|||
|
|
|||
|
//Added parameters findBuf and searchHandle to work for OS/2 longnames
|
|||
|
// and OS/2 1.1, 1.2 and DOS
|
|||
|
|
|||
|
char * NEAR
|
|||
|
searchPath(p,name,findBuf, searchHandle)
|
|||
|
char *p;
|
|||
|
char *name;
|
|||
|
void *findBuf;
|
|||
|
NMHANDLE *searchHandle;
|
|||
|
{
|
|||
|
register char *s; /* since it's not in use */
|
|||
|
|
|||
|
/* CONSIDER: Why aren't we using access() here? FindFirst has problems
|
|||
|
* CONSIDER: with networks and DOS 2.x. Also maybe cheaper. [RLB]. */
|
|||
|
|
|||
|
// We use FindFirst() because the dateTime of file matters to us
|
|||
|
// We don't need it always but then access() probably uses findFirst()
|
|||
|
// -Sundeep-
|
|||
|
|
|||
|
if (findFirst(name,&findBuf, searchHandle)) /* check current dir first*/
|
|||
|
return(makeString(name));
|
|||
|
/*
|
|||
|
* Check if environment string is NULL. Unnecessary if check is done
|
|||
|
* elsewhere, but it's more convenient and safer to do it here.
|
|||
|
*/
|
|||
|
if (p == NULL)
|
|||
|
return(NULL);
|
|||
|
for (s = buf; ;) {
|
|||
|
if (!*p || (*s = *p++) == ';') { /* found a dir separator */
|
|||
|
if (s == buf) { /* ignore ; w/out name */
|
|||
|
if (*p) continue;
|
|||
|
return(NULL); /* list exhausted ... */
|
|||
|
}
|
|||
|
if (*(s-1) != '\\' && *(s-1) != '/') /* append path separator */
|
|||
|
*s++ = '\\';
|
|||
|
*s = '\0';
|
|||
|
if (_ftcspbrk(buf,"*?")) { /* wildcards not allowed */
|
|||
|
s = buf;
|
|||
|
continue;
|
|||
|
}
|
|||
|
_ftcscpy(s,name); /* append file name, zap ;*/
|
|||
|
if (findFirst(buf,&findBuf, searchHandle))
|
|||
|
return(makeString(buf));
|
|||
|
#ifdef DEBUG_ALL
|
|||
|
heapdump(__FILE__, __LINE__);
|
|||
|
#endif
|
|||
|
s = buf; /* reset ptr to begin of */
|
|||
|
} /* buf and check next dir*/
|
|||
|
else ++s; /* we keep copying chars */
|
|||
|
} /* until find ';' or '\0'*/
|
|||
|
}
|
|||
|
|
|||
|
/* ----------------------------------------------------------------------------
|
|||
|
* findTag()
|
|||
|
*
|
|||
|
* arguments: tag pointer to tag name to be searched for
|
|||
|
*
|
|||
|
* actions: reads tokens from file
|
|||
|
* whenever it sees a newline, checks the next token
|
|||
|
* to see if 1st char is opening paren
|
|||
|
* if no, reads and discards rest of line and
|
|||
|
* checks next token to see if it's newline or EOF
|
|||
|
* and if newline loops to check next token . . .
|
|||
|
* if yes ('[' found), looks on line for tag
|
|||
|
* if tag found, looks for closing paren
|
|||
|
* if ']' found, discards rest of line and returns
|
|||
|
* else keeps looking until end of file or error
|
|||
|
*
|
|||
|
* returns: if successful, returns TRUE
|
|||
|
* if tag never found, returns FALSE
|
|||
|
*/
|
|||
|
|
|||
|
LOCAL BOOL NEAR
|
|||
|
findTag(tag)
|
|||
|
char *tag;
|
|||
|
{
|
|||
|
register BOOL endTag; /* TRUE when find [...] */
|
|||
|
register unsigned n;
|
|||
|
register char *s;
|
|||
|
|
|||
|
for (line = 0; fgets(buf,MAXBUF,file); ++line) {
|
|||
|
if (*buf == '[') {
|
|||
|
endTag = FALSE;
|
|||
|
for (s = _ftcstok(buf+1," \t\n"); s && !endTag;
|
|||
|
s = _ftcstok(NULL," \t\n")) {
|
|||
|
n = _ftcslen(s) - 1;
|
|||
|
if (s[n] == ']') {
|
|||
|
endTag = TRUE;
|
|||
|
s[n] = '\0';
|
|||
|
}
|
|||
|
if (!_ftcsicmp(s,tag)) return(TRUE);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (!feof(file)) {
|
|||
|
currentLine = line;
|
|||
|
makeError(0,CANT_READ_FILE);
|
|||
|
}
|
|||
|
return(FALSE);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#if defined(DOS)
|
|||
|
|
|||
|
/*** SearchFileInEnv -- search for a file in the environment variable ************
|
|||
|
*
|
|||
|
* Scope:
|
|||
|
* Local
|
|||
|
*
|
|||
|
* Purpose:
|
|||
|
* Given a filename, an extension, and an environment variable, construct
|
|||
|
* The pathname, and search for that pathname in the current directory, then
|
|||
|
* in each directories specified in the environment variable. If found, copy
|
|||
|
* the full pathname to the resulting string, and return a pointer to the
|
|||
|
* beginning of the extension.
|
|||
|
*
|
|||
|
* Input:
|
|||
|
* pszName -- The name (without extension) of the file to search for
|
|||
|
* pszExtension -- The extension to append to the filename
|
|||
|
* pszEnvVar -- The name of the env var (PATH, INCLUDE, ...)
|
|||
|
* pszResultPath -- The fully qualified name when found.
|
|||
|
*
|
|||
|
* Output:
|
|||
|
* Return a pointer to the extension (the dot to be precise) in the buffer
|
|||
|
* if found, NULL if not.
|
|||
|
*
|
|||
|
* Errors/Warnings:
|
|||
|
*
|
|||
|
* Assumes:
|
|||
|
* - Assumes that filenames are not quoted.
|
|||
|
*
|
|||
|
* Modifies Globals:
|
|||
|
* None.
|
|||
|
*
|
|||
|
* Uses Globals:
|
|||
|
* None.
|
|||
|
*
|
|||
|
* Notes:
|
|||
|
*
|
|||
|
* History:
|
|||
|
* 10-May-1993 HV Revise SearchFileInEnv to take care of cases when path
|
|||
|
* characters (\,/,:) are used. This fixed the recursive
|
|||
|
* problem.
|
|||
|
*
|
|||
|
*******************************************************************************/
|
|||
|
LOCAL char * NEAR
|
|||
|
SearchFileInEnv(
|
|||
|
const char * pszName,
|
|||
|
const char * pszExtension,
|
|||
|
const char * pszEnvVar,
|
|||
|
char * pszResultPath)
|
|||
|
{
|
|||
|
char szNameAndExtension[_MAX_PATH];
|
|||
|
|
|||
|
_makepath(szNameAndExtension, NULL, NULL, pszName, pszExtension);
|
|||
|
_searchenv(szNameAndExtension, pszEnvVar, pszResultPath);
|
|||
|
if (*pszResultPath && _ftcspbrk(pszName, "/\\:"))
|
|||
|
_ftcscpy(pszResultPath, szNameAndExtension);
|
|||
|
return (_ftcsrchr(pszResultPath, '.'));
|
|||
|
}
|
|||
|
|
|||
|
/*** SearchRunPath -- search PATH list for foo.COM, foo.EXE, foo.BAT ***********
|
|||
|
*
|
|||
|
* Scope:
|
|||
|
* Global.
|
|||
|
*
|
|||
|
* Purpose:
|
|||
|
* Given a program name FOO with no extention:
|
|||
|
* Look for FOO.COM, FOO.EXE, and FOO.BAT as given. If not found
|
|||
|
* and FOO does not contain any path separators, search the path
|
|||
|
* looking for FOO.COM, FOO.EXE, and FOO.BAT in each directory.
|
|||
|
* Order of search is as given.
|
|||
|
* Only called in real mode; else CMD does the searching.
|
|||
|
*
|
|||
|
* Input:
|
|||
|
* pszFilename -- The program name to search for.
|
|||
|
* pszResultPath -- The fully qualified name when found.
|
|||
|
*
|
|||
|
* Output:
|
|||
|
* Return a pointer to the extension (the dot to be precise) in the buffer
|
|||
|
* if found, NULL if not.
|
|||
|
*
|
|||
|
* Errors/Warnings:
|
|||
|
*
|
|||
|
* Assumes:
|
|||
|
*
|
|||
|
* Modifies Globals:
|
|||
|
* None.
|
|||
|
*
|
|||
|
* Uses Globals:
|
|||
|
* None.
|
|||
|
*
|
|||
|
* Notes:
|
|||
|
*
|
|||
|
* History:
|
|||
|
* 22-Apr-1993 HV Rewrite SearchRunPath() to use _makepath(), _searchenv()
|
|||
|
*
|
|||
|
*******************************************************************************/
|
|||
|
|
|||
|
char * NEAR
|
|||
|
SearchRunPath(const char *pszFilename, char *pszResultPath)
|
|||
|
{
|
|||
|
const char * pszDOSPathVar = "PATH";
|
|||
|
char * pszExtensionStart;
|
|||
|
|
|||
|
// Search .com file
|
|||
|
pszExtensionStart = SearchFileInEnv(pszFilename, ".com", pszDOSPathVar, pszResultPath);
|
|||
|
if (NULL != pszExtensionStart)
|
|||
|
return (pszExtensionStart);
|
|||
|
|
|||
|
// Search .exe file
|
|||
|
pszExtensionStart = SearchFileInEnv(pszFilename, ".exe", pszDOSPathVar, pszResultPath);
|
|||
|
if (NULL != pszExtensionStart)
|
|||
|
return (pszExtensionStart);
|
|||
|
|
|||
|
// Search .bat file
|
|||
|
pszExtensionStart = SearchFileInEnv(pszFilename, ".bat", pszDOSPathVar, pszResultPath);
|
|||
|
if (NULL != pszExtensionStart)
|
|||
|
return (pszExtensionStart);
|
|||
|
|
|||
|
// Still not found, we're out of luck.
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
#endif
|