Path: utzoo!mnetor!uunet!husc6!bloom-beacon!gatech!udel!rochester!cornell!batcomputer!sun.soe.clarkson.edu!nelson
From: nelson@sun.soe.clarkson.edu (Russ Nelson)
Newsgroups: comp.binaries.ibm.pc
Subject: Turbo C's searchpath() fixed.
Message-ID: <569@sun.soe.clarkson.edu>
Date: 17 Mar 88 15:49:28 GMT
Sender: nelson@sun.soe.clarkson.edu
Reply-To: nelson@sun.soe.clarkson.edu (Russ Nelson)
Organization: Clarkson University, Potsdam, NY
Lines: 157
/*
* This is a replacement for Turbo C's SEARCHP module. The old one
* would fail to find executables if they were in the root directory and
* the root directory was the current directory.
*
* I reverse compiled Borland's module and fixed the bug. If you wish to
* see what was wrong, then #define bug. If you do this, then the code
* that is generated is identical to Borland's.
*
* It compiles under any memory module.
*/
#pragma asm
#include
#include
#include
#if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
#define LARGEDATA
#endif
static char *pascal strlcase(char *to, char *from)
{
#ifdef LARGEDATA
asm push ds
asm lds si,from
asm les di,to
#else
_SI = (int) from;
_DI = (int) to;
#endif
asm cld;
again:
asm lodsb
asm cmp al,'a'
asm jb upper
asm cmp al,'z'
asm ja upper
asm sub al,20h
upper:
asm stosb
asm or al,al
asm jne again
asm dec di
#ifdef LARGEDATA
asm mov ax,di
asm mov dx,es
asm pop ds
#else
return ((char *)_DI);
#endif
}
static pascal findone(char *path, char *drive, char *dir, char *name, char *ext, int foo)
{
struct ffblk ff;
char *si, *di;
di = drive;
si = path;
if (*di == '\0') *di = getdisk() + 'A';
else *di &= ~0x20;
/* copy the drive in */
*si++ = *di;
*si++ = ':';
/* absolutize the filename */
if (*dir != '\\' && *dir != '/') {
*si++ = '\\';
getcurdir(*di & ~0x3f, si);
si = strlcase(si, si);
#ifdef bug
*si++ = '\\';
#else
/* if the pathname doesn't end in '\' or '/', add one */
if (si[-1] != '\\' && si[-1] != '/') *si++ = '\\';
#endif
}
si = strlcase(si, dir);
/* if the pathname doesn't end in '\' or '/', add one */
if (si[-1] != '\\' && si[-1] != '/') *si++ = '\\';
si = strlcase(si, name);
if (ext) strlcase(si, ext);
return (findfirst(path, &ff, (foo&2)?0x27:0x37)+1);
}
char *pascal
__SEARCHPATH(const char *fn, int foo)
{
register char *di, *si;
int bar;
static char drive[MAXDRIVE];
static char ext[MAXEXT];
static char path[MAXPATH];
static char dir[MAXDIR];
static char name[MAXFILE];
di = path;
si = NULL;
bar = 0;
if (fn != NULL || *fn != '\0') {
bar = fnsplit(fn, drive, dir, name, ext);
}
if ((bar & 5) != 4) return NULL;
if (foo & 2) {
if (bar & 8) foo &= ~1;
if (bar & 2) foo &= ~2;
}
if (foo & 1) {
si = getenv("PATH");
}
for (;;) {
if (findone(di, drive, dir, name, ext, foo)) break;
if (foo & 2 && findone(di, drive, dir, name, ".COM", foo)) break;
if (findone(di, drive, dir, name, ".EXE", foo)) break;
if (si == NULL || *si == '\0') {
di = NULL;
break;
}
bar = 0;
if (si[1] == ':') {
drive[bar++] = *si++;
drive[bar++] = *si++;
}
drive[bar] = 0;
for (bar = 0; (dir[bar] = *si++) != '\0'; bar++) {
if (dir[bar] == ';') {
dir[bar] = '\0';
break;
}
}
}
return di;
}
char *_Cdecl searchpath (const char *file)
{
return (__SEARCHPATH(file, 1));
}