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