xref: /vim-8.2.3635/src/version.c (revision c3d2c447)
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_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 
715 static 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  */
728 static char *(extra_patches[]) =
729 {   /* Add your patch description below this line */
730 /**/
731     NULL
732 };
733 
734     int
735 highest_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
751 has_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
764 ex_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
778 list_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
1081 version_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 
1093 static 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
1101 intro_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
1233 do_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
1313 ex_intro(eap)
1314     exarg_T	*eap UNUSED;
1315 {
1316     screenclear();
1317     intro_message(TRUE);
1318     wait_return(TRUE);
1319 }
1320