home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 15
/
CD_ASCQ_15_070894.iso
/
vrac
/
xpcbpth2.zip
/
XPCBPATH.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-10
|
8KB
|
426 lines
/* -----------------------------------------------------------------------
XPCBPATH Version 1.0, June 4, 1994.
(c) 1994 Key Software Products.
All Rights Reserved.
This software is copyrighted. You are free to use it as you
like, except:
(1) If modified, you must keep the copyright notice in the
source and executable code, and this comment in the source.
(2) It may not be incorporated into a commercial product without
the author's permission.
-----------------------------------------------------------------------
This software has been compiled with the DeSmet C88 compiler and linker.
----------------------------------------------------------------------- */
#include <stdio.h>
#define PGM_NAME "XPCBPATH"
#define VERSION "1.2"
#define MAX_ENTRIES 100
#define STACK_SIZE 1024
#define PCBSIZE 31
#define DOSSIZE 80 /* drive+colon+path+slash+file+period+ext+null */
#define ENDOF(bfr) &bfr[strlen(bfr)]
typedef struct PATH
{
char old[PCBSIZE] ;
char new[DOSSIZE] ;
} PATH ;
char path[DOSSIZE] ;
char rest[DOSSIZE] ;
int entries = 0 ;
PATH subst[MAX_ENTRIES] ;
/* These functions must be in the resident portion of the code segment */
/* If we use the ones in the library, they'll be tacked on to the end */
/* of this code, and then discarded when we go TSR! */
#define strlen _strlen
#define strncpy _strncpy
#define toupper _toupper
#define strncmpi _strncmpi
void Sign_On(void) ;
int showcs(void) ;
int showds(void) ;
void lmove(int, int, int, int, int) ;
int strlen(char *) ;
void strncpy(char *, char *, int) ;
char toupper(char) ;
int strncmpi(char *, char *, int) ;
char *Fix_Path(char *, int) ;
void TSR(int, int) ;
void CS_End(void) ;
int Substitute(int, char *[]) ;
void Announce(int, char *, char *) ;
void Usage(char *) ;
void Int21()
{
#ifndef _lint
#asm
;----------------------------------------------------------
New_Int21:
;----------------------------------------------------------
pushf ; Preserve flags
sti
cmp ah,3Bh ; Set current directory?
je Subst
cmp ah,3Dh ; Open file?
je Subst
cmp ax,4300h ; Get file attributes?
je Subst
cmp ah,4Eh ; Find first?
je Subst
popf ; Restore flags
db 0EAh ; JMP FAR DIRECT
Old_Int21 dw 0 ; offset
dw 0 ; segment
save_ss dw 0
save_sp dw 0
stack_seg dw 0
stack_ptr dw 0
Subst: add sp,2 ; Discard flags saved above
; Important input registers: AX, CX, DS:DX
mov save_ss,ss ; preserve stack
mov save_sp,sp
mov ss,stack_seg ; establish my stack
mov sp,stack_ptr
push bx ; preserve irrelevant registers
push si
push di
push es
push ax ; preserve relevant registers
push cx
push ds ; parameter #2 (segment)
push dx ; parameter #1 (offset)
mov ds,stack_seg ; establish my data segment
call Fix_Path_ ; returns DS:AX => new path
mov dx,ax
pop di ; save original DX in DI
pop si ; save original DS in SI
pop cx ; restore other relevant registers
pop ax
pushf ; Simulate INT 21h
cli
lcall DWORD Old_Int21 ; Don't change CF or AX after here!
mov dx,di ; restore REAL DX
mov ds,si ; restore REAL DS
pop es ; restore irrelevant registers
pop di
pop si
pop bx
mov ss,save_ss
mov sp,save_sp
lret 2
#end
#endif
}
int showds()
{
#ifndef _lint
#asm
mov ax,ds
#end
#endif
}
int showcs()
{
#ifndef _lint
#asm
mov ax,cs
#end
#endif
}
void lmove(bytes, src_off, src_seg, dst_off, dst_seg)
int bytes ;
int src_off ;
int src_seg ;
int dst_off ;
int dst_seg ;
{
#ifndef _lint
#asm
push ds
mov cx,#bytes
les di,#dst_off
lds si,#src_off
cld
rep movsb
pop ds
#end
#endif
}
char *Fix_Path(off, seg)
char *off ;
int seg ;
{
int i, len ;
PATH *p ;
lmove(sizeof(path), off, seg, path, showds()) ;
p = subst ;
for (i = 0; i < entries; i++, p++)
{
/* Presort during load guarantees finding longest match */
if (!strncmpi(path, p->old, len = strlen(p->old)))
{
strncpy(rest, path + len, sizeof(rest) - 1) ;
strncpy(path, p->new, sizeof(path) - 1) ;
len = strlen(p->new) ;
strncpy(path + len, rest, (DOSSIZE - 1) - len) ;
break ;
}
}
return path ;
}
int strlen(str)
char *str ;
{
int len ;
len = 0 ;
while (*str++) len++ ;
return len ;
}
void strncpy(dst, src, len)
char *dst ;
char *src ;
int len ;
{
while (len-- && *src) *dst++ = *src++ ;
*dst = '\0' ;
}
char toupper(ch)
char ch ;
{
if ('a' <= ch && ch <= 'z') ch = ch - 'a' + 'A' ;
return ch ;
}
int strncmpi(str1, str2, n)
char *str1 ;
char *str2 ;
int n ;
{
int ch1, ch2, diff ;
while (*str1 && *str2 && n--)
{
ch1 = toupper(*str1++) ;
ch2 = toupper(*str2++) ;
diff = ch1 - ch2 ;
if (diff) return diff ;
}
return 0 ;
}
void TSR(stk_ptr, stk_seg)
int stk_ptr ;
int stk_seg ;
{
#ifndef _lint
#asm
mov ax,#stk_ptr
mov WORD stack_ptr,ax
mov ax,#stk_seg
mov stack_seg,ax
xor ax,ax
mov ds,ax
; preserve old int 21h vector
les ax,[4*21h]
mov Old_Int21[0],ax
mov Old_Int21[2],es
; modify int 21h vector
cli
mov WORD [4*21h+0],OFFSET New_Int21
mov WORD [4*21h+2],cs
sti
; terminate but stay resident
mov dx,stack_seg
mov ax,cs
sub dx,ax ; DX = para size of cseg
mov ax,stack_ptr
add ax,256+15 ; PSP plus rounding
mov cl,4
shr ax,cl ; AX = stack paragraphs
add dx,ax
mov ax,3100h
int 21h
#end
#endif
}
void main(argc, argv)
int argc ;
char *argv[] ;
{
int size, dseg ;
Sign_On() ;
entries = Substitute(argc, argv) ;
dseg = showcs() + (((int) CS_End + 15) >> 4) ;
size = subst + entries ;
lmove(size, 0, showds(), 0, dseg) ;
TSR(size + STACK_SIZE, dseg) ;
}
void CS_End() /* Only initialization code below here! */
{
}
int Substitute(argc, argv)
int argc ;
char *argv[] ;
{
int i, j, entries, len1, len2 ;
static char bfr[100] ;
char *p ;
PATH temp ;
FILE *fp ;
if (argc != 2) Usage("Wrong number of command line arguments") ;
fp = fopen(argv[1], "r") ;
if (!fp) Usage("Can't find file") ;
puts("") ;
entries = 0 ;
while (fgets(bfr, sizeof(bfr), fp))
{
if (p = strchr(bfr, '\n')) *p = '\0' ;
while (isspace(*bfr)) strcpy(bfr, bfr + 1) ;
if (p = strpbrk(bfr, " \t"))
{
char *old, *new ;
old = bfr ;
*p++ = '\0' ;
while (isspace(*p)) p++ ;
new = p ;
if (p = strpbrk(new, " \t")) *p = '\0' ;
strncpy(subst[entries].old, old, PCBSIZE - 1) ;
strncpy(subst[entries].new, new, DOSSIZE - 1) ;
entries++ ;
if (entries >= MAX_ENTRIES) break ;
}
}
fclose(fp) ;
for (i = 0; i < entries - 1; i++)
{
for (j = i + 1; j < entries; j++)
{
len1 = strlen(subst[i].old) ;
len2 = strlen(subst[j].old) ;
if (len1 < len2 ||
((len1==len2) &&
strcmpi(subst[i].old, subst[j].old) < 0))
{
temp = subst[i] ;
subst[i] = subst[j] ;
subst[j] = temp ;
}
}
}
for (i = 0; i < entries; i++)
{
Announce(i + 1, subst[i].old, subst[i].new) ;
}
return entries ;
}
void Announce(entry, old, new)
int entry ;
char *old ;
char *new ;
{
char bfr[100], *p ;
strcpy(bfr, "\t ") ;
p = &bfr[1] ;
if (entry < 100) p++ ;
if (entry < 10) p++ ;
ltoa((long) entry, p, 10) ;
strcat(bfr, ": ") ;
strcat(bfr, old) ;
strcat(bfr, "\t ==> ") ;
strcat(bfr, new) ;
puts(bfr) ;
}
void Sign_On()
{
char bfr[100] ;
strcpy(bfr, "\n") ;
strcat(bfr, PGM_NAME) ;
strcat(bfr, " v") ;
strcat(bfr, VERSION) ;
strcat(bfr, " (c) 1994 Key Software Products. All Rights Reserved.");
puts(bfr) ;
}
void Usage(msg)
char *msg ;
{
char bfr[100] ;
strcpy(bfr, "\n\tError: ") ;
strcat(bfr, msg) ;
puts(bfr) ;
strcpy(bfr, "\n\tUsage: ") ;
strcat(bfr, PGM_NAME) ;
strcat(bfr, " <filespec>") ;
puts(bfr) ;
exit(255) ;
}