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