home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume16 / ms_sh-1.6 / patch01 / Patch1.6.4 < prev   
Text File  |  1991-01-19  |  39KB  |  1,394 lines

  1. Index: Notes1.6
  2. *** ../sh16.3/Notes1.6    Fri Aug 17 21:29:59 1990
  3. --- Notes1.6    Tue Nov  6 20:47:31 1990
  4. ***************
  5. *** 1,4 ****
  6. ! Version 1.6.3 Release Notes:
  7.   
  8.   Note: Release 1.6.1 did occur to comp.ibm.pc.binaries.  However, the
  9.   transmission was corrupt and by the time I was notified (the moderator having
  10. --- 1,4 ----
  11. ! Version 1.6.4 Release Notes:
  12.   
  13.   Note: Release 1.6.1 did occur to comp.ibm.pc.binaries.  However, the
  14.   transmission was corrupt and by the time I was notified (the moderator having
  15. ***************
  16. *** 41,47 ****
  17.       The code has been fixed to cope with DOS 4.
  18.     21.    A bug in the processing of functions has been fixed which caused
  19.       the shell to crash or hang has been fixed.
  20.   The following enhancements have been made:
  21.   
  22.      1.   /dev/tty and /dev/null are mapped to /dev/con and /dev/nul internally
  23. --- 41,48 ----
  24.       The code has been fixed to cope with DOS 4.
  25.     21.    A bug in the processing of functions has been fixed which caused
  26.       the shell to crash or hang has been fixed.
  27. !   22.    A bug in the function code that caused case functions to hang
  28. !     has been fixed.
  29.   The following enhancements have been made:
  30.   
  31.      1.   /dev/tty and /dev/null are mapped to /dev/con and /dev/nul internally
  32. ***************
  33. *** 78,83 ****
  34. --- 79,87 ----
  35.      20.  The POSIX variable substitution command ${#name} to give the
  36.       string length has been implemented.
  37.      21.  The POSIX I/O option <> has been implemented.
  38. +    22.  The POSIX I/O options ${#*%} and ~ have been implemented.
  39. +    23.  The builtin command command has been implemented.
  40. +    24.  The source for stdargv.c has been modified to work under OS/2
  41.   
  42.   The following enhancements/bugs remain outstanding:
  43.   
  44. ***************
  45. *** 93,98 ****
  46. --- 97,108 ----
  47.       processing of escape characters.  The shell uses the 8-bit to
  48.       mark escaped characters (Release 1.7).
  49.       
  50. +     3.  Interrupting a disk swap at the wrong time may cause the shell to
  51. +     hang.  I've tried disabling Control-Break during disk read/writes
  52. +     but this only causes the shell to hang on re-load every time in
  53. +     some environments.  In the next release, I'm going to put in some
  54. +     checks and issue re-read/writes when necessary.
  55. +     
  56.   Thanks are due to
  57.   
  58.       Greg Yachuk 
  59. ***************
  60. *** 101,106 ****
  61. --- 111,117 ----
  62.       John B Thiel 
  63.       Harry McGavran 
  64.       Bill Davidsen
  65. +     Richard J Reiner
  66.   
  67.   for their comments, fixes, tolerance etc in testing release 1.6
  68.   
  69. Index: lib/stdargv.c
  70. *** ../sh16.3/lib/stdargv.c    Fri Mar  2 11:34:58 1990
  71. --- lib/stdargv.c    Tue Nov  6 20:52:05 1990
  72. ***************
  73. *** 18,25 ****
  74.    *            This function replaces the standard MS-DOS command
  75.    *            line processing function (_setargv in stdargv.obj).
  76.    *
  77. !  *  CALLING SEQUENCE:    The following calling sequences are used:
  78.    *
  79.    *            void    _setargv ();
  80.    *
  81.    *  ERROR MESSAGES:    Out of memory
  82. --- 18,27 ----
  83.    *            This function replaces the standard MS-DOS command
  84.    *            line processing function (_setargv in stdargv.obj).
  85.    *
  86. !  *            Support for OS2 added.  Compile with -DOS2
  87.    *
  88. +  *  CALLING SEQUENCE:    The following calling sequences are used:
  89. +  *
  90.    *            void    _setargv ();
  91.    *
  92.    *  ERROR MESSAGES:    Out of memory
  93. ***************
  94. *** 32,45 ****
  95.   #include <stdio.h>            /* Standard I/O delarations         */
  96.   #include <stdlib.h>            /* Standard library functions       */
  97.   #include <errno.h>            /* Error number declarations        */
  98.   #include <dos.h>            /* DOS functions declarations       */
  99.   #include <bios.h>            /* BIOS functions declarations      */
  100.   #include <ctype.h>            /* Character type declarations      */
  101.   #include <string.h>            /* String library functions         */
  102.   #include <limits.h>            /* String library functions         */
  103.   #include <fcntl.h>            /* File Control Declarations        */
  104. - #include <io.h>                /* Input/Output Declarations        */
  105.   #include <dirent.h>            /* Direction I/O functions        */
  106.   
  107.   /*
  108.    *  DATA DEFINITIONS:
  109. --- 34,51 ----
  110.   #include <stdio.h>            /* Standard I/O delarations         */
  111.   #include <stdlib.h>            /* Standard library functions       */
  112.   #include <errno.h>            /* Error number declarations        */
  113. + #ifdef OS2
  114. + #include <os2.h>            /* OS2 functions declarations       */
  115. + #else
  116.   #include <dos.h>            /* DOS functions declarations       */
  117.   #include <bios.h>            /* BIOS functions declarations      */
  118. + #endif
  119.   #include <ctype.h>            /* Character type declarations      */
  120.   #include <string.h>            /* String library functions         */
  121.   #include <limits.h>            /* String library functions         */
  122.   #include <fcntl.h>            /* File Control Declarations        */
  123.   #include <dirent.h>            /* Direction I/O functions        */
  124. + #include <unistd.h>
  125.   
  126.   /*
  127.    *  DATA DEFINITIONS:
  128. ***************
  129. *** 65,76 ****
  130. --- 71,90 ----
  131.   static void    ex_fatal (int, char *, char *);    /* Fatal error processing*/
  132.   static char    *ex_environment (char *);    /* Process environment    */
  133.   static char    *_ex_multi_drive (char *);    /* Check for multidrive    */
  134. + static int    N_floppy_disks (void);
  135.   static char    *ex_nomem = "%s: %s\n";
  136.   
  137.   extern char far    *_pgmptr;         /* Program name            */
  138.   extern char    **__argv;         /* Current argument address    */
  139.   extern int    __argc;         /* Current argument count    */
  140.   
  141. + #ifdef OS2
  142. + static void     _dos_setdrive (unsigned int, unsigned int *);
  143. + static void     _dos_getdrive (unsigned int *);
  144. + extern ushort    _aenvseg;        /* Environment seg        */
  145. + extern ushort    _acmdln;        /* Command line offset        */
  146. + #endif
  147.   /*
  148.    *  MODULE ABSTRACT: _setargv
  149.    *
  150. ***************
  151. *** 79,92 ****
  152.   
  153.   void    _setargv ()
  154.   {
  155.                       /* Set up pointer to command line */
  156.       char far        *argvp = (char far *)((((long)_psp) << 16) + 0x081L);
  157.       unsigned int    envs = *(int far *)((((long)_psp) << 16) + 0x02cL);
  158.       char far        *s;         /* Temporary string pointer        */
  159. ! #ifndef M_I86LM
  160.       char        buf[MAX_LINE];    /* Temporary space        */
  161.       char        *cp;
  162. ! #endif
  163.   
  164.   /* Command line can be null or 0x0d terminated - convert to null */
  165.   
  166. --- 93,131 ----
  167.   
  168.   void    _setargv ()
  169.   {
  170. + #ifdef OS2
  171. +     char far        *argvp = (char far *)((((long)_aenvseg) << 16));
  172. +     ushort        off = _acmdln;
  173. +     while (--off)
  174. +     {
  175. +     if (argvp[off - 1] == 0)
  176. +          break;
  177. +     }
  178. + /* Add program name */
  179. +     _pgmptr =  &argvp[off];
  180. +     if (argvp[_acmdln] == 0)
  181. +     ex_add_arg (ex_tounix (_pgmptr));    /* Add the program name    */
  182. +     else
  183. +     {
  184. +     argvp += _acmdln;
  185. +     ex_add_arg (ex_tounix (argvp));        /* Add the program name    */
  186. +     argvp += strlen (argvp) + 1;
  187. +     exp_line (argvp);
  188. +     }
  189. + #else
  190.                       /* Set up pointer to command line */
  191.       char far        *argvp = (char far *)((((long)_psp) << 16) + 0x081L);
  192.       unsigned int    envs = *(int far *)((((long)_psp) << 16) + 0x02cL);
  193.       char far        *s;         /* Temporary string pointer        */
  194. ! #  ifndef M_I86LM
  195.       char        buf[MAX_LINE];    /* Temporary space        */
  196.       char        *cp;
  197. ! #  endif
  198.   
  199.   /* Command line can be null or 0x0d terminated - convert to null */
  200.   
  201. ***************
  202. *** 123,129 ****
  203.   
  204.       _pgmptr = s;
  205.   
  206. ! #ifndef M_I86LM
  207.       cp = buf;
  208.       while (*(cp++) = *(s++));
  209.   
  210. --- 162,168 ----
  211.   
  212.       _pgmptr = s;
  213.   
  214. ! #  ifndef M_I86LM
  215.       cp = buf;
  216.       while (*(cp++) = *(s++));
  217.   
  218. ***************
  219. *** 134,142 ****
  220.       while (*(cp++) = *(s++));
  221.   
  222.       exp_line (buf);
  223. ! #else
  224.       ex_add_arg (ex_tounix (s));        /* Add the program name        */
  225.       exp_line (argvp);
  226.   #endif
  227.   
  228.       ex_add_arg ((char *)NULL);
  229. --- 173,182 ----
  230.       while (*(cp++) = *(s++));
  231.   
  232.       exp_line (buf);
  233. ! #  else
  234.       ex_add_arg (ex_tounix (s));        /* Add the program name        */
  235.       exp_line (argvp);
  236. + #  endif
  237.   #endif
  238.   
  239.       ex_add_arg ((char *)NULL);
  240. ***************
  241. *** 262,268 ****
  242.   
  243.   /* Check to see if the second diskette drive is really there */
  244.   
  245. !         if (((_bios_equiplist () & 0x00c0) == 0x0000) && (s_drive == 2))
  246.           continue;
  247.   
  248.   /* If the drive exists and is in our list - process it */
  249. --- 302,308 ----
  250.   
  251.   /* Check to see if the second diskette drive is really there */
  252.   
  253. !         if ((N_floppy_disks () < 2) && (s_drive == 2))
  254.           continue;
  255.   
  256.   /* If the drive exists and is in our list - process it */
  257. ***************
  258. *** 619,623 ****
  259. --- 659,703 ----
  260.       }
  261.   
  262.       return (*prefix && (*(prefix + 1) == ':')) ? prefix + 1 : (char *)NULL;
  263. + }
  264. + /* Some OS/2 functions to emulate the DOS functions */
  265. + #ifdef OS2
  266. + static void     _dos_getdrive (cdp)
  267. + unsigned int    *cdp;
  268. + {
  269. +     USHORT    cdr;
  270. +     ULONG    ndr;
  271. +     DosQCurDisk((PUSHORT)&cdr, (PULONG) &ndr);
  272. +     *cdp = (unsigned int)cdr;
  273. + }
  274. + static void     _dos_setdrive (cdr, ndp)
  275. + unsigned int    cdr;
  276. + unsigned int    *ndp;
  277. + {
  278. +     USHORT    dummy;
  279. +     ULONG    ndr;
  280. +     DosQCurDisk((PUSHORT)&dummy, (PULONG) &ndr);
  281. +     *ndp = (unsigned int)ndr;
  282. +     DosSelectDisk ((USHORT)cdr);
  283. + }
  284. + #endif
  285. + /* Return the number of floppy disks */
  286. + static    int    N_floppy_disks ()
  287. + {
  288. + #ifdef OS2
  289. +     BYTE    nflop = 1;
  290. +     DosDevConfig (&nflop, 2, 0);
  291. +     return nflop;
  292. + #else
  293. +     return ((_bios_equiplist () & 0x00c0) >> 6) + 1;
  294. + #endif
  295.   }
  296.   #endif
  297. Index: sh.1
  298. Prereq: 1.11
  299. *** ../sh16.3/sh.1    Fri Aug 17 21:31:41 1990
  300. --- sh.1    Tue Nov  6 20:11:17 1990
  301. ***************
  302. *** 14,22 ****
  303.   .\" 2.  The sources (or parts thereof) or objects generated from the sources
  304.   .\"     (or parts of sources) cannot be sold under any circumstances.
  305.   .\"
  306. ! .\"    $Header: C:/SRC/SHELL/RCS/sh.1 1.11 90/08/14 23:17:25 Ian_Stewartson Exp $
  307.   .\"
  308.   .\"    $Log:    sh.1 $
  309.   .\"    Revision 1.11  90/08/14  23:17:25  Ian_Stewartson
  310.   .\"    Add IO read/write open
  311.   .\"    
  312. --- 14,26 ----
  313.   .\" 2.  The sources (or parts thereof) or objects generated from the sources
  314.   .\"     (or parts of sources) cannot be sold under any circumstances.
  315.   .\"
  316. ! .\"    $Header: D:/SRC/SHELL/RCS/sh.1 1.12 90/11/06 20:08:46 Ian_Stewartson Exp $
  317.   .\"
  318.   .\"    $Log:    sh.1 $
  319. + .\"    Revision 1.12  90/11/06  20:08:46  Ian_Stewartson
  320. + .\"    Add POSIX options {#%*} and ~
  321. + .\"    Add builtin command
  322. + .\"    
  323.   .\"    Revision 1.11  90/08/14  23:17:25  Ian_Stewartson
  324.   .\"    Add IO read/write open
  325.   .\"    
  326. ***************
  327. *** 163,172 ****
  328.   .SS Comments
  329.   A word beginning with \fB#\fR causes that word and all the following
  330.   characters up to a new-line to be ignored.
  331.   .SS Command Substitution
  332. ! The standard output from a command enclosed in a pair of grave accents
  333. ! (\fB\(ga\(ga\fR) may be used as part or all of a word; trailing new-lines
  334. ! are removed.
  335.   .SS Parameter Substitution
  336.   The character \fB$\fR is used to introduce substitutable \fIparameters\fR.
  337.   There are two types of parameters, positional and keyword.  If \fIparameter\fR
  338. --- 167,179 ----
  339.   .SS Comments
  340.   A word beginning with \fB#\fR causes that word and all the following
  341.   characters up to a new-line to be ignored.
  342. + .SS Tilde Substitution
  343. + Each word is checked to see if it begins with an unquoted\fB~\fR.  If it is,
  344. + the \fB~\fR is replaced by the value of the \fBHOME\fR parameter.    
  345.   .SS Command Substitution
  346. ! The standard output from a command enclosed in parenthesis preceded by a
  347. ! dollar sign (\fB$()\fR), or in a pair of grave accents (\fB\(ga\(ga\fR) may
  348. ! be used as part or all of a word; trailing new-lines are removed.
  349.   .SS Parameter Substitution
  350.   The character \fB$\fR is used to introduce substitutable \fIparameters\fR.
  351.   There are two types of parameters, positional and keyword.  If \fIparameter\fR
  352. ***************
  353. *** 184,196 ****
  354.   .PD 0
  355.   .TP
  356.   \fB${\fIparameter\fB}\fR
  357. ! The value, if any, of the parameter is substituted.  The braces are required
  358. ! only when \fIparameter\fR is followed by a letter, digit, or underscore that
  359. ! is not to be interpreted as part of its name.  If \fIparameter\fR is
  360. ! \fB*\fR or \fB@\fR, all the positional parameters, starting with \fB$1\fR,
  361. ! are substituted (separated by spaces).  Parameter \fB$0\fR is set from argument
  362. ! zero when the shell is invoked.
  363.   .TP
  364.   \fB${\fIparameter\fB:-\fIword\fB}\fR
  365.   If \fIparameter\fR is set and is non-null, substitute its value; otherwise
  366.   substitute \fIword\fR.
  367. --- 191,208 ----
  368.   .PD 0
  369.   .TP
  370.   \fB${\fIparameter\fB}\fR
  371. ! The value, if any, of the \fIparameter\fR is substituted.  The braces are
  372. ! required only when \fIparameter\fR is followed by a letter, digit, or
  373. ! underscore that is not to be interpreted as part of its name.  If
  374. ! \fIparameter\fR is \fB*\fR or \fB@\fR, all the positional parameters, starting
  375. ! with \fB$1\fR, are substituted (separated by spaces).  Parameter \fB$0\fR is
  376. ! set from argument zero when the shell is invoked.
  377.   .TP
  378. + \fB${#\fIparameter\fB}\fR
  379. + If \fIparameter\fR is \fB*\fR or \fB@\fR, the number of positional parameters
  380. + is substituted.  Otherwise, the length of the value of the \fIparameter\fR is
  381. + substituted.
  382. + .TP
  383.   \fB${\fIparameter\fB:-\fIword\fB}\fR
  384.   If \fIparameter\fR is set and is non-null, substitute its value; otherwise
  385.   substitute \fIword\fR.
  386. ***************
  387. *** 208,213 ****
  388. --- 220,242 ----
  389.   \fB${\fIparameter\fB:+\fIword\fB}\fR
  390.   If \fIparameter\fR is set and is non-null, substitute \fIword\fR; otherwise
  391.   substitute nothing.
  392. + .TP
  393. + \fB${\fIparameter\fB#\fIpattern\fB}\fR
  394. + \fB${\fIparameter\fB##\fIpattern\fB}\fR
  395. + If the Shell \fIpattern\fR matches the beginning of the value of
  396. + \fIparameter\fR, then the value of this substitution is the value of the
  397. + \fIparameter\fR with the matched portion deleted; otherwise the value of
  398. + this \fIparameter\fR is substituted.  In the first form the smallest matching
  399. + \fIpattern\fR is deleted and in the latter form the largest matching
  400. + \fIpattern\fR is deleted.
  401. + .TP
  402. + \fB${\fIparameter\fB%\fIpattern\fB}\fR
  403. + \fB${\fIparameter\fB%%\fIpattern\fB}\fR
  404. + If the Shell \fIpattern\fR matches the end of the value of \fIparameter\fR,
  405. + then the value of this substitution is the value of the \fIparameter\fR with
  406. + the matched portion deleted; otherwise the value of this \fIparameter\fR is
  407. + substituted.  In the first form the smallest matching \fIpattern\fR is deleted
  408. + and in the latter form the largest matching \fIpattern\fR is deleted.
  409.   .PD
  410.   .PP
  411.   In the above, \fIword\fR is not evaluated unless it is to be used as the
  412. ***************
  413. *** 830,835 ****
  414. --- 859,886 ----
  415.   Exit from the enclosing \fBfor\fR or \fBwhile\fR loop, if any.  If \fIn\fR is
  416.   specified, break \fIn\fR levels.
  417.   .TP
  418. + \fBbuiltin\fR \*(OK \fIargs\fR ... \*(CK
  419. + Force the selection of the \fBbuiltin\fR version of a command.  The builtin
  420. + shell command selected by the first \fIargs\fR value is executed with the
  421. + parameters defined by the remaining \fIargs\fRs.  If no arguments are given,
  422. + a list of all \fIbuiltin\fR commands is printed.
  423. + .sp
  424. + If the first argument is one of the following, the processing of the
  425. + builtin command in the following arguments are changed as indicated:
  426. + .RS
  427. + .TP
  428. + \fB-a\fR
  429. + Set the following builtin commands to use builtin version in preference to
  430. + any function or external versions.
  431. + .TP
  432. + \fB-d\fR
  433. + Set the following builtin commands to use the function or external version
  434. + in preference to the builtin version.
  435. + .TP
  436. + \fB-s\fR
  437. + Display the current status of the following builtin commands.
  438. + .RE
  439. + .TP
  440.   \fBcontinue\fR \*(OK \fIn\fR \*(CK
  441.   Resume the next iteration of the enclosing \fBfor\fR or \fBwhile\fR loop.  If
  442.   \fIn\fR is specified, resume at the \fIn\fR-th enclosing loop.
  443. ***************
  444. *** 986,992 ****
  445.   \fBmsdos\fR \*(OK \fIname\fR ... \*(CK
  446.   The given \fIname\fRs are marked \fImsdos\fR format and if the \fB-m\fR flag
  447.   is set, the values of the these \fIname\fRs are exported to child processes
  448. ! with any slashes in the value replaced by backslashes.
  449.   .TP
  450.   \fBpwd\fR
  451.   Print the current working directory.  
  452. --- 1037,1044 ----
  453.   \fBmsdos\fR \*(OK \fIname\fR ... \*(CK
  454.   The given \fIname\fRs are marked \fImsdos\fR format and if the \fB-m\fR flag
  455.   is set, the values of the these \fIname\fRs are exported to child processes
  456. ! with any slashes in the value replaced by backslashes.  If no arguments are
  457. ! given, a list of all \fImsdos\fR names is printed.
  458.   .TP
  459.   \fBpwd\fR
  460.   Print the current working directory.  
  461. Index: shell/sh.h
  462. Prereq: 1.21
  463. *** ../sh16.3/shell/sh.h    Fri Aug 17 21:33:20 1990
  464. --- shell/sh.h    Tue Nov  6 19:18:37 1990
  465. ***************
  466. *** 13,21 ****
  467.    * 2.  The sources (or parts thereof) or objects generated from the sources
  468.    *     (or parts of sources) cannot be sold under any circumstances.
  469.    *
  470. !  *    $Header: C:/SRC/SHELL/RCS/sh.h 1.21 90/08/14 23:54:44 MS_user Exp $
  471.    *
  472.    *    $Log:    sh.h $
  473.    * Revision 1.21  90/08/14  23:54:44  MS_user
  474.    * Add addition value to env structure
  475.    * Add some new publics
  476. --- 13,27 ----
  477.    * 2.  The sources (or parts thereof) or objects generated from the sources
  478.    *     (or parts of sources) cannot be sold under any circumstances.
  479.    *
  480. !  *    $Header: D:/SRC/SHELL/RCS/sh.h 1.23 90/09/19 15:29:54 Ian_Stewartson Exp $
  481.    *
  482.    *    $Log:    sh.h $
  483. +  * Revision 1.23  90/09/19  15:29:54  Ian_Stewartson
  484. +  * Allow builtin commands to selected/de-selected
  485. +  * 
  486. +  * Revision 1.22  90/08/24  21:53:13  Ian_Stewartson
  487. +  * Add support for POSIX macro command {x#y} and {x%y}
  488. +  * 
  489.    * Revision 1.21  90/08/14  23:54:44  MS_user
  490.    * Add addition value to env structure
  491.    * Add some new publics
  492. ***************
  493. *** 85,91 ****
  494.    * 
  495.    */
  496.   
  497. ! #define PATCHLEVEL    7
  498.   #define    LINE_MAX    1000    /* Command line length            */
  499.   #define HISTORY_MAX    100    /* History array length            */
  500.                   /* Space for full file name        */
  501. --- 91,97 ----
  502.    * 
  503.    */
  504.   
  505. ! #define PATCHLEVEL    8
  506.   #define    LINE_MAX    1000    /* Command line length            */
  507.   #define HISTORY_MAX    100    /* History array length            */
  508.                   /* Space for full file name        */
  509. ***************
  510. *** 168,179 ****
  511.   struct    builtin {
  512.       char    *command;
  513.       int        (*fn)(C_Op *);
  514.   };
  515.   
  516.   /*
  517. !  * actions determining the environment of a process
  518.    */
  519.   
  520.   #define    FEXEC        0x0001    /* execute without forking        */
  521.   
  522.   /* MSDOS Memory Control Block chain structure */
  523. --- 174,193 ----
  524.   struct    builtin {
  525.       char    *command;
  526.       int        (*fn)(C_Op *);
  527. +     int        mode;
  528.   };
  529.   
  530.   /*
  531. !  * Valid values of mode
  532.    */
  533.   
  534. + #define BLT_ALWAYS    0x0001    /* Always use builtin version        */
  535. + #define BLT_CURRENT    0x0002    /* Currently use builtin version    */
  536. + /*
  537. +  * actions determining the environment of a process
  538. +  */
  539.   #define    FEXEC        0x0001    /* execute without forking        */
  540.   
  541.   /* MSDOS Memory Control Block chain structure */
  542. ***************
  543. *** 376,384 ****
  544.                       /* depth            */
  545.   
  546.   /*
  547. !  * Variable list
  548.    */
  549.   
  550.   typedef struct var {
  551.       char        *value;        /* Value            */
  552.       char        *name;        /* Name                */
  553. --- 390,407 ----
  554.                       /* depth            */
  555.   
  556.   /*
  557. !  * Mode values for new gmatch 
  558.    */
  559.   
  560. + #define GM_ALL        0        /* Match full string        */
  561. + #define GM_SHORTEST    1        /* Shortest prefix/suffix    */
  562. + #define GM_LONGEST    2        /* Longest prefix/suffix    */
  563. + /*
  564. + /*
  565. +  * Variable list
  566. +  */
  567.   typedef struct var {
  568.       char        *value;        /* Value            */
  569.       char        *name;        /* Name                */
  570. ***************
  571. *** 531,537 ****
  572.   extern void    s_vstatus (Var_List *, int);
  573.   extern bool    isassign (char *);
  574.   extern bool    assign (char *, int);
  575. ! extern bool    gmatch (char *, char *, bool);
  576.   extern char    *getcell (unsigned int);
  577.   extern void    freecell (char *);
  578.   extern void    freearea (int);
  579. --- 554,561 ----
  580.   extern void    s_vstatus (Var_List *, int);
  581.   extern bool    isassign (char *);
  582.   extern bool    assign (char *, int);
  583. ! extern bool    gmatch (char *, char *, bool, char **, int);
  584. ! extern bool    gmatch_suffix (char *, char *, bool, char **, int);
  585.   extern char    *getcell (unsigned int);
  586.   extern void    freecell (char *);
  587.   extern void    freearea (int);
  588. ***************
  589. *** 574,580 ****
  590.   extern void    put_prompt (char *);
  591.   extern bool    eqname (char *, char *);
  592.   extern bool    any (char, char *);
  593. ! extern int    (*inbuilt (char *))();
  594.   extern char    *path_append (char *, char *, char *);
  595.   extern void    unset (char *, bool);
  596.   extern int    S_open (bool, char *, int, ...);
  597. --- 598,604 ----
  598.   extern void    put_prompt (char *);
  599.   extern bool    eqname (char *, char *);
  600.   extern bool    any (char, char *);
  601. ! extern int    (*inbuilt (char *, bool *))();
  602.   extern char    *path_append (char *, char *, char *);
  603.   extern void    unset (char *, bool);
  604.   extern int    S_open (bool, char *, int, ...);
  605. Index: shell/sh0.asm
  606. Prereq: 1.10
  607. *** ../sh16.3/shell/sh0.asm    Fri Aug 17 21:33:41 1990
  608. --- shell/sh0.asm    Tue Nov  6 19:19:30 1990
  609. ***************
  610. *** 16,22 ****
  611.   ; 2.  The sources (or parts thereof) or objects generated from the sources
  612.   ;     (or parts of sources) cannot be sold under any circumstances.
  613.   ;
  614. ! ;    $Header: C:/SRC/SHELL/RCS/sh0.asm 1.10 90/05/31 17:46:31 MS_user Exp $
  615.   ;
  616.   ;    $Log:    sh0.asm $
  617.   ;    Revision 1.10  90/05/31  17:46:31  MS_user
  618. --- 16,22 ----
  619.   ; 2.  The sources (or parts thereof) or objects generated from the sources
  620.   ;     (or parts of sources) cannot be sold under any circumstances.
  621.   ;
  622. ! ;    $Header: D:/SRC/SHELL/RCS/sh0.asm 1.10 90/05/31 17:46:31 MS_user Exp $
  623.   ;
  624.   ;    $Log:    sh0.asm $
  625.   ;    Revision 1.10  90/05/31  17:46:31  MS_user
  626. Index: shell/sh1.c
  627. Prereq: 1.17
  628. *** ../sh16.3/shell/sh1.c    Fri Aug 17 21:32:33 1990
  629. --- shell/sh1.c    Tue Nov  6 19:20:30 1990
  630. ***************
  631. *** 13,77 ****
  632.    * 2.  The sources (or parts thereof) or objects generated from the sources
  633.    *     (or parts of sources) cannot be sold under any circumstances.
  634.    *
  635. !  *    $Header: C:/SRC/SHELL/RCS/sh1.c 1.17 90/08/14 23:32:53 MS_user Exp $
  636.    *
  637.    *    $Log:    sh1.c $
  638.    * Revision 1.17  90/08/14  23:32:53  MS_user
  639.    * Fix memory bugs - Add malloc checking functions for debug
  640.    * Make Convert_Backslashes public
  641. !  * 
  642.    * Revision 1.16  90/05/31  09:48:06  MS_user
  643.    * Implement partial write when swapping to disk
  644.    * Add some signal lockouts to prevent corruption
  645. !  * 
  646.    * Revision 1.15  90/05/15  21:08:59  MS_user
  647.    * Restore original directory on exit
  648. !  * 
  649.    * Revision 1.14  90/04/25  22:33:28  MS_user
  650.    * Fix rsh check for PATH
  651. !  * 
  652.    * Revision 1.13  90/04/25  09:18:12  MS_user
  653.    * Change version message processing
  654. !  * 
  655.    * Revision 1.12  90/04/04  11:32:12  MS_user
  656.    * Change MAILPATH to use a semi-colon and not a colon for DOS
  657. !  * 
  658.    * Revision 1.11  90/04/03  17:58:35  MS_user
  659.    * Stop shell exit from lowest level CLI
  660. !  * 
  661.    * Revision 1.10  90/03/27  20:24:49  MS_user
  662.    * Fix problem with Interrupts not restoring std??? and clearing extended file
  663. !  * 
  664.    * Revision 1.9  90/03/26  20:56:13  MS_user
  665.    * Change I/O restore so that "exec >filename" works
  666. !  * 
  667.    * Revision 1.8  90/03/26  04:30:14  MS_user
  668.    * Remove original Interrupt 24 save address
  669. !  * 
  670.    * Revision 1.7  90/03/12  20:16:22  MS_user
  671.    * Save program name for Initialisation file processing
  672. !  * 
  673.    * Revision 1.6  90/03/09  16:05:33  MS_user
  674.    * Add build file name function and change the profile check to use it
  675. !  * 
  676.    * Revision 1.5  90/03/06  16:49:14  MS_user
  677.    * Add disable history option
  678. !  * 
  679.    * Revision 1.4  90/03/06  15:09:27  MS_user
  680.    * Add Unix PATH variable conversion
  681. !  * 
  682.    * Revision 1.3  90/03/05  13:47:45  MS_user
  683.    * Get /etc/profile and profile order rigth
  684.    * Use $HOME/profile and not profile
  685.    * Check cursor position before outputing prompt
  686.    * Move some of processing in main to sub-routines
  687. !  * 
  688.    * Revision 1.2  90/02/14  04:46:20  MS_user
  689.    * Add Interrupt 24 processing
  690. !  * 
  691.    * Revision 1.1  90/01/25  13:40:39  MS_user
  692.    * Initial revision
  693. !  * 
  694.    */
  695.   
  696.   #include <sys/types.h>
  697. --- 13,83 ----
  698.    * 2.  The sources (or parts thereof) or objects generated from the sources
  699.    *     (or parts of sources) cannot be sold under any circumstances.
  700.    *
  701. !  *    $Header: D:/SRC/SHELL/RCS/sh1.c 1.19 90/11/06 19:13:39 Ian_Stewartson Exp $
  702.    *
  703.    *    $Log:    sh1.c $
  704. +  * Revision 1.19  90/11/06  19:13:39  Ian_Stewartson
  705. +  * Add deletion of swap file on interrupt
  706. +  * 
  707. +  * Revision 1.18  90/08/24  21:54:05  Ian_Stewartson
  708. +  * Add support for POSIX macro command {x#y} and {x%y}
  709. +  * 
  710.    * Revision 1.17  90/08/14  23:32:53  MS_user
  711.    * Fix memory bugs - Add malloc checking functions for debug
  712.    * Make Convert_Backslashes public
  713. !  *
  714.    * Revision 1.16  90/05/31  09:48:06  MS_user
  715.    * Implement partial write when swapping to disk
  716.    * Add some signal lockouts to prevent corruption
  717. !  *
  718.    * Revision 1.15  90/05/15  21:08:59  MS_user
  719.    * Restore original directory on exit
  720. !  *
  721.    * Revision 1.14  90/04/25  22:33:28  MS_user
  722.    * Fix rsh check for PATH
  723. !  *
  724.    * Revision 1.13  90/04/25  09:18:12  MS_user
  725.    * Change version message processing
  726. !  *
  727.    * Revision 1.12  90/04/04  11:32:12  MS_user
  728.    * Change MAILPATH to use a semi-colon and not a colon for DOS
  729. !  *
  730.    * Revision 1.11  90/04/03  17:58:35  MS_user
  731.    * Stop shell exit from lowest level CLI
  732. !  *
  733.    * Revision 1.10  90/03/27  20:24:49  MS_user
  734.    * Fix problem with Interrupts not restoring std??? and clearing extended file
  735. !  *
  736.    * Revision 1.9  90/03/26  20:56:13  MS_user
  737.    * Change I/O restore so that "exec >filename" works
  738. !  *
  739.    * Revision 1.8  90/03/26  04:30:14  MS_user
  740.    * Remove original Interrupt 24 save address
  741. !  *
  742.    * Revision 1.7  90/03/12  20:16:22  MS_user
  743.    * Save program name for Initialisation file processing
  744. !  *
  745.    * Revision 1.6  90/03/09  16:05:33  MS_user
  746.    * Add build file name function and change the profile check to use it
  747. !  *
  748.    * Revision 1.5  90/03/06  16:49:14  MS_user
  749.    * Add disable history option
  750. !  *
  751.    * Revision 1.4  90/03/06  15:09:27  MS_user
  752.    * Add Unix PATH variable conversion
  753. !  *
  754.    * Revision 1.3  90/03/05  13:47:45  MS_user
  755.    * Get /etc/profile and profile order rigth
  756.    * Use $HOME/profile and not profile
  757.    * Check cursor position before outputing prompt
  758.    * Move some of processing in main to sub-routines
  759. !  *
  760.    * Revision 1.2  90/02/14  04:46:20  MS_user
  761.    * Add Interrupt 24 processing
  762. !  *
  763.    * Revision 1.1  90/01/25  13:40:39  MS_user
  764.    * Initial revision
  765. !  *
  766.    */
  767.   
  768.   #include <sys/types.h>
  769. ***************
  770. *** 528,534 ****
  771.   
  772.       Clear_Swap_File ();
  773.   
  774. ! /* If this is a command only - restore the directory because DOS doesn't 
  775.    * and the user might expect it
  776.    */
  777.   
  778. --- 534,540 ----
  779.   
  780.       Clear_Swap_File ();
  781.   
  782. ! /* If this is a command only - restore the directory because DOS doesn't
  783.    * and the user might expect it
  784.    */
  785.   
  786. ***************
  787. *** 713,720 ****
  788.       signal (SIGINT, onintr);
  789.       SW_intr = 1;
  790.   
  791. ! /* Are we talking to the user?  Yes - check in parser */
  792.   
  793.       if (talking)
  794.       {
  795.       if (inparse)
  796. --- 719,731 ----
  797.       signal (SIGINT, onintr);
  798.       SW_intr = 1;
  799.   
  800. ! /* Zap the swap file, just in case it got corrupted */
  801.   
  802. +     S_close (SW_fp, TRUE);
  803. +     Clear_Swap_File ();
  804. + /* Are we talking to the user?  Yes - check in parser */
  805.       if (talking)
  806.       {
  807.       if (inparse)
  808. ***************
  809. *** 775,782 ****
  810. --- 786,800 ----
  811.   register int    i;
  812.   {
  813.       if (i == SIGINT)        /* Need this because swapper sets it    */
  814. +     {
  815.       SW_intr = 0;
  816.   
  817. + /* Zap the swap file, just in case it got corrupted */
  818. +     S_close (SW_fp, TRUE);
  819. +     Clear_Swap_File ();
  820. +     }
  821.       trapset = i;
  822.       signal (i, sig);
  823.   }
  824. ***************
  825. *** 1185,1298 ****
  826.   }
  827.   
  828.   /*
  829. !  * Match a pattern as in sh(1).
  830.    */
  831.   
  832. ! bool        gmatch (s, p, IgnoreCase)
  833. ! register char    *s, *p;
  834.   bool        IgnoreCase;
  835.   {
  836. !     register int    sc, pc;
  837.   
  838. !     if ((s == (char *)NULL) || (p == (char *)NULL))
  839.       return FALSE;
  840.   
  841. !     while ((pc = *(p++) & CMASK) != '\0')
  842.       {
  843. !     sc = *(s++) & QMASK;
  844.   
  845. !     switch (pc)
  846.       {
  847.           case '[':            /* Class expression        */
  848. !         if ((p = cclass (p, sc, IgnoreCase)) == (char *)NULL)
  849.               return FALSE;
  850.   
  851.           break;
  852.   
  853.           case '?':            /* Match any character        */
  854. !         if (sc == 0)
  855.               return FALSE;
  856.   
  857.           break;
  858.   
  859.           case '*':            /* Match as many as possible    */
  860. !         s--;
  861.           do
  862.           {
  863. !             if (!*p || gmatch (s, p, IgnoreCase))
  864. !             return TRUE;
  865.   
  866. !         } while (*(s++));
  867.   
  868. !         return FALSE;
  869.   
  870.           default:
  871.           if (IgnoreCase)
  872.           {
  873. !             sc = tolower (sc);
  874. !             pc = tolower ((pc & ~QUOTE));
  875.           }
  876.   
  877. !         if (sc != (pc & ~QUOTE))
  878.               return FALSE;
  879.       }
  880.       }
  881.   
  882. !     return (*s == 0) ? TRUE : FALSE;
  883. ! }
  884.   
  885.   /*
  886.    * Process a class expression - []
  887.    */
  888.   
  889. ! static char    *cclass (p, sub, IgnoreCase)
  890. ! register char    *p;
  891. ! register int    sub;
  892.   bool        IgnoreCase;
  893.   {
  894. !     register int    c, d, not, found;
  895.   
  896.   /* Exclusive or inclusive class */
  897.   
  898. !     if ((not = *p == NOT) != 0)
  899. !     p++;
  900.   
  901.       found = not;
  902.   
  903.       do
  904.       {
  905. !     if (!*p)
  906.           return (char *)NULL;
  907.   
  908.   /* Get the next character in class, converting to lower case if necessary */
  909.   
  910. !     c = IgnoreCase ? tolower ((*p & CMASK)) : (*p & CMASK);
  911.   
  912.   /* If this is a range, get the end of range character */
  913.   
  914. !     if ((*(p + 1) == '-') && (*(p + 2) != ']'))
  915.       {
  916. !         d = IgnoreCase ? tolower ((*(p + 2) & CMASK)) : (*(p + 2) & CMASK);
  917. !         p++;
  918.       }
  919.   
  920.       else
  921. !         d = c;
  922.   
  923.   /* Is the current character in the class? */
  924.   
  925. !     if ((c <= sub) && (sub <= d))
  926.           found = !not;
  927.   
  928. !     } while (*(++p) != ']');
  929.   
  930. !     return found ? p + 1 : (char *)NULL;
  931.   }
  932.   
  933.   /*
  934. !  * Get a string in a malloced area
  935.    */
  936.   
  937.   char        *getcell (nbytes)
  938.   unsigned int    nbytes;
  939.   {
  940. --- 1203,1381 ----
  941.   }
  942.   
  943.   /*
  944. !  * Match a pattern as in sh(1).  Enhancement to handle prefix processing
  945. !  *
  946. !  * IgnoreCase - ignore case on comparisions.
  947. !  * end - end of match in 'string'.
  948. !  * mode - mode for match processing - see GM_ flags in sh.h
  949.    */
  950.   
  951. ! bool        gmatch (string, pattern, IgnoreCase, end, mode)
  952. ! register char    *string, *pattern;
  953.   bool        IgnoreCase;
  954. + char        **end;
  955. + int        mode;
  956.   {
  957. !     register int    string_c, pattern_c;
  958. !     char        *save_end;
  959.   
  960. !     if ((string == (char *)NULL) || (pattern == (char *)NULL))
  961.       return FALSE;
  962.   
  963. !     while ((pattern_c = *(pattern++) & CMASK) != '\0')
  964.       {
  965. !     string_c = *(string++) & QMASK;
  966.   
  967. !     switch (pattern_c)
  968.       {
  969.           case '[':            /* Class expression        */
  970. !         if ((pattern = cclass (pattern, string_c, IgnoreCase)) == (char *)NULL)
  971.               return FALSE;
  972.   
  973.           break;
  974.   
  975.           case '?':            /* Match any character        */
  976. !         if (string_c == 0)
  977.               return FALSE;
  978.   
  979.           break;
  980.   
  981.           case '*':            /* Match as many as possible    */
  982. !         --string;
  983. !         save_end = (char *)NULL;
  984.           do
  985.           {
  986. !             if (!*pattern ||
  987. !             gmatch (string, pattern, IgnoreCase, end, mode))
  988. !             {
  989. !             if (mode == GM_LONGEST)
  990. !                 save_end = *end;
  991.   
  992. !             else
  993. !                 return TRUE;
  994. !             }
  995.   
  996. !         } while (*(string++));
  997.   
  998. +         if (end != (char **)NULL)
  999. +             *end = save_end;
  1000. +         return (save_end == (char *)NULL) ? FALSE : TRUE;
  1001.           default:
  1002.           if (IgnoreCase)
  1003.           {
  1004. !             string_c = tolower (string_c);
  1005. !             pattern_c = tolower ((pattern_c & ~QUOTE));
  1006.           }
  1007.   
  1008. !         if (string_c != (pattern_c & ~QUOTE))
  1009.               return FALSE;
  1010.       }
  1011.       }
  1012.   
  1013. !     if (end != (char **)NULL)
  1014. !     {
  1015. !     *end = string;
  1016. !     return TRUE;
  1017. !     }
  1018.   
  1019. +     return (*string == 0) ? TRUE : FALSE;
  1020. + }
  1021.   /*
  1022.    * Process a class expression - []
  1023.    */
  1024.   
  1025. ! static char    *cclass (pattern, string_c, IgnoreCase)
  1026. ! register char    *pattern;
  1027. ! register int    string_c;
  1028.   bool        IgnoreCase;
  1029.   {
  1030. !     register int    llimit_c, ulimit_c, not, found;
  1031.   
  1032.   /* Exclusive or inclusive class */
  1033.   
  1034. !     if ((not = *pattern == NOT) != 0)
  1035. !     pattern++;
  1036.   
  1037.       found = not;
  1038.   
  1039.       do
  1040.       {
  1041. !     if (!*pattern)
  1042.           return (char *)NULL;
  1043.   
  1044.   /* Get the next character in class, converting to lower case if necessary */
  1045.   
  1046. !     llimit_c = IgnoreCase ? tolower ((*pattern & CMASK))
  1047. !                   : (*pattern & CMASK);
  1048.   
  1049.   /* If this is a range, get the end of range character */
  1050.   
  1051. !     if ((*(pattern + 1) == '-') && (*(pattern + 2) != ']'))
  1052.       {
  1053. !         ulimit_c = IgnoreCase ? tolower ((*(pattern + 2) & CMASK))
  1054. !                   : (*(pattern + 2) & CMASK);
  1055. !         pattern++;
  1056.       }
  1057.   
  1058.       else
  1059. !         ulimit_c = llimit_c;
  1060.   
  1061.   /* Is the current character in the class? */
  1062.   
  1063. !     if ((llimit_c <= string_c) && (string_c <= ulimit_c))
  1064.           found = !not;
  1065.   
  1066. !     } while (*(++pattern) != ']');
  1067.   
  1068. !     return found ? pattern + 1 : (char *)NULL;
  1069.   }
  1070.   
  1071.   /*
  1072. !  * Suffix processing - find the longest/shortest suffix.
  1073.    */
  1074.   
  1075. + bool        gmatch_suffix (string, pattern, IgnoreCase, start, mode)
  1076. + register char    *string, *pattern;
  1077. + bool        IgnoreCase;
  1078. + char        **start;
  1079. + int        mode;
  1080. + {
  1081. +     char    *save_start = (char *)NULL;
  1082. + /* Scan the string, looking for a match to the end */
  1083. +     while (*string)
  1084. +     {
  1085. +     if (gmatch (string, pattern, IgnoreCase, (char **)NULL, GM_ALL))
  1086. +     {
  1087. + /* If longest, stop here */
  1088. +         if (mode == GM_LONGEST)
  1089. +         {
  1090. +         *start = string;
  1091. +         return TRUE;
  1092. +         }
  1093. + /* Save the start of the shortest string so far and continue */
  1094. +         save_start = string;
  1095. +     }
  1096. +     ++string;
  1097. +     }
  1098. +     return ((*start = save_start) == (char *)NULL) ? FALSE : TRUE;
  1099. + }
  1100. + /*
  1101. +  * Get a string in a malloced area
  1102. +  */
  1103.   char        *getcell (nbytes)
  1104.   unsigned int    nbytes;
  1105.   {
  1106. ***************
  1107. *** 1323,1329 ****
  1108.       print_warn ("Malloc access to bad segment\n");
  1109.       return (char *)NULL;
  1110.       }
  1111. !     
  1112.       np->magic1             = MAGIC1;
  1113.       np->len               = nbytes;
  1114.       rp                          = (char *)(np + 1);
  1115. --- 1406,1412 ----
  1116.       print_warn ("Malloc access to bad segment\n");
  1117.       return (char *)NULL;
  1118.       }
  1119.       np->magic1             = MAGIC1;
  1120.       np->len               = nbytes;
  1121.       rp                          = (char *)(np + 1);
  1122. ***************
  1123. *** 1362,1370 ****
  1124.   /* Disable signals */
  1125.   
  1126.       save_signal = signal (SIGINT, SIG_IGN);
  1127. -     
  1128. - /* Find the string in the chain */
  1129.   
  1130.       if (s != (char *)NULL)
  1131.       {
  1132.       while (cp != (s_region *)NULL)
  1133. --- 1445,1453 ----
  1134.   /* Disable signals */
  1135.   
  1136.       save_signal = signal (SIGINT, SIG_IGN);
  1137.   
  1138. + /* Find the string in the chain */
  1139.       if (s != (char *)NULL)
  1140.       {
  1141.       while (cp != (s_region *)NULL)
  1142. ***************
  1143. *** 2012,2018 ****
  1144.       str1++;
  1145.       str2++;
  1146.       }
  1147. !     
  1148.       return rtn;
  1149.   }
  1150.   
  1151. --- 2095,2101 ----
  1152.       str1++;
  1153.       str2++;
  1154.       }
  1155.       return rtn;
  1156.   }
  1157.   
  1158. ***************
  1159. *** 2064,2074 ****
  1160.   
  1161.       while (--len >= 0)
  1162.       {
  1163. !     if ((*(str1++) = *(str2++)) == 0)    
  1164.       {
  1165.           while (--len >= 0)
  1166.           *(str1++) = 0;
  1167. !         
  1168.           break;
  1169.       }
  1170.       }
  1171. --- 2147,2157 ----
  1172.   
  1173.       while (--len >= 0)
  1174.       {
  1175. !     if ((*(str1++) = *(str2++)) == 0)
  1176.       {
  1177.           while (--len >= 0)
  1178.           *(str1++) = 0;
  1179.           break;
  1180.       }
  1181.       }
  1182. Index: shell/sh3.c
  1183. Prereq: 1.24
  1184. *** ../sh16.3/shell/sh3.c    Fri Aug 17 21:34:34 1990
  1185. --- shell/sh3.c    Tue Nov  6 19:21:26 1990
  1186. ***************
  1187. *** 13,21 ****
  1188.    * 2.  The sources (or parts thereof) or objects generated from the sources
  1189.    *     (or parts of sources) cannot be sold under any circumstances.
  1190.    *
  1191. !  *    $Header: C:/SRC/SHELL/RCS/sh3.c 1.24 90/08/16 10:28:47 Ian_Stewartson Exp $
  1192.    *
  1193.    *    $Log:    sh3.c $
  1194.    * Revision 1.24  90/08/16  10:28:47  Ian_Stewartson
  1195.    * Find setting of switch character for DOS4 for batch files
  1196.    * 
  1197. --- 13,32 ----
  1198.    * 2.  The sources (or parts thereof) or objects generated from the sources
  1199.    *     (or parts of sources) cannot be sold under any circumstances.
  1200.    *
  1201. !  *    $Header: C:/SRC/SHELL/RCS/sh3.c 1.27 90/09/19 15:30:31 Ian_Stewartson Exp $
  1202.    *
  1203.    *    $Log:    sh3.c $
  1204. +  * Revision 1.27  90/09/19  15:30:31  Ian_Stewartson
  1205. +  * Allow builtin commands to selected/de-selected
  1206. +  * 
  1207. +  * Revision 1.26  90/09/11  20:06:11  Ian_Stewartson
  1208. +  * Add support for buitlin command, including the alway builtin functions
  1209. +  * Change search order to match POSIX
  1210. +  * 
  1211. +  * Revision 1.25  90/08/24  21:55:00  Ian_Stewartson
  1212. +  * Change processing order (function, external, internal) to conform to
  1213. +  * POSIX.  Update to gmatch for macro command changes
  1214. +  * 
  1215.    * Revision 1.24  90/08/16  10:28:47  Ian_Stewartson
  1216.    * Find setting of switch character for DOS4 for batch files
  1217.    * 
  1218. ***************
  1219. *** 144,149 ****
  1220. --- 155,161 ----
  1221.   static char    *AE2big = "arg/env list too big";
  1222.   static char    *EMS_emsg = "Warning: EMS Error (%x)\n";
  1223.   static char    *XMS_emsg = "Warning: XMS Error (%x)\n";
  1224. + static char    *EF_msg = "%s: %s\n";
  1225.               /* Extended Command line processing file name    */
  1226.   static char        *Extend_file = (char *)NULL;
  1227.   static char        *Swap_File = (char *)NULL;    /* Swap file    */
  1228. ***************
  1229. *** 475,481 ****
  1230. --- 487,495 ----
  1231.       void    (*sig_int)();
  1232.       char    **owp = wp;
  1233.       bool    spawn = FALSE;
  1234. +     bool    builtin = FALSE;
  1235.       Fun_Ops    *fop;
  1236. +     int        i;
  1237.   
  1238.       if (t->type == TCOM)
  1239.       {
  1240. ***************
  1241. *** 510,522 ****
  1242.   /* Check for built in commands */
  1243.   
  1244.       else if (cp != (char *)NULL)
  1245. !         shcom = inbuilt (cp);
  1246.       }
  1247.   
  1248.   /* Unix fork simulation? */
  1249.   
  1250.       t->words = wp;
  1251. !     if (shcom == NULL && (act & FEXEC) == 0)
  1252.       {
  1253.       spawn = TRUE;
  1254.   
  1255. --- 524,536 ----
  1256.   /* Check for built in commands */
  1257.   
  1258.       else if (cp != (char *)NULL)
  1259. !         shcom = inbuilt (cp, &builtin);
  1260.       }
  1261.   
  1262.   /* Unix fork simulation? */
  1263.   
  1264.       t->words = wp;
  1265. !     if ((act & FEXEC) == 0)
  1266.       {
  1267.       spawn = TRUE;
  1268.   
  1269. ***************
  1270. *** 534,540 ****
  1271.   
  1272.       while (((cp = *owp++) != (char *)NULL) && assign (cp, COPYV))
  1273.       {
  1274. !     if (shcom == NULL)
  1275.           s_vstatus (lookup (cp, TRUE), EXPORT);
  1276.       }
  1277.   
  1278. --- 548,554 ----
  1279.   
  1280.       while (((cp = *owp++) != (char *)NULL) && assign (cp, COPYV))
  1281.       {
  1282. !     if (shcom == (int (*)())NULL) 
  1283.           s_vstatus (lookup (cp, TRUE), EXPORT);
  1284.       }
  1285.   
  1286. ***************
  1287. *** 565,572 ****
  1288.       }
  1289.       }
  1290.   
  1291. -     if (shcom)
  1292. -     return restore_std (setstatus ((*shcom)(t)), TRUE);
  1293.   
  1294.   /* All fids above 10 are autoclosed in the exec file because we have used
  1295.    * the O_NOINHERIT flag.  Note I patched open.obj to pass this flag to the
  1296. --- 579,584 ----
  1297. ***************
  1298. *** 598,604 ****
  1299.    * in some processing for return.
  1300.    */
  1301.   
  1302. !     if ((fop = Fun_Search (wp[0])) != (Fun_Ops *)NULL)
  1303.       {
  1304.       char            **s_dolv = dolv;
  1305.       int            s_dolc   = dolc;
  1306. --- 610,616 ----
  1307.    * in some processing for return.
  1308.    */
  1309.   
  1310. !     if (!builtin && (fop = Fun_Search (wp[0])) != (Fun_Ops *)NULL)
  1311.       {
  1312.       char            **s_dolv = dolv;
  1313.       int            s_dolc   = dolc;
  1314. ***************
  1315. *** 651,659 ****
  1316.   
  1317.   /* Ok - execute the program */
  1318.   
  1319. !     return restore_std (rexecve (wp[0], wp, makenv (), spawn), TRUE);
  1320. ! }
  1321.   
  1322.   /*
  1323.    * Restore Local Environment
  1324.    */
  1325. --- 663,685 ----
  1326.   
  1327.   /* Ok - execute the program */
  1328.   
  1329. !     if (!builtin)
  1330. !     rv = rexecve (wp[0], wp, makenv (), spawn);
  1331.   
  1332. + /* If we didn't find it, check for internal command */
  1333. +     if (builtin || ((rv == -1) && (errno == ENOENT)))
  1334. +     {
  1335. +     if (shcom != (int (*)())NULL) 
  1336. +         rv =  setstatus ((*shcom)(t));
  1337. +     else
  1338. +         print_warn (EF_msg, wp[0], "not found");
  1339. +     }
  1340. +     return restore_std (rv, TRUE);
  1341. + }
  1342.   /*
  1343.    * Restore Local Environment
  1344.    */
  1345. ***************
  1346. *** 835,841 ****
  1347.   
  1348.       for (wp = t1->words; *wp != (char *)NULL;)
  1349.