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