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