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