home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 17 / CD_ASCQ_17_101194.iso / dos / prg / sphinx / examples / tsr / fixpath.c__ < prev    next >
Encoding:
Text File  |  1994-04-27  |  9.8 KB  |  267 lines

  1. /*
  2.     NAME:  FIXPATH.C--
  3.     DESCRIPTION:  TSR that removes the trailing backslash in command line
  4.     AUTHOR:  Jean-Marc Lasgouttes (Jean-Marc.Lasgouttes@inria.fr)
  5.     VERSION: 1.2
  6.     27 Apr. 1994 === Small modifications by SPHINX.
  7.     NOTE:  DOC file appended to end of this source file.
  8. */
  9.  
  10. // First, some compilation directives 
  11.  
  12. ? codesize                   // optimize for code size, not speed
  13. ? alignword FALSE            // do not align words
  14. ? parsecommandline TRUE      // parse command line
  15. ? resize FALSE               // do not resize program memory block
  16.  
  17. // Then, some useful definitions
  18.  
  19. ?include "DOS.H--"
  20. ?include "TSR.H--" 
  21. ?include "STRING.H--"
  22.  
  23. ? define OLD21_OFS 0x0000    // Offset where holding the address of the old handler
  24. ? define NEW21_OFS 0x0004    // Offset at which the interrupt routine resides
  25.  
  26. byte progname = "FIXPATH";
  27. ? define len_progname 8
  28. byte usage = "Usage :   FIXPATH [/U]\n\n"
  29.              "   /U uninstalls FixPath\n$";
  30.  
  31. // Now, the serious things can begin
  32.  
  33. // Resident routine ///////////////////////////////////////////////////////
  34.  
  35. : void FIXPATH ()  // removes trailing backslash in the command line
  36. {                  //   DS:BX points to the command line
  37.   $ MOV  BX, DX
  38.   $ CMP  DSBYTE[BX+2], 0x20; // test whether the first character is a space
  39.   $ JZ   END;
  40.   $ INC  BX;
  41. LOOP:
  42.   $ INC  BX;
  43.   $ CMP  DSBYTE[BX], 0x0D;   // test for end of input
  44.   $ JZ   END;
  45.   $ CMP  DSBYTE[BX], 0x20;   // test for space
  46.   $ JZ   LOOP2;
  47.   $ CMP  DSBYTE[BX], 0x3A;   // test for colon
  48.   $ JZ   LOOP2;
  49.   $ CMP  DSWORD[BX], 0x205C; // test for backslash plus space 
  50.   $ JZ   REPLACE;
  51.   $ CMP  DSWORD[BX], 0x0D5C; // test for backslash plus carriage return
  52.   $ JNZ  LOOP;
  53. REPLACE:
  54.   $ MOV  DSBYTE[BX], 0x20;   // replace backslash with space
  55.   $ JMP  LOOP;
  56. LOOP2:
  57.   $ INC  BX;
  58.   $ CMP  DSBYTE[BX], 0x0D;   // test for end of input
  59.   $ JNZ  LOOP;
  60. END:
  61. }
  62.  
  63. word olddoshandle[2] = {0,0};    // Address of the old interrupt handler
  64.  
  65. interrupt doshandler ()    // this is called every time INT 0x21 is invoked
  66. {
  67.   $ PUSHF;
  68.   $ CMP AH, 0x0A; 
  69.   $ JZ  DOFIX;
  70.   $ POPF;
  71.   $ JMP CSDWORD[OLD21_OFS];
  72. DOFIX:
  73.   $ CALL CSDWORD[OLD21_OFS]; // call the old handler to do the edit work
  74.   $ PUSH BX;            // save BX; it will be restored later
  75.   @FIXPATH();          // Do the real work
  76. END:
  77.   $ POP  BX;            // Restore BX
  78. }
  79.  
  80. word endofdoshandle=0;  // used to compute the length of the interrupt routine
  81.  
  82.  
  83. // Transient part of the program //////////////////////////////////////////
  84.  
  85. // More FixPath-specific functions
  86.  
  87. void installint ()      // install our interrupt routine
  88. word seg;
  89. {
  90.   @RELEASEENV();
  91.   seg = @GETMEM(#endofdoshandle - #olddoshandle - 1 / 16 + 1);
  92.   IF( seg == 0 )
  93.     @DOSWRITESTR("ERROR:  environment size too small to install FixPath\n$");
  94.   ELSE{
  95.     ES = seg-1;                        // change the MCB of the block
  96.     ESWORD[1]=seg;                     //   to tell DOS that it owns itself
  97.     COPYFAR(ES,0x08,DS,#progname,len_progname); // write the name in the MCB
  98.     GETINTVECT(#olddoshandle,0x21);    // get old DOS interrupt handle 
  99.     COPYFAR(seg,OLD21_OFS,CS,#olddoshandle,#endofdoshandle-#olddoshandle); 
  100.                    // copy the interrupt routine into the new segment
  101.     SETINTVECT( ,0x21,seg,NEW21_OFS);  // attach to DOS interrupt 
  102.   }
  103. }
  104.  
  105.  
  106. void uninstall (word seg)  // remove FixPath from memory if possible
  107. word currentint21[2];
  108. {
  109.   GETINTVECT(#currentint21,0x21);  // Get the current DOS interrupt address
  110.   IF( DSWORD[#currentint21] == NEW21_OFS ) // Is it the resident
  111.     IF( DSWORD[#currentint21+2] == seg ){  //     FixPath?
  112.       ES=seg;
  113.       SETINTVECT( ,0x21,ESWORD[OLD21_OFS+2],ESWORD[OLD21_OFS]); 
  114.       @FREEMEM(seg);
  115.       @DOSWRITESTR("FixPath successfully removed from memory.\n$");
  116.       return();
  117.     }
  118.   @DOSWRITESTR("ERROR:  Unable to remove FixPath from memory.\n$");
  119. }  
  120.  
  121.  
  122. void main ()
  123. byte str[80];
  124. {
  125.   @DOSWRITESTR("FixPath 1.2 by Jean-Marc Lasgouttes.\n$");
  126.   AX = instcheck(#progname, len_progname);
  127.   DX = AX;             // AX = instcheck(): 0 or the segment where FixPath is
  128.   AX = @PARAMCOUNT();
  129.   IF( AX == 0 )
  130.       IF( DX != 0 )
  131.           @DOSWRITESTR("ERROR:  FixPath is already installed.\n$");
  132.       ELSE installint();
  133.   ELSE{
  134.       strcpy(#str, @PARAMSTR(0));
  135.       @STR_UP(#str);
  136.       IF( @STRCMP(#str,"/U") )
  137.           @DOSWRITESTR(#usage);
  138.       ELSE IF( DX != 0 )
  139.           uninstall(DX);
  140.       ELSE @DOSWRITESTR("ERROR:  FixPath is not installed.\n$"); 
  141.       }
  142.       
  143. } /* Terminate but don't stay resident.  The interrupt routine is in the
  144.      environment segment. */
  145.  
  146. /* end of FIXPATH.C-- */
  147.  
  148. /********************* FIXPATH.DOC ******************************************
  149. FixPath v1.2
  150. -------------
  151. Public Domain Software by Jean-Marc Lasgouttes.
  152.   Jean-Marc.Lasgouttes@inria.fr
  153.  
  154.  
  155. FixPath is a small TSR (96 bytes at most!) that removes the trailing
  156. backslash of directory names on the command line.  When using a
  157. command-line editor with filename completion, one often ends-up with a
  158. command like:
  159.  
  160.                     C:\>cd dos\
  161.  
  162. DOS will not accept such a command, because it does not recognize directory
  163. names that end with '\'.  Before COMMAND.COM sees it, FixPath will modify
  164. it to:
  165.  
  166.                     C:\>cd dos
  167.  
  168. You will soon find that this simple feature saves you a lot of time because
  169. you will not have to issue commands twice just because you forgot to remove
  170. the backslash of "copy *.* temp\".
  171.  
  172. There is one exception to that: when the command begins with a space
  173. character, it will not be modified by FixPath.  This allows to type
  174. complex commands flawlessly.  I have been told for example that some
  175. archivers will behave differently depending on the backslash at the
  176. end of directory names.  XCOPY is another familiar command that needs
  177. the ending \ for a purpose.
  178.  
  179.  
  180. FixPath must be installed just after your favorite command-line editor. It
  181. has been tested with Dosed v5.0 (highly recommended BTW) and should also
  182. work with CmdEdit and others.  It is not needed with Wced 1.8, since I
  183. stole the idea of FixPath from there :-) 
  184.  
  185. The installation of FixPath is as simple as typing "FixPath".  If FixPath
  186. can find a memory hole in which it can install itself, it will use no
  187. memory at all.  Otherwise, it will use a mere 96 bytes!  The only possible
  188. argument that you can specify is "/u" to uninstall FixPath from memory.
  189. Any other argument will display a short syntax help.
  190.  
  191.  
  192. Let's get technical
  193. --------------------
  194.  
  195. FixPath has been written in SPHINX C--, a freely available language written
  196. by Peter Cellik (thanks Peter!).  C-- is a sort of low-level C that allows
  197. to mix freely high-level C-like constructs and assembly instructions.  I
  198. recommend wholeheartedly that you to take a look at it.  The latest version
  199. at the time of this writing is
  200. oak.oakland.edu:/pub/msdos/misclang/c--0192.zip.
  201.  
  202. The algorithm used to remove the '\' is the following:  FixPath will remove
  203. any backslash which is followed by a space or a carriage return if and only
  204. if it is not preceded by a space or a colon.  This takes care of most cases
  205. that I encountered.  See however the "Known bugs and limitations" section
  206. below.
  207.  
  208. What makes FixPath so small was inspired is a clever technique that I stole
  209. from the screen-saver ss_80b (garbo.uwasa.fi:/pub/pc/screen/ss_80b.zip).
  210. Instead of using the classical Terminate and Stay Resident DOS call,
  211. FixPath relocates itself into a memory block that it has allocated.  This
  212. allows to avoid the overhead of the Program Segment Prefix (which take
  213. usually 256 bytes).  I would be glad to hear of any problem this weird
  214. method may cause.
  215.  
  216. The installation check is done by inspecting the Memory Control Block chain
  217. and looking for a block named "FIXPATH" which owns itself and is not the
  218. current program.  Since FixPath writes itself its name in the MCB, this
  219. method should be safe with any version of DOS since 2.0.  However, I am not
  220. sure of what happens when the program is loaded high.
  221.  
  222.  
  223. Known bugs and limitations
  224. ---------------------------
  225.  
  226. Since FixPath has been written for my own use, it has a lot of
  227. limitations.  However, if there is some interest for the program, I will be
  228. happy to try to enhance it.  If any of these limitations is a problem for
  229. you, please let me know.  
  230.  
  231.  - the backslash are not really removed, but replaced with spaces;
  232.  
  233.  - FixPath will also do its job in programs like Debug or V. Buerg's
  234.    List.  This is not necessarily what you want.  A fix for that could be
  235.    implemented under DOS 4+, but I did not write it yet;
  236.  
  237.  - some people type "cd\" to go to the root directory.  This will be
  238.    transformed into "cd", which has a different meaning;
  239.  
  240.  - there is no visual way to see how the command line has been really
  241.    modified.  This could be a problem since the algorithm used is not
  242.    really foolproof for complex commands.  However, if you really want to know,
  243.    type "echo" in front of your command;
  244.  
  245.  - the algorithm considers only the space as a valid separator.  The
  246.    comma could be considered also;
  247.  
  248.  - text enclosed in double quotes should perhaps be skipped.
  249.  
  250.  
  251. History
  252. --------
  253.  
  254.  1.0: - Initial release.
  255.  1.1: - fixed a bug where a directory name like 'C:\' was not handled
  256.         correctly;
  257.       - changed the initialization of the program.  It uses now 96 bytes of
  258.         memory instead of 160!
  259.  1.2: - New memory allocation strategy:  FixPath is now able to fill memory
  260.         holes and will in most cases use *no* memory!
  261.       - FixPath checks whether it is already installed and refuses to
  262.         install over itself;
  263.       - new uninstall feature;
  264.       - short syntax help;
  265.       - the screen output of the program can be redirected.
  266.  
  267. ****************************************************************************/