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 / unix / vim-6.2.tar.bz2 / vim-6.2.tar / vim62 / src / misc2.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-05-25  |  128.5 KB  |  5,524 lines

  1. /* vi:set ts=8 sts=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.  * See README.txt for an overview of the Vim source code.
  8.  */
  9.  
  10. /*
  11.  * misc2.c: Various functions.
  12.  */
  13. #include "vim.h"
  14.  
  15. #ifdef HAVE_FCNTL_H
  16. # include <fcntl.h>        /* for chdir() */
  17. #endif
  18.  
  19. #if defined(FEAT_VIRTUALEDIT) || defined(PROTO)
  20. static int coladvance2 __ARGS((pos_T *pos, int addspaces, int finetune, colnr_T wcol));
  21.  
  22. /*
  23.  * Return TRUE if in the current mode we need to use virtual.
  24.  */
  25.     int
  26. virtual_active()
  27. {
  28.     /* While an operator is being executed we return "virtual_op", because
  29.      * VIsual_active has already been reset, thus we can't check for "block"
  30.      * being used. */
  31.     if (virtual_op != MAYBE)
  32.     return virtual_op;
  33.     return (ve_flags == VE_ALL
  34. # ifdef FEAT_VISUAL
  35.         || ((ve_flags & VE_BLOCK) && VIsual_active && VIsual_mode == Ctrl_V)
  36. # endif
  37.         || ((ve_flags & VE_INSERT) && (State & INSERT)));
  38. }
  39.  
  40. /*
  41.  * Get the screen position of the cursor.
  42.  */
  43.     int
  44. getviscol()
  45. {
  46.     colnr_T    x;
  47.  
  48.     getvvcol(curwin, &curwin->w_cursor, &x, NULL, NULL);
  49.     return (int)x;
  50. }
  51.  
  52. /*
  53.  * Get the screen position of character col with a coladd in the cursor line.
  54.  */
  55.     int
  56. getviscol2(col, coladd)
  57.     colnr_T    col;
  58.     colnr_T    coladd;
  59. {
  60.     colnr_T    x;
  61.     pos_T    pos;
  62.  
  63.     pos.lnum = curwin->w_cursor.lnum;
  64.     pos.col = col;
  65.     pos.coladd = coladd;
  66.     getvvcol(curwin, &pos, &x, NULL, NULL);
  67.     return (int)x;
  68. }
  69.  
  70. /*
  71.  * Go to column "wcol", and add/insert white space as neccessary to get the
  72.  * cursor in that column.
  73.  * The caller must have saved the cursor line for undo!
  74.  */
  75.     int
  76. coladvance_force(wcol)
  77.     colnr_T wcol;
  78. {
  79.     int rc = coladvance2(&curwin->w_cursor, TRUE, FALSE, wcol);
  80.  
  81.     if (wcol == MAXCOL)
  82.     curwin->w_valid &= ~VALID_VIRTCOL;
  83.     else
  84.     {
  85.     /* Virtcol is valid */
  86.     curwin->w_valid |= VALID_VIRTCOL;
  87.     curwin->w_virtcol = wcol;
  88.     }
  89.     return rc;
  90. }
  91. #endif
  92.  
  93. /*
  94.  * Try to advance the Cursor to the specified screen column.
  95.  * If virtual editing: fine tune the cursor position.
  96.  * Note that all virtual positions off the end of a line should share
  97.  * a curwin->w_cursor.col value (n.b. this is equal to STRLEN(line)),
  98.  * beginning at coladd 0.
  99.  *
  100.  * return OK if desired column is reached, FAIL if not
  101.  */
  102.     int
  103. coladvance(wcol)
  104.     colnr_T    wcol;
  105. {
  106.     int rc = getvpos(&curwin->w_cursor, wcol);
  107.  
  108.     if (wcol == MAXCOL)
  109.     curwin->w_valid &= ~VALID_VIRTCOL;
  110.     else
  111.     {
  112.     /* Virtcol is valid */
  113.     curwin->w_valid |= VALID_VIRTCOL;
  114.     curwin->w_virtcol = wcol;
  115.     }
  116.     return rc;
  117. }
  118.  
  119. /*
  120.  * Return in "pos" the position of the cursor advanced to screen column "wcol".
  121.  * return OK if desired column is reached, FAIL if not
  122.  */
  123.     int
  124. getvpos(pos, wcol)
  125.     pos_T   *pos;
  126.     colnr_T wcol;
  127. {
  128. #ifdef FEAT_VIRTUALEDIT
  129.     return coladvance2(pos, FALSE, virtual_active(), wcol);
  130. }
  131.  
  132.     static int
  133. coladvance2(pos, addspaces, finetune, wcol)
  134.     pos_T    *pos;
  135.     int        addspaces;    /* change the text to achieve our goal? */
  136.     int        finetune;    /* change char offset for the excact column */
  137.     colnr_T    wcol;        /* column to move to */
  138. {
  139. #endif
  140.     int        idx;
  141.     char_u    *ptr;
  142.     char_u    *line;
  143.     colnr_T    col = 0;
  144.     int        csize = 0;
  145.     int        one_more;
  146. #ifdef FEAT_LINEBREAK
  147.     int        head = 0;
  148. #endif
  149.  
  150.     one_more = (State & INSERT) || restart_edit != NUL
  151. #ifdef FEAT_VISUAL
  152.                       || (VIsual_active && *p_sel != 'o')
  153. #endif
  154.                       ;
  155.     line = ml_get_curline();
  156.  
  157.     if (wcol >= MAXCOL)
  158.     {
  159.         idx = (int)STRLEN(line) - 1 + one_more;
  160.         col = wcol;
  161.  
  162. #ifdef FEAT_VIRTUALEDIT
  163.         if ((addspaces || finetune) && !VIsual_active)
  164.         {
  165.         curwin->w_curswant = linetabsize(line) + one_more;
  166.         if (curwin->w_curswant > 0)
  167.             --curwin->w_curswant;
  168.         }
  169. #endif
  170.     }
  171.     else
  172.     {
  173. #ifdef FEAT_VIRTUALEDIT
  174.     int width = W_WIDTH(curwin) - win_col_off(curwin);
  175.  
  176.     if ((addspaces || finetune)
  177.         && curwin->w_p_wrap
  178. # ifdef FEAT_VERTSPLIT
  179.         && curwin->w_width != 0
  180. # endif
  181.         && wcol >= (colnr_T)width)
  182.     {
  183.         csize = linetabsize(line);
  184.         if (csize > 0)
  185.         csize--;
  186.  
  187.         if (wcol / width > (colnr_T)csize / width)
  188.         {
  189.         /* In case of line wrapping don't move the cursor beyond the
  190.          * right screen edge. */
  191.         wcol = (csize / width + 1) * width - 1;
  192.         }
  193.     }
  194. #endif
  195.  
  196.     idx = -1;
  197.     ptr = line;
  198.     while (col <= wcol && *ptr != NUL)
  199.     {
  200.         /* Count a tab for what it's worth (if list mode not on) */
  201. #ifdef FEAT_LINEBREAK
  202.         csize = win_lbr_chartabsize(curwin, ptr, col, &head);
  203. # ifdef FEAT_MBYTE
  204.         if (has_mbyte)
  205.         ptr += (*mb_ptr2len_check)(ptr);
  206.         else
  207. # endif
  208.         ++ptr;
  209. #else
  210.         csize = lbr_chartabsize_adv(&ptr, col);
  211. #endif
  212.         col += csize;
  213.     }
  214.     idx = (int)(ptr - line);
  215.     /*
  216.      * Handle all the special cases.  The virtual_active() check
  217.      * is needed to ensure that a virtual position off the end of
  218.      * a line has the correct indexing.  The one_more comparison
  219.      * replaces an explicit add of one_more later on.
  220.      */
  221.     if (col > wcol || (!virtual_active() && one_more == 0))
  222.     {
  223.         idx -= 1;
  224. # ifdef FEAT_LINEBREAK
  225.         /* Don't count the chars from 'showbreak'. */
  226.         csize -= head;
  227. # endif
  228.         col -= csize;
  229.     }
  230.  
  231. #ifdef FEAT_VIRTUALEDIT
  232.     if (virtual_active()
  233.         && addspaces
  234.         && ((col != wcol && col != wcol + 1) || csize > 1))
  235.     {
  236.         /* 'virtualedit' is set: The difference between wcol and col is
  237.          * filled with spaces. */
  238.  
  239.         if (line[idx] == NUL)
  240.         {
  241.         /* Append spaces */
  242.         int    correct = wcol - col;
  243.         char_u    *newline = alloc(idx + correct + 1);
  244.         int    t;
  245.  
  246.         if (newline == NULL)
  247.             return FAIL;
  248.  
  249.         for (t = 0; t < idx; ++t)
  250.             newline[t] = line[t];
  251.  
  252.         for (t = 0; t < correct; ++t)
  253.             newline[t + idx] = ' ';
  254.  
  255.         newline[idx + correct] = NUL;
  256.  
  257.         ml_replace(pos->lnum, newline, FALSE);
  258.         changed_bytes(pos->lnum, (colnr_T)idx);
  259.         idx += correct;
  260.         col = wcol;
  261.         }
  262.         else
  263.         {
  264.         /* Break a tab */
  265.         int    linelen = (int)STRLEN(line);
  266.         int    correct = wcol - col - csize + 1; /* negative!! */
  267.         char_u    *newline = alloc(linelen + csize);
  268.         int    t, s = 0;
  269.         int    v;
  270.  
  271.         /*
  272.          * break a tab
  273.          */
  274.         if (newline == NULL || -correct > csize)
  275.             return FAIL;
  276.  
  277.         for (t = 0; t < linelen; t++)
  278.         {
  279.             if (t != idx)
  280.             newline[s++] = line[t];
  281.             else
  282.             for (v = 0; v < csize; v++)
  283.                 newline[s++] = ' ';
  284.         }
  285.  
  286.         newline[linelen + csize - 1] = NUL;
  287.  
  288.         ml_replace(pos->lnum, newline, FALSE);
  289.         changed_bytes(pos->lnum, idx);
  290.         idx += (csize - 1 + correct);
  291.         col += correct;
  292.         }
  293.     }
  294. #endif
  295.     }
  296.  
  297.     if (idx < 0)
  298.     pos->col = 0;
  299.     else
  300.     pos->col = idx;
  301.  
  302. #ifdef FEAT_VIRTUALEDIT
  303.     pos->coladd = 0;
  304.  
  305.     if (finetune)
  306.     {
  307.     int a = col;
  308.     int b = wcol - a;
  309.  
  310.     /* 'virtualedit' is set: The difference between wcol and col is used
  311.      * to set coladd. */
  312.     if (b > 0 && b < (MAXCOL - 2 * W_WIDTH(curwin)))
  313.         pos->coladd = b;
  314.  
  315.     col += b;
  316.     }
  317. #endif
  318.  
  319. #ifdef FEAT_MBYTE
  320.     /* prevent cursor from moving on the trail byte */
  321.     if (has_mbyte)
  322.     mb_adjust_cursor();
  323. #endif
  324.  
  325.     if (col < wcol)
  326.     return FAIL;
  327.     return OK;
  328. }
  329.  
  330. /*
  331.  * inc(p)
  332.  *
  333.  * Increment the line pointer 'p' crossing line boundaries as necessary.
  334.  * Return 1 when going to the next line.
  335.  * Return 2 when moving forward onto a NUL at the end of the line).
  336.  * Return -1 when at the end of file.
  337.  * Return 0 otherwise.
  338.  */
  339.     int
  340. inc_cursor()
  341. {
  342.     return inc(&curwin->w_cursor);
  343. }
  344.  
  345.     int
  346. inc(lp)
  347.     pos_T  *lp;
  348. {
  349.     char_u  *p = ml_get_pos(lp);
  350.  
  351.     if (*p != NUL)    /* still within line, move to next char (may be NUL) */
  352.     {
  353. #ifdef FEAT_MBYTE
  354.     if (has_mbyte)
  355.     {
  356.         int l = (*mb_ptr2len_check)(p);
  357.  
  358.         lp->col += l;
  359.         return ((p[l] != NUL) ? 0 : 2);
  360.     }
  361. #endif
  362.     lp->col++;
  363. #ifdef FEAT_VIRTUALEDIT
  364.     lp->coladd = 0;
  365. #endif
  366.     return ((p[1] != NUL) ? 0 : 2);
  367.     }
  368.     if (lp->lnum != curbuf->b_ml.ml_line_count)     /* there is a next line */
  369.     {
  370.     lp->col = 0;
  371.     lp->lnum++;
  372. #ifdef FEAT_VIRTUALEDIT
  373.     lp->coladd = 0;
  374. #endif
  375.     return 1;
  376.     }
  377.     return -1;
  378. }
  379.  
  380. /*
  381.  * incl(lp): same as inc(), but skip the NUL at the end of non-empty lines
  382.  */
  383.     int
  384. incl(lp)
  385.     pos_T    *lp;
  386. {
  387.     int        r;
  388.  
  389.     if ((r = inc(lp)) >= 1 && lp->col)
  390.     r = inc(lp);
  391.     return r;
  392. }
  393.  
  394. /*
  395.  * dec(p)
  396.  *
  397.  * Decrement the line pointer 'p' crossing line boundaries as necessary.
  398.  * Return 1 when crossing a line, -1 when at start of file, 0 otherwise.
  399.  */
  400.     int
  401. dec_cursor()
  402. {
  403. #ifdef FEAT_MBYTE
  404.     return (has_mbyte ? mb_dec(&curwin->w_cursor) : dec(&curwin->w_cursor));
  405. #else
  406.     return dec(&curwin->w_cursor);
  407. #endif
  408. }
  409.  
  410.     int
  411. dec(lp)
  412.     pos_T  *lp;
  413. {
  414.     if (lp->col > 0)
  415.     {        /* still within line */
  416.     lp->col--;
  417.     return 0;
  418.     }
  419.     if (lp->lnum > 1)
  420.     {        /* there is a prior line */
  421.     lp->lnum--;
  422.     lp->col = (colnr_T)STRLEN(ml_get(lp->lnum));
  423.     return 1;
  424.     }
  425.     return -1;            /* at start of file */
  426. }
  427.  
  428. /*
  429.  * decl(lp): same as dec(), but skip the NUL at the end of non-empty lines
  430.  */
  431.     int
  432. decl(lp)
  433.     pos_T    *lp;
  434. {
  435.     int        r;
  436.  
  437.     if ((r = dec(lp)) == 1 && lp->col)
  438.     r = dec(lp);
  439.     return r;
  440. }
  441.  
  442. /*
  443.  * Make sure curwin->w_cursor.lnum is valid.
  444.  */
  445.     void
  446. check_cursor_lnum()
  447. {
  448.     if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
  449.     {
  450. #ifdef FEAT_FOLDING
  451.     /* If there is a closed fold at the end of the file, put the cursor in
  452.      * its first line.  Otherwise in the last line. */
  453.     if (!hasFolding(curbuf->b_ml.ml_line_count,
  454.                         &curwin->w_cursor.lnum, NULL))
  455. #endif
  456.         curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
  457.     }
  458.     if (curwin->w_cursor.lnum <= 0)
  459.     curwin->w_cursor.lnum = 1;
  460. }
  461.  
  462. /*
  463.  * Make sure curwin->w_cursor.col is valid.
  464.  */
  465.     void
  466. check_cursor_col()
  467. {
  468.     colnr_T len;
  469. #ifdef FEAT_VIRTUALEDIT
  470.     colnr_T oldcol = curwin->w_cursor.col + curwin->w_cursor.coladd;
  471. #endif
  472.  
  473.     len = (colnr_T)STRLEN(ml_get_curline());
  474.     if (len == 0)
  475.     curwin->w_cursor.col = 0;
  476.     else if (curwin->w_cursor.col >= len)
  477.     {
  478.     /* Allow cursor past end-of-line in Insert mode, restarting Insert
  479.      * mode or when in Visual mode and 'selection' isn't "old" */
  480.     if (State & INSERT || restart_edit
  481. #ifdef FEAT_VISUAL
  482.         || (VIsual_active && *p_sel != 'o')
  483. #endif
  484.         || virtual_active())
  485.         curwin->w_cursor.col = len;
  486.     else
  487.         curwin->w_cursor.col = len - 1;
  488.     }
  489.  
  490. #ifdef FEAT_VIRTUALEDIT
  491.     /* If virtual editing is on, we can leave the cursor on the old position,
  492.      * only we must set it to virtual.  But don't do it when at the end of the
  493.      * line. */
  494.     if (oldcol == MAXCOL)
  495.     curwin->w_cursor.coladd = 0;
  496.     else if (ve_flags == VE_ALL)
  497.     curwin->w_cursor.coladd = oldcol - curwin->w_cursor.col;
  498. #endif
  499. }
  500.  
  501. /*
  502.  * make sure curwin->w_cursor in on a valid character
  503.  */
  504.     void
  505. check_cursor()
  506. {
  507.     check_cursor_lnum();
  508.     check_cursor_col();
  509. }
  510.  
  511. #if defined(FEAT_TEXTOBJ) || defined(PROTO)
  512. /*
  513.  * Make sure curwin->w_cursor is not on the NUL at the end of the line.
  514.  * Allow it when in Visual mode and 'selection' is not "old".
  515.  */
  516.     void
  517. adjust_cursor_col()
  518. {
  519.     if (curwin->w_cursor.col > 0
  520. # ifdef FEAT_VISUAL
  521.         && (!VIsual_active || *p_sel == 'o')
  522. # endif
  523.         && gchar_cursor() == NUL)
  524.     --curwin->w_cursor.col;
  525. }
  526. #endif
  527.  
  528. /*
  529.  * When curwin->w_leftcol has changed, adjust the cursor position.
  530.  * Return TRUE if the cursor was moved.
  531.  */
  532.     int
  533. leftcol_changed()
  534. {
  535.     long    lastcol;
  536.     colnr_T    s, e;
  537.     int        retval = FALSE;
  538.  
  539.     changed_cline_bef_curs();
  540.     lastcol = curwin->w_leftcol + W_WIDTH(curwin) - curwin_col_off() - 1;
  541.     validate_virtcol();
  542.  
  543.     /*
  544.      * If the cursor is right or left of the screen, move it to last or first
  545.      * character.
  546.      */
  547.     if (curwin->w_virtcol > (colnr_T)(lastcol - p_siso))
  548.     {
  549.     retval = TRUE;
  550.     coladvance((colnr_T)(lastcol - p_siso));
  551.     }
  552.     else if (curwin->w_virtcol < curwin->w_leftcol + p_siso)
  553.     {
  554.     retval = TRUE;
  555.     (void)coladvance((colnr_T)(curwin->w_leftcol + p_siso));
  556.     }
  557.  
  558.     /*
  559.      * If the start of the character under the cursor is not on the screen,
  560.      * advance the cursor one more char.  If this fails (last char of the
  561.      * line) adjust the scrolling.
  562.      */
  563.     getvcol(curwin, &curwin->w_cursor, &s, NULL, &e);
  564.     if (e > (colnr_T)lastcol)
  565.     {
  566.     retval = TRUE;
  567.     coladvance(s - 1);
  568.     }
  569.     else if (s < curwin->w_leftcol)
  570.     {
  571.     retval = TRUE;
  572.     if (coladvance(e + 1) == FAIL)    /* there isn't another character */
  573.     {
  574.         curwin->w_leftcol = s;    /* adjust w_leftcol instead */
  575.         changed_cline_bef_curs();
  576.     }
  577.     }
  578.  
  579.     if (retval)
  580.     curwin->w_set_curswant = TRUE;
  581.     redraw_later(NOT_VALID);
  582.     return retval;
  583. }
  584.  
  585. /**********************************************************************
  586.  * Various routines dealing with allocation and deallocation of memory.
  587.  */
  588.  
  589. #if defined(MEM_PROFILE) || defined(PROTO)
  590.  
  591. # define MEM_SIZES  8200
  592. static long_u mem_allocs[MEM_SIZES];
  593. static long_u mem_frees[MEM_SIZES];
  594. static long_u mem_allocated;
  595. static long_u mem_freed;
  596. static long_u mem_peak;
  597. static long_u num_alloc;
  598. static long_u num_freed;
  599.  
  600. static void mem_pre_alloc_s __ARGS((size_t *sizep));
  601. static void mem_pre_alloc_l __ARGS((long_u *sizep));
  602. static void mem_post_alloc __ARGS((void **pp, size_t size));
  603. static void mem_pre_free __ARGS((void **pp));
  604.  
  605.     static void
  606. mem_pre_alloc_s(sizep)
  607.     size_t *sizep;
  608. {
  609.     *sizep += sizeof(size_t);
  610. }
  611.  
  612.     static void
  613. mem_pre_alloc_l(sizep)
  614.     long_u *sizep;
  615. {
  616.     *sizep += sizeof(size_t);
  617. }
  618.  
  619.     static void
  620. mem_post_alloc(pp, size)
  621.     void **pp;
  622.     size_t size;
  623. {
  624.     if (*pp == NULL)
  625.     return;
  626.     size -= sizeof(size_t);
  627.     *(long_u *)*pp = size;
  628.     if (size <= MEM_SIZES-1)
  629.     mem_allocs[size-1]++;
  630.     else
  631.     mem_allocs[MEM_SIZES-1]++;
  632.     mem_allocated += size;
  633.     if (mem_allocated - mem_freed > mem_peak)
  634.     mem_peak = mem_allocated - mem_freed;
  635.     num_alloc++;
  636.     *pp = (void *)((char *)*pp + sizeof(size_t));
  637. }
  638.  
  639.     static void
  640. mem_pre_free(pp)
  641.     void **pp;
  642. {
  643.     long_u size;
  644.  
  645.     *pp = (void *)((char *)*pp - sizeof(size_t));
  646.     size = *(size_t *)*pp;
  647.     if (size <= MEM_SIZES-1)
  648.     mem_frees[size-1]++;
  649.     else
  650.     mem_frees[MEM_SIZES-1]++;
  651.     mem_freed += size;
  652.     num_freed++;
  653. }
  654.  
  655. /*
  656.  * called on exit via atexit()
  657.  */
  658.     void
  659. vim_mem_profile_dump()
  660. {
  661.     int i, j;
  662.  
  663.     printf("\r\n");
  664.     j = 0;
  665.     for (i = 0; i < MEM_SIZES - 1; i++)
  666.     {
  667.     if (mem_allocs[i] || mem_frees[i])
  668.     {
  669.         if (mem_frees[i] > mem_allocs[i])
  670.         printf("\r\n%s", _("ERROR: "));
  671.         printf("[%4d / %4lu-%-4lu] ", i + 1, mem_allocs[i], mem_frees[i]);
  672.         j++;
  673.         if (j > 3)
  674.         {
  675.         j = 0;
  676.         printf("\r\n");
  677.         }
  678.     }
  679.     }
  680.  
  681.     i = MEM_SIZES - 1;
  682.     if (mem_allocs[i])
  683.     {
  684.     printf("\r\n");
  685.     if (mem_frees[i] > mem_allocs[i])
  686.         printf(_("ERROR: "));
  687.     printf("[>%d / %4lu-%-4lu]", i, mem_allocs[i], mem_frees[i]);
  688.     }
  689.  
  690.     printf(_("\n[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"),
  691.         mem_allocated, mem_freed, mem_allocated - mem_freed, mem_peak);
  692.     printf(_("[calls] total re/malloc()'s %lu, total free()'s %lu\n\n"),
  693.         num_alloc, num_freed);
  694. }
  695.  
  696. #endif /* MEM_PROFILE */
  697.  
  698. /*
  699.  * Some memory is reserved for error messages and for being able to
  700.  * call mf_release_all(), which needs some memory for mf_trans_add().
  701.  */
  702. #if defined(MSDOS) && !defined(DJGPP)
  703. # define SMALL_MEM
  704. # define KEEP_ROOM 8192L
  705. #else
  706. # define KEEP_ROOM (2 * 8192L)
  707. #endif
  708.  
  709. /*
  710.  * Note: if unsinged is 16 bits we can only allocate up to 64K with alloc().
  711.  * Use lalloc for larger blocks.
  712.  */
  713.     char_u *
  714. alloc(size)
  715.     unsigned        size;
  716. {
  717.     return (lalloc((long_u)size, TRUE));
  718. }
  719.  
  720. /*
  721.  * Allocate memory and set all bytes to zero.
  722.  */
  723.     char_u *
  724. alloc_clear(size)
  725.     unsigned        size;
  726. {
  727.     char_u *p;
  728.  
  729.     p = (lalloc((long_u)size, TRUE));
  730.     if (p != NULL)
  731.     (void)vim_memset(p, 0, (size_t)size);
  732.     return p;
  733. }
  734.  
  735. /*
  736.  * alloc() with check for maximum line length
  737.  */
  738.     char_u *
  739. alloc_check(size)
  740.     unsigned        size;
  741. {
  742. #if !defined(UNIX) && !defined(__EMX__)
  743.     if (sizeof(int) == 2 && size > 0x7fff)
  744.     {
  745.     /* Don't hide this message */
  746.     emsg_silent = 0;
  747.     EMSG(_("E340: Line is becoming too long"));
  748.     return NULL;
  749.     }
  750. #endif
  751.     return (lalloc((long_u)size, TRUE));
  752. }
  753.  
  754. /*
  755.  * Allocate memory like lalloc() and set all bytes to zero.
  756.  */
  757.     char_u *
  758. lalloc_clear(size, message)
  759.     long_u    size;
  760.     int        message;
  761. {
  762.     char_u *p;
  763.  
  764.     p = (lalloc(size, message));
  765.     if (p != NULL)
  766.     (void)vim_memset(p, 0, (size_t)size);
  767.     return p;
  768. }
  769.  
  770. /*
  771.  * Low level memory allocation function.
  772.  * This is used often, KEEP IT FAST!
  773.  */
  774.     char_u *
  775. lalloc(size, message)
  776.     long_u    size;
  777.     int        message;
  778. {
  779.     char_u    *p;            /* pointer to new storage space */
  780.     static int    releasing = FALSE;  /* don't do mf_release_all() recursive */
  781.     int        try_again;
  782. #if defined(HAVE_AVAIL_MEM) && !defined(SMALL_MEM)
  783.     static long_u allocated = 0;    /* allocated since last avail check */
  784. #endif
  785.  
  786.     /* Safety check for allocating zero bytes */
  787.     if (size == 0)
  788.     {
  789.     /* Don't hide this message */
  790.     emsg_silent = 0;
  791.     EMSGN(_("E341: Internal error: lalloc(%ld, )"), size);
  792.     return NULL;
  793.     }
  794.  
  795. #ifdef MEM_PROFILE
  796.     mem_pre_alloc_l(&size);
  797. #endif
  798.  
  799. #if defined(MSDOS) && !defined(DJGPP)
  800.     if (size >= 0xfff0)        /* in MSDOS we can't deal with >64K blocks */
  801.     p = NULL;
  802.     else
  803. #endif
  804.  
  805.     /*
  806.      * Loop when out of memory: Try to release some memfile blocks and
  807.      * if some blocks are released call malloc again.
  808.      */
  809.     for (;;)
  810.     {
  811.     /*
  812.      * Handle three kind of systems:
  813.      * 1. No check for available memory: Just return.
  814.      * 2. Slow check for available memory: call mch_avail_mem() after
  815.      *    allocating KEEP_ROOM amount of memory.
  816.      * 3. Strict check for available memory: call mch_avail_mem()
  817.      */
  818.     if ((p = (char_u *)malloc((size_t)size)) != NULL)
  819.     {
  820. #ifndef HAVE_AVAIL_MEM
  821.         /* 1. No check for available memory: Just return. */
  822.         goto theend;
  823. #else
  824. # ifndef SMALL_MEM
  825.         /* 2. Slow check for available memory: call mch_avail_mem() after
  826.          *    allocating (KEEP_ROOM / 2) amount of memory. */
  827.         allocated += size;
  828.         if (allocated < KEEP_ROOM / 2)
  829.         goto theend;
  830.         allocated = 0;
  831. # endif
  832.         /* 3. check for available memory: call mch_avail_mem() */
  833.         if (mch_avail_mem(TRUE) < KEEP_ROOM && !releasing)
  834.         {
  835.         vim_free((char *)p);    /* System is low... no go! */
  836.         p = NULL;
  837.         }
  838.         else
  839.         goto theend;
  840. #endif
  841.     }
  842.     /*
  843.      * Remember that mf_release_all() is being called to avoid an endless
  844.      * loop, because mf_release_all() may call alloc() recursively.
  845.      */
  846.     if (releasing)
  847.         break;
  848.     releasing = TRUE;
  849.     try_again = mf_release_all();
  850.     releasing = FALSE;
  851.     if (!try_again)
  852.         break;
  853.     }
  854.  
  855.     if (message && p == NULL)
  856.     do_outofmem_msg(size);
  857.  
  858. theend:
  859. #ifdef MEM_PROFILE
  860.     mem_post_alloc((void **)&p, (size_t)size);
  861. #endif
  862.     return p;
  863. }
  864.  
  865. #if defined(MEM_PROFILE) || defined(PROTO)
  866. /*
  867.  * realloc() with memory profiling.
  868.  */
  869.     void *
  870. mem_realloc(ptr, size)
  871.     void *ptr;
  872.     size_t size;
  873. {
  874.     void *p;
  875.  
  876.     mem_pre_free(&ptr);
  877.     mem_pre_alloc_s(&size);
  878.  
  879.     p = realloc(ptr, size);
  880.  
  881.     mem_post_alloc(&p, size);
  882.  
  883.     return p;
  884. }
  885. #endif
  886.  
  887. /*
  888. * Avoid repeating the error message many times (they take 1 second each).
  889. * Did_outofmem_msg is reset when a character is read.
  890. */
  891.     void
  892. do_outofmem_msg(size)
  893.     long_u    size;
  894. {
  895.     if (!did_outofmem_msg)
  896.     {
  897.     /* Don't hide this message */
  898.     emsg_silent = 0;
  899.     EMSG2(_("E342: Out of memory!  (allocating %lu bytes)"), size);
  900.     did_outofmem_msg = TRUE;
  901.     }
  902. }
  903.  
  904. /*
  905.  * copy a string into newly allocated memory
  906.  */
  907.     char_u *
  908. vim_strsave(string)
  909.     char_u    *string;
  910. {
  911.     char_u    *p;
  912.     unsigned    len;
  913.  
  914.     len = (unsigned)STRLEN(string) + 1;
  915.     p = alloc(len);
  916.     if (p != NULL)
  917.     mch_memmove(p, string, (size_t)len);
  918.     return p;
  919. }
  920.  
  921.     char_u *
  922. vim_strnsave(string, len)
  923.     char_u    *string;
  924.     int        len;
  925. {
  926.     char_u    *p;
  927.  
  928.     p = alloc((unsigned)(len + 1));
  929.     if (p != NULL)
  930.     {
  931.     STRNCPY(p, string, len);
  932.     p[len] = NUL;
  933.     }
  934.     return p;
  935. }
  936.  
  937. #if 0    /* not used */
  938. /*
  939.  * like vim_strnsave(), but remove backslashes from the string.
  940.  */
  941.     char_u *
  942. vim_strnsave_esc(string, len)
  943.     char_u    *string;
  944.     int        len;
  945. {
  946.     char_u *p1, *p2;
  947.  
  948.     p1 = alloc((unsigned) (len + 1));
  949.     if (p1 != NULL)
  950.     {
  951.     STRNCPY(p1, string, len);
  952.     p1[len] = NUL;
  953.     for (p2 = p1; *p2; ++p2)
  954.         if (*p2 == '\\' && *(p2 + 1) != NUL)
  955.         STRCPY(p2, p2 + 1);
  956.     }
  957.     return p1;
  958. }
  959. #endif
  960.  
  961. /*
  962.  * Same as vim_strsave(), but any characters found in esc_chars are preceded
  963.  * by a backslash.
  964.  */
  965.     char_u *
  966. vim_strsave_escaped(string, esc_chars)
  967.     char_u    *string;
  968.     char_u    *esc_chars;
  969. {
  970.     char_u    *p;
  971.     char_u    *p2;
  972.     char_u    *escaped_string;
  973.     unsigned    length;
  974. #ifdef FEAT_MBYTE
  975.     int        l;
  976. #endif
  977.  
  978.     /*
  979.      * First count the number of backslashes required.
  980.      * Then allocate the memory and insert them.
  981.      */
  982.     length = 1;                /* count the trailing NUL */
  983.     for (p = string; *p; p++)
  984.     {
  985. #ifdef FEAT_MBYTE
  986.     if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1)
  987.     {
  988.         length += l;        /* count a multibyte char */
  989.         p += l - 1;
  990.         continue;
  991.     }
  992. #endif
  993.     if (vim_strchr(esc_chars, *p) != NULL)
  994.         ++length;            /* count a backslash */
  995.     ++length;            /* count an ordinary char */
  996.     }
  997.     escaped_string = alloc(length);
  998.     if (escaped_string != NULL)
  999.     {
  1000.     p2 = escaped_string;
  1001.     for (p = string; *p; p++)
  1002.     {
  1003. #ifdef FEAT_MBYTE
  1004.         if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1)
  1005.         {
  1006.         mch_memmove(p2, p, (size_t)l);
  1007.         p2 += l;
  1008.         p += l - 1;        /* skip multibyte char  */
  1009.         continue;
  1010.         }
  1011. #endif
  1012.         if (vim_strchr(esc_chars, *p) != NULL)
  1013.         *p2++ = '\\';
  1014.         *p2++ = *p;
  1015.     }
  1016.     *p2 = NUL;
  1017.     }
  1018.     return escaped_string;
  1019. }
  1020.  
  1021. /*
  1022.  * Like vim_strsave(), but make all characters uppercase.
  1023.  * This uses ASCII lower-to-upper case translation, language independent.
  1024.  */
  1025.     char_u *
  1026. vim_strsave_up(string)
  1027.     char_u    *string;
  1028. {
  1029.     char_u *p1;
  1030.  
  1031.     p1 = vim_strsave(string);
  1032.     vim_strup(p1);
  1033.     return p1;
  1034. }
  1035.  
  1036. /*
  1037.  * Like vim_strnsave(), but make all characters uppercase.
  1038.  * This uses ASCII lower-to-upper case translation, language independent.
  1039.  */
  1040.     char_u *
  1041. vim_strnsave_up(string, len)
  1042.     char_u    *string;
  1043.     int        len;
  1044. {
  1045.     char_u *p1;
  1046.  
  1047.     p1 = vim_strnsave(string, len);
  1048.     vim_strup(p1);
  1049.     return p1;
  1050. }
  1051.  
  1052. /*
  1053.  * ASCII lower-to-upper case translation, language independent.
  1054.  */
  1055.     void
  1056. vim_strup(p)
  1057.     char_u    *p;
  1058. {
  1059.     char_u  *p2;
  1060.     int        c;
  1061.  
  1062.     if (p != NULL)
  1063.     {
  1064.     p2 = p;
  1065.     while ((c = *p2) != NUL)
  1066. #ifdef EBCDIC
  1067.         *p2++ = isalpha(c) ? toupper(c) : c;
  1068. #else
  1069.         *p2++ = (c < 'a' || c > 'z') ? c : (c - 0x20);
  1070. #endif
  1071.     }
  1072. }
  1073.  
  1074. /*
  1075.  * copy a space a number of times
  1076.  */
  1077.     void
  1078. copy_spaces(ptr, count)
  1079.     char_u    *ptr;
  1080.     size_t    count;
  1081. {
  1082.     size_t    i = count;
  1083.     char_u    *p = ptr;
  1084.  
  1085.     while (i--)
  1086.     *p++ = ' ';
  1087. }
  1088.  
  1089. #if defined(FEAT_VISUALEXTRA) || defined(PROTO)
  1090. /*
  1091.  * copy a character a number of times
  1092.  */
  1093.     void
  1094. copy_chars(ptr, count, c)
  1095.     char_u    *ptr;
  1096.     size_t    count;
  1097.     int        c;
  1098. {
  1099.     size_t    i = count;
  1100.     char_u    *p = ptr;
  1101.  
  1102.     while (i--)
  1103.     *p++ = c;
  1104. }
  1105. #endif
  1106.  
  1107. /*
  1108.  * delete spaces at the end of a string
  1109.  */
  1110.     void
  1111. del_trailing_spaces(ptr)
  1112.     char_u    *ptr;
  1113. {
  1114.     char_u    *q;
  1115.  
  1116.     q = ptr + STRLEN(ptr);
  1117.     while (--q > ptr && vim_iswhite(q[0]) && q[-1] != '\\' && q[-1] != Ctrl_V)
  1118.     *q = NUL;
  1119. }
  1120.  
  1121. /*
  1122.  * This is here because strncpy() does not guarantee successful results when
  1123.  * the to and from strings overlap.  It is only currently called from
  1124.  * nextwild() which copies part of the command line to another part of the
  1125.  * command line.  This produced garbage when expanding files etc in the middle
  1126.  * of the command line (on my terminal, anyway) -- webb.
  1127.  * Note: strncpy() pads the remainder of the buffer with NUL bytes,
  1128.  * vim_strncpy() doesn't do that.
  1129.  */
  1130.     void
  1131. vim_strncpy(to, from, len)
  1132.     char_u *to;
  1133.     char_u *from;
  1134.     int len;
  1135. {
  1136.     int i;
  1137.  
  1138.     if (to <= from)
  1139.     {
  1140.     while (len-- && *from)
  1141.         *to++ = *from++;
  1142.     if (len >= 0)
  1143.         *to = *from;    /* Copy NUL */
  1144.     }
  1145.     else
  1146.     {
  1147.     for (i = 0; i < len; i++)
  1148.     {
  1149.         to++;
  1150.         if (*from++ == NUL)
  1151.         {
  1152.         i++;
  1153.         break;
  1154.         }
  1155.     }
  1156.     for (; i > 0; i--)
  1157.         *--to = *--from;
  1158.     }
  1159. }
  1160.  
  1161. /*
  1162.  * Isolate one part of a string option where parts are separated with
  1163.  * "sep_chars".
  1164.  * The part is copied into buf[maxlen].
  1165.  * "*option" is advanced to the next part.
  1166.  * The length is returned.
  1167.  */
  1168.     int
  1169. copy_option_part(option, buf, maxlen, sep_chars)
  1170.     char_u    **option;
  1171.     char_u    *buf;
  1172.     int        maxlen;
  1173.     char    *sep_chars;
  1174. {
  1175.     int        len = 0;
  1176.     char_u  *p = *option;
  1177.  
  1178.     /* skip '.' at start of option part, for 'suffixes' */
  1179.     if (*p == '.')
  1180.     buf[len++] = *p++;
  1181.     while (*p != NUL && vim_strchr((char_u *)sep_chars, *p) == NULL)
  1182.     {
  1183.     /*
  1184.      * Skip backslash before a separator character and space.
  1185.      */
  1186.     if (p[0] == '\\' && vim_strchr((char_u *)sep_chars, p[1]) != NULL)
  1187.         ++p;
  1188.     if (len < maxlen - 1)
  1189.         buf[len++] = *p;
  1190.     ++p;
  1191.     }
  1192.     buf[len] = NUL;
  1193.  
  1194.     if (*p != NUL && *p != ',')    /* skip non-standard separator */
  1195.     ++p;
  1196.     p = skip_to_option_part(p);    /* p points to next file name */
  1197.  
  1198.     *option = p;
  1199.     return len;
  1200. }
  1201.  
  1202. /*
  1203.  * replacement for free() that ignores NULL pointers
  1204.  */
  1205.     void
  1206. vim_free(x)
  1207.     void *x;
  1208. {
  1209.     if (x != NULL)
  1210.     {
  1211. #ifdef MEM_PROFILE
  1212.     mem_pre_free(&x);
  1213. #endif
  1214.     free(x);
  1215.     }
  1216. }
  1217.  
  1218. #ifndef HAVE_MEMSET
  1219.     void *
  1220. vim_memset(ptr, c, size)
  1221.     void    *ptr;
  1222.     int        c;
  1223.     size_t  size;
  1224. {
  1225.     char *p = ptr;
  1226.  
  1227.     while (size-- > 0)
  1228.     *p++ = c;
  1229.     return ptr;
  1230. }
  1231. #endif
  1232.  
  1233. #ifdef VIM_MEMCMP
  1234. /*
  1235.  * Return zero when "b1" and "b2" are the same for "len" bytes.
  1236.  * Return non-zero otherwise.
  1237.  */
  1238.     int
  1239. vim_memcmp(b1, b2, len)
  1240.     void    *b1;
  1241.     void    *b2;
  1242.     size_t  len;
  1243. {
  1244.     char_u  *p1 = (char_u *)b1, *p2 = (char_u *)b2;
  1245.  
  1246.     for ( ; len > 0; --len)
  1247.     {
  1248.     if (*p1 != *p2)
  1249.         return 1;
  1250.     ++p1;
  1251.     ++p2;
  1252.     }
  1253.     return 0;
  1254. }
  1255. #endif
  1256.  
  1257. #ifdef VIM_MEMMOVE
  1258. /*
  1259.  * Version of memmove() that handles overlapping source and destination.
  1260.  * For systems that don't have a function that is guaranteed to do that (SYSV).
  1261.  */
  1262.     void
  1263. mch_memmove(dst_arg, src_arg, len)
  1264.     void    *src_arg, *dst_arg;
  1265.     size_t  len;
  1266. {
  1267.     /*
  1268.      * A void doesn't have a size, we use char pointers.
  1269.      */
  1270.     char *dst = dst_arg, *src = src_arg;
  1271.  
  1272.                     /* overlap, copy backwards */
  1273.     if (dst > src && dst < src + len)
  1274.     {
  1275.     src += len;
  1276.     dst += len;
  1277.     while (len-- > 0)
  1278.         *--dst = *--src;
  1279.     }
  1280.     else                /* copy forwards */
  1281.     while (len-- > 0)
  1282.         *dst++ = *src++;
  1283. }
  1284. #endif
  1285.  
  1286. #if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP)) || defined(PROTO)
  1287. /*
  1288.  * Compare two strings, ignoring case, using current locale.
  1289.  * Doesn't work for multi-byte characters.
  1290.  * return 0 for match, < 0 for smaller, > 0 for bigger
  1291.  */
  1292.     int
  1293. vim_stricmp(s1, s2)
  1294.     char    *s1;
  1295.     char    *s2;
  1296. {
  1297.     int        i;
  1298.  
  1299.     for (;;)
  1300.     {
  1301.     i = (int)TOLOWER_LOC(*s1) - (int)TOLOWER_LOC(*s2);
  1302.     if (i != 0)
  1303.         return i;                /* this character different */
  1304.     if (*s1 == NUL)
  1305.         break;                /* strings match until NUL */
  1306.     ++s1;
  1307.     ++s2;
  1308.     }
  1309.     return 0;                    /* strings match */
  1310. }
  1311. #endif
  1312.  
  1313. #if (!defined(HAVE_STRNCASECMP) && !defined(HAVE_STRNICMP)) || defined(PROTO)
  1314. /*
  1315.  * Compare two strings, for length "len", ignoring case, using current locale.
  1316.  * Doesn't work for multi-byte characters.
  1317.  * return 0 for match, < 0 for smaller, > 0 for bigger
  1318.  */
  1319.     int
  1320. vim_strnicmp(s1, s2, len)
  1321.     char    *s1;
  1322.     char    *s2;
  1323.     size_t    len;
  1324. {
  1325.     int        i;
  1326.  
  1327.     while (len > 0)
  1328.     {
  1329.     i = (int)TOLOWER_LOC(*s1) - (int)TOLOWER_LOC(*s2);
  1330.     if (i != 0)
  1331.         return i;                /* this character different */
  1332.     if (*s1 == NUL)
  1333.         break;                /* strings match until NUL */
  1334.     ++s1;
  1335.     ++s2;
  1336.     --len;
  1337.     }
  1338.     return 0;                    /* strings match */
  1339. }
  1340. #endif
  1341.  
  1342. #if 0    /* currently not used */
  1343. /*
  1344.  * Check if string "s2" appears somewhere in "s1" while ignoring case.
  1345.  * Return NULL if not, a pointer to the first occurrence if it does.
  1346.  */
  1347.     char_u *
  1348. vim_stristr(s1, s2)
  1349.     char_u    *s1;
  1350.     char_u    *s2;
  1351. {
  1352.     char_u    *p;
  1353.     int        len = STRLEN(s2);
  1354.     char_u    *end = s1 + STRLEN(s1) - len;
  1355.  
  1356.     for (p = s1; p <= end; ++p)
  1357.     if (STRNICMP(p, s2, len) == 0)
  1358.         return p;
  1359.     return NULL;
  1360. }
  1361. #endif
  1362.  
  1363. /*
  1364.  * Version of strchr() and strrchr() that handle unsigned char strings
  1365.  * with characters above 128 correctly. Also it doesn't return a pointer to
  1366.  * the NUL at the end of the string.
  1367.  */
  1368.     char_u  *
  1369. vim_strchr(string, c)
  1370.     char_u    *string;
  1371.     int        c;
  1372. {
  1373.     char_u    *p;
  1374.     int        b;
  1375.  
  1376.     p = string;
  1377. #ifdef FEAT_MBYTE
  1378.     if (enc_utf8 && c >= 0x80)
  1379.     {
  1380.     while (*p != NUL)
  1381.     {
  1382.         if (utf_ptr2char(p) == c)
  1383.         return p;
  1384.         p += (*mb_ptr2len_check)(p);
  1385.     }
  1386.     return NULL;
  1387.     }
  1388.     if (enc_dbcs != 0 && c > 255)
  1389.     {
  1390.     int    n2 = c & 0xff;
  1391.  
  1392.     c = ((unsigned)c >> 8) & 0xff;
  1393.     while ((b = *p) != NUL)
  1394.     {
  1395.         if (b == c && p[1] == n2)
  1396.         return p;
  1397.         p += (*mb_ptr2len_check)(p);
  1398.     }
  1399.     return NULL;
  1400.     }
  1401.     if (has_mbyte)
  1402.     {
  1403.     while ((b = *p) != NUL)
  1404.     {
  1405.         if (b == c)
  1406.         return p;
  1407.         p += (*mb_ptr2len_check)(p);
  1408.     }
  1409.     return NULL;
  1410.     }
  1411. #endif
  1412.     while ((b = *p) != NUL)
  1413.     {
  1414.     if (b == c)
  1415.         return p;
  1416.     ++p;
  1417.     }
  1418.     return NULL;
  1419. }
  1420.  
  1421. /*
  1422.  * Search for last occurrence of "c" in "string".
  1423.  * return NULL if not found.
  1424.  * Does not handle multi-byte!
  1425.  */
  1426.     char_u  *
  1427. vim_strrchr(string, c)
  1428.     char_u    *string;
  1429.     int        c;
  1430. {
  1431.     char_u    *retval = NULL;
  1432.  
  1433.     while (*string)
  1434.     {
  1435.     if (*string == c)
  1436.         retval = string;
  1437. #ifdef FEAT_MBYTE
  1438.     if (has_mbyte)
  1439.         string += (*mb_ptr2len_check)(string);
  1440.     else
  1441. #endif
  1442.         ++string;
  1443.     }
  1444.     return retval;
  1445. }
  1446.  
  1447. /*
  1448.  * Vim's version of strpbrk(), in case it's missing.
  1449.  * Don't generate a prototype for this, causes problems when it's not used.
  1450.  */
  1451. #ifndef PROTO
  1452. # ifndef HAVE_STRPBRK
  1453. #  ifdef vim_strpbrk
  1454. #   undef vim_strpbrk
  1455. #  endif
  1456.     char_u *
  1457. vim_strpbrk(s, charset)
  1458.     char_u    *s;
  1459.     char_u    *charset;
  1460. {
  1461.     while (*s)
  1462.     {
  1463.     if (vim_strchr(charset, *s) != NULL)
  1464.         return s;
  1465. #ifdef FEAT_MBYTE
  1466.     if (has_mbyte)
  1467.         s += (*mb_ptr2len_check)(s);
  1468.     else
  1469. #endif
  1470.         ++s;
  1471.     }
  1472.     return NULL;
  1473. }
  1474. # endif
  1475. #endif
  1476.  
  1477. /*
  1478.  * Vim has its own isspace() function, because on some machines isspace()
  1479.  * can't handle characters above 128.
  1480.  */
  1481.     int
  1482. vim_isspace(x)
  1483.     int        x;
  1484. {
  1485.     return ((x >= 9 && x <= 13) || x == ' ');
  1486. }
  1487.  
  1488. /************************************************************************
  1489.  * Functions for hanlding growing arrays.
  1490.  */
  1491.  
  1492. /*
  1493.  * Clear an allocated growing array.
  1494.  */
  1495.     void
  1496. ga_clear(gap)
  1497.     garray_T *gap;
  1498. {
  1499.     vim_free(gap->ga_data);
  1500.     ga_init(gap);
  1501. }
  1502.  
  1503. #if defined(FEAT_EVAL) || defined(PROTO)
  1504. /*
  1505.  * Clear a growing array that contains a list of strings.
  1506.  */
  1507.     void
  1508. ga_clear_strings(gap)
  1509.     garray_T *gap;
  1510. {
  1511.     int        i;
  1512.  
  1513.     for (i = 0; i < gap->ga_len; ++i)
  1514.     vim_free(((char_u **)(gap->ga_data))[i]);
  1515.     ga_clear(gap);
  1516. }
  1517. #endif
  1518.  
  1519. /*
  1520.  * Initialize a growing array.    Don't forget to set ga_itemsize and
  1521.  * ga_growsize!  Or use ga_init2().
  1522.  */
  1523.     void
  1524. ga_init(gap)
  1525.     garray_T *gap;
  1526. {
  1527.     gap->ga_data = NULL;
  1528.     gap->ga_room = 0;
  1529.     gap->ga_len = 0;
  1530. }
  1531.  
  1532.     void
  1533. ga_init2(gap, itemsize, growsize)
  1534.     garray_T    *gap;
  1535.     int        itemsize;
  1536.     int        growsize;
  1537. {
  1538.     ga_init(gap);
  1539.     gap->ga_itemsize = itemsize;
  1540.     gap->ga_growsize = growsize;
  1541. }
  1542.  
  1543. /*
  1544.  * Make room in growing array "gap" for at least "n" items.
  1545.  * Return FAIL for failure, OK otherwise.
  1546.  */
  1547.     int
  1548. ga_grow(gap, n)
  1549.     garray_T    *gap;
  1550.     int        n;
  1551. {
  1552.     size_t    len;
  1553.     char_u    *pp;
  1554.  
  1555.     if (gap->ga_room < n)
  1556.     {
  1557.     if (n < gap->ga_growsize)
  1558.         n = gap->ga_growsize;
  1559.     len = gap->ga_itemsize * (gap->ga_len + n);
  1560.     pp = alloc_clear((unsigned)len);
  1561.     if (pp == NULL)
  1562.         return FAIL;
  1563.     gap->ga_room = n;
  1564.     if (gap->ga_data != NULL)
  1565.     {
  1566.         mch_memmove(pp, gap->ga_data,
  1567.                       (size_t)(gap->ga_itemsize * gap->ga_len));
  1568.         vim_free(gap->ga_data);
  1569.     }
  1570.     gap->ga_data = pp;
  1571.     }
  1572.     return OK;
  1573. }
  1574.  
  1575. #if defined(FEAT_EVAL) || defined(FEAT_CMDL_COMPL) || defined(FEAT_PYTHON) \
  1576.     || defined(FEAT_RUBY) || defined(FEAT_TCL) || defined(FEAT_PERL) \
  1577.     || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MOTIF) \
  1578.     || defined(MSWIN_FIND_REPLACE) \
  1579.     || defined(FEAT_CLIENTSERVER) || defined(PROTO)
  1580. /*
  1581.  * Concatenate a string to a growarray which contains characters.
  1582.  * Note: Does NOT copy the NUL at the end!
  1583.  */
  1584.     void
  1585. ga_concat(gap, s)
  1586.     garray_T    *gap;
  1587.     char_u    *s;
  1588. {
  1589.     int    len = (int)STRLEN(s);
  1590.  
  1591.     if (ga_grow(gap, len) == OK)
  1592.     {
  1593.     mch_memmove((char *)gap->ga_data + gap->ga_len, s, (size_t)len);
  1594.     gap->ga_len += len;
  1595.     gap->ga_room -= len;
  1596.     }
  1597. }
  1598. #endif
  1599.  
  1600. #if defined(FEAT_EVAL) || defined(FEAT_CMDL_COMPL) || defined(FEAT_PYTHON) \
  1601.     || defined(FEAT_RUBY) || defined(FEAT_TCL) || defined(FEAT_PERL) \
  1602.     || defined(FEAT_CLIENTSERVER) \
  1603.     || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MOTIF) \
  1604.     || defined(MSWIN_FIND_REPLACE) \
  1605.     || (defined(FEAT_PRINTER) && defined(FEAT_POSTSCRIPT)) || defined(PROTO)
  1606. /*
  1607.  * Append one byte to a growarray which contains bytes.
  1608.  */
  1609.     void
  1610. ga_append(gap, c)
  1611.     garray_T    *gap;
  1612.     int        c;
  1613. {
  1614.     if (ga_grow(gap, 1) == OK)
  1615.     {
  1616.     *((char *)gap->ga_data + gap->ga_len) = c;
  1617.     ++gap->ga_len;
  1618.     --gap->ga_room;
  1619.     }
  1620. }
  1621. #endif
  1622.  
  1623. /************************************************************************
  1624.  * functions that use lookup tables for various things, generally to do with
  1625.  * special key codes.
  1626.  */
  1627.  
  1628. /*
  1629.  * Some useful tables.
  1630.  */
  1631.  
  1632. static struct modmasktable
  1633. {
  1634.     short    mod_mask;    /* Bit-mask for particular key modifier */
  1635.     short    mod_flag;    /* Bit(s) for particular key modifier */
  1636.     char_u    name;        /* Single letter name of modifier */
  1637. } mod_mask_table[] =
  1638. {
  1639.     {MOD_MASK_ALT,        MOD_MASK_ALT,        (char_u)'M'},
  1640.     {MOD_MASK_CTRL,        MOD_MASK_CTRL,        (char_u)'C'},
  1641.     {MOD_MASK_SHIFT,        MOD_MASK_SHIFT,        (char_u)'S'},
  1642.     {MOD_MASK_MULTI_CLICK,    MOD_MASK_2CLICK,    (char_u)'2'},
  1643.     {MOD_MASK_MULTI_CLICK,    MOD_MASK_3CLICK,    (char_u)'3'},
  1644.     {MOD_MASK_MULTI_CLICK,    MOD_MASK_4CLICK,    (char_u)'4'},
  1645. #ifdef MACOS
  1646.     {MOD_MASK_CMD,        MOD_MASK_CMD,        (char_u)'D'},
  1647. #endif
  1648.     /* 'A' must be the last one */
  1649.     {MOD_MASK_ALT,        MOD_MASK_ALT,        (char_u)'A'},
  1650.     {0, 0, NUL}
  1651. };
  1652.  
  1653. /*
  1654.  * Shifted key terminal codes and their unshifted equivalent.
  1655.  * Don't add mouse codes here, they are handled seperately!
  1656.  */
  1657. #define MOD_KEYS_ENTRY_SIZE 5
  1658.  
  1659. static char_u modifier_keys_table[] =
  1660. {
  1661. /*  mod mask        with modifier        without modifier */
  1662.     MOD_MASK_SHIFT, '&', '9',            '@', '1',    /* begin */
  1663.     MOD_MASK_SHIFT, '&', '0',            '@', '2',    /* cancel */
  1664.     MOD_MASK_SHIFT, '*', '1',            '@', '4',    /* command */
  1665.     MOD_MASK_SHIFT, '*', '2',            '@', '5',    /* copy */
  1666.     MOD_MASK_SHIFT, '*', '3',            '@', '6',    /* create */
  1667.     MOD_MASK_SHIFT, '*', '4',            'k', 'D',    /* delete char */
  1668.     MOD_MASK_SHIFT, '*', '5',            'k', 'L',    /* delete line */
  1669.     MOD_MASK_SHIFT, '*', '7',            '@', '7',    /* end */
  1670.     MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_END,    '@', '7',    /* end */
  1671.     MOD_MASK_SHIFT, '*', '9',            '@', '9',    /* exit */
  1672.     MOD_MASK_SHIFT, '*', '0',            '@', '0',    /* find */
  1673.     MOD_MASK_SHIFT, '#', '1',            '%', '1',    /* help */
  1674.     MOD_MASK_SHIFT, '#', '2',            'k', 'h',    /* home */
  1675.     MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_HOME,    'k', 'h',    /* home */
  1676.     MOD_MASK_SHIFT, '#', '3',            'k', 'I',    /* insert */
  1677.     MOD_MASK_SHIFT, '#', '4',            'k', 'l',    /* left arrow */
  1678.     MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_LEFT,    'k', 'l',    /* left arrow */
  1679.     MOD_MASK_SHIFT, '%', 'a',            '%', '3',    /* message */
  1680.     MOD_MASK_SHIFT, '%', 'b',            '%', '4',    /* move */
  1681.     MOD_MASK_SHIFT, '%', 'c',            '%', '5',    /* next */
  1682.     MOD_MASK_SHIFT, '%', 'd',            '%', '7',    /* options */
  1683.     MOD_MASK_SHIFT, '%', 'e',            '%', '8',    /* previous */
  1684.     MOD_MASK_SHIFT, '%', 'f',            '%', '9',    /* print */
  1685.     MOD_MASK_SHIFT, '%', 'g',            '%', '0',    /* redo */
  1686.     MOD_MASK_SHIFT, '%', 'h',            '&', '3',    /* replace */
  1687.     MOD_MASK_SHIFT, '%', 'i',            'k', 'r',    /* right arr. */
  1688.     MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_RIGHT,    'k', 'r',    /* right arr. */
  1689.     MOD_MASK_SHIFT, '%', 'j',            '&', '5',    /* resume */
  1690.     MOD_MASK_SHIFT, '!', '1',            '&', '6',    /* save */
  1691.     MOD_MASK_SHIFT, '!', '2',            '&', '7',    /* suspend */
  1692.     MOD_MASK_SHIFT, '!', '3',            '&', '8',    /* undo */
  1693.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_UP,    'k', 'u',    /* up arrow */
  1694.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_DOWN,    'k', 'd',    /* down arrow */
  1695.  
  1696.                                 /* vt100 F1 */
  1697.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF1,    KS_EXTRA, (int)KE_XF1,
  1698.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF2,    KS_EXTRA, (int)KE_XF2,
  1699.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF3,    KS_EXTRA, (int)KE_XF3,
  1700.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF4,    KS_EXTRA, (int)KE_XF4,
  1701.  
  1702.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F1,    'k', '1',    /* F1 */
  1703.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F2,    'k', '2',
  1704.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F3,    'k', '3',
  1705.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F4,    'k', '4',
  1706.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F5,    'k', '5',
  1707.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F6,    'k', '6',
  1708.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F7,    'k', '7',
  1709.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F8,    'k', '8',
  1710.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F9,    'k', '9',
  1711.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F10,    'k', ';',    /* F10 */
  1712.  
  1713.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F11,    'F', '1',
  1714.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F12,    'F', '2',
  1715.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F13,    'F', '3',
  1716.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F14,    'F', '4',
  1717.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F15,    'F', '5',
  1718.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F16,    'F', '6',
  1719.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F17,    'F', '7',
  1720.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F18,    'F', '8',
  1721.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F19,    'F', '9',
  1722.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F20,    'F', 'A',
  1723.  
  1724.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F21,    'F', 'B',
  1725.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F22,    'F', 'C',
  1726.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F23,    'F', 'D',
  1727.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F24,    'F', 'E',
  1728.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F25,    'F', 'F',
  1729.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F26,    'F', 'G',
  1730.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F27,    'F', 'H',
  1731.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F28,    'F', 'I',
  1732.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F29,    'F', 'J',
  1733.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F30,    'F', 'K',
  1734.  
  1735.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F31,    'F', 'L',
  1736.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F32,    'F', 'M',
  1737.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F33,    'F', 'N',
  1738.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F34,    'F', 'O',
  1739.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F35,    'F', 'P',
  1740.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F36,    'F', 'Q',
  1741.     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F37,    'F', 'R',
  1742.  
  1743.                                 /* TAB pseudo code*/
  1744.     MOD_MASK_SHIFT, 'k', 'B',            KS_EXTRA, (int)KE_TAB,
  1745.  
  1746.     NUL
  1747. };
  1748.  
  1749. static struct key_name_entry
  1750. {
  1751.     int        key;    /* Special key code or ascii value */
  1752.     char_u  *name;    /* Name of key */
  1753. } key_names_table[] =
  1754. {
  1755.     {' ',        (char_u *)"Space"},
  1756.     {TAB,        (char_u *)"Tab"},
  1757.     {K_TAB,        (char_u *)"Tab"},
  1758.     {NL,        (char_u *)"NL"},
  1759.     {NL,        (char_u *)"NewLine"},    /* Alternative name */
  1760.     {NL,        (char_u *)"LineFeed"},    /* Alternative name */
  1761.     {NL,        (char_u *)"LF"},    /* Alternative name */
  1762.     {CR,        (char_u *)"CR"},
  1763.     {CR,        (char_u *)"Return"},    /* Alternative name */
  1764.     {CR,        (char_u *)"Enter"},    /* Alternative name */
  1765.     {K_BS,        (char_u *)"BS"},
  1766.     {K_BS,        (char_u *)"BackSpace"},    /* Alternative name */
  1767.     {ESC,        (char_u *)"Esc"},
  1768.     {CSI,        (char_u *)"CSI"},
  1769.     {K_CSI,        (char_u *)"xCSI"},
  1770.     {'|',        (char_u *)"Bar"},
  1771.     {'\\',        (char_u *)"Bslash"},
  1772.     {K_DEL,        (char_u *)"Del"},
  1773.     {K_DEL,        (char_u *)"Delete"},    /* Alternative name */
  1774.     {K_KDEL,        (char_u *)"kDel"},
  1775.     {K_UP,        (char_u *)"Up"},
  1776.     {K_DOWN,        (char_u *)"Down"},
  1777.     {K_LEFT,        (char_u *)"Left"},
  1778.     {K_RIGHT,        (char_u *)"Right"},
  1779.  
  1780.     {K_F1,        (char_u *)"F1"},
  1781.     {K_F2,        (char_u *)"F2"},
  1782.     {K_F3,        (char_u *)"F3"},
  1783.     {K_F4,        (char_u *)"F4"},
  1784.     {K_F5,        (char_u *)"F5"},
  1785.     {K_F6,        (char_u *)"F6"},
  1786.     {K_F7,        (char_u *)"F7"},
  1787.     {K_F8,        (char_u *)"F8"},
  1788.     {K_F9,        (char_u *)"F9"},
  1789.     {K_F10,        (char_u *)"F10"},
  1790.  
  1791.     {K_F11,        (char_u *)"F11"},
  1792.     {K_F12,        (char_u *)"F12"},
  1793.     {K_F13,        (char_u *)"F13"},
  1794.     {K_F14,        (char_u *)"F14"},
  1795.     {K_F15,        (char_u *)"F15"},
  1796.     {K_F16,        (char_u *)"F16"},
  1797.     {K_F17,        (char_u *)"F17"},
  1798.     {K_F18,        (char_u *)"F18"},
  1799.     {K_F19,        (char_u *)"F19"},
  1800.     {K_F20,        (char_u *)"F20"},
  1801.  
  1802.     {K_F21,        (char_u *)"F21"},
  1803.     {K_F22,        (char_u *)"F22"},
  1804.     {K_F23,        (char_u *)"F23"},
  1805.     {K_F24,        (char_u *)"F24"},
  1806.     {K_F25,        (char_u *)"F25"},
  1807.     {K_F26,        (char_u *)"F26"},
  1808.     {K_F27,        (char_u *)"F27"},
  1809.     {K_F28,        (char_u *)"F28"},
  1810.     {K_F29,        (char_u *)"F29"},
  1811.     {K_F30,        (char_u *)"F30"},
  1812.  
  1813.     {K_F31,        (char_u *)"F31"},
  1814.     {K_F32,        (char_u *)"F32"},
  1815.     {K_F33,        (char_u *)"F33"},
  1816.     {K_F34,        (char_u *)"F34"},
  1817.     {K_F35,        (char_u *)"F35"},
  1818.     {K_F36,        (char_u *)"F36"},
  1819.     {K_F37,        (char_u *)"F37"},
  1820.  
  1821.     {K_XF1,        (char_u *)"xF1"},
  1822.     {K_XF2,        (char_u *)"xF2"},
  1823.     {K_XF3,        (char_u *)"xF3"},
  1824.     {K_XF4,        (char_u *)"xF4"},
  1825.  
  1826.     {K_HELP,        (char_u *)"Help"},
  1827.     {K_UNDO,        (char_u *)"Undo"},
  1828.     {K_INS,        (char_u *)"Insert"},
  1829.     {K_INS,        (char_u *)"Ins"},    /* Alternative name */
  1830.     {K_KINS,        (char_u *)"kInsert"},
  1831.     {K_HOME,        (char_u *)"Home"},
  1832.     {K_KHOME,        (char_u *)"kHome"},
  1833.     {K_XHOME,        (char_u *)"xHome"},
  1834.     {K_END,        (char_u *)"End"},
  1835.     {K_KEND,        (char_u *)"kEnd"},
  1836.     {K_XEND,        (char_u *)"xEnd"},
  1837.     {K_PAGEUP,        (char_u *)"PageUp"},
  1838.     {K_PAGEDOWN,    (char_u *)"PageDown"},
  1839.     {K_KPAGEUP,        (char_u *)"kPageUp"},
  1840.     {K_KPAGEDOWN,    (char_u *)"kPageDown"},
  1841.  
  1842.     {K_KPLUS,        (char_u *)"kPlus"},
  1843.     {K_KMINUS,        (char_u *)"kMinus"},
  1844.     {K_KDIVIDE,        (char_u *)"kDivide"},
  1845.     {K_KMULTIPLY,    (char_u *)"kMultiply"},
  1846.     {K_KENTER,        (char_u *)"kEnter"},
  1847.     {K_KPOINT,        (char_u *)"kPoint"},
  1848.  
  1849.     {K_K0,        (char_u *)"k0"},
  1850.     {K_K1,        (char_u *)"k1"},
  1851.     {K_K2,        (char_u *)"k2"},
  1852.     {K_K3,        (char_u *)"k3"},
  1853.     {K_K4,        (char_u *)"k4"},
  1854.     {K_K5,        (char_u *)"k5"},
  1855.     {K_K6,        (char_u *)"k6"},
  1856.     {K_K7,        (char_u *)"k7"},
  1857.     {K_K8,        (char_u *)"k8"},
  1858.     {K_K9,        (char_u *)"k9"},
  1859.  
  1860.     {'<',        (char_u *)"lt"},
  1861.  
  1862.     {K_MOUSE,        (char_u *)"Mouse"},
  1863.     {K_NETTERM_MOUSE,    (char_u *)"NetMouse"},
  1864.     {K_DEC_MOUSE,    (char_u *)"DecMouse"},
  1865.     {K_JSBTERM_MOUSE,    (char_u *)"JsbMouse"},
  1866.     {K_PTERM_MOUSE,    (char_u *)"PtermMouse"},
  1867.     {K_LEFTMOUSE,    (char_u *)"LeftMouse"},
  1868.     {K_LEFTMOUSE_NM,    (char_u *)"LeftMouseNM"},
  1869.     {K_LEFTDRAG,    (char_u *)"LeftDrag"},
  1870.     {K_LEFTRELEASE,    (char_u *)"LeftRelease"},
  1871.     {K_LEFTRELEASE_NM,    (char_u *)"LeftReleaseNM"},
  1872.     {K_MIDDLEMOUSE,    (char_u *)"MiddleMouse"},
  1873.     {K_MIDDLEDRAG,    (char_u *)"MiddleDrag"},
  1874.     {K_MIDDLERELEASE,    (char_u *)"MiddleRelease"},
  1875.     {K_RIGHTMOUSE,    (char_u *)"RightMouse"},
  1876.     {K_RIGHTDRAG,    (char_u *)"RightDrag"},
  1877.     {K_RIGHTRELEASE,    (char_u *)"RightRelease"},
  1878.     {K_MOUSEDOWN,    (char_u *)"MouseDown"},
  1879.     {K_MOUSEUP,        (char_u *)"MouseUp"},
  1880.     {K_X1MOUSE,        (char_u *)"X1Mouse"},
  1881.     {K_X1DRAG,        (char_u *)"X1Drag"},
  1882.     {K_X1RELEASE,        (char_u *)"X1Release"},
  1883.     {K_X2MOUSE,        (char_u *)"X2Mouse"},
  1884.     {K_X2DRAG,        (char_u *)"X2Drag"},
  1885.     {K_X2RELEASE,        (char_u *)"X2Release"},
  1886.     {K_DROP,        (char_u *)"Drop"},
  1887.     {K_ZERO,        (char_u *)"Nul"},
  1888. #ifdef FEAT_EVAL
  1889.     {K_SNR,        (char_u *)"SNR"},
  1890. #endif
  1891.     {K_PLUG,        (char_u *)"Plug"},
  1892.     {0,            NULL}
  1893. };
  1894.  
  1895. #define KEY_NAMES_TABLE_LEN (sizeof(key_names_table) / sizeof(struct key_name_entry))
  1896.  
  1897. #ifdef FEAT_MOUSE
  1898. static struct mousetable
  1899. {
  1900.     int        pseudo_code;    /* Code for pseudo mouse event */
  1901.     int        button;        /* Which mouse button is it? */
  1902.     int        is_click;        /* Is it a mouse button click event? */
  1903.     int        is_drag;        /* Is it a mouse drag event? */
  1904. } mouse_table[] =
  1905. {
  1906.     {(int)KE_LEFTMOUSE,        MOUSE_LEFT,    TRUE,    FALSE},
  1907. #ifdef FEAT_GUI
  1908.     {(int)KE_LEFTMOUSE_NM,    MOUSE_LEFT,    TRUE,    FALSE},
  1909. #endif
  1910.     {(int)KE_LEFTDRAG,        MOUSE_LEFT,    FALSE,    TRUE},
  1911.     {(int)KE_LEFTRELEASE,    MOUSE_LEFT,    FALSE,    FALSE},
  1912. #ifdef FEAT_GUI
  1913.     {(int)KE_LEFTRELEASE_NM,    MOUSE_LEFT,    FALSE,    FALSE},
  1914. #endif
  1915.     {(int)KE_MIDDLEMOUSE,    MOUSE_MIDDLE,    TRUE,    FALSE},
  1916.     {(int)KE_MIDDLEDRAG,    MOUSE_MIDDLE,    FALSE,    TRUE},
  1917.     {(int)KE_MIDDLERELEASE,    MOUSE_MIDDLE,    FALSE,    FALSE},
  1918.     {(int)KE_RIGHTMOUSE,    MOUSE_RIGHT,    TRUE,    FALSE},
  1919.     {(int)KE_RIGHTDRAG,        MOUSE_RIGHT,    FALSE,    TRUE},
  1920.     {(int)KE_RIGHTRELEASE,    MOUSE_RIGHT,    FALSE,    FALSE},
  1921.     {(int)KE_X1MOUSE,        MOUSE_X1,    TRUE,    FALSE},
  1922.     {(int)KE_X1DRAG,        MOUSE_X1,    FALSE,    TRUE},
  1923.     {(int)KE_X1RELEASE,        MOUSE_X1,    FALSE,    FALSE},
  1924.     {(int)KE_X2MOUSE,        MOUSE_X2,    TRUE,    FALSE},
  1925.     {(int)KE_X2DRAG,        MOUSE_X2,    FALSE,    TRUE},
  1926.     {(int)KE_X2RELEASE,        MOUSE_X2,    FALSE,    FALSE},
  1927.     /* DRAG without CLICK */
  1928.     {(int)KE_IGNORE,        MOUSE_RELEASE,    FALSE,    TRUE},
  1929.     /* RELEASE without CLICK */
  1930.     {(int)KE_IGNORE,        MOUSE_RELEASE,    FALSE,    FALSE},
  1931.     {0,                0,        0,    0},
  1932. };
  1933. #endif /* FEAT_MOUSE */
  1934.  
  1935. /*
  1936.  * Return the modifier mask bit (MOD_MASK_*) which corresponds to the given
  1937.  * modifier name ('S' for Shift, 'C' for Ctrl etc).
  1938.  */
  1939.     int
  1940. name_to_mod_mask(c)
  1941.     int        c;
  1942. {
  1943.     int        i;
  1944.  
  1945.     c = TOUPPER_ASC(c);
  1946.     for (i = 0; mod_mask_table[i].mod_mask != 0; i++)
  1947.     if (c == mod_mask_table[i].name)
  1948.         return mod_mask_table[i].mod_flag;
  1949.     return 0;
  1950. }
  1951.  
  1952. #if 0 /* not used */
  1953. /*
  1954.  * Decide whether the given key code (K_*) is a shifted special
  1955.  * key (by looking at mod_mask).  If it is, then return the appropriate shifted
  1956.  * key code, otherwise just return the character as is.
  1957.  */
  1958.     int
  1959. check_shifted_spec_key(c)
  1960.     int        c;
  1961. {
  1962.     return simplify_key(c, &mod_mask);
  1963. }
  1964. #endif
  1965.  
  1966. /*
  1967.  * Check if if there is a special key code for "key" that includes the
  1968.  * modifiers specified.
  1969.  */
  1970.     int
  1971. simplify_key(key, modifiers)
  1972.     int        key;
  1973.     int        *modifiers;
  1974. {
  1975.     int        i;
  1976.     int        key0;
  1977.     int        key1;
  1978.  
  1979.     if (*modifiers & (MOD_MASK_SHIFT | MOD_MASK_CTRL | MOD_MASK_ALT))
  1980.     {
  1981.     /* TAB is a special case */
  1982.     if (key == TAB && (*modifiers & MOD_MASK_SHIFT))
  1983.     {
  1984.         *modifiers &= ~MOD_MASK_SHIFT;
  1985.         return K_S_TAB;
  1986.     }
  1987.     key0 = KEY2TERMCAP0(key);
  1988.     key1 = KEY2TERMCAP1(key);
  1989.     for (i = 0; modifier_keys_table[i] != NUL; i += MOD_KEYS_ENTRY_SIZE)
  1990.         if (key0 == modifier_keys_table[i + 3]
  1991.             && key1 == modifier_keys_table[i + 4]
  1992.             && (*modifiers & modifier_keys_table[i]))
  1993.         {
  1994.         *modifiers &= ~modifier_keys_table[i];
  1995.         return TERMCAP2KEY(modifier_keys_table[i + 1],
  1996.                            modifier_keys_table[i + 2]);
  1997.         }
  1998.     }
  1999.     return key;
  2000. }
  2001.  
  2002. /*
  2003.  * Return a string which contains the name of the given key when the given
  2004.  * modifiers are down.
  2005.  */
  2006.     char_u *
  2007. get_special_key_name(c, modifiers)
  2008.     int        c;
  2009.     int        modifiers;
  2010. {
  2011.     static char_u string[MAX_KEY_NAME_LEN + 1];
  2012.  
  2013.     int        i, idx;
  2014.     int        table_idx;
  2015.     char_u  *s;
  2016.  
  2017.     string[0] = '<';
  2018.     idx = 1;
  2019.  
  2020.     /* Key that stands for a normal character. */
  2021.     if (IS_SPECIAL(c) && KEY2TERMCAP0(c) == KS_KEY)
  2022.     c = KEY2TERMCAP1(c);
  2023.  
  2024.     /*
  2025.      * Translate shifted special keys into unshifted keys and set modifier.
  2026.      * Same for CTRL and ALT modifiers.
  2027.      */
  2028.     if (IS_SPECIAL(c))
  2029.     {
  2030.     for (i = 0; modifier_keys_table[i] != 0; i += MOD_KEYS_ENTRY_SIZE)
  2031.         if (       KEY2TERMCAP0(c) == (int)modifier_keys_table[i + 1]
  2032.             && (int)KEY2TERMCAP1(c) == (int)modifier_keys_table[i + 2])
  2033.         {
  2034.         modifiers |= modifier_keys_table[i];
  2035.         c = TERMCAP2KEY(modifier_keys_table[i + 3],
  2036.                            modifier_keys_table[i + 4]);
  2037.         break;
  2038.         }
  2039.     }
  2040.  
  2041.     /* try to find the key in the special key table */
  2042.     table_idx = find_special_key_in_table(c);
  2043.  
  2044.     /*
  2045.      * When not a known special key, and not a printable character, try to
  2046.      * extract modifiers.
  2047.      */
  2048.     if (c > 0
  2049. #ifdef FEAT_MBYTE
  2050.         && (*mb_char2len)(c) == 1
  2051. #endif
  2052.        )
  2053.     {
  2054.     if (table_idx < 0
  2055.         && (!vim_isprintc(c) || (c & 0x7f) == ' ')
  2056.         && (c & 0x80))
  2057.     {
  2058.         c &= 0x7f;
  2059.         modifiers |= MOD_MASK_ALT;
  2060.         /* try again, to find the un-alted key in the special key table */
  2061.         table_idx = find_special_key_in_table(c);
  2062.     }
  2063.     if (table_idx < 0 && !vim_isprintc(c) && c < ' ')
  2064.     {
  2065. #ifdef EBCDIC
  2066.         c = CtrlChar(c);
  2067. #else
  2068.         c += '@';
  2069. #endif
  2070.         modifiers |= MOD_MASK_CTRL;
  2071.     }
  2072.     }
  2073.  
  2074.     /* translate the modifier into a string */
  2075.     for (i = 0; mod_mask_table[i].name != 'A'; i++)
  2076.     if ((modifiers & mod_mask_table[i].mod_mask)
  2077.                         == mod_mask_table[i].mod_flag)
  2078.     {
  2079.         string[idx++] = mod_mask_table[i].name;
  2080.         string[idx++] = (char_u)'-';
  2081.     }
  2082.  
  2083.     if (table_idx < 0)        /* unknown special key, may output t_xx */
  2084.     {
  2085.     if (IS_SPECIAL(c))
  2086.     {
  2087.         string[idx++] = 't';
  2088.         string[idx++] = '_';
  2089.         string[idx++] = KEY2TERMCAP0(c);
  2090.         string[idx++] = KEY2TERMCAP1(c);
  2091.     }
  2092.     /* Not a special key, only modifiers, output directly */
  2093.     else
  2094.     {
  2095. #ifdef FEAT_MBYTE
  2096.         if (has_mbyte && (*mb_char2len)(c) > 1)
  2097.         idx += (*mb_char2bytes)(c, string + idx);
  2098.         else
  2099. #endif
  2100.         if (vim_isprintc(c))
  2101.         string[idx++] = c;
  2102.         else
  2103.         {
  2104.         s = transchar(c);
  2105.         while (*s)
  2106.             string[idx++] = *s++;
  2107.         }
  2108.     }
  2109.     }
  2110.     else        /* use name of special key */
  2111.     {
  2112.     STRCPY(string + idx, key_names_table[table_idx].name);
  2113.     idx = (int)STRLEN(string);
  2114.     }
  2115.     string[idx++] = '>';
  2116.     string[idx] = NUL;
  2117.     return string;
  2118. }
  2119.  
  2120. /*
  2121.  * Try translating a <> name at (*srcp)[] to dst[].
  2122.  * Return the number of characters added to dst[], zero for no match.
  2123.  * If there is a match, srcp is advanced to after the <> name.
  2124.  * dst[] must be big enough to hold the result (up to six characters)!
  2125.  */
  2126.     int
  2127. trans_special(srcp, dst, keycode)
  2128.     char_u    **srcp;
  2129.     char_u    *dst;
  2130.     int        keycode; /* prefer key code, e.g. K_DEL instead of DEL */
  2131. {
  2132.     int        modifiers;
  2133.     int        key;
  2134.     int        dlen = 0;
  2135.  
  2136.     key = find_special_key(srcp, &modifiers, keycode);
  2137.     if (key == 0)
  2138.     return 0;
  2139.  
  2140.     /* Put the appropriate modifier in a string */
  2141.     if (modifiers != 0)
  2142.     {
  2143.     dst[dlen++] = K_SPECIAL;
  2144.     dst[dlen++] = KS_MODIFIER;
  2145.     dst[dlen++] = modifiers;
  2146.     }
  2147.  
  2148.     if (IS_SPECIAL(key))
  2149.     {
  2150.     dst[dlen++] = K_SPECIAL;
  2151.     dst[dlen++] = KEY2TERMCAP0(key);
  2152.     dst[dlen++] = KEY2TERMCAP1(key);
  2153.     }
  2154. #ifdef FEAT_MBYTE
  2155.     else if (has_mbyte && !keycode)
  2156.     dlen += (*mb_char2bytes)(key, dst + dlen);
  2157. #endif
  2158.     else if (keycode)
  2159.     dlen = (int)(add_char2buf(key, dst + dlen) - dst);
  2160.     else
  2161.     dst[dlen++] = key;
  2162.  
  2163.     return dlen;
  2164. }
  2165.  
  2166. /*
  2167.  * Try translating a <> name at (*srcp)[], return the key and modifiers.
  2168.  * srcp is advanced to after the <> name.
  2169.  * returns 0 if there is no match.
  2170.  */
  2171.     int
  2172. find_special_key(srcp, modp, keycode)
  2173.     char_u    **srcp;
  2174.     int        *modp;
  2175.     int        keycode; /* prefer key code, e.g. K_DEL instead of DEL */
  2176. {
  2177.     char_u    *last_dash;
  2178.     char_u    *end_of_name;
  2179.     char_u    *src;
  2180.     char_u    *bp;
  2181.     int        modifiers;
  2182.     int        bit;
  2183.     int        key;
  2184.     long_u    n;
  2185.  
  2186.     src = *srcp;
  2187.     if (src[0] != '<')
  2188.     return 0;
  2189.  
  2190.     /* Find end of modifier list */
  2191.     last_dash = src;
  2192.     for (bp = src + 1; *bp == '-' || vim_isIDc(*bp); bp++)
  2193.     {
  2194.     if (*bp == '-')
  2195.     {
  2196.         last_dash = bp;
  2197.         if (bp[1] != NUL && bp[2] == '>')
  2198.         ++bp;    /* anything accepted, like <C-?> */
  2199.     }
  2200.     if (bp[0] == 't' && bp[1] == '_' && bp[2] && bp[3])
  2201.         bp += 3;    /* skip t_xx, xx may be '-' or '>' */
  2202.     }
  2203.  
  2204.     if (*bp == '>')    /* found matching '>' */
  2205.     {
  2206.     end_of_name = bp + 1;
  2207.  
  2208.     if (STRNICMP(src + 1, "char-", 5) == 0 && isdigit(src[6]))
  2209.     {
  2210.         /* <Char-123> or <Char-033> or <Char-0x33> */
  2211.         vim_str2nr(src + 6, NULL, NULL, TRUE, TRUE, NULL, &n);
  2212.         *modp = 0;
  2213.         *srcp = end_of_name;
  2214.         return (int)n;
  2215.     }
  2216.  
  2217.     /* Which modifiers are given? */
  2218.     modifiers = 0x0;
  2219.     for (bp = src + 1; bp < last_dash; bp++)
  2220.     {
  2221.         if (*bp != '-')
  2222.         {
  2223.         bit = name_to_mod_mask(*bp);
  2224.         if (bit == 0x0)
  2225.             break;    /* Illegal modifier name */
  2226.         modifiers |= bit;
  2227.         }
  2228.     }
  2229.  
  2230.     /*
  2231.      * Legal modifier name.
  2232.      */
  2233.     if (bp >= last_dash)
  2234.     {
  2235.         /*
  2236.          * Modifier with single letter, or special key name.
  2237.          */
  2238.         if (modifiers != 0 && last_dash[2] == '>')
  2239.         key = last_dash[1];
  2240.         else
  2241.         key = get_special_key_code(last_dash + 1);
  2242.  
  2243.         /*
  2244.          * get_special_key_code() may return NUL for invalid
  2245.          * special key name.
  2246.          */
  2247.         if (key != NUL)
  2248.         {
  2249.         /*
  2250.          * Only use a modifier when there is no special key code that
  2251.          * includes the modifier.
  2252.          */
  2253.         key = simplify_key(key, &modifiers);
  2254.  
  2255.         if (!keycode)
  2256.         {
  2257.             /* don't want keycode, use single byte code */
  2258.             if (key == K_BS)
  2259.             key = BS;
  2260.             else if (key == K_DEL || key == K_KDEL)
  2261.             key = DEL;
  2262.         }
  2263.  
  2264.         /*
  2265.          * Normal Key with modifier: Try to make a single byte code.
  2266.          */
  2267.         if (!IS_SPECIAL(key))
  2268.             key = extract_modifiers(key, &modifiers);
  2269.  
  2270.         *modp = modifiers;
  2271.         *srcp = end_of_name;
  2272.         return key;
  2273.         }
  2274.     }
  2275.     }
  2276.     return 0;
  2277. }
  2278.  
  2279. /*
  2280.  * Try to include modifiers in the key.
  2281.  * Changes "Shift-a" to 'A', "Alt-A" to 0xc0, etc.
  2282.  */
  2283.     int
  2284. extract_modifiers(key, modp)
  2285.     int        key;
  2286.     int        *modp;
  2287. {
  2288.     int    modifiers = *modp;
  2289.  
  2290. #ifdef MACOS
  2291.     /* Command-key really special, No fancynest */
  2292.     if (!(modifiers & MOD_MASK_CMD))
  2293. #endif
  2294.     if ((modifiers & MOD_MASK_SHIFT) && ASCII_ISALPHA(key))
  2295.     {
  2296.     key = TOUPPER_ASC(key);
  2297.     modifiers &= ~MOD_MASK_SHIFT;
  2298.     }
  2299.     if ((modifiers & MOD_MASK_CTRL)
  2300. #ifdef EBCDIC
  2301.         /* * TODO: EBCDIC Better use:
  2302.          * && (Ctrl_chr(key) || key == '?')
  2303.          * ???  */
  2304.         && strchr("?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_", key)
  2305.                                != NULL
  2306. #else
  2307.         && ((key >= '?' && key <= '_') || ASCII_ISALPHA(key))
  2308. #endif
  2309.         )
  2310.     {
  2311.     key = Ctrl_chr(key);
  2312.     modifiers &= ~MOD_MASK_CTRL;
  2313.     /* <C-@> is <Nul> */
  2314.     if (key == 0)
  2315.         key = K_ZERO;
  2316.     }
  2317. #ifdef MACOS
  2318.     /* Command-key really special, No fancynest */
  2319.     if (!(modifiers & MOD_MASK_CMD))
  2320. #endif
  2321.     if ((modifiers & MOD_MASK_ALT) && key < 0x80)
  2322.     {
  2323.     key |= 0x80;
  2324.     modifiers &= ~MOD_MASK_ALT;    /* remove the META modifier */
  2325.     }
  2326.  
  2327.     *modp = modifiers;
  2328.     return key;
  2329. }
  2330.  
  2331. /*
  2332.  * Try to find key "c" in the special key table.
  2333.  * Return the index when found, -1 when not found.
  2334.  */
  2335.     int
  2336. find_special_key_in_table(c)
  2337.     int        c;
  2338. {
  2339.     int        i;
  2340.  
  2341.     for (i = 0; key_names_table[i].name != NULL; i++)
  2342.     if (c == key_names_table[i].key)
  2343.         break;
  2344.     if (key_names_table[i].name == NULL)
  2345.     i = -1;
  2346.     return i;
  2347. }
  2348.  
  2349. /*
  2350.  * Find the special key with the given name (the given string does not have to
  2351.  * end with NUL, the name is assumed to end before the first non-idchar).
  2352.  * If the name starts with "t_" the next two characters are interpreted as a
  2353.  * termcap name.
  2354.  * Return the key code, or 0 if not found.
  2355.  */
  2356.     int
  2357. get_special_key_code(name)
  2358.     char_u  *name;
  2359. {
  2360.     char_u  *table_name;
  2361.     char_u  string[3];
  2362.     int        i, j;
  2363.  
  2364.     /*
  2365.      * If it's <t_xx> we get the code for xx from the termcap
  2366.      */
  2367.     if (name[0] == 't' && name[1] == '_' && name[2] != NUL && name[3] != NUL)
  2368.     {
  2369.     string[0] = name[2];
  2370.     string[1] = name[3];
  2371.     string[2] = NUL;
  2372.     if (add_termcap_entry(string, FALSE) == OK)
  2373.         return TERMCAP2KEY(name[2], name[3]);
  2374.     }
  2375.     else
  2376.     for (i = 0; key_names_table[i].name != NULL; i++)
  2377.     {
  2378.         table_name = key_names_table[i].name;
  2379.         for (j = 0; vim_isIDc(name[j]) && table_name[j] != NUL; j++)
  2380.         if (TOLOWER_ASC(table_name[j]) != TOLOWER_ASC(name[j]))
  2381.             break;
  2382.         if (!vim_isIDc(name[j]) && table_name[j] == NUL)
  2383.         return key_names_table[i].key;
  2384.     }
  2385.     return 0;
  2386. }
  2387.  
  2388. #ifdef FEAT_CMDL_COMPL
  2389.     char_u *
  2390. get_key_name(i)
  2391.     int        i;
  2392. {
  2393.     if (i >= KEY_NAMES_TABLE_LEN)
  2394.     return NULL;
  2395.     return  key_names_table[i].name;
  2396. }
  2397. #endif
  2398.  
  2399. #ifdef FEAT_MOUSE
  2400. /*
  2401.  * Look up the given mouse code to return the relevant information in the other
  2402.  * arguments.  Return which button is down or was released.
  2403.  */
  2404.     int
  2405. get_mouse_button(code, is_click, is_drag)
  2406.     int        code;
  2407.     int        *is_click;
  2408.     int        *is_drag;
  2409. {
  2410.     int        i;
  2411.  
  2412.     for (i = 0; mouse_table[i].pseudo_code; i++)
  2413.     if (code == mouse_table[i].pseudo_code)
  2414.     {
  2415.         *is_click = mouse_table[i].is_click;
  2416.         *is_drag = mouse_table[i].is_drag;
  2417.         return mouse_table[i].button;
  2418.     }
  2419.     return 0;        /* Shouldn't get here */
  2420. }
  2421.  
  2422. /*
  2423.  * Return the appropriate pseudo mouse event token (KE_LEFTMOUSE etc) based on
  2424.  * the given information about which mouse button is down, and whether the
  2425.  * mouse was clicked, dragged or released.
  2426.  */
  2427.     int
  2428. get_pseudo_mouse_code(button, is_click, is_drag)
  2429.     int        button;    /* eg MOUSE_LEFT */
  2430.     int        is_click;
  2431.     int        is_drag;
  2432. {
  2433.     int        i;
  2434.  
  2435.     for (i = 0; mouse_table[i].pseudo_code; i++)
  2436.     if (button == mouse_table[i].button
  2437.         && is_click == mouse_table[i].is_click
  2438.         && is_drag == mouse_table[i].is_drag)
  2439.     {
  2440. #ifdef FEAT_GUI
  2441.         /* Trick: a non mappable left click and release has mouse_col < 0.
  2442.          * Used for 'mousefocus' in gui_mouse_moved() */
  2443.         if (mouse_col < 0)
  2444.         {
  2445.         mouse_col = 0;
  2446.         if (mouse_table[i].pseudo_code == (int)KE_LEFTMOUSE)
  2447.             return (int)KE_LEFTMOUSE_NM;
  2448.         if (mouse_table[i].pseudo_code == (int)KE_LEFTRELEASE)
  2449.             return (int)KE_LEFTRELEASE_NM;
  2450.         }
  2451. #endif
  2452.         return mouse_table[i].pseudo_code;
  2453.     }
  2454.     return (int)KE_IGNORE;        /* not recongnized, ignore it */
  2455. }
  2456. #endif /* FEAT_MOUSE */
  2457.  
  2458. /*
  2459.  * Return the current end-of-line type: EOL_DOS, EOL_UNIX or EOL_MAC.
  2460.  */
  2461.     int
  2462. get_fileformat(buf)
  2463.     buf_T    *buf;
  2464. {
  2465.     int        c = *buf->b_p_ff;
  2466.  
  2467.     if (buf->b_p_bin || c == 'u')
  2468.     return EOL_UNIX;
  2469.     if (c == 'm')
  2470.     return EOL_MAC;
  2471.     return EOL_DOS;
  2472. }
  2473.  
  2474. /*
  2475.  * Like get_fileformat(), but override 'fileformat' with "p" for "++opt=val"
  2476.  * argument.
  2477.  */
  2478.     int
  2479. get_fileformat_force(buf, eap)
  2480.     buf_T    *buf;
  2481.     exarg_T    *eap;        /* can be NULL! */
  2482. {
  2483.     int        c;
  2484.  
  2485.     if (eap != NULL && eap->force_ff != 0)
  2486.     c = eap->cmd[eap->force_ff];
  2487.     else
  2488.     {
  2489.     if (buf->b_p_bin)
  2490.         return EOL_UNIX;
  2491.     c = *buf->b_p_ff;
  2492.     }
  2493.     if (c == 'u')
  2494.     return EOL_UNIX;
  2495.     if (c == 'm')
  2496.     return EOL_MAC;
  2497.     return EOL_DOS;
  2498. }
  2499.  
  2500. /*
  2501.  * Set the current end-of-line type to EOL_DOS, EOL_UNIX or EOL_MAC.
  2502.  * Sets both 'textmode' and 'fileformat'.
  2503.  * Note: Does _not_ set global value of 'textmode'!
  2504.  */
  2505.     void
  2506. set_fileformat(t, opt_flags)
  2507.     int        t;
  2508.     int        opt_flags;    /* OPT_LOCAL and/or OPT_GLOBAL */
  2509. {
  2510.     char    *p = NULL;
  2511.  
  2512.     switch (t)
  2513.     {
  2514.     case EOL_DOS:
  2515.     p = FF_DOS;
  2516.     curbuf->b_p_tx = TRUE;
  2517.     break;
  2518.     case EOL_UNIX:
  2519.     p = FF_UNIX;
  2520.     curbuf->b_p_tx = FALSE;
  2521.     break;
  2522.     case EOL_MAC:
  2523.     p = FF_MAC;
  2524.     curbuf->b_p_tx = FALSE;
  2525.     break;
  2526.     }
  2527.     if (p != NULL)
  2528.     set_string_option_direct((char_u *)"ff", -1, (char_u *)p,
  2529.                             OPT_FREE | opt_flags);
  2530. #ifdef FEAT_WINDOWS
  2531.     check_status(curbuf);
  2532. #endif
  2533. #ifdef FEAT_TITLE
  2534.     need_maketitle = TRUE;        /* set window title later */
  2535. #endif
  2536. }
  2537.  
  2538. /*
  2539.  * Return the default fileformat from 'fileformats'.
  2540.  */
  2541.     int
  2542. default_fileformat()
  2543. {
  2544.     switch (*p_ffs)
  2545.     {
  2546.     case 'm':   return EOL_MAC;
  2547.     case 'd':   return EOL_DOS;
  2548.     }
  2549.     return EOL_UNIX;
  2550. }
  2551.  
  2552. /*
  2553.  * Call shell.    Calls mch_call_shell, with 'shellxquote' added.
  2554.  */
  2555.     int
  2556. call_shell(cmd, opt)
  2557.     char_u    *cmd;
  2558.     int        opt;
  2559. {
  2560.     char_u    *ncmd;
  2561.     int        retval;
  2562.  
  2563.     if (p_verbose > 3)
  2564.     {
  2565.     msg_str((char_u *)_("Calling shell to execute: \"%s\""),
  2566.                             cmd == NULL ? p_sh : cmd);
  2567.     out_char('\n');
  2568.     cursor_on();
  2569.     }
  2570.  
  2571.     if (*p_sh == NUL)
  2572.     {
  2573.     EMSG(_(e_shellempty));
  2574.     retval = -1;
  2575.     }
  2576.     else
  2577.     {
  2578. #ifdef FEAT_GUI_MSWIN
  2579.     /* Don't hide the pointer while executing a shell command. */
  2580.     gui_mch_mousehide(FALSE);
  2581. #endif
  2582. #ifdef FEAT_GUI
  2583.     ++hold_gui_events;
  2584. #endif
  2585.     /* The external command may update a tags file, clear cached tags. */
  2586.     tag_freematch();
  2587.  
  2588.     if (cmd == NULL || *p_sxq == NUL)
  2589.         retval = mch_call_shell(cmd, opt);
  2590.     else
  2591.     {
  2592.         ncmd = alloc((unsigned)(STRLEN(cmd) + STRLEN(p_sxq) * 2 + 1));
  2593.         if (ncmd != NULL)
  2594.         {
  2595.         STRCPY(ncmd, p_sxq);
  2596.         STRCAT(ncmd, cmd);
  2597.         STRCAT(ncmd, p_sxq);
  2598.         retval = mch_call_shell(ncmd, opt);
  2599.         vim_free(ncmd);
  2600.         }
  2601.         else
  2602.         retval = -1;
  2603.     }
  2604. #ifdef FEAT_GUI
  2605.     --hold_gui_events;
  2606. #endif
  2607.     /*
  2608.      * Check the window size, in case it changed while executing the
  2609.      * external command.
  2610.      */
  2611.     shell_resized_check();
  2612.     }
  2613.  
  2614. #ifdef FEAT_EVAL
  2615.     set_vim_var_nr(VV_SHELL_ERROR, (long)retval);
  2616. #endif
  2617.  
  2618.     return retval;
  2619. }
  2620.  
  2621. /*
  2622.  * VISUAL and OP_PENDING State are never set, they are equal to NORMAL State
  2623.  * with a condition.  This function returns the real State.
  2624.  */
  2625.     int
  2626. get_real_state()
  2627. {
  2628.     if (State & NORMAL)
  2629.     {
  2630. #ifdef FEAT_VISUAL
  2631.     if (VIsual_active)
  2632.         return VISUAL;
  2633.     else
  2634. #endif
  2635.         if (finish_op)
  2636.         return OP_PENDING;
  2637.     }
  2638.     return State;
  2639. }
  2640.  
  2641. #if defined(FEAT_SESSION) || defined(MSWIN) \
  2642.     || (defined(FEAT_GUI_GTK) && defined(FEAT_WINDOWS)) \
  2643.     || defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG) \
  2644.     || defined(PROTO)
  2645. /*
  2646.  * Change to a file's directory.
  2647.  * Caller must call shorten_fnames()!
  2648.  * Return OK or FAIL.
  2649.  */
  2650.     int
  2651. vim_chdirfile(fname)
  2652.     char_u    *fname;
  2653. {
  2654.     char_u    temp_string[MAXPATHL];
  2655.     char_u    *p;
  2656.     char_u    *t;
  2657.  
  2658.     STRCPY(temp_string, fname);
  2659.     p = get_past_head(temp_string);
  2660.     t = gettail(temp_string);
  2661.     while (t > p && vim_ispathsep(t[-1]))
  2662.     --t;
  2663.     *t = NUL; /* chop off end of string */
  2664.  
  2665.     return mch_chdir((char *)temp_string) == 0 ? OK : FAIL;
  2666. }
  2667. #endif
  2668.  
  2669. #if defined(STAT_IGNORES_SLASH) || defined(PROTO)
  2670. /*
  2671.  * Check if "name" ends in a slash and is not a directory.
  2672.  * Used for systems where stat() ignores a trailing slash on a file name.
  2673.  * The Vim code assumes a trailing slash is only ignored for a directory.
  2674.  */
  2675.     int
  2676. illegal_slash(name)
  2677.     char *name;
  2678. {
  2679.     if (name[0] == NUL)
  2680.     return FALSE;        /* no file name is not illegal */
  2681.     if (name[strlen(name) - 1] != '/')
  2682.     return FALSE;        /* no trailing slash */
  2683.     if (mch_isdir((char_u *)name))
  2684.     return FALSE;        /* trailing slash for a directory */
  2685.     return TRUE;
  2686. }
  2687. #endif
  2688.  
  2689. #if defined(CURSOR_SHAPE) || defined(PROTO)
  2690.  
  2691. /*
  2692.  * Handling of cursor and mouse pointer shapes in various modes.
  2693.  */
  2694.  
  2695. cursorentry_T shape_table[SHAPE_IDX_COUNT] =
  2696. {
  2697.     /* The values will be filled in from the 'guicursor' and 'mouseshape'
  2698.      * defaults when Vim starts.
  2699.      * Adjust the SHAPE_IDX_ defines when making changes! */
  2700.     {0,    0, 0, 700L, 400L, 250L, 0, 0, "n", SHAPE_CURSOR+SHAPE_MOUSE},
  2701.     {0,    0, 0, 700L, 400L, 250L, 0, 0, "v", SHAPE_CURSOR+SHAPE_MOUSE},
  2702.     {0,    0, 0, 700L, 400L, 250L, 0, 0, "i", SHAPE_CURSOR+SHAPE_MOUSE},
  2703.     {0,    0, 0, 700L, 400L, 250L, 0, 0, "r", SHAPE_CURSOR+SHAPE_MOUSE},
  2704.     {0,    0, 0, 700L, 400L, 250L, 0, 0, "c", SHAPE_CURSOR+SHAPE_MOUSE},
  2705.     {0,    0, 0, 700L, 400L, 250L, 0, 0, "ci", SHAPE_CURSOR+SHAPE_MOUSE},
  2706.     {0,    0, 0, 700L, 400L, 250L, 0, 0, "cr", SHAPE_CURSOR+SHAPE_MOUSE},
  2707.     {0,    0, 0, 700L, 400L, 250L, 0, 0, "o", SHAPE_CURSOR+SHAPE_MOUSE},
  2708.     {0,    0, 0, 700L, 400L, 250L, 0, 0, "ve", SHAPE_CURSOR+SHAPE_MOUSE},
  2709.     {0,    0, 0,   0L,   0L,   0L, 0, 0, "e", SHAPE_MOUSE},
  2710.     {0,    0, 0,   0L,   0L,   0L, 0, 0, "s", SHAPE_MOUSE},
  2711.     {0,    0, 0,   0L,   0L,   0L, 0, 0, "sd", SHAPE_MOUSE},
  2712.     {0,    0, 0,   0L,   0L,   0L, 0, 0, "vs", SHAPE_MOUSE},
  2713.     {0,    0, 0,   0L,   0L,   0L, 0, 0, "vd", SHAPE_MOUSE},
  2714.     {0,    0, 0,   0L,   0L,   0L, 0, 0, "m", SHAPE_MOUSE},
  2715.     {0,    0, 0,   0L,   0L,   0L, 0, 0, "ml", SHAPE_MOUSE},
  2716.     {0,    0, 0, 100L, 100L, 100L, 0, 0, "sm", SHAPE_CURSOR},
  2717. };
  2718.  
  2719. #ifdef FEAT_MOUSESHAPE
  2720. /*
  2721.  * Table with names for mouse shapes.  Keep in sync with all the tables for
  2722.  * mch_set_mouse_shape()!.
  2723.  */
  2724. static char * mshape_names[] =
  2725. {
  2726.     "arrow",    /* default, must be the first one */
  2727.     "blank",    /* hidden */
  2728.     "beam",
  2729.     "updown",
  2730.     "udsizing",
  2731.     "leftright",
  2732.     "lrsizing",
  2733.     "busy",
  2734.     "no",
  2735.     "crosshair",
  2736.     "hand1",
  2737.     "hand2",
  2738.     "pencil",
  2739.     "question",
  2740.     "rightup-arrow",
  2741.     "up-arrow",
  2742.     NULL
  2743. };
  2744. #endif
  2745.  
  2746. /*
  2747.  * Parse the 'guicursor' option ("what" is SHAPE_CURSOR) or 'mouseshape'
  2748.  * ("what" is SHAPE_MOUSE).
  2749.  * Returns error message for an illegal option, NULL otherwise.
  2750.  */
  2751.     char_u *
  2752. parse_shape_opt(what)
  2753.     int        what;
  2754. {
  2755.     char_u    *modep;
  2756.     char_u    *colonp;
  2757.     char_u    *commap;
  2758.     char_u    *slashp;
  2759.     char_u    *p, *endp;
  2760.     int        idx = 0;        /* init for GCC */
  2761.     int        all_idx;
  2762.     int        len;
  2763.     int        i;
  2764.     long    n;
  2765.     int        found_ve = FALSE;    /* found "ve" flag */
  2766.     int        round;
  2767.  
  2768.     /*
  2769.      * First round: check for errors; second round: do it for real.
  2770.      */
  2771.     for (round = 1; round <= 2; ++round)
  2772.     {
  2773.     /*
  2774.      * Repeat for all comma separated parts.
  2775.      */
  2776. #ifdef FEAT_MOUSESHAPE
  2777.     if (what == SHAPE_MOUSE)
  2778.         modep = p_mouseshape;
  2779.     else
  2780. #endif
  2781.         modep = p_guicursor;
  2782.     while (*modep != NUL)
  2783.     {
  2784.         colonp = vim_strchr(modep, ':');
  2785.         if (colonp == NULL)
  2786.         return (char_u *)N_("E545: Missing colon");
  2787.         if (colonp == modep)
  2788.         return (char_u *)N_("E546: Illegal mode");
  2789.         commap = vim_strchr(modep, ',');
  2790.  
  2791.         /*
  2792.          * Repeat for all mode's before the colon.
  2793.          * For the 'a' mode, we loop to handle all the modes.
  2794.          */
  2795.         all_idx = -1;
  2796.         while (modep < colonp || all_idx >= 0)
  2797.         {
  2798.         if (all_idx < 0)
  2799.         {
  2800.             /* Find the mode. */
  2801.             if (modep[1] == '-' || modep[1] == ':')
  2802.             len = 1;
  2803.             else
  2804.             len = 2;
  2805.             if (len == 1 && TOLOWER_ASC(modep[0]) == 'a')
  2806.             all_idx = SHAPE_IDX_COUNT - 1;
  2807.             else
  2808.             {
  2809.             for (idx = 0; idx < SHAPE_IDX_COUNT; ++idx)
  2810.                 if (STRNICMP(modep, shape_table[idx].name, len)
  2811.                                      == 0)
  2812.                 break;
  2813.             if (idx == SHAPE_IDX_COUNT
  2814.                    || (shape_table[idx].used_for & what) == 0)
  2815.                 return (char_u *)N_("E546: Illegal mode");
  2816.             if (len == 2 && modep[0] == 'v' && modep[1] == 'e')
  2817.                 found_ve = TRUE;
  2818.             }
  2819.             modep += len + 1;
  2820.         }
  2821.  
  2822.         if (all_idx >= 0)
  2823.             idx = all_idx--;
  2824.         else if (round == 2)
  2825.         {
  2826. #ifdef FEAT_MOUSESHAPE
  2827.             if (what == SHAPE_MOUSE)
  2828.             {
  2829.             /* Set the default, for the missing parts */
  2830.             shape_table[idx].mshape = 0;
  2831.             }
  2832.             else
  2833. #endif
  2834.             {
  2835.             /* Set the defaults, for the missing parts */
  2836.             shape_table[idx].shape = SHAPE_BLOCK;
  2837.             shape_table[idx].blinkwait = 700L;
  2838.             shape_table[idx].blinkon = 400L;
  2839.             shape_table[idx].blinkoff = 250L;
  2840.             }
  2841.         }
  2842.  
  2843.         /* Parse the part after the colon */
  2844.         for (p = colonp + 1; *p && *p != ','; )
  2845.         {
  2846. #ifdef FEAT_MOUSESHAPE
  2847.             if (what == SHAPE_MOUSE)
  2848.             {
  2849.             for (i = 0; ; ++i)
  2850.             {
  2851.                 if (mshape_names[i] == NULL)
  2852.                 {
  2853.                 if (!isdigit(*p))
  2854.                     return (char_u *)N_("E547: Illegal mouseshape");
  2855.                 if (round == 2)
  2856.                     shape_table[idx].mshape =
  2857.                           getdigits(&p) + MSHAPE_NUMBERED;
  2858.                 else
  2859.                     (void)getdigits(&p);
  2860.                 break;
  2861.                 }
  2862.                 len = (int)STRLEN(mshape_names[i]);
  2863.                 if (STRNICMP(p, mshape_names[i], len) == 0)
  2864.                 {
  2865.                 if (round == 2)
  2866.                     shape_table[idx].mshape = i;
  2867.                 p += len;
  2868.                 break;
  2869.                 }
  2870.             }
  2871.             }
  2872.             else /* if (what == SHAPE_MOUSE) */
  2873. #endif
  2874.             {
  2875.             /*
  2876.              * First handle the ones with a number argument.
  2877.              */
  2878.             i = *p;
  2879.             len = 0;
  2880.             if (STRNICMP(p, "ver", 3) == 0)
  2881.                 len = 3;
  2882.             else if (STRNICMP(p, "hor", 3) == 0)
  2883.                 len = 3;
  2884.             else if (STRNICMP(p, "blinkwait", 9) == 0)
  2885.                 len = 9;
  2886.             else if (STRNICMP(p, "blinkon", 7) == 0)
  2887.                 len = 7;
  2888.             else if (STRNICMP(p, "blinkoff", 8) == 0)
  2889.                 len = 8;
  2890.             if (len != 0)
  2891.             {
  2892.                 p += len;
  2893.                 if (!isdigit(*p))
  2894.                 return (char_u *)N_("E548: digit expected");
  2895.                 n = getdigits(&p);
  2896.                 if (len == 3)   /* "ver" or "hor" */
  2897.                 {
  2898.                 if (n == 0)
  2899.                     return (char_u *)N_("E549: Illegal percentage");
  2900.                 if (round == 2)
  2901.                 {
  2902.                     if (TOLOWER_ASC(i) == 'v')
  2903.                     shape_table[idx].shape = SHAPE_VER;
  2904.                     else
  2905.                     shape_table[idx].shape = SHAPE_HOR;
  2906.                     shape_table[idx].percentage = n;
  2907.                 }
  2908.                 }
  2909.                 else if (round == 2)
  2910.                 {
  2911.                 if (len == 9)
  2912.                     shape_table[idx].blinkwait = n;
  2913.                 else if (len == 7)
  2914.                     shape_table[idx].blinkon = n;
  2915.                 else
  2916.                     shape_table[idx].blinkoff = n;
  2917.                 }
  2918.             }
  2919.             else if (STRNICMP(p, "block", 5) == 0)
  2920.             {
  2921.                 if (round == 2)
  2922.                 shape_table[idx].shape = SHAPE_BLOCK;
  2923.                 p += 5;
  2924.             }
  2925.             else    /* must be a highlight group name then */
  2926.             {
  2927.                 endp = vim_strchr(p, '-');
  2928.                 if (commap == NULL)            /* last part */
  2929.                 {
  2930.                 if (endp == NULL)
  2931.                     endp = p + STRLEN(p);   /* find end of part */
  2932.                 }
  2933.                 else if (endp > commap || endp == NULL)
  2934.                 endp = commap;
  2935.                 slashp = vim_strchr(p, '/');
  2936.                 if (slashp != NULL && slashp < endp)
  2937.                 {
  2938.                 /* "group/langmap_group" */
  2939.                 i = syn_check_group(p, (int)(slashp - p));
  2940.                 p = slashp + 1;
  2941.                 }
  2942.                 if (round == 2)
  2943.                 {
  2944.                 shape_table[idx].id = syn_check_group(p,
  2945.                                  (int)(endp - p));
  2946.                 shape_table[idx].id_lm = shape_table[idx].id;
  2947.                 if (slashp != NULL && slashp < endp)
  2948.                     shape_table[idx].id = i;
  2949.                 }
  2950.                 p = endp;
  2951.             }
  2952.             } /* if (what != SHAPE_MOUSE) */
  2953.  
  2954.             if (*p == '-')
  2955.             ++p;
  2956.         }
  2957.         }
  2958.         modep = p;
  2959.         if (*modep == ',')
  2960.         ++modep;
  2961.     }
  2962.     }
  2963.  
  2964.     /* If the 's' flag is not given, use the 'v' cursor for 's' */
  2965.     if (!found_ve)
  2966.     {
  2967. #ifdef FEAT_MOUSESHAPE
  2968.     if (what == SHAPE_MOUSE)
  2969.     {
  2970.         shape_table[SHAPE_IDX_VE].mshape = shape_table[SHAPE_IDX_V].mshape;
  2971.     }
  2972.     else
  2973. #endif
  2974.     {
  2975.         shape_table[SHAPE_IDX_VE].shape = shape_table[SHAPE_IDX_V].shape;
  2976.         shape_table[SHAPE_IDX_VE].percentage =
  2977.                      shape_table[SHAPE_IDX_V].percentage;
  2978.         shape_table[SHAPE_IDX_VE].blinkwait =
  2979.                       shape_table[SHAPE_IDX_V].blinkwait;
  2980.         shape_table[SHAPE_IDX_VE].blinkon =
  2981.                         shape_table[SHAPE_IDX_V].blinkon;
  2982.         shape_table[SHAPE_IDX_VE].blinkoff =
  2983.                        shape_table[SHAPE_IDX_V].blinkoff;
  2984.         shape_table[SHAPE_IDX_VE].id = shape_table[SHAPE_IDX_V].id;
  2985.         shape_table[SHAPE_IDX_VE].id_lm = shape_table[SHAPE_IDX_V].id_lm;
  2986.     }
  2987.     }
  2988.  
  2989.     return NULL;
  2990. }
  2991.  
  2992. /*
  2993.  * Return the index into shape_table[] for the current mode.
  2994.  * When "mouse" is TRUE, consider indexes valid for the mouse pointer.
  2995.  */
  2996.     int
  2997. get_shape_idx(mouse)
  2998.     int    mouse;
  2999. {
  3000. #ifdef FEAT_MOUSESHAPE
  3001.     if (mouse && (State == HITRETURN || State == ASKMORE))
  3002.     {
  3003. # ifdef FEAT_GUI
  3004.     if (Y_2_ROW(gui_mch_get_mouse_y()) == Rows - 1)
  3005.         return SHAPE_IDX_MOREL;
  3006. # endif
  3007.     return SHAPE_IDX_MORE;
  3008.     }
  3009.     if (mouse && drag_status_line)
  3010.     return SHAPE_IDX_SDRAG;
  3011. # ifdef FEAT_VERTSPLIT
  3012.     if (mouse && drag_sep_line)
  3013.     return SHAPE_IDX_VDRAG;
  3014. # endif
  3015. #endif
  3016.     if (!mouse && State == SHOWMATCH)
  3017.     return SHAPE_IDX_SM;
  3018. #ifdef FEAT_VREPLACE
  3019.     if (State & VREPLACE_FLAG)
  3020.     return SHAPE_IDX_R;
  3021. #endif
  3022.     if (State & REPLACE_FLAG)
  3023.     return SHAPE_IDX_R;
  3024.     if (State & INSERT)
  3025.     return SHAPE_IDX_I;
  3026.     if (State & CMDLINE)
  3027.     {
  3028.     if (cmdline_at_end())
  3029.         return SHAPE_IDX_C;
  3030.     if (cmdline_overstrike())
  3031.         return SHAPE_IDX_CR;
  3032.     return SHAPE_IDX_CI;
  3033.     }
  3034.     if (finish_op)
  3035.     return SHAPE_IDX_O;
  3036. #ifdef FEAT_VISUAL
  3037.     if (VIsual_active)
  3038.     {
  3039.     if (*p_sel == 'e')
  3040.         return SHAPE_IDX_VE;
  3041.     else
  3042.         return SHAPE_IDX_V;
  3043.     }
  3044. #endif
  3045.     return SHAPE_IDX_N;
  3046. }
  3047.  
  3048. # if defined(FEAT_MOUSESHAPE) || defined(PROTO)
  3049. static int old_mouse_shape = 0;
  3050.  
  3051. /*
  3052.  * Set the mouse shape:
  3053.  * If "shape" is -1, use shape depending on the current mode,
  3054.  * depending on the current state.
  3055.  * If "shape" is -2, only update the shape when it's CLINE or STATUS (used
  3056.  * when the mouse moves off the status or command line).
  3057.  */
  3058.     void
  3059. update_mouseshape(shape_idx)
  3060.     int    shape_idx;
  3061. {
  3062.     int new_mouse_shape;
  3063.  
  3064.     /* Only works in GUI mode. */
  3065.     if (!gui.in_use)
  3066.     return;
  3067.  
  3068.     /* Postpone the updating when more is to come.  Speeds up executing of
  3069.      * mappings. */
  3070.     if (shape_idx == -1 && char_avail())
  3071.     {
  3072.     postponed_mouseshape = TRUE;
  3073.     return;
  3074.     }
  3075.  
  3076.     if (shape_idx == -2
  3077.         && old_mouse_shape != shape_table[SHAPE_IDX_CLINE].mshape
  3078.         && old_mouse_shape != shape_table[SHAPE_IDX_STATUS].mshape
  3079.         && old_mouse_shape != shape_table[SHAPE_IDX_VSEP].mshape)
  3080.     return;
  3081.     if (shape_idx < 0)
  3082.     new_mouse_shape = shape_table[get_shape_idx(TRUE)].mshape;
  3083.     else
  3084.     new_mouse_shape = shape_table[shape_idx].mshape;
  3085.     if (new_mouse_shape != old_mouse_shape)
  3086.     {
  3087.     mch_set_mouse_shape(new_mouse_shape);
  3088.     old_mouse_shape = new_mouse_shape;
  3089.     }
  3090.     postponed_mouseshape = FALSE;
  3091. }
  3092. # endif
  3093.  
  3094. #endif /* CURSOR_SHAPE */
  3095.  
  3096.  
  3097. #ifdef FEAT_CRYPT
  3098. /*
  3099.  * Optional encryption suypport.
  3100.  * Mohsin Ahmed, mosh@sasi.com, 98-09-24
  3101.  * Based on zip/crypt sources.
  3102.  *
  3103.  * NOTE FOR USA: Since 2000 exporting this code from the USA is allowed to
  3104.  * most countries.  There are a few exceptions, but that still should not be a
  3105.  * problem since this code was originally created in Europe and India.
  3106.  */
  3107.  
  3108. /* from zip.h */
  3109.  
  3110. typedef unsigned short ush;    /* unsigned 16-bit value */
  3111. typedef unsigned long  ulg;    /* unsigned 32-bit value */
  3112.  
  3113. static void make_crc_tab __ARGS((void));
  3114.  
  3115. ulg crc_32_tab[256];
  3116.  
  3117. /*
  3118.  * Fill the CRC table.
  3119.  */
  3120.     static void
  3121. make_crc_tab()
  3122. {
  3123.     ulg        s,t,v;
  3124.     static int    done = FALSE;
  3125.  
  3126.     if (done)
  3127.     return;
  3128.     for (t = 0; t < 256; t++)
  3129.     {
  3130.     v = t;
  3131.     for (s = 0; s < 8; s++)
  3132.         v = (v >> 1) ^ ((v & 1) * (ulg)0xedb88320L);
  3133.     crc_32_tab[t] = v;
  3134.     }
  3135.     done = TRUE;
  3136. }
  3137.  
  3138. #define CRC32(c, b) (crc_32_tab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
  3139.  
  3140.  
  3141. static ulg keys[3]; /* keys defining the pseudo-random sequence */
  3142.  
  3143. /*
  3144.  * Return the next byte in the pseudo-random sequence
  3145.  */
  3146.     int
  3147. decrypt_byte()
  3148. {
  3149.     ush temp;
  3150.  
  3151.     temp = (ush)keys[2] | 2;
  3152.     return (int)(((unsigned)(temp * (temp ^ 1)) >> 8) & 0xff);
  3153. }
  3154.  
  3155. /*
  3156.  * Update the encryption keys with the next byte of plain text
  3157.  */
  3158.     int
  3159. update_keys(c)
  3160.     int c;            /* byte of plain text */
  3161. {
  3162.     keys[0] = CRC32(keys[0], c);
  3163.     keys[1] += keys[0] & 0xff;
  3164.     keys[1] = keys[1] * 134775813L + 1;
  3165.     keys[2] = CRC32(keys[2], (int)(keys[1] >> 24));
  3166.     return c;
  3167. }
  3168.  
  3169. /*
  3170.  * Initialize the encryption keys and the random header according to
  3171.  * the given password.
  3172.  * If "passwd" is NULL or empty, don't do anything.
  3173.  */
  3174.     void
  3175. crypt_init_keys(passwd)
  3176.     char_u *passwd;        /* password string with which to modify keys */
  3177. {
  3178.     if (passwd != NULL && *passwd != NUL)
  3179.     {
  3180.     make_crc_tab();
  3181.     keys[0] = 305419896L;
  3182.     keys[1] = 591751049L;
  3183.     keys[2] = 878082192L;
  3184.     while (*passwd != '\0')
  3185.         update_keys((int)*passwd++);
  3186.     }
  3187. }
  3188.  
  3189. /*
  3190.  * Ask the user for a crypt key.
  3191.  * When "store" is TRUE, the new key in stored in the 'key' option, and the
  3192.  * 'key' option value is returned: Don't free it.
  3193.  * When "store" is FALSE, the typed key is returned in allocated memory.
  3194.  * Returns NULL on failure.
  3195.  */
  3196.     char_u *
  3197. get_crypt_key(store, twice)
  3198.     int        store;
  3199.     int        twice;        /* Ask for the key twice. */
  3200. {
  3201.     char_u    *p1, *p2 = NULL;
  3202.     int        round;
  3203.  
  3204.     for (round = 0; ; ++round)
  3205.     {
  3206.     cmdline_star = TRUE;
  3207.     cmdline_row = msg_row;
  3208.     p1 = getcmdline_prompt(NUL, round == 0
  3209.         ? (char_u *)_("Enter encryption key: ")
  3210.         : (char_u *)_("Enter same key again: "), 0);
  3211.     cmdline_star = FALSE;
  3212.  
  3213.     if (p1 == NULL)
  3214.         break;
  3215.  
  3216.     if (round == twice)
  3217.     {
  3218.         if (p2 != NULL && STRCMP(p1, p2) != 0)
  3219.         {
  3220.         MSG(_("Keys don't match!"));
  3221.         vim_free(p1);
  3222.         vim_free(p2);
  3223.         p2 = NULL;
  3224.         round = -1;        /* do it again */
  3225.         continue;
  3226.         }
  3227.         if (store)
  3228.         {
  3229.         set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL);
  3230.         vim_free(p1);
  3231.         p1 = curbuf->b_p_key;
  3232.         }
  3233.         break;
  3234.     }
  3235.     p2 = p1;
  3236.     }
  3237.  
  3238.     /* since the user typed this, no need to wait for return */
  3239.     need_wait_return = FALSE;
  3240.     msg_didout = FALSE;
  3241.  
  3242.     vim_free(p2);
  3243.     return p1;
  3244. }
  3245.  
  3246. #endif /* FEAT_CRYPT */
  3247.  
  3248. /* TODO: make some #ifdef for this */
  3249. /*--------[ file searching ]-------------------------------------------------*/
  3250. /*
  3251.  * File searching functions for 'path', 'tags' and 'cdpath' options.
  3252.  * External visible functions:
  3253.  * vim_findfile_init()        creates/initialises the search context
  3254.  * vim_findfile_free_visited()    free list of visited files/dirs of search
  3255.  *                context
  3256.  * vim_findfile()        find a file in the search context
  3257.  * vim_findfile_cleanup()    cleanup/free search context created by
  3258.  *                vim_findfile_init()
  3259.  *
  3260.  * All static functions and variables start with 'ff_'
  3261.  *
  3262.  * In general it works like this:
  3263.  * First you create yourself a search context by calling vim_findfile_init().
  3264.  * It is possible to give a search context from a previous call to
  3265.  * vim_findfile_init(), so it can be reused. After this you call vim_findfile()
  3266.  * until you are satisfied with the result or it returns NULL. On every call it
  3267.  * returns the next file which matches the conditions given to
  3268.  * vim_findfile_init(). If it doesn't find a next file it returns NULL.
  3269.  *
  3270.  * It is possible to call vim_findfile_init() again to reinitialise your search
  3271.  * with some new parameters. Don't forget to pass your old search context to
  3272.  * it, so it can reuse it and especially reuse the list of already visited
  3273.  * directories. If you want to delete the list of already visited directories
  3274.  * simply call vim_findfile_free_visited().
  3275.  *
  3276.  * When you are done call vim_findfile_cleanup() to free the search context.
  3277.  *
  3278.  * The function vim_findfile_init() has a long comment, which describes the
  3279.  * needed parameters.
  3280.  *
  3281.  *
  3282.  *
  3283.  * ATTENTION:
  3284.  * ==========
  3285.  *    Also we use an allocated search context here, this functions ARE NOT
  3286.  *    thread-safe!!!!!
  3287.  *
  3288.  *    To minimize parameter passing (or because I'm to lazy), only the
  3289.  *    external visible functions get a search context as a parameter. This is
  3290.  *    then assigned to a static global, which is used throughout the local
  3291.  *    functions.
  3292.  */
  3293.  
  3294. /*
  3295.  * type for the directory search stack
  3296.  */
  3297. typedef struct ff_stack
  3298. {
  3299.     struct ff_stack    *ffs_prev;
  3300.  
  3301.     /* the fix part (no wildcards) and the part containing the wildcards
  3302.      * of the search path
  3303.      */
  3304.     char_u        *ffs_fix_path;
  3305. #ifdef FEAT_PATH_EXTRA
  3306.     char_u        *ffs_wc_path;
  3307. #endif
  3308.  
  3309.     /* files/dirs found in the above directory, matched by the first wildcard
  3310.      * of wc_part
  3311.      */
  3312.     char_u        **ffs_filearray;
  3313.     int            ffs_filearray_size;
  3314.     char_u        ffs_filearray_cur;   /* needed for partly handled dirs */
  3315.  
  3316.     /* to store status of partly handled directories
  3317.      * 0: we work the on this directory for the first time
  3318.      * 1: this directory was partly searched in an earlier step
  3319.     */
  3320.     int            ffs_stage;
  3321.  
  3322.     /* How deep are we in the directory tree?
  3323.      * Counts backward from value of level parameter to vim_findfile_init
  3324.      */
  3325.     int            ffs_level;
  3326.  
  3327.     /* Did we already expand '**' to an empty string? */
  3328.     int            ffs_star_star_empty;
  3329. } ff_stack_T;
  3330.  
  3331. /*
  3332.  * type for already visited directories or files.
  3333.  */
  3334. typedef struct ff_visited
  3335. {
  3336.     struct ff_visited    *ffv_next;
  3337.  
  3338. #ifdef FEAT_PATH_EXTRA
  3339.     /* Visited directories are different if the wildcard string are
  3340.      * different. So we have to save it.
  3341.      */
  3342.     char_u        *ffv_wc_path;
  3343. #endif
  3344.     /* for unix use inode etc for comparison (needed because of links), else
  3345.      * use filename.
  3346.      */
  3347. #ifdef UNIX
  3348.     int            ffv_dev;    /* device number (-1 if not set) */
  3349.     ino_t        ffv_ino;    /* inode number */
  3350. #endif
  3351.     /* The memory for this struct is allocated according to the length of
  3352.      * ffv_fname.
  3353.      */
  3354.     char_u        ffv_fname[1];    /* actually longer */
  3355. } ff_visited_T;
  3356.  
  3357. /*
  3358.  * We might have to manage several visited lists during a search.
  3359.  * This is expecially needed for the tags option. If tags is set to:
  3360.  *      "./++/tags,./++/TAGS,++/tags"  (replace + with *)
  3361.  * So we have to do 3 searches:
  3362.  *   1) search from the current files directory downward for the file "tags"
  3363.  *   2) search from the current files directory downward for the file "TAGS"
  3364.  *   3) search from Vims current directory downwards for the file "tags"
  3365.  * As you can see, the first and the third search are for the same file, so for
  3366.  * the third search we can use the visited list of the first search. For the
  3367.  * second search we must start from a empty visited list.
  3368.  * The struct ff_visited_list_hdr is used to manage a linked list of already
  3369.  * visited lists.
  3370.  */
  3371. typedef struct ff_visited_list_hdr
  3372. {
  3373.     struct ff_visited_list_hdr    *ffvl_next;
  3374.  
  3375.     /* the filename the attached visited list is for */
  3376.     char_u            *ffvl_filename;
  3377.  
  3378.     ff_visited_T        *ffvl_visited_list;
  3379.  
  3380. } ff_visited_list_hdr_T;
  3381.  
  3382.  
  3383. /*
  3384.  * '**' can be expanded to several directory levels.
  3385.  * Set the default maximium depth.
  3386.  */
  3387. #define FF_MAX_STAR_STAR_EXPAND ((char_u)30)
  3388. /*
  3389.  * The search context:
  3390.  *   ffsc_stack_ptr:    the stack for the dirs to search
  3391.  *   ffsc_visited_list: the currently active visited list
  3392.  *   ffsc_dir_visited_list: the currently active visited list for search dirs
  3393.  *   ffsc_visited_lists_list: the list of all visited lists
  3394.  *   ffsc_dir_visited_lists_list: the list of all visited lists for search dirs
  3395.  *   ffsc_file_to_search:     the file to search for
  3396.  *   ffsc_start_dir:    the starting directory, if search path was relative
  3397.  *   ffsc_fix_path:    the fix part of the given path (without wildcards)
  3398.  *            Needed for upward search.
  3399.  *   ffsc_wc_path:    the part of the given path containing wildcards
  3400.  *   ffsc_level:    how many levels of dirs to search downwards
  3401.  *   ffsc_stopdirs_v:    array of stop directories for upward search
  3402.  *   ffsc_need_dir:    TRUE if we search for a directory
  3403.  */
  3404. typedef struct ff_search_ctx_T
  3405. {
  3406.      ff_stack_T            *ffsc_stack_ptr;
  3407.      ff_visited_list_hdr_T    *ffsc_visited_list;
  3408.      ff_visited_list_hdr_T    *ffsc_dir_visited_list;
  3409.      ff_visited_list_hdr_T    *ffsc_visited_lists_list;
  3410.      ff_visited_list_hdr_T    *ffsc_dir_visited_lists_list;
  3411.      char_u            *ffsc_file_to_search;
  3412.      char_u            *ffsc_start_dir;
  3413.      char_u            *ffsc_fix_path;
  3414. #ifdef FEAT_PATH_EXTRA
  3415.      char_u            *ffsc_wc_path;
  3416.      int            ffsc_level;
  3417.      char_u            **ffsc_stopdirs_v;
  3418. #endif
  3419.      int            ffsc_need_dir;
  3420. }ff_search_ctx_T;
  3421. static ff_search_ctx_T *ff_search_ctx = NULL;
  3422.  
  3423. /* used for expanding filenames */
  3424. static char_u        *ff_expand_buffer = NULL;
  3425.  
  3426. /* locally needed functions */
  3427. #ifdef FEAT_PATH_EXTRA
  3428. static int ff_check_visited __ARGS((ff_visited_T **, char_u *, char_u *));
  3429. #else
  3430. static int ff_check_visited __ARGS((ff_visited_T **, char_u *));
  3431. #endif
  3432. static void vim_findfile_free_visited_list __ARGS((ff_visited_list_hdr_T **list_headp));
  3433. static void ff_free_visited_list __ARGS((ff_visited_T *vl));
  3434. static ff_visited_list_hdr_T* ff_get_visited_list __ARGS((char_u *, ff_visited_list_hdr_T **list_headp));
  3435. #ifdef FEAT_PATH_EXTRA
  3436. static int ff_wc_equal __ARGS((char_u *s1, char_u *s2));
  3437. #endif
  3438.  
  3439. static void ff_push __ARGS((ff_stack_T *));
  3440. static ff_stack_T * ff_pop __ARGS((void));
  3441. static void ff_clear __ARGS((void));
  3442. static void ff_free_stack_element __ARGS((ff_stack_T *));
  3443. #ifdef FEAT_PATH_EXTRA
  3444. static ff_stack_T *ff_create_stack_element __ARGS((char_u *, char_u *, int, int));
  3445. #else
  3446. static ff_stack_T *ff_create_stack_element __ARGS((char_u *, int, int));
  3447. #endif
  3448. #ifdef FEAT_PATH_EXTRA
  3449. static int ff_path_in_stoplist __ARGS((char_u *, int, char_u **));
  3450. #endif
  3451.  
  3452. #ifdef FEAT_SEARCHPATH
  3453. static char_u *find_file_in_path_option __ARGS((char_u *ptr, int len, int options, int first, char_u *path_option, int need_dir, char_u *rel_fname));
  3454. #endif
  3455.  
  3456. #if 0
  3457. /*
  3458.  * if someone likes findfirst/findnext, here are the functions
  3459.  * NOT TESTED!!
  3460.  */
  3461.  
  3462. static void *ff_fn_search_context = NULL;
  3463.  
  3464.     char_u *
  3465. vim_findfirst(path, filename, level)
  3466.     char_u    *path;
  3467.     char_u    *filename;
  3468.     int        level;
  3469. {
  3470.     ff_fn_search_context =
  3471.     vim_findfile_init(path, filename, NULL, level, TRUE, FALSE,
  3472.         ff_fn_search_context, rel_fname);
  3473.     if (NULL == ff_fn_search_context)
  3474.     return NULL;
  3475.     else
  3476.     return vim_findnext()
  3477. }
  3478.  
  3479.     char_u *
  3480. vim_findnext()
  3481. {
  3482.     char_u *ret = vim_findfile(ff_fn_search_context);
  3483.  
  3484.     if (NULL == ret)
  3485.     {
  3486.     vim_findfile_cleanup(ff_fn_search_context);
  3487.     ff_fn_search_context = NULL;
  3488.     }
  3489.     return ret;
  3490. }
  3491. #endif
  3492.  
  3493. /*
  3494.  * Initialization routine for vim_findfile.
  3495.  *
  3496.  * Returns the newly allocated search context or NULL if an error occured.
  3497.  *
  3498.  * Don't forget to clean up by calling vim_findfile_cleanup() if you are done
  3499.  * with the search context.
  3500.  *
  3501.  * Find the file 'filename' in the directory 'path'.
  3502.  * The parameter 'path' may contain wildcards. If so only search 'level'
  3503.  * directories deep. The parameter 'level' is the absolute maximum and is
  3504.  * not related to restricts given to the '**' wildcard. If 'level' is 100
  3505.  * and you use '**200' vim_findfile() will stop after 100 levels.
  3506.  *
  3507.  * If 'stopdirs' is not NULL and nothing is found downward, the search is
  3508.  * restarted on the next higher directory level. This is repeated until the
  3509.  * start-directory of a search is contained in 'stopdirs'. 'stopdirs' has the
  3510.  * format ";*<dirname>*\(;<dirname>\)*;\=$".
  3511.  *
  3512.  * If the 'path' is relative, the starting dir for the search is either VIM's
  3513.  * current dir or if the path starts with "./" the current files dir.
  3514.  * If the 'path' is absolut, the starting dir is that part of the path before
  3515.  * the first wildcard.
  3516.  *
  3517.  * Upward search is only done on the starting dir.
  3518.  *
  3519.  * If 'free_visited' is TRUE the list of already visited files/directories is
  3520.  * cleared. Set this to FALSE if you just want to search from another
  3521.  * directory, but want to be sure that no directory from a previous search is
  3522.  * searched again. This is useful if you search for a file at different places.
  3523.  * The list of visited files/dirs can also be cleared with the function
  3524.  * vim_findfile_free_visited().
  3525.  *
  3526.  * Set the parameter 'need_dir' to TRUE if you want to search for a directory
  3527.  * instead of a file.
  3528.  *
  3529.  * A search context returned by a previous call to vim_findfile_init() can be
  3530.  * passed in the parameter 'search_ctx'. This context is than reused and
  3531.  * reinitialized with the new parameters. The list of already viseted
  3532.  * directories from this context is only deleted if the parameter
  3533.  * 'free_visited' is true. Be aware that the passed search_context is freed if
  3534.  * the reinitialization fails.
  3535.  *
  3536.  * If you don't have a search context from a previous call 'search_ctx' must be
  3537.  * NULL.
  3538.  *
  3539.  * This function silently ignores a few errors, vim_findfile() will have
  3540.  * limited functionality then.
  3541.  */
  3542. /*ARGSUSED*/
  3543.     void *
  3544. vim_findfile_init(path, filename, stopdirs, level, free_visited, need_dir,
  3545.                         search_ctx, tagfile, rel_fname)
  3546.     char_u    *path;
  3547.     char_u    *filename;
  3548.     char_u    *stopdirs;
  3549.     int        level;
  3550.     int        free_visited;
  3551.     int        need_dir;
  3552.     void    *search_ctx;
  3553.     int        tagfile;
  3554.     char_u    *rel_fname;    /* file name to use for "." */
  3555. {
  3556. #ifdef FEAT_PATH_EXTRA
  3557.     char_u    *wc_part;
  3558. #endif
  3559.     ff_stack_T    *sptr;
  3560.  
  3561.     /* If a search context is given by the caller, reuse it, else allocate a
  3562.      * new one.
  3563.      */
  3564.     if (search_ctx != NULL)
  3565.     ff_search_ctx = search_ctx;
  3566.     else
  3567.     {
  3568.     ff_search_ctx = (ff_search_ctx_T*)alloc(
  3569.                        (unsigned)sizeof(ff_search_ctx_T));
  3570.     if (ff_search_ctx == NULL)
  3571.         goto error_return;
  3572.     memset(ff_search_ctx, 0, sizeof(ff_search_ctx_T));
  3573.     }
  3574.  
  3575.     /* clear the search context, but NOT the visited lists */
  3576.     ff_clear();
  3577.  
  3578.     /* clear visited list if wanted */
  3579.     if (free_visited == TRUE)
  3580.     vim_findfile_free_visited(ff_search_ctx);
  3581.     else
  3582.     {
  3583.     /* Reuse old visited lists. Get the visited list for the given
  3584.      * filename. If no list for the current filename exists, creates a new
  3585.      * one.
  3586.      */
  3587.     ff_search_ctx->ffsc_visited_list = ff_get_visited_list(filename,
  3588.                      &ff_search_ctx->ffsc_visited_lists_list);
  3589.     if (ff_search_ctx->ffsc_visited_list == NULL)
  3590.         goto error_return;
  3591.     ff_search_ctx->ffsc_dir_visited_list = ff_get_visited_list(filename,
  3592.                  &ff_search_ctx->ffsc_dir_visited_lists_list);
  3593.     if (ff_search_ctx->ffsc_dir_visited_list == NULL)
  3594.         goto error_return;
  3595.     }
  3596.  
  3597.     if (ff_expand_buffer == NULL)
  3598.     {
  3599.     ff_expand_buffer = (char_u*)alloc(MAXPATHL);
  3600.     if (ff_expand_buffer == NULL)
  3601.         goto error_return;
  3602.     }
  3603.  
  3604.     /* Store information on starting dir now if path is relative.
  3605.      * If path is absolute, we do that later.
  3606.      */
  3607.     if (path[0] == '.'
  3608.         && (vim_ispathsep(path[1]) || path[1] == NUL)
  3609.         && (!tagfile || vim_strchr(p_cpo, CPO_DOTTAG) == NULL)
  3610.         && rel_fname != NULL)
  3611.     {
  3612.     int    len = (int)(gettail(rel_fname) - rel_fname);
  3613.  
  3614.     if (!vim_isAbsName(rel_fname) && len + 1 < MAXPATHL)
  3615.     {
  3616.         /* Make the start dir an absolute path name. */
  3617.         STRNCPY(ff_expand_buffer, rel_fname, len);
  3618.         ff_expand_buffer[len] = NUL;
  3619.         ff_search_ctx->ffsc_start_dir = FullName_save(ff_expand_buffer,
  3620.                                        FALSE);
  3621.     }
  3622.     else
  3623.         ff_search_ctx->ffsc_start_dir = vim_strnsave(rel_fname, len);
  3624.     if (ff_search_ctx->ffsc_start_dir == NULL)
  3625.         goto error_return;
  3626.     if (*++path != NUL)
  3627.         ++path;
  3628.     }
  3629.     else if (*path == NUL || !vim_isAbsName(path))
  3630.     {
  3631. #ifdef BACKSLASH_IN_FILENAME
  3632.     /* "c:dir" needs "c:" to be expanded, otherwise use current dir */
  3633.     if (*path != NUL && path[1] == ':')
  3634.     {
  3635.         char_u  drive[3];
  3636.  
  3637.         drive[0] = path[0];
  3638.         drive[1] = ':';
  3639.         drive[2] = NUL;
  3640.         if (vim_FullName(drive, ff_expand_buffer, MAXPATHL, TRUE) == FAIL)
  3641.         goto error_return;
  3642.         path += 2;
  3643.     }
  3644.     else
  3645. #endif
  3646.     if (mch_dirname(ff_expand_buffer, MAXPATHL) == FAIL)
  3647.         goto error_return;
  3648.  
  3649.     ff_search_ctx->ffsc_start_dir = vim_strsave(ff_expand_buffer);
  3650.     if (ff_search_ctx->ffsc_start_dir == NULL)
  3651.         goto error_return;
  3652.  
  3653. #ifdef BACKSLASH_IN_FILENAME
  3654.     /* A path that starts with "/dir" is relative to the drive, not to the
  3655.      * directory (but not for "//machine/dir").  Only use the drive name. */
  3656.     if ((*path == '/' || *path == '\\')
  3657.         && path[1] != path[0]
  3658.         && ff_search_ctx->ffsc_start_dir[1] == ':')
  3659.         ff_search_ctx->ffsc_start_dir[2] = NUL;
  3660. #endif
  3661.     }
  3662.  
  3663. #ifdef FEAT_PATH_EXTRA
  3664.     /*
  3665.      * If stopdirs are given, split them into an array of pointers.
  3666.      * If this fails (mem allocation), there is no upward search at all or a
  3667.      * stop directory is not recognized -> continue silently.
  3668.      * If stopdirs just contains a ";" or is empty,
  3669.      * ff_search_ctx->ffsc_stopdirs_v will only contain a  NULL pointer. This
  3670.      * is handled as unlimited upward search.  See function
  3671.      * ff_path_in_stoplist() for details.
  3672.      */
  3673.     if (stopdirs != NULL)
  3674.     {
  3675.     char_u    *walker = stopdirs;
  3676.     int    dircount;
  3677.  
  3678.     while (*walker == ';')
  3679.         walker++;
  3680.  
  3681.     dircount = 1;
  3682.     ff_search_ctx->ffsc_stopdirs_v =
  3683.         (char_u **)alloc((unsigned)sizeof(char_u *));
  3684.  
  3685.     if (ff_search_ctx->ffsc_stopdirs_v != NULL)
  3686.     {
  3687.         do
  3688.         {
  3689.         char_u    *helper;
  3690.         void    *ptr;
  3691.  
  3692.         helper = walker;
  3693.         ptr = vim_realloc(ff_search_ctx->ffsc_stopdirs_v,
  3694.                        (dircount + 1) * sizeof(char_u *));
  3695.         if (ptr)
  3696.             ff_search_ctx->ffsc_stopdirs_v = ptr;
  3697.         else
  3698.             /* ignore, keep what we have and continue */
  3699.             break;
  3700.         walker = vim_strchr(walker, ';');
  3701.         if (walker)
  3702.         {
  3703.             ff_search_ctx->ffsc_stopdirs_v[dircount-1] =
  3704.             vim_strnsave(helper, (int)(walker - helper));
  3705.             walker++;
  3706.         }
  3707.         else
  3708.             /* this might be "", which means ascent till top
  3709.              * of directory tree.
  3710.              */
  3711.             ff_search_ctx->ffsc_stopdirs_v[dircount-1] =
  3712.             vim_strsave(helper);
  3713.  
  3714.         dircount++;
  3715.  
  3716.         } while (walker != NULL);
  3717.         ff_search_ctx->ffsc_stopdirs_v[dircount-1] = NULL;
  3718.     }
  3719.     }
  3720. #endif
  3721.  
  3722. #ifdef FEAT_PATH_EXTRA
  3723.     ff_search_ctx->ffsc_level = level;
  3724.  
  3725.     /* split into:
  3726.      *  -fix path
  3727.      *  -wildcard_stuff (might be NULL)
  3728.      */
  3729.     wc_part = vim_strchr(path, '*');
  3730.     if (wc_part != NULL)
  3731.     {
  3732.     int    llevel;
  3733.     int    len;
  3734.     char_u    *errpt;
  3735.  
  3736.     /* save the fix part of the path */
  3737.     ff_search_ctx->ffsc_fix_path = vim_strnsave(path,
  3738.                                (int)(wc_part - path));
  3739.  
  3740.     /*
  3741.      * copy wc_path and add restricts to the '**' wildcard.
  3742.      * The octett after a '**' is used as a (binary) counter.
  3743.      * So '**3' is transposed to '**^C' ('^C' is ASCII value 3)
  3744.      * or '**76' is transposed to '**N'( 'N' is ASCII value 76).
  3745.      * For EBCDIC you get different character values.
  3746.      * If no restrict is given after '**' the default is used.
  3747.      * Due to this technic the path looks awful if you print it as a
  3748.      * string.
  3749.      */
  3750.     len = 0;
  3751.     while (*wc_part != NUL)
  3752.     {
  3753.         if (STRNCMP(wc_part, "**", 2) == 0)
  3754.         {
  3755.         ff_expand_buffer[len++] = *wc_part++;
  3756.         ff_expand_buffer[len++] = *wc_part++;
  3757.  
  3758.         llevel = strtol((char *)wc_part, (char **)&errpt, 10);
  3759.         if (errpt != wc_part && llevel > 0 && llevel < 255)
  3760.             ff_expand_buffer[len++] = llevel;
  3761.         else if (errpt != wc_part && llevel == 0)
  3762.             /* restrict is 0 -> remove already added '**' */
  3763.             len -= 2;
  3764.         else
  3765.             ff_expand_buffer[len++] = FF_MAX_STAR_STAR_EXPAND;
  3766.         wc_part = errpt;
  3767.         if (*wc_part != PATHSEP && *wc_part != NUL)
  3768.         {
  3769.             EMSG2(_("E343: Invalid path: '**[number]' must be at the end of the path or be followed by '%s'."), PATHSEPSTR);
  3770.             goto error_return;
  3771.         }
  3772.         }
  3773.         else
  3774.         ff_expand_buffer[len++] = *wc_part++;
  3775.     }
  3776.     ff_expand_buffer[len] = NUL;
  3777.     ff_search_ctx->ffsc_wc_path =
  3778.         vim_strsave(ff_expand_buffer);
  3779.  
  3780.     if (ff_search_ctx->ffsc_wc_path == NULL)
  3781.         goto error_return;
  3782.     }
  3783.     else
  3784. #endif
  3785.     ff_search_ctx->ffsc_fix_path = vim_strsave(path);
  3786.  
  3787.     if (ff_search_ctx->ffsc_start_dir == NULL)
  3788.     {
  3789.     /* store the fix part as startdir.
  3790.      * This is needed if the parameter path is fully qualified.
  3791.      */
  3792.     ff_search_ctx->ffsc_start_dir = vim_strsave(ff_search_ctx->ffsc_fix_path);
  3793.     if (ff_search_ctx->ffsc_start_dir)
  3794.         ff_search_ctx->ffsc_fix_path[0] = NUL;
  3795.     }
  3796.  
  3797.     /* create an absolute path */
  3798.     STRCPY(ff_expand_buffer, ff_search_ctx->ffsc_start_dir);
  3799.     add_pathsep(ff_expand_buffer);
  3800.     STRCAT(ff_expand_buffer, ff_search_ctx->ffsc_fix_path);
  3801.     add_pathsep(ff_expand_buffer);
  3802.  
  3803.     sptr = ff_create_stack_element(ff_expand_buffer,
  3804. #ifdef FEAT_PATH_EXTRA
  3805.         ff_search_ctx->ffsc_wc_path,
  3806. #endif
  3807.         level, 0);
  3808.  
  3809.     if (sptr == NULL)
  3810.     goto error_return;
  3811.  
  3812.     ff_push(sptr);
  3813.  
  3814.     ff_search_ctx->ffsc_file_to_search = vim_strsave(filename);
  3815.     if (ff_search_ctx->ffsc_file_to_search == NULL)
  3816.     goto error_return;
  3817.  
  3818.     return ff_search_ctx;
  3819.  
  3820. error_return:
  3821.     /*
  3822.      * We clear the search context now!
  3823.      * Even when the caller gave us a (perhaps valid) context we free it here,
  3824.      * as we might have already destroyed it.
  3825.      */
  3826.     vim_findfile_cleanup(ff_search_ctx);
  3827.     return NULL;
  3828. }
  3829.  
  3830. #if defined(FEAT_PATH_EXTRA) || defined(PROTO)
  3831. /*
  3832.  * Get the stopdir string.  Check that ';' is not escaped.
  3833.  */
  3834.     char_u *
  3835. vim_findfile_stopdir(buf)
  3836.     char_u    *buf;
  3837. {
  3838.     char_u    *r_ptr = buf;
  3839.  
  3840.     while (*r_ptr != NUL && *r_ptr != ';')
  3841.     {
  3842.     if (r_ptr[0] == '\\' && r_ptr[1] == ';')
  3843.     {
  3844.         /* overwrite the escape char,
  3845.          * use STRLEN(r_ptr) to move the trailing '\0'
  3846.          */
  3847.         mch_memmove(r_ptr, r_ptr + 1, STRLEN(r_ptr));
  3848.         r_ptr++;
  3849.     }
  3850.     r_ptr++;
  3851.     }
  3852.     if (*r_ptr == ';')
  3853.     {
  3854.     *r_ptr = 0;
  3855.     r_ptr++;
  3856.     }
  3857.     else if (*r_ptr == NUL)
  3858.     r_ptr = NULL;
  3859.     return r_ptr;
  3860. }
  3861. #endif
  3862.  
  3863. /* Clean up the given search context. Can handle a NULL pointer */
  3864.     void
  3865. vim_findfile_cleanup(ctx)
  3866.     void    *ctx;
  3867. {
  3868.     if (NULL == ctx)
  3869.     return;
  3870.  
  3871.     ff_search_ctx = ctx;
  3872.  
  3873.     vim_findfile_free_visited(ctx);
  3874.     ff_clear();
  3875.     vim_free(ctx);
  3876.     ff_search_ctx = NULL;
  3877. }
  3878.  
  3879. /*
  3880.  * Find a file in a search context.
  3881.  * The search context was created with vim_findfile_init() above.
  3882.  * Return a pointer to an allocated file name or NULL if nothing found.
  3883.  * To get all matching files call this function until you get NULL.
  3884.  *
  3885.  * If the passed search_context is NULL, it the returns NULL.
  3886.  *
  3887.  * The search algorithm is depth first. To change this replace the
  3888.  * stack with a list (don't forget to leave partly searched directories on the
  3889.  * top of the list).
  3890.  */
  3891.     char_u *
  3892. vim_findfile(search_ctx)
  3893.     void    *search_ctx;
  3894. {
  3895.     char_u    *file_path;
  3896. #ifdef FEAT_PATH_EXTRA
  3897.     char_u    *rest_of_wildcards;
  3898.     char_u    *path_end = NULL;
  3899. #endif
  3900.     ff_stack_T    *ctx;
  3901. #if defined(FEAT_SEARCHPATH) || defined(FEAT_PATH_EXTRA)
  3902.     int        len;
  3903. #endif
  3904.     int        i;
  3905.     char_u    *p;
  3906. #ifdef FEAT_SEARCHPATH
  3907.     char_u    *suf;
  3908. #endif
  3909.  
  3910.     if (search_ctx == NULL)
  3911.     return NULL;
  3912.  
  3913.     ff_search_ctx = (ff_search_ctx_T*)search_ctx;
  3914.  
  3915.     /*
  3916.      * filepath is used as buffer for various actions and as the storage to
  3917.      * return a found filename.
  3918.      */
  3919.     if ((file_path = alloc((int)MAXPATHL)) == NULL)
  3920.     return NULL;
  3921.  
  3922. #ifdef FEAT_PATH_EXTRA
  3923.     /* store the end of the start dir -- needed for upward search */
  3924.     if (ff_search_ctx->ffsc_start_dir != NULL)
  3925.     path_end = &ff_search_ctx->ffsc_start_dir[STRLEN(ff_search_ctx->ffsc_start_dir)];
  3926. #endif
  3927.  
  3928. #ifdef FEAT_PATH_EXTRA
  3929.     /* upward search loop */
  3930.     for (;;)
  3931.     {
  3932. #endif
  3933.     /* downward search loop */
  3934.     for (;;)
  3935.     {
  3936.         /* check if user user wants to stop the search*/
  3937.         ui_breakcheck();
  3938.         if (got_int)
  3939.         break;
  3940.  
  3941.         /* get directory to work on from stack */
  3942.         ctx = ff_pop();
  3943.         if (ctx == NULL)
  3944.         break;
  3945.  
  3946.         /*
  3947.          * TODO: decide if we leave this test in
  3948.          *
  3949.          * GOOD: don't search a directory(-tree) twice.
  3950.          * BAD:  - check linked list for every new directory entered.
  3951.          *       - check for double files also done below
  3952.          *
  3953.          * Here we check if we already searched this directory.
  3954.          * We already searched a directory if:
  3955.          * 1) The directory is the same.
  3956.          * 2) We would use the same wildcard string.
  3957.          *
  3958.          * Good if you have links on same directory via several ways
  3959.          *  or you have selfreferences in directories (e.g. SuSE Linux 6.3:
  3960.          *  /etc/rc.d/init.d is linked to /etc/rc.d -> endless loop)
  3961.          *
  3962.          * This check is only needed for directories we work on for the
  3963.          * first time (hence ctx->ff_filearray == NULL)
  3964.          */
  3965.         if (ctx->ffs_filearray == NULL
  3966.             && ff_check_visited(&ff_search_ctx->ffsc_dir_visited_list
  3967.                               ->ffvl_visited_list,
  3968.             ctx->ffs_fix_path
  3969. #ifdef FEAT_PATH_EXTRA
  3970.             , ctx->ffs_wc_path
  3971. #endif
  3972.             ) == FAIL)
  3973.         {
  3974. #ifdef FF_VERBOSE
  3975.         if (p_verbose >= 5)
  3976.         {
  3977.             /* always scroll up, don't overwrite */
  3978.             msg_scroll = TRUE;
  3979.             smsg((char_u *)"Already Searched: %s (%s)",
  3980.                        ctx->ffs_fix_path, ctx->ffs_wc_path);
  3981.             /* don't overwrite this either */
  3982.             msg_puts((char_u *)"\n");
  3983.             cmdline_row = msg_row;
  3984.         }
  3985. #endif
  3986.         ff_free_stack_element(ctx);
  3987.         continue;
  3988.         }
  3989. #ifdef FF_VERBOSE
  3990.         else if (p_verbose >= 5)
  3991.         {
  3992.         /* always scroll up, don't overwrite */
  3993.         msg_scroll = TRUE;
  3994.         smsg((char_u *)"Searching: %s (%s)", ctx->ffs_fix_path,
  3995.             ctx->ffs_wc_path);
  3996.         /* don't overwrite this either */
  3997.         msg_puts((char_u *)"\n");
  3998.         cmdline_row = msg_row;
  3999.         }
  4000. #endif
  4001.  
  4002.         /* check depth */
  4003.         if (ctx->ffs_level <= 0)
  4004.         {
  4005.         ff_free_stack_element(ctx);
  4006.         continue;
  4007.         }
  4008.  
  4009.         file_path[0] = NUL;
  4010.  
  4011.         /*
  4012.          * If no filearray till now expand wildcards
  4013.          * The function expand_wildcards() can handle an array of paths
  4014.          * and all possible expands are returned in one array. We use this
  4015.          * to handle the expansion of '**' into an empty string.
  4016.          */
  4017.         if (ctx->ffs_filearray == NULL)
  4018.         {
  4019.         char_u *dirptrs[2];
  4020.  
  4021.         /* we use filepath to build the path expand_wildcards() should
  4022.          * expand.
  4023.          */
  4024.         dirptrs[0] = file_path;
  4025.         dirptrs[1] = NULL;
  4026.  
  4027.         /* if we have a start dir copy it in */
  4028.         if (!vim_isAbsName(ctx->ffs_fix_path)
  4029.             && ff_search_ctx->ffsc_start_dir)
  4030.         {
  4031.             STRCPY(file_path, ff_search_ctx->ffsc_start_dir);
  4032.             add_pathsep(file_path);
  4033.         }
  4034.  
  4035.         /* append the fix part of the search path */
  4036.         STRCAT(file_path, ctx->ffs_fix_path);
  4037.         add_pathsep(file_path);
  4038.  
  4039. #ifdef FEAT_PATH_EXTRA
  4040.         rest_of_wildcards = ctx->ffs_wc_path;
  4041.         if (*rest_of_wildcards != NUL)
  4042.         {
  4043.             len = (int)STRLEN(file_path);
  4044.             if (STRNCMP(rest_of_wildcards, "**", 2) == 0)
  4045.             {
  4046.             /* pointer to the restrict byte
  4047.              * The restrict byte is not a character!
  4048.              */
  4049.             p = rest_of_wildcards + 2;
  4050.  
  4051.             if (*p > 0)
  4052.             {
  4053.                 (*p)--;
  4054.                 file_path[len++] = '*';
  4055.             }
  4056.  
  4057.             if (*p == 0)
  4058.             {
  4059.                 /* remove '**<numb> from wildcards */
  4060.                 mch_memmove(rest_of_wildcards,
  4061.                     rest_of_wildcards + 3,
  4062.                     STRLEN(rest_of_wildcards + 3) + 1);
  4063.             }
  4064.             else
  4065.                 rest_of_wildcards += 3;
  4066.  
  4067.             if (ctx->ffs_star_star_empty == 0)
  4068.             {
  4069.                 /* if not done before, expand '**' to empty */
  4070.                 ctx->ffs_star_star_empty = 1;
  4071.                 dirptrs[1] = ctx->ffs_fix_path;
  4072.             }
  4073.             }
  4074.  
  4075.             /*
  4076.              * Here we copy until the next path separator or the end of
  4077.              * the path. If we stop at a path separator, there is
  4078.              * still somthing else left. This is handled below by
  4079.              * pushing every directory returned from expand_wildcards()
  4080.              * on the stack again for further search.
  4081.              */
  4082.             while (*rest_of_wildcards
  4083.                 && !vim_ispathsep(*rest_of_wildcards))
  4084.             file_path[len++] = *rest_of_wildcards++;
  4085.  
  4086.             file_path[len] = NUL;
  4087.             if (vim_ispathsep(*rest_of_wildcards))
  4088.             rest_of_wildcards++;
  4089.         }
  4090. #endif
  4091.  
  4092.         /*
  4093.          * Expand wildcards like "*" and "$VAR".
  4094.          * If the path is a URL don't try this.
  4095.          */
  4096.         if (path_with_url(dirptrs[0]))
  4097.         {
  4098.             ctx->ffs_filearray = (char_u **)
  4099.                           alloc((unsigned)sizeof(char *));
  4100.             if (ctx->ffs_filearray != NULL
  4101.                 && (ctx->ffs_filearray[0]
  4102.                 = vim_strsave(dirptrs[0])) != NULL)
  4103.             ctx->ffs_filearray_size = 1;
  4104.             else
  4105.             ctx->ffs_filearray_size = 0;
  4106.         }
  4107.         else
  4108.             expand_wildcards((dirptrs[1] == NULL) ? 1 : 2, dirptrs,
  4109.                 &ctx->ffs_filearray_size,
  4110.                 &ctx->ffs_filearray,
  4111.                 EW_DIR|EW_ADDSLASH|EW_SILENT);
  4112.  
  4113.         ctx->ffs_filearray_cur = 0;
  4114.         ctx->ffs_stage = 0;
  4115.         }
  4116. #ifdef FEAT_PATH_EXTRA
  4117.         else
  4118.         rest_of_wildcards = &ctx->ffs_wc_path[STRLEN(ctx->ffs_wc_path)];
  4119. #endif
  4120.  
  4121.         if (ctx->ffs_stage == 0)
  4122.         {
  4123.         /* this is the first time we work on this directory */
  4124. #ifdef FEAT_PATH_EXTRA
  4125.         if (*rest_of_wildcards == NUL)
  4126. #endif
  4127.         {
  4128.             /*
  4129.              * we don't have further wildcards to expand, so we have to
  4130.              * check for the final file now
  4131.              */
  4132.             for (i = ctx->ffs_filearray_cur;
  4133.                          i < ctx->ffs_filearray_size; ++i)
  4134.             {
  4135.             if (!path_with_url(ctx->ffs_filearray[i])
  4136.                      && !mch_isdir(ctx->ffs_filearray[i]))
  4137.                 continue;   /* not a directory */
  4138.  
  4139.             /* prepare the filename to be checked for existance
  4140.              * below */
  4141.             STRCPY(file_path, ctx->ffs_filearray[i]);
  4142.             add_pathsep(file_path);
  4143.             STRCAT(file_path, ff_search_ctx->ffsc_file_to_search);
  4144.  
  4145.             /*
  4146.              * Try without extra suffix and then with suffixes
  4147.              * from 'suffixesadd'.
  4148.              */
  4149. #ifdef FEAT_SEARCHPATH
  4150.             len = (int)STRLEN(file_path);
  4151.             suf = curbuf->b_p_sua;
  4152.             for (;;)
  4153. #endif
  4154.             {
  4155.                 /* if file exists and we didn't already find it */
  4156.                 if ((path_with_url(file_path)
  4157.                     || (mch_getperm(file_path) >= 0
  4158.                         && (!ff_search_ctx->ffsc_need_dir
  4159.                         || mch_isdir(file_path))))
  4160. #ifndef FF_VERBOSE
  4161.                     && (ff_check_visited(
  4162.                         &ff_search_ctx->ffsc_visited_list->ffvl_visited_list,
  4163.                         file_path
  4164. #ifdef FEAT_PATH_EXTRA
  4165.                         , (char_u *)""
  4166. #endif
  4167.                         ) == OK)
  4168. #endif
  4169.                    )
  4170.                 {
  4171. #ifdef FF_VERBOSE
  4172.                 if (ff_check_visited(
  4173.                         &ff_search_ctx->ffsc_visited_list->ffvl_visited_list,
  4174.                         file_path
  4175. #ifdef FEAT_PATH_EXTRA
  4176.                         , (char_u *)""
  4177. #endif
  4178.                             ) == FAIL)
  4179.                 {
  4180.                     if (p_verbose >= 5)
  4181.                     {
  4182.                     /* always scroll up, don't overwrite */
  4183.                     msg_scroll = TRUE;
  4184.                     msg_str((char_u *)"Already: %s",
  4185.                                    file_path);
  4186.                     /* don't overwrite this either */
  4187.                     msg_puts((char_u *)"\n");
  4188.                     cmdline_row = msg_row;
  4189.                     }
  4190.                     continue;
  4191.                 }
  4192. #endif
  4193.  
  4194.                 /* push dir to examine rest of subdirs later */
  4195.                 ctx->ffs_filearray_cur = i + 1;
  4196.                 ff_push(ctx);
  4197.  
  4198.                 simplify_filename(file_path);
  4199.                 if (mch_dirname(ff_expand_buffer, MAXPATHL)
  4200.                                     == OK)
  4201.                 {
  4202.                     p = shorten_fname(file_path,
  4203.                                 ff_expand_buffer);
  4204.                     if (p != NULL)
  4205.                     mch_memmove(file_path, p,
  4206.                                    STRLEN(p) + 1);
  4207.                 }
  4208. #ifdef FF_VERBOSE
  4209.                 if (p_verbose >= 5)
  4210.                 {
  4211.                     /* always scroll up, don't overwrite */
  4212.                     msg_scroll = TRUE;
  4213.                     msg_str((char_u *)"HIT: %s", file_path);
  4214.                     /* don't overwrite this either */
  4215.                     msg_puts((char_u *)"\n");
  4216.                     cmdline_row = msg_row;
  4217.                 }
  4218. #endif
  4219.                 return file_path;
  4220.                 }
  4221.  
  4222. #ifdef FEAT_SEARCHPATH
  4223.                 /* Not found or found already, try next suffix. */
  4224.                 if (*suf == NUL)
  4225.                 break;
  4226.                 copy_option_part(&suf, file_path + len,
  4227.                              MAXPATHL - len, ",");
  4228. #endif
  4229.             }
  4230.             }
  4231.         }
  4232. #ifdef FEAT_PATH_EXTRA
  4233.         else
  4234.         {
  4235.             /*
  4236.              * still wildcards left, push the directories for further
  4237.              * search
  4238.              */
  4239.             for (i = ctx->ffs_filearray_cur; i < ctx->ffs_filearray_size;
  4240.                                       ++i)
  4241.             {
  4242.             if (!mch_isdir(ctx->ffs_filearray[i]))
  4243.                 continue;    /* not a directory */
  4244.  
  4245.             ff_push(ff_create_stack_element(ctx->ffs_filearray[i],
  4246.                       rest_of_wildcards, ctx->ffs_level - 1, 0));
  4247.             }
  4248.         }
  4249. #endif
  4250.         ctx->ffs_filearray_cur = 0;
  4251.         ctx->ffs_stage = 1;
  4252.         }
  4253.  
  4254. #ifdef FEAT_PATH_EXTRA
  4255.         /*
  4256.          * if wildcards contains '**' we have to descent till we reach the
  4257.          * leaves of the directory tree.
  4258.          */
  4259.         if (STRNCMP(ctx->ffs_wc_path, "**", 2) == 0)
  4260.         {
  4261.         for (i = ctx->ffs_filearray_cur; i < ctx->ffs_filearray_size; ++i)
  4262.         {
  4263.             if (fnamecmp(ctx->ffs_filearray[i], ctx->ffs_fix_path) == 0)
  4264.             continue; /* don't repush same directory */
  4265.             if (!mch_isdir(ctx->ffs_filearray[i]))
  4266.             continue;   /* not a directory */
  4267.             ff_push(ff_create_stack_element(ctx->ffs_filearray[i],
  4268.                 ctx->ffs_wc_path, ctx->ffs_level - 1, 1));
  4269.         }
  4270.         }
  4271. #endif
  4272.  
  4273.         /* we are done with the current directory */
  4274.         ff_free_stack_element(ctx);
  4275.  
  4276.     }
  4277.  
  4278. #ifdef FEAT_PATH_EXTRA
  4279.     /* If we reached this, we didn't find anything downwards.
  4280.      * Let's check if we should do an upward search.
  4281.      */
  4282.     if (ff_search_ctx->ffsc_start_dir
  4283.         && ff_search_ctx->ffsc_stopdirs_v != NULL && !got_int)
  4284.     {
  4285.         ff_stack_T  *sptr;
  4286.  
  4287.         /* is the last starting directory in the stop list? */
  4288.         if (ff_path_in_stoplist(ff_search_ctx->ffsc_start_dir,
  4289.                (int)(path_end - ff_search_ctx->ffsc_start_dir),
  4290.                ff_search_ctx->ffsc_stopdirs_v) == TRUE)
  4291.         break;
  4292.  
  4293.         /* cut of last dir */
  4294.         while (path_end > ff_search_ctx->ffsc_start_dir
  4295.             && *path_end == PATHSEP)
  4296.         path_end--;
  4297.         while (path_end > ff_search_ctx->ffsc_start_dir
  4298.             && *(path_end-1) != PATHSEP)
  4299.         path_end--;
  4300.         *path_end = 0;
  4301.         path_end--;
  4302.  
  4303.         if (*ff_search_ctx->ffsc_start_dir == 0)
  4304.         break;
  4305.  
  4306.         STRCPY(file_path, ff_search_ctx->ffsc_start_dir);
  4307.         add_pathsep(file_path);
  4308.         STRCAT(file_path, ff_search_ctx->ffsc_fix_path);
  4309.  
  4310.         /* create a new stack entry */
  4311.         sptr = ff_create_stack_element(file_path,
  4312.             ff_search_ctx->ffsc_wc_path, ff_search_ctx->ffsc_level, 0);
  4313.         if (sptr == NULL)
  4314.         break;
  4315.         ff_push(sptr);
  4316.     }
  4317.     else
  4318.         break;
  4319.     }
  4320. #endif
  4321.  
  4322.     vim_free(file_path);
  4323.     return NULL;
  4324. }
  4325.  
  4326. /*
  4327.  * Free the list of lists of visited files and directories
  4328.  * Can handle it if the passed search_context is NULL;
  4329.  */
  4330.     void
  4331. vim_findfile_free_visited(search_ctx)
  4332.     void    *search_ctx;
  4333. {
  4334.     if (search_ctx == NULL)
  4335.     return;
  4336.  
  4337.     ff_search_ctx = (ff_search_ctx_T *)search_ctx;
  4338.  
  4339.     vim_findfile_free_visited_list(&ff_search_ctx->ffsc_visited_lists_list);
  4340.     vim_findfile_free_visited_list(&ff_search_ctx->ffsc_dir_visited_lists_list);
  4341. }
  4342.  
  4343.     static void
  4344. vim_findfile_free_visited_list(list_headp)
  4345.     ff_visited_list_hdr_T    **list_headp;
  4346. {
  4347.     ff_visited_list_hdr_T *vp;
  4348.  
  4349.     while (*list_headp != NULL)
  4350.     {
  4351.     vp = (*list_headp)->ffvl_next;
  4352.     ff_free_visited_list((*list_headp)->ffvl_visited_list);
  4353.  
  4354.     vim_free((*list_headp)->ffvl_filename);
  4355.     vim_free(*list_headp);
  4356.     *list_headp = vp;
  4357.     }
  4358.     *list_headp = NULL;
  4359. }
  4360.  
  4361.     static void
  4362. ff_free_visited_list(vl)
  4363.     ff_visited_T *vl;
  4364. {
  4365.     ff_visited_T *vp;
  4366.  
  4367.     while (vl != NULL)
  4368.     {
  4369.     vp = vl->ffv_next;
  4370.     vim_free(vl);
  4371.     vl = vp;
  4372.     }
  4373.     vl = NULL;
  4374. }
  4375.  
  4376. /*
  4377.  * Returns the already visited list for the given filename. If none is found it
  4378.  * allocates a new one.
  4379.  */
  4380.     static ff_visited_list_hdr_T*
  4381. ff_get_visited_list(filename, list_headp)
  4382.     char_u            *filename;
  4383.     ff_visited_list_hdr_T    **list_headp;
  4384. {
  4385.     ff_visited_list_hdr_T  *retptr = NULL;
  4386.  
  4387.     /* check if a visited list for the given filename exists */
  4388.     if (*list_headp != NULL)
  4389.     {
  4390.     retptr = *list_headp;
  4391.     while (retptr != NULL)
  4392.     {
  4393.         if (fnamecmp(filename, retptr->ffvl_filename) == 0)
  4394.         {
  4395. #ifdef FF_VERBOSE
  4396.         if (p_verbose >= 5)
  4397.         {
  4398.             /* always scroll up, don't overwrite */
  4399.             msg_scroll = TRUE;
  4400.             msg_str((char_u *)"ff_get_visited_list: FOUND list for %s",
  4401.                                     filename);
  4402.             /* don't overwrite this either */
  4403.             msg_puts((char_u *)"\n");
  4404.             cmdline_row = msg_row;
  4405.         }
  4406. #endif
  4407.         return retptr;
  4408.         }
  4409.         retptr = retptr->ffvl_next;
  4410.     }
  4411.     }
  4412.  
  4413. #ifdef FF_VERBOSE
  4414.     if (p_verbose >= 5)
  4415.     {
  4416.     /* always scroll up, don't overwrite */
  4417.     msg_scroll = TRUE;
  4418.     msg_str((char_u *)"ff_get_visited_list: new list for %s", filename);
  4419.     /* don't overwrite this either */
  4420.     msg_puts((char_u *)"\n");
  4421.     cmdline_row = msg_row;
  4422.     }
  4423. #endif
  4424.  
  4425.     /*
  4426.      * if we reach this we didn't find a list and we have to allocate new list
  4427.      */
  4428.     retptr = (ff_visited_list_hdr_T*)alloc((unsigned)sizeof(*retptr));
  4429.     if (retptr == NULL)
  4430.     return NULL;
  4431.  
  4432.     retptr->ffvl_visited_list = NULL;
  4433.     retptr->ffvl_filename = vim_strsave(filename);
  4434.     if (retptr->ffvl_filename == NULL)
  4435.     {
  4436.     vim_free(retptr);
  4437.     return NULL;
  4438.     }
  4439.     retptr->ffvl_next = *list_headp;
  4440.     *list_headp = retptr;
  4441.  
  4442.     return retptr;
  4443. }
  4444.  
  4445. #ifdef FEAT_PATH_EXTRA
  4446. /*
  4447.  * check if two wildcard paths are equal. Returns TRUE or FALSE.
  4448.  * They are equal if:
  4449.  *  - both paths are NULL
  4450.  *  - they have the same length
  4451.  *  - char by char comparison is OK
  4452.  *  - the only differences are in the counters behind a '**', so
  4453.  *    '**\20' is equal to '**\24'
  4454.  */
  4455.     static int
  4456. ff_wc_equal(s1, s2)
  4457.     char_u    *s1;
  4458.     char_u    *s2;
  4459. {
  4460.     int        i;
  4461.  
  4462.     if (s1 == s2)
  4463.     return TRUE;
  4464.  
  4465.     if (s1 == NULL || s2 == NULL)
  4466.     return FALSE;
  4467.  
  4468.     if (STRLEN(s1) != STRLEN(s2))
  4469.     return FAIL;
  4470.  
  4471.     for (i = 0; s1[i] != NUL && s2[i] != NUL; i++)
  4472.     {
  4473.     if (s1[i] != s2[i]
  4474. #ifdef CASE_INSENSITIVE_FILENAME
  4475.         && TOUPPER_LOC(s1[i]) != TOUPPER_LOC(s2[i])
  4476. #endif
  4477.         )
  4478.     {
  4479.         if (i >= 2)
  4480.         if (s1[i-1] == '*' && s1[i-2] == '*')
  4481.             continue;
  4482.         else
  4483.             return FAIL;
  4484.         else
  4485.         return FAIL;
  4486.     }
  4487.     }
  4488.     return TRUE;
  4489. }
  4490. #endif
  4491.  
  4492. /*
  4493.  * maintains the list of already visited files and dirs
  4494.  * returns FAIL if the given file/dir is already in the list
  4495.  * returns OK if it is newly added
  4496.  *
  4497.  * TODO: What to do on memory allocation problems?
  4498.  *     -> return TRUE - Better the file is found several times instead of
  4499.  *        never.
  4500.  */
  4501.     static int
  4502. ff_check_visited(visited_list, fname
  4503. #ifdef FEAT_PATH_EXTRA
  4504.     , wc_path
  4505. #endif
  4506.     )
  4507.     ff_visited_T    **visited_list;
  4508.     char_u        *fname;
  4509. #ifdef FEAT_PATH_EXTRA
  4510.     char_u        *wc_path;
  4511. #endif
  4512. {
  4513.     ff_visited_T    *vp;
  4514. #ifdef UNIX
  4515.     struct stat        st;
  4516.     int            url = FALSE;
  4517. #endif
  4518.  
  4519.     /* For an URL we only compare the name, otherwise we compare the
  4520.      * device/inode (unix) or the full path name (not Unix). */
  4521.     if (path_with_url(fname))
  4522.     {
  4523.     STRNCPY(ff_expand_buffer, fname, MAXPATHL);
  4524. #ifdef UNIX
  4525.     url = TRUE;
  4526. #endif
  4527.     }
  4528.     else
  4529.     {
  4530.     ff_expand_buffer[0] = NUL;
  4531. #ifdef UNIX
  4532.     if (mch_stat((char *)fname, &st) < 0)
  4533. #else
  4534.     if (vim_FullName(fname, ff_expand_buffer, MAXPATHL, TRUE) == FAIL)
  4535. #endif
  4536.         return FAIL;
  4537.     }
  4538.  
  4539.     /* check against list of already visited files */
  4540.     for (vp = *visited_list; vp != NULL; vp = vp->ffv_next)
  4541.     {
  4542.     if (
  4543. #ifdef UNIX
  4544.         !url
  4545.             ? (vp->ffv_dev == st.st_dev
  4546.             && vp->ffv_ino == st.st_ino)
  4547.             :
  4548. #endif
  4549.         fnamecmp(vp->ffv_fname, ff_expand_buffer) == 0
  4550.        )
  4551.     {
  4552. #ifdef FEAT_PATH_EXTRA
  4553.         /* are the wildcard parts equal */
  4554.         if (ff_wc_equal(vp->ffv_wc_path, wc_path) == TRUE)
  4555. #endif
  4556.         /* already visited */
  4557.         return FAIL;
  4558.     }
  4559.     }
  4560.  
  4561.     /*
  4562.      * New file/dir.  Add it to the list of visited files/dirs.
  4563.      */
  4564.     vp = (ff_visited_T *)alloc((unsigned)(sizeof(ff_visited_T)
  4565.                          + STRLEN(ff_expand_buffer)));
  4566.  
  4567.     if (vp != NULL)
  4568.     {
  4569. #ifdef UNIX
  4570.     if (!url)
  4571.     {
  4572.         vp->ffv_ino = st.st_ino;
  4573.         vp->ffv_dev = st.st_dev;
  4574.         vp->ffv_fname[0] = NUL;
  4575.     }
  4576.     else
  4577.     {
  4578.         vp->ffv_ino = 0;
  4579.         vp->ffv_dev = -1;
  4580. #endif
  4581.         STRCPY(vp->ffv_fname, ff_expand_buffer);
  4582. #ifdef UNIX
  4583.     }
  4584. #endif
  4585. #ifdef FEAT_PATH_EXTRA
  4586.     if (wc_path != NULL)
  4587.         vp->ffv_wc_path = vim_strsave(wc_path);
  4588.     else
  4589.         vp->ffv_wc_path = NULL;
  4590. #endif
  4591.  
  4592.     vp->ffv_next = *visited_list;
  4593.     *visited_list = vp;
  4594.     }
  4595.  
  4596.     return OK;
  4597. }
  4598.  
  4599. /*
  4600.  * create stack element from given path pieces
  4601.  */
  4602.     static ff_stack_T *
  4603. ff_create_stack_element(fix_part,
  4604. #ifdef FEAT_PATH_EXTRA
  4605.     wc_part,
  4606. #endif
  4607.     level, star_star_empty)
  4608.     char_u    *fix_part;
  4609. #ifdef FEAT_PATH_EXTRA
  4610.     char_u    *wc_part;
  4611. #endif
  4612.     int        level;
  4613.     int        star_star_empty;
  4614. {
  4615.     ff_stack_T    *new;
  4616.  
  4617.     new = (ff_stack_T *)alloc((unsigned)sizeof(ff_stack_T));
  4618.     if (new == NULL)
  4619.     return NULL;
  4620.  
  4621.     new->ffs_prev       = NULL;
  4622.     new->ffs_filearray       = NULL;
  4623.     new->ffs_filearray_size = 0;
  4624.     new->ffs_filearray_cur  = 0;
  4625.     new->ffs_stage       = 0;
  4626.     new->ffs_level       = level;
  4627.     new->ffs_star_star_empty = star_star_empty;;
  4628.  
  4629.     /* the following saves NULL pointer checks in vim_findfile */
  4630.     if (fix_part == NULL)
  4631.     fix_part = (char_u *)"";
  4632.     new->ffs_fix_path = vim_strsave(fix_part);
  4633.  
  4634. #ifdef FEAT_PATH_EXTRA
  4635.     if (wc_part == NULL)
  4636.     wc_part  = (char_u *)"";
  4637.     new->ffs_wc_path = vim_strsave(wc_part);
  4638. #endif
  4639.  
  4640.     if (new->ffs_fix_path == NULL
  4641. #ifdef FEAT_PATH_EXTRA
  4642.         || new->ffs_wc_path == NULL
  4643. #endif
  4644.         )
  4645.     {
  4646.     ff_free_stack_element(new);
  4647.     new = NULL;
  4648.     }
  4649.  
  4650.     return new;
  4651. }
  4652.  
  4653. /*
  4654.  * push a dir on the directory stack
  4655.  */
  4656.     static void
  4657. ff_push(ctx)
  4658.     ff_stack_T *ctx;
  4659. {
  4660.     /* check for NULL pointer, not to return an error to the user, but
  4661.      * to prevent a crash
  4662.      */
  4663.     if (ctx != NULL)
  4664.     {
  4665.     ctx->ffs_prev   = ff_search_ctx->ffsc_stack_ptr;
  4666.     ff_search_ctx->ffsc_stack_ptr = ctx;
  4667.     }
  4668. }
  4669.  
  4670. /*
  4671.  * pop a dir from the directory stack
  4672.  * returns NULL if stack is empty
  4673.  */
  4674.     static ff_stack_T *
  4675. ff_pop()
  4676. {
  4677.     ff_stack_T  *sptr;
  4678.  
  4679.     sptr = ff_search_ctx->ffsc_stack_ptr;
  4680.     if (ff_search_ctx->ffsc_stack_ptr != NULL)
  4681.     ff_search_ctx->ffsc_stack_ptr = ff_search_ctx->ffsc_stack_ptr->ffs_prev;
  4682.  
  4683.     return sptr;
  4684. }
  4685.  
  4686. /*
  4687.  * free the given stack element
  4688.  */
  4689.     static void
  4690. ff_free_stack_element(ctx)
  4691.     ff_stack_T  *ctx;
  4692. {
  4693.     /* vim_free handles possible NULL pointers */
  4694.     vim_free(ctx->ffs_fix_path);
  4695. #ifdef FEAT_PATH_EXTRA
  4696.     vim_free(ctx->ffs_wc_path);
  4697. #endif
  4698.  
  4699.     if (ctx->ffs_filearray != NULL)
  4700.     FreeWild(ctx->ffs_filearray_size, ctx->ffs_filearray);
  4701.  
  4702.     vim_free(ctx);
  4703. }
  4704.  
  4705. /*
  4706.  * clear the search context
  4707.  */
  4708.     static void
  4709. ff_clear()
  4710. {
  4711.     ff_stack_T   *sptr;
  4712.  
  4713.     /* clear up stack */
  4714.     while ((sptr = ff_pop()) != NULL)
  4715.     ff_free_stack_element(sptr);
  4716.  
  4717.     vim_free(ff_search_ctx->ffsc_file_to_search);
  4718.     vim_free(ff_search_ctx->ffsc_start_dir);
  4719.     vim_free(ff_search_ctx->ffsc_fix_path);
  4720. #ifdef FEAT_PATH_EXTRA
  4721.     vim_free(ff_search_ctx->ffsc_wc_path);
  4722. #endif
  4723.  
  4724. #ifdef FEAT_PATH_EXTRA
  4725.     if (ff_search_ctx->ffsc_stopdirs_v != NULL)
  4726.     {
  4727.     int  i = 0;
  4728.  
  4729.     while (ff_search_ctx->ffsc_stopdirs_v[i] != NULL)
  4730.     {
  4731.         vim_free(ff_search_ctx->ffsc_stopdirs_v[i]);
  4732.         i++;
  4733.     }
  4734.     vim_free(ff_search_ctx->ffsc_stopdirs_v);
  4735.     }
  4736.     ff_search_ctx->ffsc_stopdirs_v = NULL;
  4737. #endif
  4738.  
  4739.     /* reset everything */
  4740.     ff_search_ctx->ffsc_file_to_search    = NULL;
  4741.     ff_search_ctx->ffsc_start_dir    = NULL;
  4742.     ff_search_ctx->ffsc_fix_path    = NULL;
  4743. #ifdef FEAT_PATH_EXTRA
  4744.     ff_search_ctx->ffsc_wc_path        = NULL;
  4745.     ff_search_ctx->ffsc_level        = 0;
  4746. #endif
  4747. }
  4748.  
  4749. #ifdef FEAT_PATH_EXTRA
  4750. /*
  4751.  * check if the given path is in the stopdirs
  4752.  * returns TRUE if yes else FALSE
  4753.  */
  4754.     static int
  4755. ff_path_in_stoplist(path, path_len, stopdirs_v)
  4756.     char_u    *path;
  4757.     int        path_len;
  4758.     char_u    **stopdirs_v;
  4759. {
  4760.     int        i = 0;
  4761.  
  4762.     /* eat up trailing path separators, except the first */
  4763.     while (path_len > 1 && path[path_len - 1] == PATHSEP)
  4764.     path_len--;
  4765.  
  4766.     /* if no path consider it as match */
  4767.     if (path_len == 0)
  4768.     return TRUE;
  4769.  
  4770.     for (i = 0; stopdirs_v[i] != NULL; i++)
  4771.     {
  4772.     if ((int)STRLEN(stopdirs_v[i]) > path_len)
  4773.     {
  4774.         /* match for parent directory. So '/home' also matches
  4775.          * '/home/rks'. Check for PATHSEP in stopdirs_v[i], else
  4776.          * '/home/r' would also match '/home/rks'
  4777.          */
  4778.         if (fnamencmp(stopdirs_v[i], path, path_len) == 0
  4779.             && stopdirs_v[i][path_len] == PATHSEP)
  4780.         return TRUE;
  4781.     }
  4782.     else
  4783.     {
  4784.         if (fnamecmp(stopdirs_v[i], path) == 0)
  4785.         return TRUE;
  4786.     }
  4787.     }
  4788.     return FALSE;
  4789. }
  4790. #endif
  4791.  
  4792. #if defined(FEAT_SEARCHPATH) || defined(PROTO)
  4793. /*
  4794.  * Find the file name "ptr[len]" in the path.
  4795.  *
  4796.  * On the first call set the parameter 'first' to TRUE to initialize
  4797.  * the search.  For repeating calls to FALSE.
  4798.  *
  4799.  * Repeating calls will return other files called 'ptr[len]' from the path.
  4800.  *
  4801.  * Only on the first call 'ptr' and 'len' are used.  For repeating calls they
  4802.  * don't need valid values.
  4803.  *
  4804.  * If nothing found on the first call the option FNAME_MESS will issue the
  4805.  * message:
  4806.  *        'Can't find file "<file>" in path'
  4807.  * On repeating calls:
  4808.  *        'No more file "<file>" found in path'
  4809.  *
  4810.  * options:
  4811.  * FNAME_MESS        give error message when not found
  4812.  *
  4813.  * Uses NameBuff[]!
  4814.  *
  4815.  * Returns an allocated string for the file name.  NULL for error.
  4816.  *
  4817.  */
  4818.     char_u *
  4819. find_file_in_path(ptr, len, options, first, rel_fname)
  4820.     char_u    *ptr;        /* file name */
  4821.     int        len;        /* length of file name */
  4822.     int        options;
  4823.     int        first;        /* use count'th matching file name */
  4824.     char_u    *rel_fname;    /* file name searching relative to */
  4825. {
  4826.     return find_file_in_path_option(ptr, len, options, first,
  4827.         *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path,
  4828.         FALSE, rel_fname);
  4829. }
  4830.  
  4831. /*
  4832.  * Find the directory name "ptr[len]" in the path.
  4833.  *
  4834.  * options:
  4835.  * FNAME_MESS        give error message when not found
  4836.  *
  4837.  * Uses NameBuff[]!
  4838.  *
  4839.  * Returns an allocated string for the file name.  NULL for error.
  4840.  */
  4841.     char_u *
  4842. find_directory_in_path(ptr, len, options, rel_fname)
  4843.     char_u    *ptr;        /* file name */
  4844.     int        len;        /* length of file name */
  4845.     int        options;
  4846.     char_u    *rel_fname;    /* file name searching relative to */
  4847. {
  4848.     return find_file_in_path_option(ptr, len, options, TRUE, p_cdpath,
  4849.                                  TRUE, rel_fname);
  4850. }
  4851.  
  4852.     static char_u *
  4853. find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fname)
  4854.     char_u    *ptr;        /* file name */
  4855.     int        len;        /* length of file name */
  4856.     int        options;
  4857.     int        first;        /* use count'th matching file name */
  4858.     char_u    *path_option;    /* p_path or p_cdpath */
  4859.     int        need_dir;    /* looking for directory name */
  4860.     char_u    *rel_fname;    /* file name we are looking relative to. */
  4861. {
  4862.     static void        *search_ctx = NULL;
  4863.     static char_u    *dir;
  4864.     static char_u    *file_to_find = NULL;
  4865.     static int        did_findfile_init = FALSE;
  4866.     char_u        save_char;
  4867.     char_u        *file_name = NULL;
  4868.     char_u        *buf = NULL;
  4869.     int            rel_to_curdir;
  4870. #ifdef AMIGA
  4871.     struct Process    *proc = (struct Process *)FindTask(0L);
  4872.     APTR        save_winptr = proc->pr_WindowPtr;
  4873.  
  4874.     /* Avoid a requester here for a volume that doesn't exist. */
  4875.     proc->pr_WindowPtr = (APTR)-1L;
  4876. #endif
  4877.  
  4878.     if (first == TRUE)
  4879.     {
  4880.     /* copy file name into NameBuff, expanding environment variables */
  4881.     save_char = ptr[len];
  4882.     ptr[len] = NUL;
  4883.     expand_env(ptr, NameBuff, MAXPATHL);
  4884.     ptr[len] = save_char;
  4885.  
  4886.     vim_free(file_to_find);
  4887.     file_to_find = vim_strsave(NameBuff);
  4888.     if (file_to_find == NULL)    /* out of memory */
  4889.     {
  4890.         file_name = NULL;
  4891.         goto theend;
  4892.     }
  4893.     }
  4894.  
  4895.     rel_to_curdir = (file_to_find[0] == '.'
  4896.             && (file_to_find[1] == NUL
  4897.             || vim_ispathsep(file_to_find[1])
  4898.             || (file_to_find[1] == '.'
  4899.                 && (file_to_find[2] == NUL
  4900.                 || vim_ispathsep(file_to_find[2])))));
  4901.     if (vim_isAbsName(file_to_find)
  4902.         /* "..", "../path", "." and "./path": don't use the path_option */
  4903.         || rel_to_curdir
  4904. #if defined(MSWIN) || defined(MSDOS) || defined(OS2)
  4905.         /* handle "\tmp" as absolute path */
  4906.         || vim_ispathsep(file_to_find[0])
  4907.         /* handle "c:name" as absulute path */
  4908.         || (file_to_find[0] != NUL && file_to_find[1] == ':')
  4909. #endif
  4910. #ifdef AMIGA
  4911.         /* handle ":tmp" as absolute path */
  4912.         || file_to_find[0] == ':'
  4913. #endif
  4914.        )
  4915.     {
  4916.     /*
  4917.      * Absolute path, no need to use "path_option".
  4918.      * If this is not a first call, return NULL.  We already returned a
  4919.      * filename on the first call.
  4920.      */
  4921.     if (first == TRUE)
  4922.     {
  4923.         int        l;
  4924.         int        run;
  4925.  
  4926.         if (path_with_url(file_to_find))
  4927.         {
  4928.         file_name = vim_strsave(file_to_find);
  4929.         goto theend;
  4930.         }
  4931.  
  4932.         /* When FNAME_REL flag given first use the directory of the file.
  4933.          * Otherwise or when this fails use the current directory. */
  4934.         for (run = 1; run <= 2; ++run)
  4935.         {
  4936.         l = (int)STRLEN(file_to_find);
  4937.         if (run == 1
  4938.             && rel_to_curdir
  4939.             && (options & FNAME_REL)
  4940.             && rel_fname != NULL
  4941.             && STRLEN(rel_fname) + l < MAXPATHL)
  4942.         {
  4943.             STRCPY(NameBuff, rel_fname);
  4944.             STRCPY(gettail(NameBuff), file_to_find);
  4945.             l = (int)STRLEN(NameBuff);
  4946.         }
  4947.         else
  4948.         {
  4949.             STRCPY(NameBuff, file_to_find);
  4950.             run = 2;
  4951.         }
  4952.  
  4953.         /* When the file doesn't exist, try adding parts of
  4954.          * 'suffixesadd'. */
  4955.         buf = curbuf->b_p_sua;
  4956.         for (;;)
  4957.         {
  4958.             if (
  4959. #ifdef DJGPP
  4960.                 /* "C:" by itself will fail for mch_getperm(),
  4961.                  * assume it's always valid. */
  4962.                 (need_dir && NameBuff[0] != NUL
  4963.                   && NameBuff[1] == ':'
  4964.                   && NameBuff[2] == NUL) ||
  4965. #endif
  4966.                 (mch_getperm(NameBuff) >= 0
  4967.                        && (!need_dir || mch_isdir(NameBuff))))
  4968.             {
  4969.             file_name = vim_strsave(NameBuff);
  4970.             goto theend;
  4971.             }
  4972.             if (*buf == NUL)
  4973.             break;
  4974.             copy_option_part(&buf, NameBuff + l, MAXPATHL - l, ",");
  4975.         }
  4976.         }
  4977.     }
  4978.     }
  4979.     else
  4980.     {
  4981.     /*
  4982.      * Loop over all paths in the 'path' or 'cdpath' option.
  4983.      * When "first" is set, first setup to the start of the option.
  4984.      * Otherwise continue to find the next match.
  4985.      */
  4986.     if (first == TRUE)
  4987.     {
  4988.         /* vim_findfile_free_visited can handle a possible NULL pointer */
  4989.         vim_findfile_free_visited(search_ctx);
  4990.         dir = path_option;
  4991.         did_findfile_init = FALSE;
  4992.     }
  4993.  
  4994.     for (;;)
  4995.     {
  4996.         if (did_findfile_init)
  4997.         {
  4998.         ff_search_ctx->ffsc_need_dir = need_dir;
  4999.         file_name = vim_findfile(search_ctx);
  5000.         ff_search_ctx->ffsc_need_dir = FALSE;
  5001.         if (file_name != NULL)
  5002.             break;
  5003.  
  5004.         did_findfile_init = FALSE;
  5005.         }
  5006.         else
  5007.         {
  5008.         char_u  *r_ptr;
  5009.  
  5010.         if (dir == NULL || *dir == NUL)
  5011.         {
  5012.             /* We searched all paths of the option, now we can
  5013.              * free the search context. */
  5014.             vim_findfile_cleanup(search_ctx);
  5015.             search_ctx = NULL;
  5016.             break;
  5017.         }
  5018.  
  5019.         if ((buf = alloc((int)(MAXPATHL))) == NULL)
  5020.             break;
  5021.  
  5022.         /* copy next path */
  5023.         buf[0] = 0;
  5024.         copy_option_part(&dir, buf, MAXPATHL, " ,");
  5025.  
  5026. #ifdef FEAT_PATH_EXTRA
  5027.         /* get the stopdir string */
  5028.         r_ptr = vim_findfile_stopdir(buf);
  5029. #else
  5030.         r_ptr = NULL;
  5031. #endif
  5032.         search_ctx = vim_findfile_init(buf, file_to_find, r_ptr, 100,
  5033.                    FALSE, TRUE, search_ctx, FALSE, rel_fname);
  5034.         if (search_ctx != NULL)
  5035.             did_findfile_init = TRUE;
  5036.         vim_free(buf);
  5037.         }
  5038.     }
  5039.     }
  5040.     if (file_name == NULL && (options & FNAME_MESS))
  5041.     {
  5042.     if (first == TRUE)
  5043.     {
  5044.         if (need_dir)
  5045.         EMSG2(_("E344: Can't find directory \"%s\" in cdpath"),
  5046.             file_to_find);
  5047.         else
  5048.         EMSG2(_("E345: Can't find file \"%s\" in path"),
  5049.             file_to_find);
  5050.     }
  5051.     else
  5052.     {
  5053.         if (need_dir)
  5054.         EMSG2(_("E346: No more directory \"%s\" found in cdpath"),
  5055.             file_to_find);
  5056.         else
  5057.         EMSG2(_("E347: No more file \"%s\" found in path"),
  5058.             file_to_find);
  5059.     }
  5060.     }
  5061.  
  5062. theend:
  5063. #ifdef AMIGA
  5064.     proc->pr_WindowPtr = save_winptr;
  5065. #endif
  5066.     return file_name;
  5067. }
  5068.  
  5069. #endif /* FEAT_SEARCHPATH */
  5070.  
  5071. /*
  5072.  * Change directory to "new_dir".  If FEAT_SEARCHPATH is defined, search
  5073.  * 'cdpath' for relative directory names, otherwise just mch_chdir().
  5074.  */
  5075.     int
  5076. vim_chdir(new_dir)
  5077.     char_u    *new_dir;
  5078. {
  5079. #ifndef FEAT_SEARCHPATH
  5080.     return mch_chdir((char *)new_dir);
  5081. #else
  5082.     char_u    *dir_name;
  5083.     int        r;
  5084.  
  5085.     dir_name = find_directory_in_path(new_dir, (int)STRLEN(new_dir),
  5086.                         FNAME_MESS, curbuf->b_ffname);
  5087.     if (dir_name == NULL)
  5088.     return -1;
  5089.     r = mch_chdir((char *)dir_name);
  5090.     vim_free(dir_name);
  5091.     return r;
  5092. #endif
  5093. }
  5094.  
  5095. /*
  5096.  * Get user name from machine-specific function and cache it.
  5097.  * Returns the user name in "buf[len]".
  5098.  * Some systems are quite slow in obtaining the user name (Windows NT).
  5099.  * Returns OK or FAIL.
  5100.  */
  5101.     int
  5102. get_user_name(buf, len)
  5103.     char_u    *buf;
  5104.     int        len;
  5105. {
  5106.     static char_u    *name = NULL;
  5107.  
  5108.     if (name == NULL)
  5109.     {
  5110.     if (mch_get_user_name(buf, len) == FAIL)
  5111.         return FAIL;
  5112.     name = vim_strsave(buf);
  5113.     }
  5114.     else
  5115.     STRNCPY(buf, name, len);
  5116.     return OK;
  5117. }
  5118.  
  5119. #ifndef HAVE_QSORT
  5120. /*
  5121.  * Our own qsort(), for systems that don't have it.
  5122.  * It's simple and slow.  From the K&R C book.
  5123.  */
  5124.     void
  5125. qsort(base, elm_count, elm_size, cmp)
  5126.     void    *base;
  5127.     size_t    elm_count;
  5128.     size_t    elm_size;
  5129.     int (*cmp) __ARGS((const void *, const void *));
  5130. {
  5131.     char_u    *buf;
  5132.     char_u    *p1;
  5133.     char_u    *p2;
  5134.     int        i, j;
  5135.     int        gap;
  5136.  
  5137.     buf = alloc((unsigned)elm_size);
  5138.     if (buf == NULL)
  5139.     return;
  5140.  
  5141.     for (gap = elm_count / 2; gap > 0; gap /= 2)
  5142.     for (i = gap; i < elm_count; ++i)
  5143.         for (j = i - gap; j >= 0; j -= gap)
  5144.         {
  5145.         /* Compare the elements. */
  5146.         p1 = (char_u *)base + j * elm_size;
  5147.         p2 = (char_u *)base + (j + gap) * elm_size;
  5148.         if ((*cmp)((void *)p1, (void *)p2) <= 0)
  5149.             break;
  5150.         /* Exchange the elemets. */
  5151.         mch_memmove(buf, p1, elm_size);
  5152.         mch_memmove(p1, p2, elm_size);
  5153.         mch_memmove(p2, buf, elm_size);
  5154.         }
  5155.  
  5156.     vim_free(buf);
  5157. }
  5158. #endif
  5159.  
  5160. #if defined(FEAT_EX_EXTRA) || defined(FEAT_CMDL_COMPL) || defined(PROTO)
  5161. /*
  5162.  * Sort an array of strings.
  5163.  */
  5164. static int
  5165. #ifdef __BORLANDC__
  5166. _RTLENTRYF
  5167. #endif
  5168. sort_compare __ARGS((const void *s1, const void *s2));
  5169.  
  5170.     static int
  5171. #ifdef __BORLANDC__
  5172. _RTLENTRYF
  5173. #endif
  5174. sort_compare(s1, s2)
  5175.     const void    *s1;
  5176.     const void    *s2;
  5177. {
  5178.     return STRCMP(*(char **)s1, *(char **)s2);
  5179. }
  5180.  
  5181.     void
  5182. sort_strings(files, count)
  5183.     char_u    **files;
  5184.     int        count;
  5185. {
  5186.     qsort((void *)files, (size_t)count, sizeof(char_u *), sort_compare);
  5187. }
  5188. #endif
  5189.  
  5190. #if !defined(NO_EXPANDPATH) || defined(PROTO)
  5191. /*
  5192.  * Compare path "p[]" to "q[]".
  5193.  * Return value like strcmp(p, q), but consider path separators.
  5194.  */
  5195.     int
  5196. pathcmp(p, q)
  5197.     const char *p, *q;
  5198. {
  5199.     int        i;
  5200.     const char    *s;
  5201.  
  5202.     for (i = 0; ; ++i)
  5203.     {
  5204.     /* End of "p": check if "q" also ends or just has a slash. */
  5205.     if (p[i] == NUL)
  5206.     {
  5207.         if (q[i] == NUL)  /* full match */
  5208.         return 0;
  5209.         s = q;
  5210.         break;
  5211.     }
  5212.  
  5213.     /* End of "q": check if "p" just has a slash. */
  5214.     if (q[i] == NUL)
  5215.     {
  5216.         s = p;
  5217.         break;
  5218.     }
  5219.  
  5220.     if (
  5221. #ifdef CASE_INSENSITIVE_FILENAME
  5222.         TOUPPER_LOC(p[i]) != TOUPPER_LOC(q[i])
  5223. #else
  5224.         p[i] != q[i]
  5225. #endif
  5226. #ifdef BACKSLASH_IN_FILENAME
  5227.         /* consider '/' and '\\' to be equal */
  5228.         && !((p[i] == '/' && q[i] == '\\')
  5229.             || (p[i] == '\\' && q[i] == '/'))
  5230. #endif
  5231.         )
  5232.     {
  5233.         if (vim_ispathsep(p[i]))
  5234.         return -1;
  5235.         if (vim_ispathsep(q[i]))
  5236.         return 1;
  5237.         return ((char_u *)p)[i] - ((char_u *)q)[i];        /* no match */
  5238.     }
  5239.     }
  5240.  
  5241.     /* ignore a trailing slash, but not "//" or ":/" */
  5242.     if (s[i + 1] == NUL && i > 0 && !vim_ispathsep(s[i - 1])
  5243. #ifdef BACKSLASH_IN_FILENAME
  5244.         && (s[i] == '/' || s[i] == '\\')
  5245. #else
  5246.         && s[i] == '/'
  5247. #endif
  5248.        )
  5249.     return 0;   /* match with trailing slash */
  5250.     if (s == q)
  5251.     return -1;        /* no match */
  5252.     return 1;
  5253. }
  5254. #endif
  5255.  
  5256. #if defined(FEAT_PRINTER) || defined(PROTO)
  5257. /*
  5258.  * Parse a list of options in the form
  5259.  * option:value,option:value,option:value
  5260.  *
  5261.  * "value" can start with a number which is parsed out, e.g.
  5262.  * margin:12mm
  5263.  *
  5264.  * Returns error message for an illegal option, NULL otherwise.
  5265.  * Only used for the printer at the moment...
  5266.  */
  5267.     char_u *
  5268. parse_list_options(option_str, table, table_size)
  5269.     char_u        *option_str;
  5270.     option_table_T    *table;
  5271.     int            table_size;
  5272. {
  5273.     char_u    *stringp;
  5274.     char_u    *colonp;
  5275.     char_u    *commap;
  5276.     char_u    *p;
  5277.     int        idx = 0;        /* init for GCC */
  5278.     int        len;
  5279.  
  5280.     for (idx = 0; idx < table_size; ++idx)
  5281.     table[idx].present = FALSE;
  5282.  
  5283.     /*
  5284.      * Repeat for all comma separated parts.
  5285.      */
  5286.     stringp = option_str;
  5287.     while (*stringp)
  5288.     {
  5289.     colonp = vim_strchr(stringp, ':');
  5290.     if (colonp == NULL)
  5291.         return (char_u *)N_("E550: Missing colon");
  5292.     commap = vim_strchr(stringp, ',');
  5293.     if (commap == NULL)
  5294.         commap = option_str + STRLEN(option_str);
  5295.  
  5296.     len = (int)(colonp - stringp);
  5297.  
  5298.     for (idx = 0; idx < table_size; ++idx)
  5299.         if (STRNICMP(stringp, table[idx].name, len) == 0)
  5300.         break;
  5301.  
  5302.     if (idx == table_size)
  5303.         return (char_u *)N_("E551: Illegal component");
  5304.  
  5305.     p = colonp + 1;
  5306.     table[idx].present = TRUE;
  5307.  
  5308.     if (table[idx].hasnum)
  5309.     {
  5310.         if (!isdigit(*p))
  5311.         return (char_u *)N_("E552: digit expected");
  5312.  
  5313.         table[idx].number = getdigits(&p); /*advances p*/
  5314.     }
  5315.  
  5316.     table[idx].string = p;
  5317.     table[idx].strlen = (int)(commap - p);
  5318.  
  5319.     stringp = commap;
  5320.     if (*stringp == ',')
  5321.         ++stringp;
  5322.     }
  5323.  
  5324.     return NULL;
  5325. }
  5326.  
  5327.  
  5328. #endif /*FEAT_PRINTER*/
  5329.  
  5330. /*
  5331.  * The putenv() implementation below comes from the "screen" program.
  5332.  * Included with permission from Juergen Weigert.
  5333.  * See pty.c for the copyright notice.
  5334.  */
  5335.  
  5336. /*
  5337.  *  putenv  --    put value into environment
  5338.  *
  5339.  *  Usage:  i = putenv (string)
  5340.  *    int i;
  5341.  *    char  *string;
  5342.  *
  5343.  *  where string is of the form <name>=<value>.
  5344.  *  Putenv returns 0 normally, -1 on error (not enough core for malloc).
  5345.  *
  5346.  *  Putenv may need to add a new name into the environment, or to
  5347.  *  associate a value longer than the current value with a particular
  5348.  *  name.  So, to make life simpler, putenv() copies your entire
  5349.  *  environment into the heap (i.e. malloc()) from the stack
  5350.  *  (i.e. where it resides when your process is initiated) the first
  5351.  *  time you call it.
  5352.  *
  5353.  *  (history removed, not very interesting.  See the "screen" sources.)
  5354.  */
  5355.  
  5356. #if !defined(HAVE_SETENV) && !defined(HAVE_PUTENV)
  5357.  
  5358. #define EXTRASIZE 5        /* increment to add to env. size */
  5359.  
  5360. static int  envsize = -1;    /* current size of environment */
  5361. #ifndef MACOS_CLASSIC
  5362. extern
  5363. #endif
  5364.        char **environ;        /* the global which is your env. */
  5365.  
  5366. static int  findenv __ARGS((char *name)); /* look for a name in the env. */
  5367. static int  newenv __ARGS((void));    /* copy env. from stack to heap */
  5368. static int  moreenv __ARGS((void));    /* incr. size of env. */
  5369.  
  5370.     int
  5371. putenv(string)
  5372.     const char *string;
  5373. {
  5374.     int        i;
  5375.     char    *p;
  5376.  
  5377.     if (envsize < 0)
  5378.     {                /* first time putenv called */
  5379.     if (newenv() < 0)    /* copy env. to heap */
  5380.         return -1;
  5381.     }
  5382.  
  5383.     i = findenv((char *)string); /* look for name in environment */
  5384.  
  5385.     if (i < 0)
  5386.     {                /* name must be added */
  5387.     for (i = 0; environ[i]; i++);
  5388.     if (i >= (envsize - 1))
  5389.     {            /* need new slot */
  5390.         if (moreenv() < 0)
  5391.         return -1;
  5392.     }
  5393.     p = (char *)alloc((unsigned)(strlen(string) + 1));
  5394.     if (p == NULL)        /* not enough core */
  5395.         return -1;
  5396.     environ[i + 1] = 0;    /* new end of env. */
  5397.     }
  5398.     else
  5399.     {                /* name already in env. */
  5400.     p = vim_realloc(environ[i], strlen(string) + 1);
  5401.     if (p == NULL)
  5402.         return -1;
  5403.     }
  5404.     sprintf(p, "%s", string);    /* copy into env. */
  5405.     environ[i] = p;
  5406.  
  5407.     return 0;
  5408. }
  5409.  
  5410.     static int
  5411. findenv(name)
  5412.     char *name;
  5413. {
  5414.     char    *namechar, *envchar;
  5415.     int        i, found;
  5416.  
  5417.     found = 0;
  5418.     for (i = 0; environ[i] && !found; i++)
  5419.     {
  5420.     envchar = environ[i];
  5421.     namechar = name;
  5422.     while (*namechar && *namechar != '=' && (*namechar == *envchar))
  5423.     {
  5424.         namechar++;
  5425.         envchar++;
  5426.     }
  5427.     found = ((*namechar == '\0' || *namechar == '=') && *envchar == '=');
  5428.     }
  5429.     return found ? i - 1 : -1;
  5430. }
  5431.  
  5432.     static int
  5433. newenv()
  5434. {
  5435.     char    **env, *elem;
  5436.     int        i, esize;
  5437.  
  5438. #ifdef MACOS
  5439.     /* for Mac a new, empty environment is created */
  5440.     i = 0;
  5441. #else
  5442.     for (i = 0; environ[i]; i++)
  5443.     ;
  5444. #endif
  5445.     esize = i + EXTRASIZE + 1;
  5446.     env = (char **)alloc((unsigned)(esize * sizeof (elem)));
  5447.     if (env == NULL)
  5448.     return -1;
  5449.  
  5450. #ifndef MACOS
  5451.     for (i = 0; environ[i]; i++)
  5452.     {
  5453.     elem = (char *)alloc((unsigned)(strlen(environ[i]) + 1));
  5454.     if (elem == NULL)
  5455.         return -1;
  5456.     env[i] = elem;
  5457.     strcpy(elem, environ[i]);
  5458.     }
  5459. #endif
  5460.  
  5461.     env[i] = 0;
  5462.     environ = env;
  5463.     envsize = esize;
  5464.     return 0;
  5465. }
  5466.  
  5467.     static int
  5468. moreenv()
  5469. {
  5470.     int        esize;
  5471.     char    **env;
  5472.  
  5473.     esize = envsize + EXTRASIZE;
  5474.     env = (char **)vim_realloc((char *)environ, esize * sizeof (*env));
  5475.     if (env == 0)
  5476.     return -1;
  5477.     environ = env;
  5478.     envsize = esize;
  5479.     return 0;
  5480. }
  5481.  
  5482. # ifdef USE_VIMPTY_GETENV
  5483.     char_u *
  5484. vimpty_getenv(string)
  5485.     const char_u *string;
  5486. {
  5487.     int i;
  5488.     char_u *p;
  5489.  
  5490.     if (envsize < 0)
  5491.     return NULL;
  5492.  
  5493.     i = findenv((char *)string);
  5494.  
  5495.     if (i < 0)
  5496.     return NULL;
  5497.  
  5498.     p = vim_strchr((char_u *)environ[i], '=');
  5499.     return (p + 1);
  5500. }
  5501. # endif
  5502.  
  5503. #endif /* !defined(HAVE_SETENV) && !defined(HAVE_PUTENV) */
  5504.  
  5505. /*
  5506.  * Print a message with one string argument.
  5507.  * Make sure that the result fits in IObuff.
  5508.  * This is not in message.c, because the prototype for smsg() isn't used
  5509.  * there.
  5510.  */
  5511.     void
  5512. msg_str(s, arg)
  5513.     char_u    *s;
  5514.     char_u    *arg;
  5515. {
  5516.     int        ls = STRLEN(s);
  5517.     int        larg = STRLEN(arg);
  5518.  
  5519.     if (ls + larg >= IOSIZE)
  5520.     smsg(s, arg + (ls + larg - IOSIZE));
  5521.     else
  5522.     smsg(s, arg);
  5523. }
  5524.