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