home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / amiga / vim46src.lha / vim-4.6 / src / amiga.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-06  |  30.6 KB  |  1,492 lines

  1. /* vi:set ts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved        by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  */
  8.  
  9. /*
  10.  * amiga.c
  11.  *
  12.  * Amiga system-dependent routines.
  13.  */
  14.  
  15. #include "vim.h"
  16. #include "globals.h"
  17. #include "proto.h"
  18. #include "option.h"
  19.  
  20. #ifdef HAVE_FCNTL_H
  21. # include <fcntl.h>
  22. #endif
  23.  
  24. #undef TRUE             /* will be redefined by exec/types.h */
  25. #undef FALSE
  26.  
  27. #ifndef LATTICE
  28. # include <exec/types.h>
  29. # include <exec/exec.h>
  30. # include <libraries/dos.h>
  31. # include <libraries/dosextens.h>
  32. # include <intuition/intuition.h>
  33. #else
  34. # include <proto/dos.h>
  35. # include <libraries/dosextens.h>
  36. # include <proto/intuition.h>
  37. # include <proto/exec.h>
  38. #endif
  39.  
  40. #include <exec/memory.h>
  41.  
  42. #include <dos/dostags.h>            /* for 2.0 functions */
  43. #include <dos/dosasl.h>
  44.  
  45. #if defined(LATTICE) && !defined(SASC) && !defined(NO_ARP)
  46. # include <libraries/arp_pragmas.h>
  47. #endif
  48.  
  49. /*
  50.  * At this point TRUE and FALSE are defined as 1L and 0L, but we want 1 and 0.
  51.  */
  52. #undef    TRUE
  53. #define TRUE (1)
  54. #undef    FALSE
  55. #define FALSE (0)
  56.  
  57. #ifndef AZTEC_C
  58. static long dos_packet __ARGS((struct MsgPort *, long, long));
  59. #endif
  60. static int lock2name __ARGS((BPTR lock, char_u *buf, long    len));
  61. static struct FileInfoBlock *get_fib __ARGS((char_u *));
  62. static int sortcmp __ARGS((char **a, char **b));
  63.  
  64. static BPTR                raw_in = (BPTR)NULL;
  65. static BPTR                raw_out = (BPTR)NULL;
  66. static int                close_win = FALSE;    /* set if Vim opened the window */
  67.  
  68. struct IntuitionBase    *IntuitionBase = NULL;
  69. #ifndef NO_ARP
  70. struct ArpBase            *ArpBase = NULL;
  71. #endif
  72.  
  73. static struct Window    *wb_window;
  74. static char_u            *oldwindowtitle = NULL;
  75.  
  76. #ifndef NO_ARP
  77. int                        dos2 = FALSE;        /* Amiga DOS 2.0x or higher */
  78. #endif
  79. int                        size_set = FALSE;    /* set to TRUE if window size was set */
  80.  
  81.     void
  82. win_resize_on()
  83. {
  84.     OUTSTRN("\033[12{");
  85. }
  86.  
  87.     void
  88. win_resize_off()
  89. {
  90.     OUTSTRN("\033[12}");
  91. }
  92.  
  93.     void
  94. mch_write(p, len)
  95.     char_u    *p;
  96.     int        len;
  97. {
  98.     Write(raw_out, (char *)p, (long)len);
  99. }
  100.  
  101. /*
  102.  * mch_inchar(): low level input funcion.
  103.  * Get a characters from the keyboard.
  104.  * If time == 0 do not wait for characters.
  105.  * If time == n wait a short time for characters.
  106.  * If time == -1 wait forever for characters.
  107.  *
  108.  * Return number of characters read.
  109.  */
  110.     int
  111. mch_inchar(buf, maxlen, time)
  112.     char_u    *buf;
  113.     int        maxlen;
  114.     long    time;                /* milli seconds */
  115. {
  116.     int        len;
  117.     long    utime;
  118.     
  119.     if (time >= 0)
  120.     {
  121.         if (time == 0)
  122.             utime = 100L;            /* time = 0 causes problems in DOS 1.2 */
  123.         else
  124.             utime = time * 1000L;    /* convert from milli to micro secs */
  125.         if (WaitForChar(raw_in, utime) == 0)    /* no character available */
  126.             return 0;
  127.     }
  128.     else    /* time == -1 */
  129.     {
  130.     /*
  131.      * If there is no character available within 2 seconds (default)
  132.      * write the autoscript file to disk
  133.      */
  134.         if (WaitForChar(raw_in, p_ut * 1000L) == 0)
  135.             updatescript(0);
  136.     }
  137.  
  138.     for (;;)        /* repeat until we got a character */
  139.     {
  140.         len = Read(raw_in, (char *)buf, (long)maxlen);
  141.         if (len > 0)
  142.             return len;
  143.     }
  144. }
  145.  
  146. /*
  147.  * return non-zero if a character is available
  148.  */
  149.     int
  150. mch_char_avail()
  151. {
  152.     return (WaitForChar(raw_in, 100L) != 0);
  153. }
  154.  
  155.     long
  156. mch_avail_mem(special)
  157.     int        special;
  158. {
  159.     return (long)AvailMem(special ? (long)MEMF_CHIP : (long)MEMF_ANY);
  160. }
  161.  
  162.     void
  163. mch_delay(msec, ignoreinput)
  164.     long    msec;
  165.     int        ignoreinput;
  166. {
  167. #ifndef LATTICE            /* SAS declares void Delay(UNLONG) */
  168.     void            Delay __ARGS((long));
  169. #endif
  170.  
  171.     if (msec > 0)
  172.     {
  173.         if (ignoreinput)
  174.             Delay(msec / 20L);        /* Delay works with 20 msec intervals */
  175.         else
  176.             WaitForChar(raw_in, msec * 1000L);
  177.     }
  178. }
  179.  
  180. /*
  181.  * We have no job control, fake it by starting a new shell.
  182.  */
  183.     void
  184. mch_suspend()
  185. {
  186.     MSG_OUTSTR("new shell started\n");
  187.     (void)call_shell(NULL, SHELL_COOKED);
  188.     need_check_timestamps = TRUE;
  189. }
  190.  
  191. #define DOS_LIBRARY     ((UBYTE *) "dos.library")
  192.  
  193.     void
  194. mch_windinit()
  195. {
  196.     static char        intlibname[] = "intuition.library";
  197.  
  198. #ifdef AZTEC_C
  199.     Enable_Abort = 0;            /* disallow vim to be aborted */
  200. #endif
  201.     Columns = 80;
  202.     Rows = 24;
  203.  
  204.     /*
  205.      * Set input and output channels, unless we have opened our own window
  206.      */
  207.     if (raw_in == (BPTR)NULL)
  208.     {
  209.         raw_in = Input();
  210.         raw_out = Output();
  211.     }
  212.  
  213.     flushbuf();
  214.  
  215.     wb_window = NULL;
  216.     if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary((UBYTE *)intlibname, 0L)) == NULL)
  217.     {
  218.         fprintf(stderr, "cannot open %s!?\n", intlibname);
  219.         mch_windexit(3);
  220.     }
  221.     (void)mch_get_winsize();
  222. }
  223.  
  224. #include <workbench/startup.h>
  225.  
  226. /*
  227.  * Check_win checks whether we have an interactive window.
  228.  * If not, a new window is opened with the newcli command.
  229.  * If we would open a window ourselves, the :sh and :! commands would not
  230.  * work properly (Why? probably because we are then running in a background
  231.  * CLI). This also is the best way to assure proper working in a next
  232.  * Workbench release.
  233.  *
  234.  * For the -e option (quickfix mode) and -x we open our own window and disable
  235.  * :sh. Otherwise the compiler would never know when editing is finished.
  236.  */
  237. #define BUF2SIZE 320        /* length of buffer for argument with complete path */
  238.  
  239.     int
  240. mch_check_win(argc, argv)
  241.     int argc;
  242.     char **argv;
  243. {
  244.     int                i;
  245.     BPTR            nilfh, fh;
  246.     char_u            buf1[20];
  247.     char_u            buf2[BUF2SIZE];
  248.     static char_u    *(constrings[3]) = {(char_u *)"con:0/0/662/210/",
  249.                                       (char_u *)"con:0/0/640/200/",
  250.                                       (char_u *)"con:0/0/320/200/"};
  251.     static char_u    winerr[] = "VIM: Can't open window!\n";
  252.     struct WBArg    *argp;
  253.     int                ac;
  254.     char            *av;
  255.     char_u            *device = NULL;
  256.     int                exitval = 4;
  257.     struct Library    *DosBase;
  258.     int                usewin = FALSE;
  259.  
  260. /*
  261.  * check if we are running under DOS 2.0x or higher
  262.  */
  263.     if (DosBase = OpenLibrary(DOS_LIBRARY, 37L))
  264.     {
  265.         CloseLibrary(DosBase);
  266. #ifndef NO_ARP
  267.         dos2 = TRUE;
  268. #endif
  269.     }
  270.     else            /* without arp functions we NEED 2.0 */
  271.     {
  272. #ifdef NO_ARP
  273.         fprintf(stderr, "Need Amigados version 2.04 or later\n");
  274.         exit(3);
  275. #else
  276.                     /* need arp functions for dos 1.x */
  277.         if (!(ArpBase = (struct ArpBase *) OpenLibrary((UBYTE *)ArpName, ArpVersion)))
  278.         {
  279.             fprintf(stderr, "Need %s version %ld\n", ArpName, ArpVersion);
  280.             exit(3);
  281.         }
  282. #endif
  283.     }
  284.  
  285. /*
  286.  * scan argv[] for the '-e', '-x' and '-d' arguments
  287.  */
  288.     for (i = 1; i < argc; ++i)
  289.         if (argv[i][0] == '-')
  290.         {
  291.             switch (argv[i][1])
  292.             {
  293.             case 'e':
  294.             case 'x':
  295.                 usewin = TRUE;
  296.                 break;
  297.  
  298.             case 'd':
  299.                 if (i < argc - 1)
  300.                     device = (char_u *)argv[i + 1];
  301.                 break;
  302.             }
  303.         }
  304.  
  305. /*
  306.  * If we were not started from workbench, do not have a '-d' argument and
  307.  * we have been started with an interactive window, use that window.
  308.  */
  309.     if (argc != 0 && device == NULL &&
  310.                             IsInteractive(Input()) && IsInteractive(Output()))
  311.         return OK;
  312.  
  313. /*
  314.  * If we are in quickfix mode, we open our own window. We can't use the
  315.  * newcli trick below, because the compiler would not know when we are finished.
  316.  * We do the same with the '-x' option, for mail, rn, etc.
  317.  */
  318.     if (usewin)
  319.     {
  320.         /*
  321.          * Try to open a window. First try the specified device.
  322.          * Then try a 24 line 80 column window.
  323.          * If that fails, try two smaller ones.
  324.          */
  325.         for (i = -1; i < 3; ++i)
  326.         {
  327.             if (i >= 0)
  328.                 device = constrings[i];
  329.             if (device && (raw_in = Open((UBYTE *)device, (long)MODE_NEWFILE)) != (BPTR)NULL)
  330.                 break;
  331.         }
  332.         if (raw_in == (BPTR)NULL)        /* all three failed */
  333.         {
  334.             fprintf(stderr, (char *)winerr);
  335.             goto exit;
  336.         }
  337.         raw_out = raw_in;
  338.         close_win = TRUE;
  339.         return OK;
  340.     }
  341.  
  342.     if ((nilfh = Open((UBYTE *)"NIL:", (long)MODE_NEWFILE)) == (BPTR)NULL)
  343.     {
  344.         fprintf(stderr, "Cannot open NIL:\n");
  345.         goto exit;
  346.     }
  347.  
  348.     /*
  349.      * make a unique name for the temp file (which we will not delete!)
  350.      */
  351.     sprintf((char *)buf1, "t:nc%ld", (char *)buf1);    /* nobody else is using our stack */
  352.     if ((fh = Open((UBYTE *)buf1, (long)MODE_NEWFILE)) == (BPTR)NULL)
  353.     {
  354.         fprintf(stderr, "Cannot create %s\n", (char *)buf1);
  355.         goto exit;
  356.     }
  357.     /*
  358.      * Write the command into the file, put quotes around the arguments that
  359.      * have a space in them.
  360.      */
  361.     if (argc == 0)        /* run from workbench */
  362.         ac = ((struct WBStartup *)argv)->sm_NumArgs;
  363.     else
  364.         ac = argc;
  365.     for (i = 0; i < ac; ++i)
  366.     {
  367.         if (argc == 0)
  368.         {
  369.             *buf2 = NUL;
  370.             argp = &(((struct WBStartup *)argv)->sm_ArgList[i]);
  371.             if (argp->wa_Lock)
  372.                 (void)lock2name(argp->wa_Lock, buf2, (long)(BUF2SIZE - 1));
  373. #ifndef NO_ARP
  374.             if (dos2)        /* use 2.0 function */
  375. #endif
  376.                 AddPart((UBYTE *)buf2, (UBYTE *)argp->wa_Name, (long)(BUF2SIZE - 1));
  377. #ifndef NO_ARP
  378.             else            /* use arp function */
  379.                 TackOn((char *)buf2, argp->wa_Name);
  380. #endif
  381.             av = (char *)buf2;
  382.         }
  383.         else
  384.             av = argv[i];
  385.  
  386.         if (av[0] == '-' && av[1] == 'd')        /* skip '-d' option */
  387.         {
  388.             ++i;
  389.             continue;
  390.         }
  391.         if (vim_strchr((char_u *)av, ' '))
  392.             Write(fh, "\"", 1L);
  393.         Write(fh, av, (long)strlen(av));
  394.         if (vim_strchr((char_u *)av, ' '))
  395.             Write(fh, "\"", 1L);
  396.         Write(fh, " ", 1L);
  397.     }
  398.     Write(fh, "\nendcli\n", 8L);
  399.     Close(fh);
  400.  
  401. /*
  402.  * Try to open a new cli in a window. If '-d' argument was given try to open
  403.  * the specified device. Then try a 24 line 80 column window.
  404.  * If that fails, try two smaller ones.
  405.  */
  406.     for (i = -1; i < 3; ++i)
  407.     {
  408.         if (i >= 0)
  409.             device = constrings[i];
  410.         else if (device == NULL)
  411.             continue;
  412.         sprintf((char *)buf2, "newcli <nil: >nil: %s from %s", (char *)device, (char *)buf1);
  413. #ifndef NO_ARP
  414.         if (dos2)
  415.         {
  416. #endif
  417.             if (!SystemTags((UBYTE *)buf2, SYS_UserShell, TRUE, TAG_DONE))
  418.                 break;
  419. #ifndef NO_ARP
  420.         }
  421.         else
  422.         {
  423.             if (Execute((UBYTE *)buf2, nilfh, nilfh))
  424.                 break;
  425.         }
  426. #endif
  427.     }
  428.     if (i == 3)        /* all three failed */
  429.     {
  430.         DeleteFile((UBYTE *)buf1);
  431.         fprintf(stderr, (char *)winerr);
  432.         goto exit;
  433.     }
  434.     exitval = 0;    /* The Execute succeeded: exit this program */
  435.  
  436. exit:
  437. #ifndef NO_ARP
  438.     if (ArpBase)
  439.         CloseLibrary((struct Library *) ArpBase);
  440. #endif
  441.     exit(exitval);
  442.     /* NOTREACHED */
  443.     return FAIL;
  444. }
  445.  
  446. /*
  447.  * Return OK if the input comes from a terminal, FAIL otherwise.
  448.  * We fake there is a window, because we can always open one!
  449.  */
  450.     int
  451. mch_check_input()
  452. {
  453.     return OK;
  454. }
  455.  
  456. /*
  457.  * fname_case(): Set the case of the filename, if it already exists.
  458.  *                 This will cause the filename to remain exactly the same.
  459.  */
  460.     void
  461. fname_case(name)
  462.     char_u    *name;
  463. {
  464.     register struct FileInfoBlock    *fib;
  465.     register size_t                    len;
  466.  
  467.     fib = get_fib(name);
  468.     if (fib != NULL)
  469.     {
  470.         len = STRLEN(name);
  471.         if (len == strlen(fib->fib_FileName))    /* safety check */
  472.             vim_memmove(name, fib->fib_FileName, len);
  473.         vim_free(fib);
  474.     }
  475. }
  476.  
  477. /*
  478.  * Get the FileInfoBlock for file "fname"
  479.  * The returned structure has to be free()d.
  480.  * Returns NULL on error.
  481.  */
  482.     static struct FileInfoBlock *
  483. get_fib(fname)
  484.     char_u *fname;
  485. {
  486.     register BPTR                    flock;
  487.     register struct FileInfoBlock    *fib;
  488.  
  489.     if (fname == NULL)        /* safety check */
  490.         return NULL;
  491.     fib = (struct FileInfoBlock *)malloc(sizeof(struct FileInfoBlock));
  492.     if (fib != NULL)
  493.     {
  494.         flock = Lock((UBYTE *)fname, (long)ACCESS_READ);
  495.         if (flock == (BPTR)NULL || !Examine(flock, fib))
  496.         {
  497.             vim_free(fib);    /* in case of an error the memory is freed here */
  498.             fib = NULL;
  499.         }
  500.         if (flock)
  501.             UnLock(flock);
  502.     }
  503.     return fib;
  504. }
  505.  
  506. /*
  507.  * set the title of our window
  508.  * icon name is not set
  509.  */
  510.     void
  511. mch_settitle(title, icon)
  512.     char_u    *title;
  513.     char_u    *icon;
  514. {
  515.     if (wb_window != NULL && title != NULL)
  516.         SetWindowTitles(wb_window, (UBYTE *)title, (UBYTE *)-1L);
  517. }
  518.  
  519. /*
  520.  * Restore the window/icon title.
  521.  * which is one of:
  522.  *    1  Just restore title
  523.  *  2  Just restore icon (which we don't have)
  524.  *    3  Restore title and icon (which we don't have)
  525.  */
  526.     void
  527. mch_restore_title(which)
  528.     int which;
  529. {
  530.     if (which & 1)
  531.         mch_settitle(oldwindowtitle, NULL);
  532. }
  533.  
  534.     int
  535. mch_can_restore_title()
  536. {
  537.     return (wb_window != NULL);
  538. }
  539.  
  540.     int
  541. mch_can_restore_icon()
  542. {
  543.     return FALSE;
  544. }
  545.  
  546. /*
  547.  * Insert user name in s[len].
  548.  */
  549.     int
  550. mch_get_user_name(s, len)
  551.     char_u    *s;
  552.     int        len;
  553. {
  554.     *s = NUL;
  555.     return FAIL;
  556. }
  557.  
  558. /*
  559.  * Insert host name is s[len].
  560.  */
  561.     void
  562. mch_get_host_name(s, len)
  563.     char_u    *s;
  564.     int        len;
  565. {
  566.     STRNCPY(s, "Amiga", len);
  567. }
  568.  
  569. /*
  570.  * return process ID
  571.  */
  572.     long
  573. mch_get_pid()
  574. {
  575.     return (long)0;
  576. }
  577.  
  578. /*
  579.  * Get name of current directory into buffer 'buf' of length 'len' bytes.
  580.  * Return OK for success, FAIL for failure.
  581.  */
  582.     int
  583. mch_dirname(buf, len)
  584.     char_u        *buf;
  585.     int            len;
  586. {
  587.     return FullName((char_u *)"", buf, len, FALSE);
  588. }
  589.  
  590. /*
  591.  * get absolute filename into buffer 'buf' of length 'len' bytes
  592.  *
  593.  * return FAIL for failure, OK otherwise
  594.  */
  595.     int
  596. FullName(fname, buf, len, force)
  597.     char_u        *fname, *buf;
  598.     int            len;
  599.     int            force;
  600. {
  601.     BPTR        l;
  602.     int            retval = FAIL;
  603.     int            i;
  604.  
  605.     *buf = NUL;
  606.     if (fname == NULL)    /* always fail */
  607.         return FAIL;
  608.  
  609.     if ((l = Lock((UBYTE *)fname, (long)ACCESS_READ)) != (BPTR)0)/* lock the file */
  610.     {
  611.         retval = lock2name(l, buf, (long)len);
  612.         UnLock(l);
  613.     }
  614.     else if (force || !isFullName(fname))        /* not a full path yet */
  615.     {
  616.         /*
  617.          * If cannot lock the file, try to lock the current directory and then
  618.          * concatenate the file name.  Works when file doesn't exist yet.
  619.          */
  620.         if ((l = Lock((UBYTE *)"", (long)ACCESS_READ)) != (BPTR)NULL) /* lock current dir */
  621.         {
  622.             retval = lock2name(l, buf, (long)len);
  623.             UnLock(l);
  624.             if (retval == OK)
  625.             {
  626.                 i = STRLEN(buf);
  627.                 if (i < len - 1 && (i == 0 || buf[i - 1] != ':'))
  628.                     buf[i++] = '/';
  629.                 STRNCPY(buf + i, fname, (len - i));    /* concatenate the fname */
  630.             }
  631.         }
  632.     }
  633.     if (retval == FAIL || *buf == 0 || *buf == ':')
  634.         STRCPY(buf, fname);    /* something failed; use the filename */
  635.     return retval;
  636. }
  637.  
  638. /*
  639.  * return TRUE is fname is an absolute path name
  640.  */
  641.     int
  642. isFullName(fname)
  643.     char_u        *fname;
  644. {
  645.     return (vim_strchr(fname, ':') != NULL);
  646. }
  647.  
  648. /*
  649.  * Get the full filename from a lock. Use 2.0 function if possible, because
  650.  * the arp function has more restrictions on the path length.
  651.  *
  652.  * return FAIL for failure, OK otherwise
  653.  */
  654.     static int
  655. lock2name(lock, buf, len)
  656.     BPTR    lock;
  657.     char_u    *buf;
  658.     long    len;
  659. {
  660. #ifndef NO_ARP
  661.     if (dos2)                /* use 2.0 function */
  662. #endif
  663.         return ((int)NameFromLock(lock, (UBYTE *)buf, len) ? OK : FAIL);
  664. #ifndef NO_ARP
  665.     else                /* use arp function */
  666.         return ((int)PathName(lock, (char *)buf, (long)(len/32)) ? OK : FAIL);
  667. #endif
  668. }
  669.  
  670. /*
  671.  * get file permissions for 'name'
  672.  */
  673.     long
  674. getperm(name)
  675.     char_u        *name;
  676. {
  677.     struct FileInfoBlock    *fib;
  678.     long                     retval = -1;
  679.  
  680.     fib = get_fib(name);
  681.     if (fib != NULL)
  682.     {
  683.         retval = fib->fib_Protection;
  684.         vim_free(fib);
  685.     }
  686.     return retval;
  687. }
  688.  
  689. /*
  690.  * set file permission for 'name' to 'perm'
  691.  *
  692.  * return FAIL for failure, OK otherwise
  693.  */
  694.     int
  695. setperm(name, perm)
  696.     char_u        *name;
  697.     long        perm;
  698. {
  699.     perm &= ~FIBF_ARCHIVE;                /* reset archived bit */
  700.     return (SetProtection((UBYTE *)name, (long)perm) ? OK : FAIL);
  701. }
  702.  
  703. /*
  704.  * return FALSE if "name" is not a directory
  705.  * return TRUE if "name" is a directory.
  706.  * return FALSE for error.
  707.  */
  708.     int
  709. mch_isdir(name)
  710.     char_u        *name;
  711. {
  712.     struct FileInfoBlock    *fib;
  713.     int                     retval = FALSE;
  714.  
  715.     fib = get_fib(name);
  716.     if (fib != NULL)
  717.     {
  718.         retval = ((fib->fib_DirEntryType >= 0) ? TRUE : FALSE);
  719.         vim_free(fib);
  720.     }
  721.     return retval;
  722. }
  723.  
  724. /*
  725.  * Careful: mch_windexit() may be called before mch_windinit()!
  726.  */
  727.     void
  728. mch_windexit(r)
  729.     int             r;
  730. {
  731.     if (raw_in)                        /* put terminal in 'normal' mode */
  732.     {
  733.         settmode(0);
  734.         stoptermcap();
  735.     }
  736.     outchar('\n');
  737.     if (raw_out)
  738.     {
  739.         if (term_console)
  740.         {
  741.             win_resize_off();        /* window resize events de-activated */
  742.             if (size_set)
  743.                 OUTSTR("\233t\233u");    /* reset window size (CSI t CSI u) */
  744.         }
  745.         flushbuf();
  746.     }
  747.  
  748.     mch_restore_title(3);            /* restore window title */
  749.  
  750.     ml_close_all(TRUE);                /* remove all memfiles */
  751.  
  752. #ifndef NO_ARP
  753.     if (ArpBase)
  754.         CloseLibrary((struct Library *) ArpBase);
  755. #endif
  756.     if (close_win)
  757.         Close(raw_in);
  758.     if (r)
  759.         printf("Vim exiting with %d\n", r);    /* somehow this makes :cq work!? */
  760.     exit(r);
  761. }
  762.  
  763. /*
  764.  * This is a routine for setting a given stream to raw or cooked mode on the
  765.  * Amiga . This is useful when you are using Lattice C to produce programs
  766.  * that want to read single characters with the "getch()" or "fgetc" call.
  767.  *
  768.  * Written : 18-Jun-87 By Chuck McManis.
  769.  */
  770.  
  771. #define MP(xx)    ((struct MsgPort *)((struct FileHandle *) (BADDR(xx)))->fh_Type)
  772.  
  773. /*
  774.  * Function mch_settmode() - Convert the specified file pointer to 'raw' or 'cooked'
  775.  * mode. This only works on TTY's.
  776.  *
  777.  * Raw: keeps DOS from translating keys for you, also (BIG WIN) it means
  778.  *        getch() will return immediately rather than wait for a return. You
  779.  *        lose editing features though.
  780.  *
  781.  * Cooked: This function returns the designate file pointer to it's normal,
  782.  *        wait for a <CR> mode. This is exactly like raw() except that
  783.  *        it sends a 0 to the console to make it back into a CON: from a RAW:
  784.  */
  785.     void
  786. mch_settmode(raw)
  787.     int            raw;
  788. {
  789.     if (dos_packet(MP(raw_in), (long)ACTION_SCREEN_MODE, raw ? -1L : 0L) == 0)
  790.         fprintf(stderr, "cannot change console mode ?!\n");
  791. }
  792.  
  793. /*
  794.  * set screen mode, always fails.
  795.  */
  796.     int
  797. mch_screenmode(arg)
  798.     char_u     *arg;
  799. {
  800.     EMSG("Screen mode setting not supported");
  801.     return FAIL;
  802. }
  803.  
  804. /*
  805.  * Code for this routine came from the following :
  806.  *
  807.  * ConPackets.c -  C. Scheppner, A. Finkel, P. Lindsay    CBM
  808.  *     DOS packet example
  809.  *     Requires 1.2
  810.  *
  811.  * Found on Fish Disk 56.
  812.  *
  813.  * Heavely modified by mool.
  814.  */
  815.  
  816. #include <devices/conunit.h>
  817.  
  818. /*
  819.  * try to get the real window size
  820.  * return FAIL for failure, OK otherwise
  821.  */
  822.     int
  823. mch_get_winsize()
  824. {
  825.     struct ConUnit    *conUnit;
  826.      char            id_a[sizeof(struct InfoData) + 3];
  827.     struct InfoData *id;
  828.  
  829.     if (!term_console)    /* not an amiga window */
  830.         return FAIL;
  831.  
  832.     /* insure longword alignment */
  833.      id = (struct InfoData *)(((long)id_a + 3L) & ~3L);
  834.  
  835.     /*
  836.      * Should make console aware of real window size, not the one we set.
  837.      * Unfortunately, under DOS 2.0x this redraws the window and it
  838.      * is rarely needed, so we skip it now, unless we changed the size.
  839.      */
  840.     if (size_set)
  841.         OUTSTR("\233t\233u");    /* CSI t CSI u */
  842.     flushbuf();
  843.  
  844.     if (dos_packet(MP(raw_out), (long)ACTION_DISK_INFO, ((ULONG) id) >> 2) == 0 ||
  845.                 (wb_window = (struct Window *)id->id_VolumeNode) == NULL)
  846.     {
  847.         /* it's not an amiga window, maybe aux device */
  848.         /* terminal type should be set */
  849.         term_console = FALSE;
  850.         return FAIL;
  851.     }
  852.     if (oldwindowtitle == NULL)
  853.         oldwindowtitle = (char_u *)wb_window->Title;
  854.     if (id->id_InUse == (BPTR)NULL)
  855.     {
  856.         fprintf(stderr, "mch_get_winsize: not a console??\n");
  857.         return FAIL;
  858.     }
  859.     conUnit = (struct ConUnit *) ((struct IOStdReq *) id->id_InUse)->io_Unit;
  860.  
  861.     /* get window size */
  862.     Rows = conUnit->cu_YMax + 1;
  863.     Columns = conUnit->cu_XMax + 1;
  864.     if (Rows < 0 || Rows > 200)     /* cannot be an amiga window */
  865.     {
  866.         Columns = 80;
  867.         Rows = 24;
  868.         term_console = FALSE;
  869.         return FAIL;
  870.     }
  871.     check_winsize();
  872.  
  873.     return OK;
  874. }
  875.  
  876. /*
  877.  * try to set the real window size
  878.  */
  879.     void
  880. mch_set_winsize()
  881. {
  882.     if (term_console)
  883.     {
  884.         size_set = TRUE;
  885.         outchar(CSI);
  886.         outnum((long)Rows);
  887.         outchar('t');
  888.         outchar(CSI);
  889.         outnum((long)Columns);
  890.         outchar('u');
  891.         flushbuf();
  892.     }
  893. }
  894.  
  895. #ifndef AZTEC_C
  896. /*
  897.  * Sendpacket.c
  898.  *
  899.  * An invaluable addition to your Amiga.lib file. This code sends a packet to
  900.  * the given message port. This makes working around DOS lots easier.
  901.  *
  902.  * Note, I didn't write this, those wonderful folks at CBM did. I do suggest
  903.  * however that you may wish to add it to Amiga.Lib, to do so, compile it and
  904.  * say 'oml lib:amiga.lib -r sendpacket.o'
  905.  */
  906.  
  907. /* #include <proto/exec.h> */
  908. /* #include <proto/dos.h> */
  909. #include <exec/memory.h>
  910.  
  911. /*
  912.  * Function - dos_packet written by Phil Lindsay, Carolyn Scheppner, and Andy
  913.  * Finkel. This function will send a packet of the given type to the Message
  914.  * Port supplied.
  915.  */
  916.  
  917.     static long
  918. dos_packet(pid, action, arg)
  919.     struct MsgPort *pid;    /* process indentifier ... (handlers message port) */
  920.     long            action, /* packet type ... (what you want handler to do)   */
  921.                     arg;    /* single argument */
  922. {
  923. # ifndef NO_ARP
  924.     struct MsgPort            *replyport;
  925.     struct StandardPacket    *packet;
  926.     long                    res1;
  927.  
  928.     if (dos2)
  929. # endif
  930.         return DoPkt(pid, action, arg, 0L, 0L, 0L, 0L);    /* use 2.0 function */
  931. # ifndef NO_ARP
  932.  
  933.     replyport = (struct MsgPort *) CreatePort(NULL, 0);    /* use arp function */
  934.     if (!replyport)
  935.         return (0);
  936.  
  937.     /* Allocate space for a packet, make it public and clear it */
  938.     packet = (struct StandardPacket *)
  939.         AllocMem((long) sizeof(struct StandardPacket), MEMF_PUBLIC | MEMF_CLEAR);
  940.     if (!packet) {
  941.         DeletePort(replyport);
  942.         return (0);
  943.     }
  944.     packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
  945.     packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
  946.     packet->sp_Pkt.dp_Port = replyport;
  947.     packet->sp_Pkt.dp_Type = action;
  948.     packet->sp_Pkt.dp_Arg1 = arg;
  949.  
  950.     PutMsg(pid, (struct Message *)packet);        /* send packet */
  951.  
  952.     WaitPort(replyport);
  953.     GetMsg(replyport);
  954.  
  955.     res1 = packet->sp_Pkt.dp_Res1;
  956.  
  957.     FreeMem(packet, (long) sizeof(struct StandardPacket));
  958.     DeletePort(replyport);
  959.  
  960.     return (res1);
  961. # endif
  962. }
  963. #endif
  964.  
  965. /*
  966.  * call shell, return FAIL for failure, OK otherwise
  967.  */
  968.     int
  969. call_shell(cmd, options)
  970.     char_u    *cmd;
  971.     int        options;        /* SHELL_FILTER if called by do_filter() */
  972.                             /* SHELL_COOKED if term needs cooked mode */
  973. {
  974.     BPTR    mydir;
  975.     int        x;
  976. #ifdef AZTEC_C
  977.     int        use_execute;
  978.     char_u    *shellcmd = NULL;
  979.     char_u    *shellarg;
  980. #endif
  981.     int    retval = OK;
  982.  
  983.     if (close_win)
  984.     {
  985.         /* if Vim opened a window: Executing a shell may cause crashes */
  986.         EMSG("Cannot execute shell with -e or -x option");
  987.         return FAIL;
  988.     }
  989.  
  990.     if (term_console)
  991.         win_resize_off();             /* window resize events de-activated */
  992.     flushbuf();
  993.  
  994.     if (options & SHELL_COOKED)
  995.         settmode(0);                 /* set to cooked mode */
  996.     mydir = Lock((UBYTE *)"", (long)ACCESS_READ);    /* remember current directory */
  997.  
  998. #if !defined(AZTEC_C)                /* not tested very much */
  999.     if (cmd == NULL)
  1000.     {
  1001. # ifndef NO_ARP
  1002.         if (dos2)
  1003. # endif
  1004.             x = SystemTags(p_sh, SYS_UserShell, TRUE, TAG_DONE);
  1005. # ifndef NO_ARP
  1006.         else
  1007.             x = Execute(p_sh, raw_in, raw_out);
  1008. # endif
  1009.     }
  1010.     else
  1011.     {
  1012. # ifndef NO_ARP
  1013.         if (dos2)
  1014. # endif
  1015.             x = SystemTags((char *)cmd, SYS_UserShell, TRUE, TAG_DONE);
  1016. # ifndef NO_ARP
  1017.         else
  1018.             x = Execute((char *)cmd, 0L, raw_out);
  1019. # endif
  1020.     }
  1021. # ifdef NO_ARP
  1022.     if (x < 0)
  1023. # else
  1024.     if ((dos2 && x < 0) || (!dos2 && !x))
  1025. # endif
  1026.     {
  1027.         MSG_OUTSTR("Cannot execute ");
  1028.         if (cmd == NULL)
  1029.         {
  1030.             MSG_OUTSTR("shell ");
  1031.             msg_outtrans(p_sh);
  1032.         }
  1033.         else
  1034.             msg_outtrans(cmd);
  1035.         msg_outchar('\n');
  1036.         retval = FAIL;
  1037.     }
  1038. # ifdef NO_ARP
  1039.     else if (x)
  1040. # else
  1041.     else if (!dos2 || x)
  1042. # endif
  1043.     {
  1044.         if (x = IoErr())
  1045.         {
  1046.             if (!expand_interactively)
  1047.             {
  1048.                 msg_outchar('\n');
  1049.                 msg_outnum(x);
  1050.                 MSG_OUTSTR(" returned\n");
  1051.             }
  1052.             retval = FAIL;
  1053.         }
  1054.     }
  1055. #else    /* else part is for AZTEC_C */
  1056.     if (p_st >= 4 || (p_st >= 2 && options != SHELL_FILTER))
  1057.         use_execute = 1;
  1058.     else
  1059.         use_execute = 0;
  1060.     if (!use_execute)
  1061.     {
  1062.         /*
  1063.          * separate shell name from argument
  1064.          */
  1065.         shellcmd = strsave(p_sh);
  1066.         if (shellcmd == NULL)        /* out of memory, use Execute */
  1067.             use_execute = 1;
  1068.         else
  1069.         {
  1070.             shellarg = skiptowhite(shellcmd);    /* find start of arguments */
  1071.             if (*shellarg != NUL)
  1072.             {
  1073.                 *shellarg++ = NUL;
  1074.                 shellarg = skipwhite(shellarg);
  1075.             }
  1076.         }
  1077.     }
  1078.     if (cmd == NULL)
  1079.     {
  1080.         if (use_execute)
  1081.         {
  1082. # ifndef NO_ARP
  1083.             if (dos2)
  1084. # endif
  1085.                 x = SystemTags((UBYTE *)p_sh, SYS_UserShell, TRUE, TAG_DONE);
  1086. # ifndef NO_ARP
  1087.             else
  1088.                 x = !Execute((UBYTE *)p_sh, raw_in, raw_out);
  1089. # endif
  1090.         }
  1091.         else
  1092.             x = fexecl((char *)shellcmd, (char *)shellcmd, (char *)shellarg, NULL);
  1093.     }
  1094.     else if (use_execute)
  1095.     {
  1096. # ifndef NO_ARP
  1097.         if (dos2)
  1098. # endif
  1099.             x = SystemTags((UBYTE *)cmd, SYS_UserShell, TRUE, TAG_DONE);
  1100. # ifndef NO_ARP
  1101.         else
  1102.             x = !Execute((UBYTE *)cmd, 0L, raw_out);
  1103. # endif
  1104.     }
  1105.     else if (p_st & 1)
  1106.         x = fexecl((char *)shellcmd, (char *)shellcmd, (char *)shellarg, (char *)cmd, NULL);
  1107.     else
  1108.         x = fexecl((char *)shellcmd, (char *)shellcmd, (char *)shellarg, (char *)p_shcf, (char *)cmd, NULL);
  1109. # ifdef NO_ARP
  1110.     if (x < 0)
  1111. # else
  1112.     if ((dos2 && x < 0) || (!dos2 && x))
  1113. # endif
  1114.     {
  1115.         MSG_OUTSTR("Cannot execute ");
  1116.         if (use_execute)
  1117.         {
  1118.             if (cmd == NULL)
  1119.                 msg_outstr(p_sh);
  1120.             else
  1121.                 msg_outstr(cmd);
  1122.         }
  1123.         else
  1124.         {
  1125.             MSG_OUTSTR("shell ");
  1126.             msg_outstr(shellcmd);
  1127.         }
  1128.         msg_outchar('\n');
  1129.         retval = FAIL;
  1130.     }
  1131.     else
  1132.     {
  1133.         if (use_execute)
  1134.         {
  1135. # ifdef NO_ARP
  1136.             if (x)
  1137. # else
  1138.             if (!dos2 || x)
  1139. # endif
  1140.                 x = IoErr();
  1141.         }
  1142.         else
  1143.             x = wait();
  1144.         if (x)
  1145.         {
  1146.             if (!expand_interactively)
  1147.             {
  1148.                 msg_outchar('\n');
  1149.                 msg_outnum((long)x);
  1150.                 MSG_OUTSTR(" returned\n");
  1151.             }
  1152.             retval = FAIL;
  1153.         }
  1154.     }
  1155.     vim_free(shellcmd);
  1156. #endif    /* AZTEC_C */
  1157.  
  1158.     if (mydir = CurrentDir(mydir))        /* make sure we stay in the same directory */
  1159.         UnLock(mydir);
  1160.     settmode(1);                         /* set to raw mode */
  1161.     resettitle();
  1162.     if (term_console)
  1163.         win_resize_on();                 /* window resize events activated */
  1164.     return retval;
  1165. }
  1166.  
  1167. /*
  1168.  * check for an "interrupt signal"
  1169.  * We only react to a CTRL-C, but also clear the other break signals to avoid
  1170.  * trouble with lattice-c programs.
  1171.  */
  1172.     void
  1173. mch_breakcheck()
  1174. {
  1175.    if (SetSignal(0L, (long)(SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F)) & SIGBREAKF_CTRL_C)
  1176.         got_int = TRUE;
  1177. }
  1178.  
  1179. /* this routine causes manx to use this Chk_Abort() rather than it's own */
  1180. /* otherwise it resets our ^C when doing any I/O (even when Enable_Abort */
  1181. /* is zero).  Since we want to check for our own ^C's                    */
  1182.  
  1183. #ifdef _DCC
  1184. #define Chk_Abort chkabort
  1185. #endif
  1186.  
  1187. #ifdef LATTICE
  1188. void __regargs __chkabort(void);
  1189.  
  1190. void __regargs __chkabort(void)
  1191. {}
  1192.  
  1193. #else
  1194.     long
  1195. Chk_Abort(void)
  1196. {
  1197.     return(0L);
  1198. }
  1199. #endif
  1200.  
  1201. /*
  1202.  * ExpandWildCards() - this code does wild-card pattern matching using the arp
  1203.  *                      routines. This is based on WildDemo2.c (found in arp1.1
  1204.  *                      distribution). That code's copyright follows :
  1205.  *-------------------------------------------------------------------------
  1206.  * WildDemo2.c - Search filesystem for patterns, and separate into directories
  1207.  *         and files, sorting each separately using DA lists.
  1208.  *
  1209.  * -+=SDB=+-
  1210.  *
  1211.  * Copyright (c) 1987, Scott Ballantyne
  1212.  * Use and abuse as you please.
  1213.  *
  1214.  * num_pat is number of input patterns
  1215.  * pat is array of pointers to input patterns
  1216.  * num_file is pointer to number of matched file names
  1217.  * file is pointer to array of pointers to matched file names
  1218.  * if file_only is TRUE we match only files, no dirs
  1219.  * if list_notfound is TRUE we include not-found entries (probably locked)
  1220.  * return OK for success, FAIL for error (you may loose some memory)
  1221.  *-------------------------------------------------------------------------
  1222.  */
  1223.  
  1224. /* #include <arpfunctions.h> */
  1225. extern void *malloc __ARGS((size_t)), *calloc __ARGS((size_t, size_t));
  1226. static int insfile __ARGS((char_u *, int));
  1227. static void freefiles __ARGS((void));
  1228.  
  1229. #define ANCHOR_BUF_SIZE (512)
  1230. #define ANCHOR_SIZE (sizeof(struct AnchorPath) + ANCHOR_BUF_SIZE)
  1231.  
  1232. /*
  1233.  * we use this structure to built a list of file names
  1234.  */
  1235. struct onefile
  1236. {
  1237.     struct onefile    *next;
  1238.     char_u            name[1];    /* really longer */
  1239. } *namelist = NULL;
  1240.  
  1241. /*
  1242.  * insert one file into the list of file names
  1243.  * return FAIL for failure
  1244.  * return OK for success
  1245.  */
  1246.     static int
  1247. insfile(name, isdir)
  1248.     char_u    *name;
  1249.     int        isdir;
  1250. {
  1251.     struct onefile *newp;
  1252.  
  1253.     newp = (struct onefile *)alloc((unsigned)(sizeof(struct onefile) +
  1254.                                                     STRLEN(name) + isdir));
  1255.     if (newp == NULL)
  1256.         return FAIL;
  1257.     STRCPY(&(newp->name[0]), name);
  1258.     if (isdir)
  1259.         STRCAT(&(newp->name[0]), "/");
  1260.     newp->next = namelist;
  1261.     namelist = newp;
  1262.     return OK;
  1263. }
  1264.  
  1265. /*
  1266.  * free a whole list of file names
  1267.  */
  1268.     static void
  1269. freefiles()
  1270. {
  1271.     struct onefile *p;
  1272.  
  1273.     while (namelist)
  1274.     {
  1275.         p = namelist->next;
  1276.         vim_free(namelist);
  1277.         namelist = p;
  1278.     }
  1279. }
  1280.  
  1281.     static int
  1282. sortcmp(a, b)
  1283.     char **a, **b;
  1284. {
  1285.     return strcmp(*a, *b);
  1286. }
  1287.  
  1288.     int
  1289. ExpandWildCards(num_pat, pat, num_file, file, files_only, list_notfound)
  1290.     int             num_pat;
  1291.     char_u          **pat;
  1292.     int            *num_file;
  1293.     char_u         ***file;
  1294.     int            files_only;
  1295.     int            list_notfound;
  1296. {
  1297.     int                     i;
  1298.     int                        cur_pat;
  1299.     struct AnchorPath        *Anchor;
  1300.     int                        domatchend = FALSE;
  1301.     LONG                    Result;
  1302.     struct onefile            *p;
  1303.     char_u                    *errmsg = NULL;
  1304.     char_u                    *starbuf, *sp, *dp;
  1305.     int                        foundone;
  1306.     int                        prev_num_file = 0;
  1307.     char_u                    **file_new;
  1308.  
  1309.     *num_file = 0;
  1310.     *file = (char_u **)"";
  1311.  
  1312.     /* Get our AnchorBase */
  1313.     Anchor = (struct AnchorPath *) calloc((size_t)1, (size_t)ANCHOR_SIZE);
  1314.     if (Anchor == NULL)
  1315.         goto OUT_OF_MEMORY;
  1316.     Anchor->ap_Strlen = ANCHOR_BUF_SIZE;    /* ap_Length not supported anymore */
  1317. #ifdef APF_DODOT
  1318.     Anchor->ap_Flags = APF_DODOT | APF_DOWILD;        /* allow '.' for current dir */
  1319. #else
  1320.     Anchor->ap_Flags = APF_DoDot | APF_DoWild;        /* allow '.' for current dir */
  1321. #endif
  1322.  
  1323.     for (cur_pat = 0; cur_pat < num_pat; cur_pat++)
  1324.     {
  1325. #ifndef NO_ARP
  1326.         if (dos2)
  1327.         {
  1328. #endif
  1329.                 /* hack to replace '*' by '#?' */
  1330.             starbuf = alloc((unsigned)(2 * STRLEN(pat[cur_pat]) + 1));
  1331.             if (starbuf == NULL)
  1332.                 goto OUT_OF_MEMORY;
  1333.             for (sp = pat[cur_pat], dp = starbuf; *sp; ++sp)
  1334.             {
  1335.                 if (*sp == '*')
  1336.                 {
  1337.                     *dp++ = '#';
  1338.                     *dp++ = '?';
  1339.                 }
  1340.                 else
  1341.                     *dp++ = *sp;
  1342.             }
  1343.             *dp = NUL;
  1344.             Result = MatchFirst((UBYTE *)starbuf, Anchor);
  1345.             vim_free(starbuf);
  1346. #ifndef NO_ARP
  1347.         }
  1348.         else
  1349.             Result = FindFirst((char *)pat[cur_pat], Anchor);
  1350. #endif
  1351.         domatchend = TRUE;
  1352.         foundone = FALSE;
  1353.         while (Result == 0)
  1354.         {
  1355.             if (!files_only || Anchor->ap_Info.fib_DirEntryType < 0)
  1356.             {
  1357.                 (*num_file)++;
  1358.                 if (insfile((char_u *)Anchor->ap_Buf, Anchor->ap_Info.fib_DirEntryType >= 0) == FAIL)
  1359.                 {
  1360. OUT_OF_MEMORY:
  1361.                     errmsg = (char_u *)"Out of memory";
  1362.                     goto Return;
  1363.                 }
  1364.                 foundone = TRUE;
  1365.             }
  1366. #ifndef NO_ARP
  1367.             if (dos2)
  1368. #endif
  1369.                 Result = MatchNext(Anchor);
  1370. #ifndef NO_ARP
  1371.             else
  1372.                 Result = FindNext(Anchor);
  1373. #endif
  1374.         }
  1375.         if (Result == ERROR_BUFFER_OVERFLOW)
  1376.         {
  1377.             errmsg = (char_u *)"ANCHOR_BUF_SIZE too small.";
  1378.             goto Return;
  1379.         }
  1380.         if (!foundone)
  1381.         {
  1382.             if (list_notfound)    /* put object with error in list */
  1383.             {
  1384.                 (*num_file)++;
  1385.                 if (insfile(pat[cur_pat], FALSE) == FAIL)
  1386.                     goto OUT_OF_MEMORY;
  1387.             }
  1388.             else if (Result != ERROR_OBJECT_NOT_FOUND && Result != ERROR_NO_MORE_ENTRIES)
  1389.             {
  1390.                 errmsg = (char_u *)"I/O ERROR";
  1391.                 goto Return;
  1392.             }
  1393.         }
  1394. #ifndef NO_ARP
  1395.         if (dos2)
  1396. #endif
  1397.             MatchEnd(Anchor);
  1398. #ifndef NO_ARP
  1399.         else
  1400.             FreeAnchorChain(Anchor);
  1401. #endif
  1402.         domatchend = FALSE;
  1403.         /*
  1404.          * Sort the files for this pattern.
  1405.          * Move the already found files to the newly allocated array.
  1406.          */
  1407.         if (namelist)
  1408.         {
  1409.             file_new = (char_u **) malloc(sizeof(char_u *) * *num_file);
  1410.             if (file_new == NULL)
  1411.                 goto OUT_OF_MEMORY;
  1412.             if (prev_num_file)
  1413.             {
  1414.                 for (i = 0; i < prev_num_file; ++i)
  1415.                     file_new[i] = (*file)[i];
  1416.                 vim_free(*file);
  1417.             }
  1418.             *file = file_new;
  1419.  
  1420.             p = namelist;
  1421.             for (i = *num_file - 1; p; p = p->next, --i)
  1422.             {
  1423.                 (*file)[i] = (char_u *) malloc(STRLEN(p->name) + 1);
  1424.                 if ((*file)[i] == NULL)
  1425.                     goto OUT_OF_MEMORY;
  1426.                 STRCPY((*file)[i], p->name);
  1427.             }
  1428.             qsort((void *)&((*file)[prev_num_file]),
  1429.                                            (size_t)(*num_file - prev_num_file),
  1430.                                                      sizeof(char_u *), sortcmp);
  1431.             prev_num_file = *num_file;
  1432.             freefiles();
  1433.         }
  1434.     }
  1435.  
  1436. Return:
  1437.     if (domatchend)
  1438.     {
  1439. #ifndef NO_ARP
  1440.         if (dos2)
  1441. #endif
  1442.             MatchEnd(Anchor);
  1443. #ifndef NO_ARP
  1444.         else
  1445.             FreeAnchorChain(Anchor);
  1446. #endif
  1447.     }
  1448.     if (Anchor)
  1449.         vim_free(Anchor);
  1450.     freefiles();
  1451.     if (errmsg)
  1452.     {
  1453.         emsg(errmsg);
  1454.         *num_file = 0;
  1455.         return FAIL;
  1456.     }
  1457.     return OK;
  1458. }
  1459.  
  1460.     int
  1461. mch_has_wildcard(p)
  1462.     char_u *p;
  1463. {
  1464.     for ( ; *p; ++p)
  1465.         if (vim_strchr((char_u *)"*?[(~#", *p) != NULL)
  1466.             return TRUE;
  1467.     return FALSE;
  1468. }
  1469.  
  1470. /*
  1471.  * With 2.0 support for reading local environment variables
  1472.  * Careful: uses IObuff!
  1473.  */
  1474.     char_u *
  1475. vim_getenv(var)
  1476.     char_u *var;
  1477. {
  1478.     int len;
  1479.  
  1480. #ifndef NO_ARP
  1481.     if (!dos2)
  1482.         return (char_u *)getenv((char *)var);
  1483. #endif
  1484.  
  1485.     len = GetVar((UBYTE *)var, (UBYTE *)IObuff, (long)(IOSIZE - 1), (long)0);
  1486.  
  1487.     if (len == -1)
  1488.         return NULL;
  1489.     else
  1490.         return IObuff;
  1491. }
  1492.