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