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
|