nelson@sun.soe.clarkson.edu (Russ Nelson) (03/17/88)
/* * 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 <dir.h> #include <stdio.h> #include <stdlib.h> #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)); }
nelson@sun.soe.clarkson.edu (Russ Nelson) (03/23/88)
In article <569@sun.soe.clarkson.edu> nelson@sun.soe.clarkson.edu (Russ Nelson) writes:
Oops. I mistook:
ADD AX,FFC0 << right!
for:
AND AX,FFC0 << wrong!
And these are the diffs to fix it on a source level:
*** searchp.bak
--- searchp.c
**************
*** 70,76
/* absolutize the filename */
if (*dir != '\\' && *dir != '/') {
*si++ = '\\';
! getcurdir(*di & ~0x3f, si);
si = strlcase(si, si);
#ifdef bug
*si++ = '\\';
--- 70,76 -----
/* absolutize the filename */
if (*dir != '\\' && *dir != '/') {
*si++ = '\\';
! getcurdir(*di - '@', si);
si = strlcase(si, si);
#ifdef bug
*si++ = '\\';
--
-russ
AT&T: (315)268-6591 BITNET: NELSON@CLUTX Internet: nelson@clutx.clarkson.edu
GEnie: BH01 Compu$erve: 70441,205