home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 15 / CD_ASCQ_15_070894.iso / vrac / xpcbpth2.zip / XPCBPATH.C < prev    next >
C/C++ Source or Header  |  1994-06-10  |  8KB  |  426 lines

  1. /* -----------------------------------------------------------------------
  2.     XPCBPATH Version 1.0, June 4, 1994.
  3.     (c) 1994 Key Software Products.
  4.     All Rights Reserved.
  5.  
  6.     This software is copyrighted.  You are free to use it as you
  7.     like, except:
  8.  
  9.     (1) If modified, you must keep the copyright notice in the
  10.         source and executable code, and this comment in the source.
  11.  
  12.     (2) It may not be incorporated into a commercial product without
  13.         the author's permission.
  14.  
  15.    -----------------------------------------------------------------------
  16.    This software has been compiled with the DeSmet C88 compiler and linker.
  17.    ----------------------------------------------------------------------- */
  18.  
  19. #include    <stdio.h>
  20.  
  21. #define    PGM_NAME    "XPCBPATH"
  22. #define    VERSION        "1.2"
  23.  
  24. #define    MAX_ENTRIES    100
  25.  
  26. #define    STACK_SIZE    1024
  27.  
  28. #define    PCBSIZE        31
  29. #define    DOSSIZE        80 /* drive+colon+path+slash+file+period+ext+null */
  30.  
  31. #define    ENDOF(bfr)    &bfr[strlen(bfr)]
  32.  
  33. typedef struct PATH
  34.     {
  35.     char    old[PCBSIZE] ;
  36.     char    new[DOSSIZE] ;
  37.     } PATH ;
  38.  
  39. char path[DOSSIZE] ;
  40. char rest[DOSSIZE] ;
  41.  
  42. int entries = 0 ;
  43. PATH subst[MAX_ENTRIES] ;
  44.  
  45. /* These functions must be in the resident portion of the code segment */
  46. /* If we use the ones in the library, they'll be tacked on to the end  */
  47. /* of this code, and then discarded when we go TSR!               */
  48.  
  49. #define    strlen        _strlen
  50. #define    strncpy        _strncpy
  51. #define toupper        _toupper
  52. #define    strncmpi    _strncmpi
  53.  
  54. void Sign_On(void) ;
  55. int showcs(void) ;
  56. int showds(void) ;
  57. void lmove(int, int, int, int, int) ;
  58. int strlen(char *) ;
  59. void strncpy(char *, char *, int) ;
  60. char toupper(char) ;
  61. int strncmpi(char *, char *, int) ;
  62. char *Fix_Path(char *, int) ;
  63. void TSR(int, int) ;
  64. void CS_End(void) ;
  65. int Substitute(int, char *[]) ;
  66. void Announce(int, char *, char *) ;
  67. void Usage(char *) ;
  68.  
  69. void Int21()
  70.     {
  71. #ifndef    _lint
  72. #asm
  73. ;----------------------------------------------------------
  74. New_Int21:
  75. ;----------------------------------------------------------
  76.         pushf            ; Preserve flags
  77.         sti
  78.         cmp    ah,3Bh        ; Set current directory?
  79.         je    Subst
  80.         cmp    ah,3Dh        ; Open file?
  81.         je    Subst
  82.         cmp    ax,4300h    ; Get file attributes?
  83.         je    Subst
  84.         cmp    ah,4Eh        ; Find first?
  85.         je    Subst
  86.         popf            ; Restore flags
  87.  
  88.         db    0EAh        ; JMP FAR DIRECT
  89. Old_Int21    dw    0        ;  offset
  90.         dw    0        ;  segment
  91.  
  92. save_ss        dw    0
  93. save_sp        dw    0
  94.  
  95. stack_seg    dw    0
  96. stack_ptr    dw    0
  97.  
  98. Subst:        add    sp,2        ; Discard flags saved above
  99.  
  100.     ; Important input registers: AX, CX, DS:DX
  101.  
  102.         mov    save_ss,ss    ; preserve stack
  103.         mov    save_sp,sp
  104.  
  105.         mov    ss,stack_seg    ; establish my stack
  106.         mov    sp,stack_ptr
  107.  
  108.         push    bx        ; preserve irrelevant registers
  109.         push    si
  110.         push    di
  111.         push    es
  112.  
  113.         push    ax        ; preserve relevant registers
  114.         push    cx
  115.         push    ds        ; parameter #2 (segment)
  116.         push    dx        ; parameter #1 (offset)
  117.  
  118.         mov    ds,stack_seg    ; establish my data segment
  119.         call    Fix_Path_    ; returns DS:AX => new path
  120.         mov    dx,ax
  121.  
  122.         pop    di        ; save original DX in DI
  123.         pop    si        ; save original DS in SI
  124.         pop    cx        ; restore other relevant registers
  125.         pop    ax
  126.  
  127.         pushf            ; Simulate INT 21h
  128.         cli
  129.         lcall    DWORD Old_Int21    ; Don't change CF or AX after here!
  130.  
  131.         mov    dx,di        ; restore REAL DX
  132.         mov    ds,si        ; restore REAL DS
  133.  
  134.         pop    es        ; restore irrelevant registers
  135.         pop    di
  136.         pop    si
  137.         pop    bx
  138.  
  139.         mov    ss,save_ss
  140.         mov    sp,save_sp
  141.  
  142.         lret    2
  143. #end
  144. #endif
  145.     }
  146.  
  147. int showds()
  148.     {
  149. #ifndef    _lint
  150. #asm
  151.         mov    ax,ds
  152. #end
  153. #endif
  154.     }
  155.  
  156. int showcs()
  157.     {
  158. #ifndef    _lint
  159. #asm
  160.         mov    ax,cs
  161. #end
  162. #endif
  163.     }
  164.  
  165. void lmove(bytes, src_off, src_seg, dst_off, dst_seg)
  166. int bytes ;
  167. int src_off ;
  168. int src_seg ;
  169. int dst_off ;
  170. int dst_seg ;
  171.     {
  172. #ifndef    _lint
  173. #asm
  174.         push    ds
  175.         mov    cx,#bytes
  176.         les    di,#dst_off
  177.         lds    si,#src_off
  178.         cld
  179.         rep    movsb
  180.         pop    ds
  181. #end
  182. #endif
  183.     }
  184.  
  185. char *Fix_Path(off, seg)
  186. char *off ;
  187. int seg ;
  188.     {
  189.     int i, len ;
  190.     PATH *p ;
  191.  
  192.     lmove(sizeof(path), off, seg, path, showds()) ;
  193.     p = subst ;
  194.     for (i = 0; i < entries; i++, p++)
  195.         {
  196.         /* Presort during load guarantees finding longest match */
  197.  
  198.         if (!strncmpi(path, p->old, len = strlen(p->old)))
  199.             {
  200.             strncpy(rest, path + len, sizeof(rest) - 1) ;
  201.             strncpy(path, p->new, sizeof(path) - 1) ;
  202.             len = strlen(p->new) ;
  203.             strncpy(path + len, rest, (DOSSIZE - 1) - len) ;
  204.             break ;
  205.             }
  206.         }
  207.  
  208.     return path ;
  209.     }
  210.  
  211. int strlen(str)
  212. char *str ;
  213.     {
  214.     int len ;
  215.  
  216.     len = 0 ;
  217.     while (*str++) len++ ;
  218.     return len ;
  219.     }
  220.  
  221. void strncpy(dst, src, len)
  222. char *dst ;
  223. char *src ;
  224. int len ;
  225.     {
  226.     while (len-- && *src) *dst++ = *src++ ;
  227.     *dst = '\0' ;
  228.     }
  229.  
  230. char toupper(ch)
  231. char ch ;
  232.     {
  233.     if ('a' <= ch && ch <= 'z') ch = ch - 'a' + 'A' ;
  234.     return ch ;
  235.     }
  236.  
  237. int strncmpi(str1, str2, n)
  238. char *str1 ;
  239. char *str2 ;
  240. int n ;
  241.     {
  242.     int ch1, ch2, diff ;
  243.  
  244.     while (*str1 && *str2 && n--)
  245.         {
  246.         ch1 = toupper(*str1++) ;
  247.         ch2 = toupper(*str2++) ;
  248.         diff = ch1 - ch2 ;
  249.         if (diff) return diff ;
  250.         }
  251.     return 0 ;
  252.     }
  253.  
  254. void TSR(stk_ptr, stk_seg)
  255. int stk_ptr ;
  256. int stk_seg ;
  257.     {
  258. #ifndef    _lint
  259. #asm
  260.         mov    ax,#stk_ptr
  261.         mov    WORD stack_ptr,ax
  262.         mov    ax,#stk_seg
  263.         mov    stack_seg,ax
  264.  
  265.         xor    ax,ax
  266.         mov    ds,ax
  267.  
  268.     ; preserve old int 21h vector
  269.  
  270.         les    ax,[4*21h]
  271.         mov    Old_Int21[0],ax
  272.         mov    Old_Int21[2],es
  273.  
  274.     ; modify int 21h vector
  275.  
  276.         cli
  277.         mov    WORD [4*21h+0],OFFSET New_Int21
  278.         mov    WORD [4*21h+2],cs
  279.         sti
  280.  
  281.     ; terminate but stay resident
  282.  
  283.         mov    dx,stack_seg
  284.         mov    ax,cs
  285.         sub    dx,ax            ; DX = para size of cseg
  286.         mov    ax,stack_ptr
  287.         add    ax,256+15        ; PSP plus rounding
  288.         mov    cl,4
  289.         shr    ax,cl            ; AX = stack paragraphs
  290.         add    dx,ax
  291.         mov    ax,3100h
  292.         int    21h
  293. #end
  294. #endif
  295.     }
  296.  
  297. void main(argc, argv)
  298. int argc ;
  299. char *argv[] ;
  300.     {
  301.     int size, dseg ;
  302.  
  303.     Sign_On() ;
  304.     entries = Substitute(argc, argv) ;
  305.     dseg = showcs() + (((int) CS_End + 15) >> 4) ;
  306.     size = subst + entries ;
  307.     lmove(size, 0, showds(), 0, dseg) ;
  308.     TSR(size + STACK_SIZE, dseg) ;
  309.     }
  310.  
  311. void CS_End()    /* Only initialization code below here! */
  312.     {
  313.     }
  314.  
  315. int Substitute(argc, argv)
  316. int argc ;
  317. char *argv[] ;
  318.     {
  319.     int i, j, entries, len1, len2 ;
  320.     static char bfr[100] ;
  321.     char *p ;
  322.     PATH temp ;
  323.     FILE *fp ;
  324.  
  325.     if (argc != 2) Usage("Wrong number of command line arguments") ;
  326.  
  327.     fp = fopen(argv[1], "r") ;
  328.     if (!fp) Usage("Can't find file") ;
  329.  
  330.     puts("") ;
  331.     entries = 0 ;
  332.     while (fgets(bfr, sizeof(bfr), fp))
  333.         {
  334.         if (p = strchr(bfr, '\n')) *p = '\0' ;
  335.         while (isspace(*bfr)) strcpy(bfr, bfr + 1) ;
  336.         if (p = strpbrk(bfr, " \t"))
  337.             {
  338.             char *old, *new ;
  339.  
  340.             old = bfr ;
  341.             *p++ = '\0' ;
  342.             while (isspace(*p)) p++ ;
  343.             new = p ;
  344.             if (p = strpbrk(new, " \t")) *p = '\0' ;
  345.             strncpy(subst[entries].old, old, PCBSIZE - 1) ;
  346.             strncpy(subst[entries].new, new, DOSSIZE - 1) ;
  347.             entries++ ;
  348.             if (entries >= MAX_ENTRIES) break ;
  349.             }
  350.         }
  351.  
  352.     fclose(fp) ;
  353.  
  354.     for (i = 0; i < entries - 1; i++)
  355.         {
  356.         for (j = i + 1; j < entries; j++)
  357.             {
  358.             len1 = strlen(subst[i].old) ;
  359.             len2 = strlen(subst[j].old) ;
  360.             if (len1 < len2 ||
  361.                 ((len1==len2) &&
  362.                  strcmpi(subst[i].old, subst[j].old) < 0))
  363.                 {
  364.                 temp = subst[i] ;
  365.                 subst[i] = subst[j] ;
  366.                 subst[j] = temp ;
  367.                 }
  368.             }
  369.         }
  370.  
  371.     for (i = 0; i < entries; i++)
  372.         {
  373.         Announce(i + 1, subst[i].old, subst[i].new) ;
  374.         }
  375.  
  376.     return entries ;
  377.     }
  378.  
  379. void Announce(entry, old, new)
  380. int entry ;
  381. char *old ;
  382. char *new ;
  383.     {
  384.     char bfr[100], *p ;
  385.  
  386.     strcpy(bfr, "\t   ") ;
  387.     p = &bfr[1] ;
  388.     if (entry < 100) p++ ;
  389.     if (entry <  10) p++ ;
  390.     ltoa((long) entry, p, 10) ;
  391.     strcat(bfr, ": ") ;
  392.     strcat(bfr, old) ;
  393.     strcat(bfr, "\t ==> ") ;
  394.     strcat(bfr, new) ;
  395.     puts(bfr) ;
  396.     }
  397.  
  398. void Sign_On()
  399.     {
  400.     char bfr[100] ;
  401.  
  402.     strcpy(bfr, "\n") ;
  403.     strcat(bfr, PGM_NAME) ;
  404.     strcat(bfr, " v") ;
  405.     strcat(bfr, VERSION) ;
  406.     strcat(bfr, " (c) 1994 Key Software Products.  All Rights Reserved.");
  407.     puts(bfr) ;
  408.     }
  409.  
  410. void Usage(msg)
  411. char *msg ;
  412.     {
  413.     char bfr[100] ;
  414.  
  415.     strcpy(bfr, "\n\tError: ") ;
  416.     strcat(bfr, msg) ;
  417.     puts(bfr) ;
  418.  
  419.     strcpy(bfr, "\n\tUsage: ") ;
  420.     strcat(bfr, PGM_NAME) ;
  421.     strcat(bfr, " <filespec>") ;
  422.     puts(bfr) ;
  423.  
  424.     exit(255) ;
  425.     }
  426.