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#include "vim.h"
11
12#ifdef AMIGA
13# include <time.h>	/* for time() */
14#endif
15
16/*
17 * Vim originated from Stevie version 3.6 (Fish disk 217) by GRWalter (Fred)
18 * It has been changed beyond recognition since then.
19 *
20 * Differences between version 6.x and 7.x can be found with ":help version7".
21 * Differences between version 5.x and 6.x can be found with ":help version6".
22 * Differences between version 4.x and 5.x can be found with ":help version5".
23 * Differences between version 3.0 and 4.x can be found with ":help version4".
24 * All the remarks about older versions have been removed, they are not very
25 * interesting.
26 */
27
28#include "version.h"
29
30char		*Version = VIM_VERSION_SHORT;
31static char	*mediumVersion = VIM_VERSION_MEDIUM;
32
33#if defined(HAVE_DATE_TIME) || defined(PROTO)
34# if (defined(VMS) && defined(VAXC)) || defined(PROTO)
35char	longVersion[sizeof(VIM_VERSION_LONG_DATE) + sizeof(__DATE__)
36						      + sizeof(__TIME__) + 3];
37    void
38make_version()
39{
40    /*
41     * Construct the long version string.  Necessary because
42     * VAX C can't catenate strings in the preprocessor.
43     */
44    strcpy(longVersion, VIM_VERSION_LONG_DATE);
45    strcat(longVersion, __DATE__);
46    strcat(longVersion, " ");
47    strcat(longVersion, __TIME__);
48    strcat(longVersion, ")");
49}
50# else
51char	*longVersion = VIM_VERSION_LONG_DATE __DATE__ " " __TIME__ ")";
52# endif
53#else
54char	*longVersion = VIM_VERSION_LONG;
55#endif
56
57static void version_msg __ARGS((char *s));
58
59static char *(features[]) =
60{
61#ifdef AMIGA		/* only for Amiga systems */
62# ifdef FEAT_ARP
63	"+ARP",
64# else
65	"-ARP",
66# endif
67#endif
68#ifdef FEAT_ARABIC
69	"+arabic",
70#else
71	"-arabic",
72#endif
73#ifdef FEAT_AUTOCMD
74	"+autocmd",
75#else
76	"-autocmd",
77#endif
78#ifdef FEAT_BEVAL
79	"+balloon_eval",
80#else
81	"-balloon_eval",
82#endif
83#ifdef FEAT_BROWSE
84	"+browse",
85#else
86	"-browse",
87#endif
88#ifdef NO_BUILTIN_TCAPS
89	"-builtin_terms",
90#endif
91#ifdef SOME_BUILTIN_TCAPS
92	"+builtin_terms",
93#endif
94#ifdef ALL_BUILTIN_TCAPS
95	"++builtin_terms",
96#endif
97#ifdef FEAT_BYTEOFF
98	"+byte_offset",
99#else
100	"-byte_offset",
101#endif
102#ifdef FEAT_CINDENT
103	"+cindent",
104#else
105	"-cindent",
106#endif
107#ifdef FEAT_CLIENTSERVER
108	"+clientserver",
109#else
110	"-clientserver",
111#endif
112#ifdef FEAT_CLIPBOARD
113	"+clipboard",
114#else
115	"-clipboard",
116#endif
117#ifdef FEAT_CMDL_COMPL
118	"+cmdline_compl",
119#else
120	"-cmdline_compl",
121#endif
122#ifdef FEAT_CMDHIST
123	"+cmdline_hist",
124#else
125	"-cmdline_hist",
126#endif
127#ifdef FEAT_CMDL_INFO
128	"+cmdline_info",
129#else
130	"-cmdline_info",
131#endif
132#ifdef FEAT_COMMENTS
133	"+comments",
134#else
135	"-comments",
136#endif
137#ifdef FEAT_CONCEAL
138	"+conceal",
139#else
140	"-conceal",
141#endif
142#ifdef FEAT_CRYPT
143	"+cryptv",
144#else
145	"-cryptv",
146#endif
147#ifdef FEAT_CSCOPE
148	"+cscope",
149#else
150	"-cscope",
151#endif
152#ifdef FEAT_CURSORBIND
153	"+cursorbind",
154#else
155	"-cursorbind",
156#endif
157#ifdef CURSOR_SHAPE
158	"+cursorshape",
159#else
160	"-cursorshape",
161#endif
162#if defined(FEAT_CON_DIALOG) && defined(FEAT_GUI_DIALOG)
163	"+dialog_con_gui",
164#else
165# if defined(FEAT_CON_DIALOG)
166	"+dialog_con",
167# else
168#  if defined(FEAT_GUI_DIALOG)
169	"+dialog_gui",
170#  else
171	"-dialog",
172#  endif
173# endif
174#endif
175#ifdef FEAT_DIFF
176	"+diff",
177#else
178	"-diff",
179#endif
180#ifdef FEAT_DIGRAPHS
181	"+digraphs",
182#else
183	"-digraphs",
184#endif
185#ifdef FEAT_DND
186	"+dnd",
187#else
188	"-dnd",
189#endif
190#ifdef EBCDIC
191	"+ebcdic",
192#else
193	"-ebcdic",
194#endif
195#ifdef FEAT_EMACS_TAGS
196	"+emacs_tags",
197#else
198	"-emacs_tags",
199#endif
200#ifdef FEAT_EVAL
201	"+eval",
202#else
203	"-eval",
204#endif
205#ifdef FEAT_EX_EXTRA
206	"+ex_extra",
207#else
208	"-ex_extra",
209#endif
210#ifdef FEAT_SEARCH_EXTRA
211	"+extra_search",
212#else
213	"-extra_search",
214#endif
215#ifdef FEAT_FKMAP
216	"+farsi",
217#else
218	"-farsi",
219#endif
220#ifdef FEAT_SEARCHPATH
221	"+file_in_path",
222#else
223	"-file_in_path",
224#endif
225#ifdef FEAT_FIND_ID
226	"+find_in_path",
227#else
228	"-find_in_path",
229#endif
230#ifdef FEAT_FLOAT
231	"+float",
232#else
233	"-float",
234#endif
235#ifdef FEAT_FOLDING
236	"+folding",
237#else
238	"-folding",
239#endif
240#ifdef FEAT_FOOTER
241	"+footer",
242#else
243	"-footer",
244#endif
245	    /* only interesting on Unix systems */
246#if !defined(USE_SYSTEM) && defined(UNIX)
247	"+fork()",
248#endif
249#ifdef FEAT_GETTEXT
250# ifdef DYNAMIC_GETTEXT
251	"+gettext/dyn",
252# else
253	"+gettext",
254# endif
255#else
256	"-gettext",
257#endif
258#ifdef FEAT_HANGULIN
259	"+hangul_input",
260#else
261	"-hangul_input",
262#endif
263#if (defined(HAVE_ICONV_H) && defined(USE_ICONV)) || defined(DYNAMIC_ICONV)
264# ifdef DYNAMIC_ICONV
265	"+iconv/dyn",
266# else
267	"+iconv",
268# endif
269#else
270	"-iconv",
271#endif
272#ifdef FEAT_INS_EXPAND
273	"+insert_expand",
274#else
275	"-insert_expand",
276#endif
277#ifdef FEAT_JUMPLIST
278	"+jumplist",
279#else
280	"-jumplist",
281#endif
282#ifdef FEAT_KEYMAP
283	"+keymap",
284#else
285	"-keymap",
286#endif
287#ifdef FEAT_LANGMAP
288	"+langmap",
289#else
290	"-langmap",
291#endif
292#ifdef FEAT_LIBCALL
293	"+libcall",
294#else
295	"-libcall",
296#endif
297#ifdef FEAT_LINEBREAK
298	"+linebreak",
299#else
300	"-linebreak",
301#endif
302#ifdef FEAT_LISP
303	"+lispindent",
304#else
305	"-lispindent",
306#endif
307#ifdef FEAT_LISTCMDS
308	"+listcmds",
309#else
310	"-listcmds",
311#endif
312#ifdef FEAT_LOCALMAP
313	"+localmap",
314#else
315	"-localmap",
316#endif
317#ifdef FEAT_LUA
318# ifdef DYNAMIC_LUA
319	"+lua/dyn",
320# else
321	"+lua",
322# endif
323#else
324	"-lua",
325#endif
326#ifdef FEAT_MENU
327	"+menu",
328#else
329	"-menu",
330#endif
331#ifdef FEAT_SESSION
332	"+mksession",
333#else
334	"-mksession",
335#endif
336#ifdef FEAT_MODIFY_FNAME
337	"+modify_fname",
338#else
339	"-modify_fname",
340#endif
341#ifdef FEAT_MOUSE
342	"+mouse",
343#  ifdef FEAT_MOUSESHAPE
344	"+mouseshape",
345#  else
346	"-mouseshape",
347#  endif
348# else
349	"-mouse",
350#endif
351#if defined(UNIX) || defined(VMS)
352# ifdef FEAT_MOUSE_DEC
353	"+mouse_dec",
354# else
355	"-mouse_dec",
356# endif
357# ifdef FEAT_MOUSE_GPM
358	"+mouse_gpm",
359# else
360	"-mouse_gpm",
361# endif
362# ifdef FEAT_MOUSE_JSB
363	"+mouse_jsbterm",
364# else
365	"-mouse_jsbterm",
366# endif
367# ifdef FEAT_MOUSE_NET
368	"+mouse_netterm",
369# else
370	"-mouse_netterm",
371# endif
372# ifdef FEAT_SYSMOUSE
373	"+mouse_sysmouse",
374# else
375	"-mouse_sysmouse",
376# endif
377# ifdef FEAT_MOUSE_XTERM
378	"+mouse_xterm",
379# else
380	"-mouse_xterm",
381# endif
382#endif
383#ifdef __QNX__
384# ifdef FEAT_MOUSE_PTERM
385	"+mouse_pterm",
386# else
387	"-mouse_pterm",
388# endif
389#endif
390#ifdef FEAT_MBYTE_IME
391# ifdef DYNAMIC_IME
392	"+multi_byte_ime/dyn",
393# else
394	"+multi_byte_ime",
395# endif
396#else
397# ifdef FEAT_MBYTE
398	"+multi_byte",
399# else
400	"-multi_byte",
401# endif
402#endif
403#ifdef FEAT_MULTI_LANG
404	"+multi_lang",
405#else
406	"-multi_lang",
407#endif
408#ifdef FEAT_MZSCHEME
409# ifdef DYNAMIC_MZSCHEME
410	"+mzscheme/dyn",
411# else
412	"+mzscheme",
413# endif
414#else
415	"-mzscheme",
416#endif
417#ifdef FEAT_NETBEANS_INTG
418	"+netbeans_intg",
419#else
420	"-netbeans_intg",
421#endif
422#ifdef FEAT_GUI_W32
423# ifdef FEAT_OLE
424	"+ole",
425# else
426	"-ole",
427# endif
428#endif
429#ifdef FEAT_OSFILETYPE
430	"+osfiletype",
431#else
432	"-osfiletype",
433#endif
434#ifdef FEAT_PATH_EXTRA
435	"+path_extra",
436#else
437	"-path_extra",
438#endif
439#ifdef FEAT_PERL
440# ifdef DYNAMIC_PERL
441	"+perl/dyn",
442# else
443	"+perl",
444# endif
445#else
446	"-perl",
447#endif
448#ifdef FEAT_PERSISTENT_UNDO
449	"+persistent_undo",
450#else
451	"-persistent_undo",
452#endif
453#ifdef FEAT_PRINTER
454# ifdef FEAT_POSTSCRIPT
455	"+postscript",
456# else
457	"-postscript",
458# endif
459	"+printer",
460#else
461	"-printer",
462#endif
463#ifdef FEAT_PROFILE
464	"+profile",
465#else
466	"-profile",
467#endif
468#ifdef FEAT_PYTHON
469# ifdef DYNAMIC_PYTHON
470	"+python/dyn",
471# else
472	"+python",
473# endif
474#else
475	"-python",
476#endif
477#ifdef FEAT_PYTHON3
478# ifdef DYNAMIC_PYTHON3
479	"+python3/dyn",
480# else
481	"+python3",
482# endif
483#else
484	"-python3",
485#endif
486#ifdef FEAT_QUICKFIX
487	"+quickfix",
488#else
489	"-quickfix",
490#endif
491#ifdef FEAT_RELTIME
492	"+reltime",
493#else
494	"-reltime",
495#endif
496#ifdef FEAT_RIGHTLEFT
497	"+rightleft",
498#else
499	"-rightleft",
500#endif
501#ifdef FEAT_RUBY
502# ifdef DYNAMIC_RUBY
503	"+ruby/dyn",
504# else
505	"+ruby",
506# endif
507#else
508	"-ruby",
509#endif
510#ifdef FEAT_SCROLLBIND
511	"+scrollbind",
512#else
513	"-scrollbind",
514#endif
515#ifdef FEAT_SIGNS
516	"+signs",
517#else
518	"-signs",
519#endif
520#ifdef FEAT_SMARTINDENT
521	"+smartindent",
522#else
523	"-smartindent",
524#endif
525#ifdef FEAT_SNIFF
526	"+sniff",
527#else
528	"-sniff",
529#endif
530#ifdef STARTUPTIME
531	"+startuptime",
532#else
533	"-startuptime",
534#endif
535#ifdef FEAT_STL_OPT
536	"+statusline",
537#else
538	"-statusline",
539#endif
540#ifdef FEAT_SUN_WORKSHOP
541	"+sun_workshop",
542#else
543	"-sun_workshop",
544#endif
545#ifdef FEAT_SYN_HL
546	"+syntax",
547#else
548	"-syntax",
549#endif
550	    /* only interesting on Unix systems */
551#if defined(USE_SYSTEM) && (defined(UNIX) || defined(__EMX__))
552	"+system()",
553#endif
554#ifdef FEAT_TAG_BINS
555	"+tag_binary",
556#else
557	"-tag_binary",
558#endif
559#ifdef FEAT_TAG_OLDSTATIC
560	"+tag_old_static",
561#else
562	"-tag_old_static",
563#endif
564#ifdef FEAT_TAG_ANYWHITE
565	"+tag_any_white",
566#else
567	"-tag_any_white",
568#endif
569#ifdef FEAT_TCL
570# ifdef DYNAMIC_TCL
571	"+tcl/dyn",
572# else
573	"+tcl",
574# endif
575#else
576	"-tcl",
577#endif
578#if defined(UNIX) || defined(__EMX__)
579/* only Unix (or OS/2 with EMX!) can have terminfo instead of termcap */
580# ifdef TERMINFO
581	"+terminfo",
582# else
583	"-terminfo",
584# endif
585#else		    /* unix always includes termcap support */
586# ifdef HAVE_TGETENT
587	"+tgetent",
588# else
589	"-tgetent",
590# endif
591#endif
592#ifdef FEAT_TERMRESPONSE
593	"+termresponse",
594#else
595	"-termresponse",
596#endif
597#ifdef FEAT_TEXTOBJ
598	"+textobjects",
599#else
600	"-textobjects",
601#endif
602#ifdef FEAT_TITLE
603	"+title",
604#else
605	"-title",
606#endif
607#ifdef FEAT_TOOLBAR
608	"+toolbar",
609#else
610	"-toolbar",
611#endif
612#ifdef FEAT_USR_CMDS
613	"+user_commands",
614#else
615	"-user_commands",
616#endif
617#ifdef FEAT_VERTSPLIT
618	"+vertsplit",
619#else
620	"-vertsplit",
621#endif
622#ifdef FEAT_VIRTUALEDIT
623	"+virtualedit",
624#else
625	"-virtualedit",
626#endif
627#ifdef FEAT_VISUAL
628	"+visual",
629# ifdef FEAT_VISUALEXTRA
630	"+visualextra",
631# else
632	"-visualextra",
633# endif
634#else
635	"-visual",
636#endif
637#ifdef FEAT_VIMINFO
638	"+viminfo",
639#else
640	"-viminfo",
641#endif
642#ifdef FEAT_VREPLACE
643	"+vreplace",
644#else
645	"-vreplace",
646#endif
647#ifdef FEAT_WILDIGN
648	"+wildignore",
649#else
650	"-wildignore",
651#endif
652#ifdef FEAT_WILDMENU
653	"+wildmenu",
654#else
655	"-wildmenu",
656#endif
657#ifdef FEAT_WINDOWS
658	"+windows",
659#else
660	"-windows",
661#endif
662#ifdef FEAT_WRITEBACKUP
663	"+writebackup",
664#else
665	"-writebackup",
666#endif
667#if defined(UNIX) || defined(VMS)
668# ifdef FEAT_X11
669	"+X11",
670# else
671	"-X11",
672# endif
673#endif
674#ifdef FEAT_XFONTSET
675	"+xfontset",
676#else
677	"-xfontset",
678#endif
679#ifdef FEAT_XIM
680	"+xim",
681#else
682	"-xim",
683#endif
684#if defined(UNIX) || defined(VMS)
685# ifdef USE_XSMP_INTERACT
686	"+xsmp_interact",
687# else
688#  ifdef USE_XSMP
689	"+xsmp",
690#  else
691	"-xsmp",
692#  endif
693# endif
694# ifdef FEAT_XCLIPBOARD
695	"+xterm_clipboard",
696# else
697	"-xterm_clipboard",
698# endif
699#endif
700#ifdef FEAT_XTERM_SAVE
701	"+xterm_save",
702#else
703	"-xterm_save",
704#endif
705#ifdef WIN3264
706# ifdef FEAT_XPM_W32
707	"+xpm_w32",
708# else
709	"-xpm_w32",
710# endif
711#endif
712	NULL
713};
714
715static int included_patches[] =
716{   /* Add new patch number below this line */
717/**/
718    0
719};
720
721/*
722 * Place to put a short description when adding a feature with a patch.
723 * Keep it short, e.g.,: "relative numbers", "persistent undo".
724 * Also add a comment marker to separate the lines.
725 * See the official Vim patches for the diff format: It must use a context of
726 * one line only.  Create it by hand or use "diff -C2" and edit the patch.
727 */
728static char *(extra_patches[]) =
729{   /* Add your patch description below this line */
730/**/
731    NULL
732};
733
734    int
735highest_patch()
736{
737    int		i;
738    int		h = 0;
739
740    for (i = 0; included_patches[i] != 0; ++i)
741	if (included_patches[i] > h)
742	    h = included_patches[i];
743    return h;
744}
745
746#if defined(FEAT_EVAL) || defined(PROTO)
747/*
748 * Return TRUE if patch "n" has been included.
749 */
750    int
751has_patch(n)
752    int		n;
753{
754    int		i;
755
756    for (i = 0; included_patches[i] != 0; ++i)
757	if (included_patches[i] == n)
758	    return TRUE;
759    return FALSE;
760}
761#endif
762
763    void
764ex_version(eap)
765    exarg_T	*eap;
766{
767    /*
768     * Ignore a ":version 9.99" command.
769     */
770    if (*eap->arg == NUL)
771    {
772	msg_putchar('\n');
773	list_version();
774    }
775}
776
777    void
778list_version()
779{
780    int		i;
781    int		first;
782    char	*s = "";
783
784    /*
785     * When adding features here, don't forget to update the list of
786     * internal variables in eval.c!
787     */
788    MSG(longVersion);
789#ifdef WIN3264
790# ifdef FEAT_GUI_W32
791#  if defined(_MSC_VER) && (_MSC_VER <= 1010)
792    /* Only MS VC 4.1 and earlier can do Win32s */
793    MSG_PUTS(_("\nMS-Windows 16/32-bit GUI version"));
794#  else
795#   ifdef _WIN64
796    MSG_PUTS(_("\nMS-Windows 64-bit GUI version"));
797#   else
798    MSG_PUTS(_("\nMS-Windows 32-bit GUI version"));
799#   endif
800#  endif
801    if (gui_is_win32s())
802	MSG_PUTS(_(" in Win32s mode"));
803# ifdef FEAT_OLE
804    MSG_PUTS(_(" with OLE support"));
805# endif
806# else
807#  ifdef _WIN64
808    MSG_PUTS(_("\nMS-Windows 64-bit console version"));
809#  else
810    MSG_PUTS(_("\nMS-Windows 32-bit console version"));
811#  endif
812# endif
813#endif
814#ifdef WIN16
815    MSG_PUTS(_("\nMS-Windows 16-bit version"));
816#endif
817#ifdef MSDOS
818# ifdef DJGPP
819    MSG_PUTS(_("\n32-bit MS-DOS version"));
820# else
821    MSG_PUTS(_("\n16-bit MS-DOS version"));
822# endif
823#endif
824#ifdef MACOS
825# ifdef MACOS_X
826#  ifdef MACOS_X_UNIX
827    MSG_PUTS(_("\nMacOS X (unix) version"));
828#  else
829    MSG_PUTS(_("\nMacOS X version"));
830#  endif
831#else
832    MSG_PUTS(_("\nMacOS version"));
833# endif
834#endif
835
836#ifdef RISCOS
837    MSG_PUTS(_("\nRISC OS version"));
838#endif
839#ifdef VMS
840    MSG_PUTS(_("\nOpenVMS version"));
841# ifdef HAVE_PATHDEF
842    if (*compiled_arch != NUL)
843    {
844	MSG_PUTS(" - ");
845	MSG_PUTS(compiled_arch);
846    }
847# endif
848
849#endif
850
851    /* Print the list of patch numbers if there is at least one. */
852    /* Print a range when patches are consecutive: "1-10, 12, 15-40, 42-45" */
853    if (included_patches[0] != 0)
854    {
855	MSG_PUTS(_("\nIncluded patches: "));
856	first = -1;
857	/* find last one */
858	for (i = 0; included_patches[i] != 0; ++i)
859	    ;
860	while (--i >= 0)
861	{
862	    if (first < 0)
863		first = included_patches[i];
864	    if (i == 0 || included_patches[i - 1] != included_patches[i] + 1)
865	    {
866		MSG_PUTS(s);
867		s = ", ";
868		msg_outnum((long)first);
869		if (first != included_patches[i])
870		{
871		    MSG_PUTS("-");
872		    msg_outnum((long)included_patches[i]);
873		}
874		first = -1;
875	    }
876	}
877    }
878
879    /* Print the list of extra patch descriptions if there is at least one. */
880    if (extra_patches[0] != NULL)
881    {
882	MSG_PUTS(_("\nExtra patches: "));
883	s = "";
884	for (i = 0; extra_patches[i] != NULL; ++i)
885	{
886	    MSG_PUTS(s);
887	    s = ", ";
888	    MSG_PUTS(extra_patches[i]);
889	}
890    }
891
892#ifdef MODIFIED_BY
893    MSG_PUTS("\n");
894    MSG_PUTS(_("Modified by "));
895    MSG_PUTS(MODIFIED_BY);
896#endif
897
898#ifdef HAVE_PATHDEF
899    if (*compiled_user != NUL || *compiled_sys != NUL)
900    {
901	MSG_PUTS(_("\nCompiled "));
902	if (*compiled_user != NUL)
903	{
904	    MSG_PUTS(_("by "));
905	    MSG_PUTS(compiled_user);
906	}
907	if (*compiled_sys != NUL)
908	{
909	    MSG_PUTS("@");
910	    MSG_PUTS(compiled_sys);
911	}
912    }
913#endif
914
915#ifdef FEAT_HUGE
916    MSG_PUTS(_("\nHuge version "));
917#else
918# ifdef FEAT_BIG
919    MSG_PUTS(_("\nBig version "));
920# else
921#  ifdef FEAT_NORMAL
922    MSG_PUTS(_("\nNormal version "));
923#  else
924#   ifdef FEAT_SMALL
925    MSG_PUTS(_("\nSmall version "));
926#   else
927    MSG_PUTS(_("\nTiny version "));
928#   endif
929#  endif
930# endif
931#endif
932#ifndef FEAT_GUI
933    MSG_PUTS(_("without GUI."));
934#else
935# ifdef FEAT_GUI_GTK
936#  ifdef FEAT_GUI_GNOME
937    MSG_PUTS(_("with GTK2-GNOME GUI."));
938#  else
939    MSG_PUTS(_("with GTK2 GUI."));
940#  endif
941# else
942#  ifdef FEAT_GUI_MOTIF
943    MSG_PUTS(_("with X11-Motif GUI."));
944#  else
945#   ifdef FEAT_GUI_ATHENA
946#    ifdef FEAT_GUI_NEXTAW
947    MSG_PUTS(_("with X11-neXtaw GUI."));
948#    else
949    MSG_PUTS(_("with X11-Athena GUI."));
950#    endif
951#   else
952#     ifdef FEAT_GUI_PHOTON
953    MSG_PUTS(_("with Photon GUI."));
954#     else
955#      if defined(MSWIN)
956    MSG_PUTS(_("with GUI."));
957#      else
958#	if defined(TARGET_API_MAC_CARBON) && TARGET_API_MAC_CARBON
959    MSG_PUTS(_("with Carbon GUI."));
960#	else
961#	 if defined(TARGET_API_MAC_OSX) && TARGET_API_MAC_OSX
962    MSG_PUTS(_("with Cocoa GUI."));
963#	 else
964#	  if defined(MACOS)
965    MSG_PUTS(_("with (classic) GUI."));
966#	  endif
967#	 endif
968#	endif
969#      endif
970#    endif
971#   endif
972#  endif
973# endif
974#endif
975    version_msg(_("  Features included (+) or not (-):\n"));
976
977    /* print all the features */
978    for (i = 0; features[i] != NULL; ++i)
979    {
980	version_msg(features[i]);
981	if (msg_col > 0)
982	    version_msg(" ");
983    }
984
985    version_msg("\n");
986#ifdef SYS_VIMRC_FILE
987    version_msg(_("   system vimrc file: \""));
988    version_msg(SYS_VIMRC_FILE);
989    version_msg("\"\n");
990#endif
991#ifdef USR_VIMRC_FILE
992    version_msg(_("     user vimrc file: \""));
993    version_msg(USR_VIMRC_FILE);
994    version_msg("\"\n");
995#endif
996#ifdef USR_VIMRC_FILE2
997    version_msg(_(" 2nd user vimrc file: \""));
998    version_msg(USR_VIMRC_FILE2);
999    version_msg("\"\n");
1000#endif
1001#ifdef USR_VIMRC_FILE3
1002    version_msg(_(" 3rd user vimrc file: \""));
1003    version_msg(USR_VIMRC_FILE3);
1004    version_msg("\"\n");
1005#endif
1006#ifdef USR_EXRC_FILE
1007    version_msg(_("      user exrc file: \""));
1008    version_msg(USR_EXRC_FILE);
1009    version_msg("\"\n");
1010#endif
1011#ifdef USR_EXRC_FILE2
1012    version_msg(_("  2nd user exrc file: \""));
1013    version_msg(USR_EXRC_FILE2);
1014    version_msg("\"\n");
1015#endif
1016#ifdef FEAT_GUI
1017# ifdef SYS_GVIMRC_FILE
1018    version_msg(_("  system gvimrc file: \""));
1019    version_msg(SYS_GVIMRC_FILE);
1020    version_msg("\"\n");
1021# endif
1022    version_msg(_("    user gvimrc file: \""));
1023    version_msg(USR_GVIMRC_FILE);
1024    version_msg("\"\n");
1025# ifdef USR_GVIMRC_FILE2
1026    version_msg(_("2nd user gvimrc file: \""));
1027    version_msg(USR_GVIMRC_FILE2);
1028    version_msg("\"\n");
1029# endif
1030# ifdef USR_GVIMRC_FILE3
1031    version_msg(_("3rd user gvimrc file: \""));
1032    version_msg(USR_GVIMRC_FILE3);
1033    version_msg("\"\n");
1034# endif
1035#endif
1036#ifdef FEAT_GUI
1037# ifdef SYS_MENU_FILE
1038    version_msg(_("    system menu file: \""));
1039    version_msg(SYS_MENU_FILE);
1040    version_msg("\"\n");
1041# endif
1042#endif
1043#ifdef HAVE_PATHDEF
1044    if (*default_vim_dir != NUL)
1045    {
1046	version_msg(_("  fall-back for $VIM: \""));
1047	version_msg((char *)default_vim_dir);
1048	version_msg("\"\n");
1049    }
1050    if (*default_vimruntime_dir != NUL)
1051    {
1052	version_msg(_(" f-b for $VIMRUNTIME: \""));
1053	version_msg((char *)default_vimruntime_dir);
1054	version_msg("\"\n");
1055    }
1056    version_msg(_("Compilation: "));
1057    version_msg((char *)all_cflags);
1058    version_msg("\n");
1059#ifdef VMS
1060    if (*compiler_version != NUL)
1061    {
1062	version_msg(_("Compiler: "));
1063	version_msg((char *)compiler_version);
1064	version_msg("\n");
1065    }
1066#endif
1067    version_msg(_("Linking: "));
1068    version_msg((char *)all_lflags);
1069#endif
1070#ifdef DEBUG
1071    version_msg("\n");
1072    version_msg(_("  DEBUG BUILD"));
1073#endif
1074}
1075
1076/*
1077 * Output a string for the version message.  If it's going to wrap, output a
1078 * newline, unless the message is too long to fit on the screen anyway.
1079 */
1080    static void
1081version_msg(s)
1082    char	*s;
1083{
1084    int		len = (int)STRLEN(s);
1085
1086    if (!got_int && len < (int)Columns && msg_col + len >= (int)Columns
1087								&& *s != '\n')
1088	msg_putchar('\n');
1089    if (!got_int)
1090	MSG_PUTS(s);
1091}
1092
1093static void do_intro_line __ARGS((int row, char_u *mesg, int add_version, int attr));
1094
1095/*
1096 * Give an introductory message about Vim.
1097 * Only used when starting Vim on an empty file, without a file name.
1098 * Or with the ":intro" command (for Sven :-).
1099 */
1100    void
1101intro_message(colon)
1102    int		colon;		/* TRUE for ":intro" */
1103{
1104    int		i;
1105    int		row;
1106    int		blanklines;
1107    int		sponsor;
1108    char	*p;
1109    static char	*(lines[]) =
1110    {
1111	N_("VIM - Vi IMproved"),
1112	"",
1113	N_("version "),
1114	N_("by Bram Moolenaar et al."),
1115#ifdef MODIFIED_BY
1116	" ",
1117#endif
1118	N_("Vim is open source and freely distributable"),
1119	"",
1120	N_("Help poor children in Uganda!"),
1121	N_("type  :help iccf<Enter>       for information "),
1122	"",
1123	N_("type  :q<Enter>               to exit         "),
1124	N_("type  :help<Enter>  or  <F1>  for on-line help"),
1125	N_("type  :help version7<Enter>   for version info"),
1126	NULL,
1127	"",
1128	N_("Running in Vi compatible mode"),
1129	N_("type  :set nocp<Enter>        for Vim defaults"),
1130	N_("type  :help cp-default<Enter> for info on this"),
1131    };
1132#ifdef FEAT_GUI
1133    static char	*(gui_lines[]) =
1134    {
1135	NULL,
1136	NULL,
1137	NULL,
1138	NULL,
1139#ifdef MODIFIED_BY
1140	NULL,
1141#endif
1142	NULL,
1143	NULL,
1144	NULL,
1145	N_("menu  Help->Orphans           for information    "),
1146	NULL,
1147	N_("Running modeless, typed text is inserted"),
1148	N_("menu  Edit->Global Settings->Toggle Insert Mode  "),
1149	N_("                              for two modes      "),
1150	NULL,
1151	NULL,
1152	NULL,
1153	N_("menu  Edit->Global Settings->Toggle Vi Compatible"),
1154	N_("                              for Vim defaults   "),
1155    };
1156#endif
1157
1158    /* blanklines = screen height - # message lines */
1159    blanklines = (int)Rows - ((sizeof(lines) / sizeof(char *)) - 1);
1160    if (!p_cp)
1161	blanklines += 4;  /* add 4 for not showing "Vi compatible" message */
1162#if defined(WIN3264) && !defined(FEAT_GUI_W32)
1163    if (mch_windows95())
1164	blanklines -= 3;  /* subtract 3 for showing "Windows 95" message */
1165#endif
1166
1167#ifdef FEAT_WINDOWS
1168    /* Don't overwrite a statusline.  Depends on 'cmdheight'. */
1169    if (p_ls > 1)
1170	blanklines -= Rows - topframe->fr_height;
1171#endif
1172    if (blanklines < 0)
1173	blanklines = 0;
1174
1175    /* Show the sponsor and register message one out of four times, the Uganda
1176     * message two out of four times. */
1177    sponsor = (int)time(NULL);
1178    sponsor = ((sponsor & 2) == 0) - ((sponsor & 4) == 0);
1179
1180    /* start displaying the message lines after half of the blank lines */
1181    row = blanklines / 2;
1182    if ((row >= 2 && Columns >= 50) || colon)
1183    {
1184	for (i = 0; i < (int)(sizeof(lines) / sizeof(char *)); ++i)
1185	{
1186	    p = lines[i];
1187#ifdef FEAT_GUI
1188	    if (p_im && gui.in_use && gui_lines[i] != NULL)
1189		p = gui_lines[i];
1190#endif
1191	    if (p == NULL)
1192	    {
1193		if (!p_cp)
1194		    break;
1195		continue;
1196	    }
1197	    if (sponsor != 0)
1198	    {
1199		if (strstr(p, "children") != NULL)
1200		    p = sponsor < 0
1201			? N_("Sponsor Vim development!")
1202			: N_("Become a registered Vim user!");
1203		else if (strstr(p, "iccf") != NULL)
1204		    p = sponsor < 0
1205			? N_("type  :help sponsor<Enter>    for information ")
1206			: N_("type  :help register<Enter>   for information ");
1207		else if (strstr(p, "Orphans") != NULL)
1208		    p = N_("menu  Help->Sponsor/Register  for information    ");
1209	    }
1210	    if (*p != NUL)
1211		do_intro_line(row, (char_u *)_(p), i == 2, 0);
1212	    ++row;
1213	}
1214#if defined(WIN3264) && !defined(FEAT_GUI_W32)
1215	if (mch_windows95())
1216	{
1217	    do_intro_line(++row,
1218		    (char_u *)_("WARNING: Windows 95/98/ME detected"),
1219							FALSE, hl_attr(HLF_E));
1220	    do_intro_line(++row,
1221		(char_u *)_("type  :help windows95<Enter>  for info on this"),
1222								    FALSE, 0);
1223	}
1224#endif
1225    }
1226
1227    /* Make the wait-return message appear just below the text. */
1228    if (colon)
1229	msg_row = row;
1230}
1231
1232    static void
1233do_intro_line(row, mesg, add_version, attr)
1234    int		row;
1235    char_u	*mesg;
1236    int		add_version;
1237    int		attr;
1238{
1239    char_u	vers[20];
1240    int		col;
1241    char_u	*p;
1242    int		l;
1243    int		clen;
1244#ifdef MODIFIED_BY
1245# define MODBY_LEN 150
1246    char_u	modby[MODBY_LEN];
1247
1248    if (*mesg == ' ')
1249    {
1250	vim_strncpy(modby, (char_u *)_("Modified by "), MODBY_LEN - 1);
1251	l = STRLEN(modby);
1252	vim_strncpy(modby + l, (char_u *)MODIFIED_BY, MODBY_LEN - l - 1);
1253	mesg = modby;
1254    }
1255#endif
1256
1257    /* Center the message horizontally. */
1258    col = vim_strsize(mesg);
1259    if (add_version)
1260    {
1261	STRCPY(vers, mediumVersion);
1262	if (highest_patch())
1263	{
1264	    /* Check for 9.9x or 9.9xx, alpha/beta version */
1265	    if (isalpha((int)mediumVersion[3]))
1266	    {
1267		if (isalpha((int)mediumVersion[4]))
1268		    sprintf((char *)vers + 5, ".%d%s", highest_patch(),
1269							   mediumVersion + 5);
1270		else
1271		    sprintf((char *)vers + 4, ".%d%s", highest_patch(),
1272							   mediumVersion + 4);
1273	    }
1274	    else
1275		sprintf((char *)vers + 3, ".%d", highest_patch());
1276	}
1277	col += (int)STRLEN(vers);
1278    }
1279    col = (Columns - col) / 2;
1280    if (col < 0)
1281	col = 0;
1282
1283    /* Split up in parts to highlight <> items differently. */
1284    for (p = mesg; *p != NUL; p += l)
1285    {
1286	clen = 0;
1287	for (l = 0; p[l] != NUL
1288			 && (l == 0 || (p[l] != '<' && p[l - 1] != '>')); ++l)
1289	{
1290#ifdef FEAT_MBYTE
1291	    if (has_mbyte)
1292	    {
1293		clen += ptr2cells(p + l);
1294		l += (*mb_ptr2len)(p + l) - 1;
1295	    }
1296	    else
1297#endif
1298		clen += byte2cells(p[l]);
1299	}
1300	screen_puts_len(p, l, row, col, *p == '<' ? hl_attr(HLF_8) : attr);
1301	col += clen;
1302    }
1303
1304    /* Add the version number to the version line. */
1305    if (add_version)
1306	screen_puts(vers, row, col, 0);
1307}
1308
1309/*
1310 * ":intro": clear screen, display intro screen and wait for return.
1311 */
1312    void
1313ex_intro(eap)
1314    exarg_T	*eap UNUSED;
1315{
1316    screenclear();
1317    intro_message(TRUE);
1318    wait_return(TRUE);
1319}
1320