summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2004-06-13 14:51:16 +0000
committerBram Moolenaar <Bram@vim.org>2004-06-13 14:51:16 +0000
commitb4210b3bc14e2918f153a7307530fbe6eba659e1 (patch)
tree610f8017f379a451dda33b061165719da444aebe /src
parentad3a468653a0f2cc23bdf5ec370f8a198d855308 (diff)
updated for version 7.0001
Diffstat (limited to 'src')
-rw-r--r--src/main.c3201
1 files changed, 3201 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000000..91854bf7aa
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,3201 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+ * Do ":help uganda" in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+#if defined(MSDOS) || defined(WIN32) || defined(_WIN64)
+# include <io.h> /* for close() and dup() */
+#endif
+
+#define EXTERN
+#include "vim.h"
+
+#ifdef SPAWNO
+# include <spawno.h> /* special MSDOS swapping library */
+#endif
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#ifdef __CYGWIN__
+# ifndef WIN32
+# include <sys/cygwin.h> /* for cygwin_conv_to_posix_path() */
+# endif
+# include <limits.h>
+#endif
+
+#if defined(UNIX) || defined(VMS)
+static int file_owned __ARGS((char *fname));
+#endif
+static void mainerr __ARGS((int, char_u *));
+static void main_msg __ARGS((char *s));
+static void usage __ARGS((void));
+static int get_number_arg __ARGS((char_u *p, int *idx, int def));
+static void main_start_gui __ARGS((void));
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+static void check_swap_exists_action __ARGS((void));
+#endif
+#ifdef FEAT_CLIENTSERVER
+static void cmdsrv_main __ARGS((int *argc, char **argv, char_u *serverName_arg, char_u **serverStr));
+static char_u *serverMakeName __ARGS((char_u *arg, char *cmd));
+#endif
+
+
+#ifdef STARTUPTIME
+static FILE *time_fd = NULL;
+#endif
+
+#define FEAT_PRECOMMANDS
+
+/*
+ * Different types of error messages.
+ */
+static char *(main_errors[]) =
+{
+ N_("Unknown option"),
+#define ME_UNKNOWN_OPTION 0
+ N_("Too many edit arguments"),
+#define ME_TOO_MANY_ARGS 1
+ N_("Argument missing after"),
+#define ME_ARG_MISSING 2
+ N_("Garbage after option"),
+#define ME_GARBAGE 3
+ N_("Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"),
+#define ME_EXTRA_CMD 4
+ N_("Invalid argument for"),
+#define ME_INVALID_ARG 5
+};
+
+/* Maximum number of commands from + or -c options */
+#define MAX_ARG_CMDS 10
+
+#ifndef PROTO /* don't want a prototype for main() */
+ int
+# ifdef VIMDLL
+_export
+# endif
+# ifdef FEAT_GUI_MSWIN
+# ifdef __BORLANDC__
+_cdecl
+# endif
+VimMain
+# else
+main
+# endif
+(argc, argv)
+ int argc;
+ char **argv;
+{
+ char_u *initstr; /* init string from environment */
+ char_u *term = NULL; /* specified terminal name */
+ char_u *fname = NULL; /* file name from command line */
+ char_u *tagname = NULL; /* tag from -t option */
+ char_u *use_vimrc = NULL; /* vimrc from -u option */
+#ifdef FEAT_QUICKFIX
+ char_u *use_ef = NULL; /* 'errorfile' from -q option */
+#endif
+#ifdef FEAT_CRYPT
+ int ask_for_key = FALSE; /* -x argument */
+#endif
+ int n_commands = 0; /* no. of commands from + or -c */
+ char_u *commands[MAX_ARG_CMDS]; /* commands from + or -c option */
+#ifdef FEAT_PRECOMMANDS
+ int p_commands = 0; /* no. of commands from --cmd */
+ char_u *pre_commands[MAX_ARG_CMDS]; /* commands from --cmd option */
+#endif
+ int no_swap_file = FALSE; /* "-n" option used */
+ int c;
+ int i;
+ char_u *p = NULL;
+ int bin_mode = FALSE; /* -b option used */
+#ifdef FEAT_EVAL
+ int use_debug_break_level = -1;
+#endif
+#ifdef FEAT_WINDOWS
+ int window_count = -1; /* number of windows to use */
+ int arg_idx; /* index in argument list */
+ int vert_windows = MAYBE; /* "-O" used instead of "-o" */
+#endif
+ int had_minmin = FALSE; /* found "--" option */
+ int argv_idx; /* index in argv[n][] */
+ int want_full_screen = TRUE;
+ int want_argument; /* option with argument */
+#define EDIT_NONE 0 /* no edit type yet */
+#define EDIT_FILE 1 /* file name argument[s] given, use argument list */
+#define EDIT_STDIN 2 /* read file from stdin */
+#define EDIT_TAG 3 /* tag name argument given, use tagname */
+#define EDIT_QF 4 /* start in quickfix mode */
+ int edit_type = EDIT_NONE; /* type of editing to do */
+#ifdef FEAT_DIFF
+ int diff_mode = FALSE; /* start with 'diff' set */
+#endif
+ int evim_mode = FALSE; /* started as "evim" */
+ int stdout_isatty; /* is stdout a terminal? */
+ int input_isatty; /* is active input a terminal? */
+#ifdef MSWIN
+ int full_path = FALSE;
+#endif
+#ifdef FEAT_CLIENTSERVER
+ char_u *serverStr = NULL;
+ char_u *serverName_arg = NULL; /* cmdline arg for server name */
+ int serverArg = FALSE; /* TRUE when argument for a server */
+ char_u *servername = NULL; /* allocated name for our server */
+#endif
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
+ int literal = FALSE; /* don't expand file names */
+#endif
+
+# ifdef NBDEBUG
+ nbdebug_log_init("SPRO_GVIM_DEBUG", "SPRO_GVIM_DLEVEL");
+ nbdebug_wait(WT_ENV | WT_WAIT | WT_STOP, "SPRO_GVIM_WAIT", 20);
+# endif
+
+ /*
+ * Do any system-specific initialisations. These can NOT use IObuff or
+ * NameBuff. Thus emsg2() cannot be called!
+ */
+ mch_early_init();
+
+#ifdef FEAT_TCL
+ vim_tcl_init(argv[0]);
+#endif
+
+#ifdef MEM_PROFILE
+ atexit(vim_mem_profile_dump);
+#endif
+
+#ifdef STARTUPTIME
+ time_fd = fopen(STARTUPTIME, "a");
+ TIME_MSG("--- VIM STARTING ---");
+#endif
+
+#ifdef __EMX__
+ _wildcard(&argc, &argv);
+#endif
+
+#ifdef FEAT_MBYTE
+ (void)mb_init(); /* init mb_bytelen_tab[] to ones */
+#endif
+
+#ifdef __QNXNTO__
+ qnx_init(); /* PhAttach() for clipboard, (and gui) */
+#endif
+
+#ifdef MAC_OS_CLASSIC
+ /* Macintosh needs this before any memory is allocated. */
+ gui_prepare(&argc, argv); /* Prepare for possibly starting GUI sometime */
+ TIME_MSG("GUI prepared");
+#endif
+
+ /* Init the table of Normal mode commands. */
+ init_normal_cmds();
+
+#if defined(HAVE_DATE_TIME) && defined(VMS) && defined(VAXC)
+ make_version();
+#endif
+
+ /*
+ * Allocate space for the generic buffers (needed for set_init_1() and
+ * EMSG2()).
+ */
+ if ((IObuff = alloc(IOSIZE)) == NULL
+ || (NameBuff = alloc(MAXPATHL)) == NULL)
+ mch_exit(0);
+
+ TIME_MSG("Allocated generic buffers");
+
+#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
+ /*
+ * Setup to use the current locale (for ctype() and many other things).
+ * NOTE: Translated messages with encodings other than latin1 will not
+ * work until set_init_1() has been called!
+ */
+ setlocale(LC_ALL, "");
+
+# ifdef FEAT_GETTEXT
+ {
+ int mustfree = FALSE;
+
+# ifdef DYNAMIC_GETTEXT
+ /* Initialize the gettext library */
+ dyn_libintl_init(NULL);
+# endif
+ /* expand_env() doesn't work yet, because chartab[] is not initialized
+ * yet, call vim_getenv() directly */
+ p = vim_getenv((char_u *)"VIMRUNTIME", &mustfree);
+ if (p != NULL && *p != NUL)
+ {
+ STRCPY(NameBuff, p);
+ STRCAT(NameBuff, "/lang");
+ bindtextdomain(VIMPACKAGE, (char *)NameBuff);
+ }
+ if (mustfree)
+ vim_free(p);
+ textdomain(VIMPACKAGE);
+ }
+# endif
+ TIME_MSG("locale set");
+#endif
+
+#ifdef FEAT_GUI
+ gui.dofork = TRUE; /* default is to use fork() */
+#endif
+
+#if defined(FEAT_XCLIPBOARD) || defined(FEAT_CLIENTSERVER)
+ /*
+ * Get the name of the display, before gui_prepare() removes it from
+ * argv[]. Used for the xterm-clipboard display.
+ *
+ * Also find the --server... arguments
+ */
+ for (i = 1; i < argc; i++)
+ {
+ if (STRCMP(argv[i], "--") == 0)
+ break;
+# ifdef FEAT_XCLIPBOARD
+ else if (STRICMP(argv[i], "-display") == 0
+# ifdef FEAT_GUI_GTK
+ || STRICMP(argv[i], "--display") == 0
+# endif
+ )
+ {
+ if (i == argc - 1)
+ mainerr_arg_missing((char_u *)argv[i]);
+ xterm_display = argv[++i];
+ }
+# endif
+# ifdef FEAT_CLIENTSERVER
+ else if (STRICMP(argv[i], "--servername") == 0)
+ {
+ if (i == argc - 1)
+ mainerr_arg_missing((char_u *)argv[i]);
+ serverName_arg = (char_u *)argv[++i];
+ }
+ else if (STRICMP(argv[i], "--serverlist") == 0
+ || STRICMP(argv[i], "--remote-send") == 0
+ || STRICMP(argv[i], "--remote-expr") == 0
+ || STRICMP(argv[i], "--remote") == 0
+ || STRICMP(argv[i], "--remote-silent") == 0)
+ serverArg = TRUE;
+ else if (STRICMP(argv[i], "--remote-wait") == 0
+ || STRICMP(argv[i], "--remote-wait-silent") == 0)
+ {
+ serverArg = TRUE;
+#ifdef FEAT_GUI
+ /* don't fork() when starting the GUI to edit the files ourself */
+ gui.dofork = FALSE;
+#endif
+ }
+# endif
+# ifdef FEAT_GUI_GTK
+ else if (STRICMP(argv[i], "--socketid") == 0)
+ {
+ unsigned int socket_id;
+ int count;
+
+ if (i == argc - 1)
+ mainerr_arg_missing((char_u *)argv[i]);
+ if (STRNICMP(argv[i+1], "0x", 2) == 0)
+ count = sscanf(&(argv[i + 1][2]), "%x", &socket_id);
+ else
+ count = sscanf(argv[i+1], "%u", &socket_id);
+ if (count != 1)
+ mainerr(ME_INVALID_ARG, (char_u *)argv[i]);
+ else
+ gtk_socket_id = socket_id;
+ i++;
+ }
+ else if (STRICMP(argv[i], "--echo-wid") == 0)
+ echo_wid_arg = TRUE;
+# endif
+ }
+#endif
+
+#ifdef FEAT_SUN_WORKSHOP
+ findYourself(argv[0]);
+#endif
+#if defined(FEAT_GUI) && !defined(MAC_OS_CLASSIC)
+ gui_prepare(&argc, argv); /* Prepare for possibly starting GUI sometime */
+ TIME_MSG("GUI prepared");
+#endif
+
+#ifdef FEAT_CLIPBOARD
+ clip_init(FALSE); /* Initialise clipboard stuff */
+ TIME_MSG("clipboard setup");
+#endif
+
+ /*
+ * Check if we have an interactive window.
+ * On the Amiga: If there is no window, we open one with a newcli command
+ * (needed for :! to * work). mch_check_win() will also handle the -d or
+ * -dev argument.
+ */
+ stdout_isatty = (mch_check_win(argc, argv) != FAIL);
+ TIME_MSG("window checked");
+
+ /*
+ * Allocate the first window and buffer. Can't do much without it.
+ */
+ win_alloc_first();
+
+ init_yank(); /* init yank buffers */
+
+ /* Init the argument list to empty. */
+ alist_init(&global_alist);
+
+ /*
+ * Set the default values for the options.
+ * NOTE: Non-latin1 translated messages are working only after this,
+ * because this is where "has_mbyte" will be set, which is used by
+ * msg_outtrans_len_attr().
+ * First find out the home directory, needed to expand "~" in options.
+ */
+ init_homedir(); /* find real value of $HOME */
+ set_init_1();
+ TIME_MSG("inits 1");
+
+#ifdef FEAT_EVAL
+ set_lang_var(); /* set v:lang and v:ctype */
+#endif
+
+#ifdef FEAT_CLIENTSERVER
+ /*
+ * Do the client-server stuff, unless "--servername ''" was used.
+ */
+ if (serverName_arg == NULL || *serverName_arg != NUL)
+ {
+# ifdef WIN32
+ /* Initialise the client/server messaging infrastructure. */
+ serverInitMessaging();
+# endif
+
+ /*
+ * When a command server argument was found, execute it. This may
+ * exit Vim when it was successful.
+ */
+ if (serverArg)
+ cmdsrv_main(&argc, argv, serverName_arg, &serverStr);
+
+ /* If we're still running, get the name to register ourselves.
+ * On Win32 can register right now, for X11 need to setup the
+ * clipboard first, it's further down. */
+ servername = serverMakeName(serverName_arg, argv[0]);
+# ifdef WIN32
+ if (servername != NULL)
+ {
+ serverSetName(servername);
+ vim_free(servername);
+ }
+# endif
+ }
+#endif
+
+ /*
+ * Check for: [r][e][g][vi|vim|view][diff][ex[im]]
+ * If the executable name starts with "r" we disable shell commands.
+ * If the next character is "e" we run in Easy mode.
+ * If the next character is "g" we run the GUI version.
+ * If the next characters are "view" we start in readonly mode.
+ * If the next characters are "diff" or "vimdiff" we start in diff mode.
+ * If the next characters are "ex" we start in Ex mode. If it's followed
+ * by "im" use improved Ex mode.
+ */
+ initstr = gettail((char_u *)argv[0]);
+
+#ifdef MACOS_X_UNIX
+ /* An issue has been seen when launching Vim in such a way that
+ * $PWD/$ARGV[0] or $ARGV[0] is not the absolute path to the
+ * executable or a symbolic link of it. Until this issue is resolved
+ * we prohibit the GUI from being used.
+ */
+ if (STRCMP(initstr, argv[0]) == 0)
+ disallow_gui = TRUE;
+#endif
+
+#ifdef FEAT_EVAL
+ set_vim_var_string(VV_PROGNAME, initstr, -1);
+#endif
+
+ /* TODO: On MacOS X default to gui if argv[0] ends in:
+ * /vim.app/Contents/MacOS/Vim */
+
+ if (TOLOWER_ASC(initstr[0]) == 'r')
+ {
+ restricted = TRUE;
+ ++initstr;
+ }
+
+ /* Avoid using evim mode for "editor". */
+ if (TOLOWER_ASC(initstr[0]) == 'e'
+ && (TOLOWER_ASC(initstr[1]) == 'v'
+ || TOLOWER_ASC(initstr[1]) == 'g'))
+ {
+#ifdef FEAT_GUI
+ gui.starting = TRUE;
+#endif
+ evim_mode = TRUE;
+ ++initstr;
+ }
+
+ if (TOLOWER_ASC(initstr[0]) == 'g')
+ {
+ main_start_gui();
+#ifdef FEAT_GUI
+ ++initstr;
+#endif
+ }
+
+ if (STRNICMP(initstr, "view", 4) == 0)
+ {
+ readonlymode = TRUE;
+ curbuf->b_p_ro = TRUE;
+ p_uc = 10000; /* don't update very often */
+ initstr += 4;
+ }
+ else if (STRNICMP(initstr, "vim", 3) == 0)
+ initstr += 3;
+
+ /* Catch "[r][g]vimdiff" and "[r][g]viewdiff". */
+ if (STRICMP(initstr, "diff") == 0)
+ {
+#ifdef FEAT_DIFF
+ diff_mode = TRUE;
+#else
+ mch_errmsg(_("This Vim was not compiled with the diff feature."));
+ mch_errmsg("\n");
+ mch_exit(2);
+#endif
+ }
+
+ if (STRNICMP(initstr, "ex", 2) == 0)
+ {
+ if (STRNICMP(initstr + 2, "im", 2) == 0)
+ exmode_active = EXMODE_VIM;
+ else
+ exmode_active = EXMODE_NORMAL;
+ change_compatible(TRUE); /* set 'compatible' */
+ }
+
+ initstr = gettail((char_u *)argv[0]);
+ ++argv;
+ --argc;
+
+ /*
+ * Process the command line arguments.
+ */
+ argv_idx = 1; /* active option letter is argv[0][argv_idx] */
+ while (argc > 0)
+ {
+ /*
+ * "+" or "+{number}" or "+/{pat}" or "+{command}" argument.
+ */
+ if (argv[0][0] == '+' && !had_minmin)
+ {
+ if (n_commands >= MAX_ARG_CMDS)
+ mainerr(ME_EXTRA_CMD, NULL);
+ argv_idx = -1; /* skip to next argument */
+ if (argv[0][1] == NUL)
+ commands[n_commands++] = (char_u *)"$";
+ else
+ commands[n_commands++] = (char_u *)&(argv[0][1]);
+ }
+
+ /*
+ * Optional argument.
+ */
+ else if (argv[0][0] == '-' && !had_minmin)
+ {
+ want_argument = FALSE;
+ c = argv[0][argv_idx++];
+#ifdef VMS
+ /*
+ * VMS only uses upper case command lines. Interpret "-X" as "-x"
+ * and "-/X" as "-X".
+ */
+ if (c == '/')
+ {
+ c = argv[0][argv_idx++];
+ c = TOUPPER_ASC(c);
+ }
+ else
+ c = TOLOWER_ASC(c);
+#endif
+ switch (c)
+ {
+ case NUL: /* "vim -" read from stdin */
+ /* "ex -" silent mode */
+ if (exmode_active)
+ silent_mode = TRUE;
+ else
+ {
+ if (edit_type != EDIT_NONE)
+ mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
+ edit_type = EDIT_STDIN;
+ read_cmd_fd = 2; /* read from stderr instead of stdin */
+ }
+ argv_idx = -1; /* skip to next argument */
+ break;
+
+ case '-': /* "--" don't take any more options */
+ /* "--help" give help message */
+ /* "--version" give version message */
+ /* "--literal" take files literally */
+ /* "--nofork" don't fork */
+ /* "--noplugin[s]" skip plugins */
+ /* "--cmd <cmd>" execute cmd before vimrc */
+ if (STRICMP(argv[0] + argv_idx, "help") == 0)
+ usage();
+ else if (STRICMP(argv[0] + argv_idx, "version") == 0)
+ {
+ Columns = 80; /* need to init Columns */
+ info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
+ list_version();
+ msg_putchar('\n');
+ msg_didout = FALSE;
+ mch_exit(0);
+ }
+ else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0)
+ {
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
+ literal = TRUE;
+#endif
+ }
+ else if (STRNICMP(argv[0] + argv_idx, "nofork", 6) == 0)
+ {
+#ifdef FEAT_GUI
+ gui.dofork = FALSE; /* don't fork() when starting GUI */
+#endif
+ }
+ else if (STRNICMP(argv[0] + argv_idx, "noplugin", 8) == 0)
+ p_lpl = FALSE;
+#ifdef FEAT_PRECOMMANDS
+ else if (STRNICMP(argv[0] + argv_idx, "cmd", 3) == 0)
+ {
+ want_argument = TRUE;
+ argv_idx += 3;
+ }
+#endif
+#ifdef FEAT_CLIENTSERVER
+ else if (STRNICMP(argv[0] + argv_idx, "serverlist", 10) == 0)
+ ; /* already processed -- no arg */
+ else if (STRNICMP(argv[0] + argv_idx, "servername", 10) == 0
+ || STRNICMP(argv[0] + argv_idx, "serversend", 10) == 0)
+ {
+ /* already processed -- snatch the following arg */
+ if (argc > 1)
+ {
+ --argc;
+ ++argv;
+ }
+ }
+#endif
+#ifdef FEAT_GUI_GTK
+ else if (STRNICMP(argv[0] + argv_idx, "socketid", 8) == 0)
+ {
+ /* already processed -- snatch the following arg */
+ if (argc > 1)
+ {
+ --argc;
+ ++argv;
+ }
+ }
+ else if (STRNICMP(argv[0] + argv_idx, "echo-wid", 8) == 0)
+ {
+ /* already processed, skip */
+ }
+#endif
+ else
+ {
+ if (argv[0][argv_idx])
+ mainerr(ME_UNKNOWN_OPTION, (char_u *)argv[0]);
+ had_minmin = TRUE;
+ }
+ if (!want_argument)
+ argv_idx = -1; /* skip to next argument */
+ break;
+
+ case 'A': /* "-A" start in Arabic mode */
+#ifdef FEAT_ARABIC
+ set_option_value((char_u *)"arabic", 1L, NULL, 0);
+#else
+ mch_errmsg(_(e_noarabic));
+ mch_exit(2);
+#endif
+ break;
+
+ case 'b': /* "-b" binary mode */
+ bin_mode = TRUE; /* postpone to after reading .exrc files */
+ break;
+
+ case 'C': /* "-C" Compatible */
+ change_compatible(TRUE);
+ break;
+
+ case 'e': /* "-e" Ex mode */
+ exmode_active = EXMODE_NORMAL;
+ break;
+
+ case 'E': /* "-E" Improved Ex mode */
+ exmode_active = EXMODE_VIM;
+ break;
+
+ case 'f': /* "-f" GUI: run in foreground. Amiga: open
+ window directly, not with newcli */
+#ifdef FEAT_GUI
+ gui.dofork = FALSE; /* don't fork() when starting GUI */
+#endif
+ break;
+
+ case 'g': /* "-g" start GUI */
+ main_start_gui();
+ break;
+
+ case 'F': /* "-F" start in Farsi mode: rl + fkmap set */
+#ifdef FEAT_FKMAP
+ curwin->w_p_rl = p_fkmap = TRUE;
+#else
+ mch_errmsg(_(e_nofarsi));
+ mch_exit(2);
+#endif
+ break;
+
+ case 'h': /* "-h" give help message */
+#ifdef FEAT_GUI_GNOME
+ /* Tell usage() to exit for "gvim". */
+ gui.starting = FALSE;
+#endif
+ usage();
+ break;
+
+ case 'H': /* "-H" start in Hebrew mode: rl + hkmap set */
+#ifdef FEAT_RIGHTLEFT
+ curwin->w_p_rl = p_hkmap = TRUE;
+#else
+ mch_errmsg(_(e_nohebrew));
+ mch_exit(2);
+#endif
+ break;
+
+ case 'l': /* "-l" lisp mode, 'lisp' and 'showmatch' on */
+#ifdef FEAT_LISP
+ set_option_value((char_u *)"lisp", 1L, NULL, 0);
+ p_sm = TRUE;
+#endif
+ break;
+
+#ifdef TARGET_API_MAC_OSX
+ /* For some reason on MacOS X, an argument like:
+ -psn_0_10223617 is passed in when invoke from Finder
+ or with the 'open' command */
+ case 'p':
+ argv_idx = -1; /* bypass full -psn */
+ main_start_gui();
+ break;
+#endif
+ case 'M': /* "-M" no changes or writing of files */
+ reset_modifiable();
+ /* FALLTRHOUGH */
+
+ case 'm': /* "-m" no writing of files */
+ p_write = FALSE;
+ break;
+
+ case 'y': /* "-y" easy mode */
+#ifdef FEAT_GUI
+ gui.starting = TRUE; /* start GUI a bit later */
+#endif
+ evim_mode = TRUE;
+ break;
+
+ case 'N': /* "-N" Nocompatible */
+ change_compatible(FALSE);
+ break;
+
+ case 'n': /* "-n" no swap file */
+ no_swap_file = TRUE;
+ break;
+
+ case 'o': /* "-o[N]" open N horizontal split windows */
+#ifdef FEAT_WINDOWS
+ /* default is 0: open window for each file */
+ window_count = get_number_arg((char_u *)argv[0], &argv_idx, 0);
+ vert_windows = FALSE;
+#endif
+ break;
+
+ case 'O': /* "-O[N]" open N vertical split windows */
+#if defined(FEAT_VERTSPLIT) && defined(FEAT_WINDOWS)
+ /* default is 0: open window for each file */
+ window_count = get_number_arg((char_u *)argv[0], &argv_idx, 0);
+ vert_windows = TRUE;
+#endif
+ break;
+
+#ifdef FEAT_QUICKFIX
+ case 'q': /* "-q" QuickFix mode */
+ if (edit_type != EDIT_NONE)
+ mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
+ edit_type = EDIT_QF;
+ if (argv[0][argv_idx]) /* "-q{errorfile}" */
+ {
+ use_ef = (char_u *)argv[0] + argv_idx;
+ argv_idx = -1;
+ }
+ else if (argc > 1) /* "-q {errorfile}" */
+ want_argument = TRUE;
+ break;
+#endif
+
+ case 'R': /* "-R" readonly mode */
+ readonlymode = TRUE;
+ curbuf->b_p_ro = TRUE;
+ p_uc = 10000; /* don't update very often */
+ break;
+
+ case 'r': /* "-r" recovery mode */
+ case 'L': /* "-L" recovery mode */
+ recoverymode = 1;
+ break;
+
+ case 's':
+ if (exmode_active) /* "-s" silent (batch) mode */
+ silent_mode = TRUE;
+ else /* "-s {scriptin}" read from script file */
+ want_argument = TRUE;
+ break;
+
+ case 't': /* "-t {tag}" or "-t{tag}" jump to tag */
+ if (edit_type != EDIT_NONE)
+ mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
+ edit_type = EDIT_TAG;
+ if (argv[0][argv_idx]) /* "-t{tag}" */
+ {
+ tagname = (char_u *)argv[0] + argv_idx;
+ argv_idx = -1;
+ }
+ else /* "-t {tag}" */
+ want_argument = TRUE;
+ break;
+
+#ifdef FEAT_EVAL
+ case 'D': /* "-D" Debugging */
+ use_debug_break_level = 9999;
+ break;
+#endif
+#ifdef FEAT_DIFF
+ case 'd': /* "-d" 'diff' */
+# ifdef AMIGA
+ /* check for "-dev {device}" */
+ if (argv[0][argv_idx] == 'e' && argv[0][argv_idx + 1] == 'v')
+ want_argument = TRUE;
+ else
+# endif
+ diff_mode = TRUE;
+ break;
+#endif
+ case 'V': /* "-V{N}" Verbose level */
+ /* default is 10: a little bit verbose */
+ p_verbose = get_number_arg((char_u *)argv[0], &argv_idx, 10);
+ break;
+
+ case 'v': /* "-v" Vi-mode (as if called "vi") */
+ exmode_active = 0;
+#ifdef FEAT_GUI
+ gui.starting = FALSE; /* don't start GUI */
+#endif
+ break;
+
+ case 'w': /* "-w{number}" set window height */
+ /* "-w {scriptout}" write to script */
+ if (vim_isdigit(((char_u *)argv[0])[argv_idx]))
+ {
+ argv_idx = -1;
+ break; /* not implemented, ignored */
+ }
+ want_argument = TRUE;
+ break;
+
+#ifdef FEAT_CRYPT
+ case 'x': /* "-x" encrypted reading/writing of files */
+ ask_for_key = TRUE;
+ break;
+#endif
+
+ case 'X': /* "-X" don't connect to X server */
+#if (defined(UNIX) || defined(VMS)) && defined(FEAT_X11)
+ x_no_connect = TRUE;
+#endif
+ break;
+
+ case 'Z': /* "-Z" restricted mode */
+ restricted = TRUE;
+ break;
+
+ case 'c': /* "-c {command}" execute command */
+ case 'S': /* "-S {file}" execute Vim script */
+ case 'i': /* "-i {viminfo}" use for viminfo */
+#ifndef FEAT_DIFF
+ case 'd': /* "-d {device}" device (for Amiga) */
+#endif
+ case 'T': /* "-T {terminal}" terminal name */
+ case 'u': /* "-u {vimrc}" vim inits file */
+ case 'U': /* "-U {gvimrc}" gvim inits file */
+ case 'W': /* "-W {scriptout}" overwrite */
+#ifdef FEAT_GUI_W32
+ case 'P': /* "-P {parent title}" MDI parent */
+#endif
+ want_argument = TRUE;
+ break;
+
+ default:
+ mainerr(ME_UNKNOWN_OPTION, (char_u *)argv[0]);
+ }
+
+ /*
+ * Handle options with argument.
+ */
+ if (want_argument)
+ {
+ /*
+ * Check for garbage immediately after the option letter.
+ */
+ if (argv[0][argv_idx] != NUL)
+ mainerr(ME_GARBAGE, (char_u *)argv[0]);
+
+ --argc;
+ if (argc < 1 && c != 'S')
+ mainerr_arg_missing((char_u *)argv[0]);
+ ++argv;
+ argv_idx = -1;
+
+ switch (c)
+ {
+ case 'c': /* "-c {command}" execute command */
+ case 'S': /* "-S {file}" execute Vim script */
+ if (n_commands >= MAX_ARG_CMDS)
+ mainerr(ME_EXTRA_CMD, NULL);
+ if (c == 'S')
+ {
+ char *a;
+
+ if (argc < 1)
+ /* "-S" without argument: use default session file
+ * name. */
+ a = SESSION_FILE;
+ else if (argv[0][0] == '-')
+ {
+ /* "-S" followed by another option: use default
+ * session file name. */
+ a = SESSION_FILE;
+ ++argc;
+ --argv;
+ }
+ else
+ a = argv[0];
+ p = alloc((unsigned)(STRLEN(a) + 4));
+ if (p == NULL)
+ mch_exit(2);
+ sprintf((char *)p, "so %s", a);
+ commands[n_commands++] = p;
+ }
+ else
+ commands[n_commands++] = (char_u *)argv[0];
+ break;
+
+#ifdef FEAT_PRECOMMANDS
+ case '-': /* "--cmd {command}" execute command */
+ if (p_commands >= MAX_ARG_CMDS)
+ mainerr(ME_EXTRA_CMD, NULL);
+ pre_commands[p_commands++] = (char_u *)argv[0];
+ break;
+#endif
+
+ /* case 'd': -d {device} is handled in mch_check_win() for the
+ * Amiga */
+
+#ifdef FEAT_QUICKFIX
+ case 'q': /* "-q {errorfile}" QuickFix mode */
+ use_ef = (char_u *)argv[0];
+ break;
+#endif
+
+ case 'i': /* "-i {viminfo}" use for viminfo */
+ use_viminfo = (char_u *)argv[0];
+ break;
+
+ case 's': /* "-s {scriptin}" read from script file */
+ if (scriptin[0] != NULL)
+ {
+scripterror:
+ mch_errmsg(_("Attempt to open script file again: \""));
+ mch_errmsg(argv[-1]);
+ mch_errmsg(" ");
+ mch_errmsg(argv[0]);
+ mch_errmsg("\"\n");
+ mch_exit(2);
+ }
+ if ((scriptin[0] = mch_fopen(argv[0], READBIN)) == NULL)
+ {
+ mch_errmsg(_("Cannot open for reading: \""));
+ mch_errmsg(argv[0]);
+ mch_errmsg("\"\n");
+ mch_exit(2);
+ }
+ if (save_typebuf() == FAIL)
+ mch_exit(2); /* out of memory */
+ break;
+
+ case 't': /* "-t {tag}" */
+ tagname = (char_u *)argv[0];
+ break;
+
+ case 'T': /* "-T {terminal}" terminal name */
+ /*
+ * The -T term option is always available and when
+ * HAVE_TERMLIB is supported it overrides the environment
+ * variable TERM.
+ */
+#ifdef FEAT_GUI
+ if (term_is_gui((char_u *)argv[0]))
+ gui.starting = TRUE; /* start GUI a bit later */
+ else
+#endif
+ term = (char_u *)argv[0];
+ break;
+
+ case 'u': /* "-u {vimrc}" vim inits file */
+ use_vimrc = (char_u *)argv[0];
+ break;
+
+ case 'U': /* "-U {gvimrc}" gvim inits file */
+#ifdef FEAT_GUI
+ use_gvimrc = (char_u *)argv[0];
+#endif
+ break;
+
+ case 'w': /* "-w {scriptout}" append to script file */
+ case 'W': /* "-W {scriptout}" overwrite script file */
+ if (scriptout != NULL)
+ goto scripterror;
+ if ((scriptout = mch_fopen(argv[0],
+ c == 'w' ? APPENDBIN : WRITEBIN)) == NULL)
+ {
+ mch_errmsg(_("Cannot open for script output: \""));
+ mch_errmsg(argv[0]);
+ mch_errmsg("\"\n");
+ mch_exit(2);
+ }
+ break;
+
+#ifdef FEAT_GUI_W32
+ case 'P': /* "-P {parent title}" MDI parent */
+ gui_mch_set_parent(argv[0]);
+ break;
+#endif
+ }
+ }
+ }
+
+ /*
+ * File name argument.
+ */
+ else
+ {
+ argv_idx = -1; /* skip to next argument */
+
+ /* Check for only one type of editing. */
+ if (edit_type != EDIT_NONE && edit_type != EDIT_FILE)
+ mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
+ edit_type = EDIT_FILE;
+
+#ifdef MSWIN
+ /* Remember if the argument was a full path before changing
+ * slashes to backslashes. */
+ if (argv[0][0] != NUL && argv[0][1] == ':' && argv[0][2] == '\\')
+ full_path = TRUE;
+#endif
+
+ /* Add the file to the global argument list. */
+ if (ga_grow(&global_alist.al_ga, 1) == FAIL
+ || (p = vim_strsave((char_u *)argv[0])) == NULL)
+ mch_exit(2);
+#ifdef FEAT_DIFF
+ if (diff_mode && mch_isdir(p) && GARGCOUNT > 0
+ && !mch_isdir(alist_name(&GARGLIST[0])))
+ {
+ char_u *r;
+
+ r = concat_fnames(p, gettail(alist_name(&GARGLIST[0])), TRUE);
+ if (r != NULL)
+ {
+ vim_free(p);
+ p = r;
+ }
+ }
+#endif
+#if defined(__CYGWIN32__) && !defined(WIN32)
+ /*
+ * If vim is invoked by non-Cygwin tools, convert away any
+ * DOS paths, so things like .swp files are created correctly.
+ * Look for evidence of non-Cygwin paths before we bother.
+ * This is only for when using the Unix files.
+ */
+ if (strpbrk(p, "\\:") != NULL)
+ {
+ char posix_path[PATH_MAX];
+
+ cygwin_conv_to_posix_path(p, posix_path);
+ vim_free(p);
+ p = vim_strsave(posix_path);
+ if (p == NULL)
+ mch_exit(2);
+ }
+#endif
+ alist_add(&global_alist, p,
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
+ literal ? 2 : 0 /* add buffer number after expanding */
+#else
+ 2 /* add buffer number now and use curbuf */
+#endif
+ );
+ }
+
+ /*
+ * If there are no more letters after the current "-", go to next
+ * argument. argv_idx is set to -1 when the current argument is to be
+ * skipped.
+ */
+ if (argv_idx <= 0 || argv[0][argv_idx] == NUL)
+ {
+ --argc;
+ ++argv;
+ argv_idx = 1;
+ }
+ }
+ TIME_MSG("parsing arguments");
+
+ /*
+ * On some systems, when we compile with the GUI, we always use it. On Mac
+ * there is no terminal version, and on Windows we can't figure out how to
+ * fork one off with :gui.
+ */
+#ifdef ALWAYS_USE_GUI
+ gui.starting = TRUE;
+#else
+# if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK)
+ /*
+ * Check if the GUI can be started. Reset gui.starting if not.
+ * Don't know about other systems, stay on the safe side and don't check.
+ */
+ if (gui.starting && gui_init_check() == FAIL)
+ {
+ gui.starting = FALSE;
+
+ /* When running "evim" or "gvim -y" we need the menus, exit if we
+ * don't have them. */
+ if (evim_mode)
+ mch_exit(1);
+ }
+# endif
+#endif
+
+ /* "-b" argument used. Check before expanding file names, because for
+ * Win32 this makes us edit a shortcut file itself, instead of the file it
+ * links to. */
+ if (bin_mode)
+ {
+ set_options_bin(curbuf->b_p_bin, 1, 0);
+ curbuf->b_p_bin = 1; /* binary file I/O */
+ }
+
+ if (GARGCOUNT > 0)
+ {
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
+ /*
+ * Expand wildcards in file names.
+ */
+ if (!literal)
+ {
+ /* Temporarily add '(' and ')' to 'isfname'. These are valid
+ * filename characters but are excluded from 'isfname' to make
+ * "gf" work on a file name in parenthesis (e.g.: see vim.h). */
+ do_cmdline_cmd((char_u *)":set isf+=(,)");
+ alist_expand();
+ do_cmdline_cmd((char_u *)":set isf&");
+ }
+#endif
+ fname = alist_name(&GARGLIST[0]);
+ }
+ if (GARGCOUNT > 1)
+ printf(_("%d files to edit\n"), GARGCOUNT);
+#ifdef MSWIN
+ else if (GARGCOUNT == 1 && full_path)
+ {
+ /*
+ * If there is one filename, fully qualified, we have very probably
+ * been invoked from explorer, so change to the file's directory.
+ * Hint: to avoid this when typing a command use a forward slash.
+ * If the cd fails, it doesn't matter.
+ */
+ (void)vim_chdirfile(fname);
+ }
+#endif
+ TIME_MSG("expanding arguments");
+
+#ifdef FEAT_DIFF
+ if (diff_mode)
+ {
+ if (window_count == -1)
+ window_count = 0; /* open up to 3 files in a window */
+ if (vert_windows == MAYBE)
+ vert_windows = TRUE; /* use vertical split */
+ }
+#endif
+
+ ++RedrawingDisabled;
+
+ /*
+ * When listing swap file names, don't do cursor positioning et. al.
+ */
+ if (recoverymode && fname == NULL)
+ want_full_screen = FALSE;
+
+ /*
+ * When certain to start the GUI, don't check capabilities of terminal.
+ * For GTK we can't be sure, but when started from the desktop it doesn't
+ * make sense to try using a terminal.
+ */
+#if defined(ALWAYS_USE_GUI) || defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK)
+ if (gui.starting
+# ifdef FEAT_GUI_GTK
+ && !isatty(2)
+# endif
+ )
+ want_full_screen = FALSE;
+#endif
+
+#if defined(FEAT_GUI_MAC) && defined(MACOS_X_UNIX)
+ /* When the GUI is started from Finder, need to display messages in a
+ * message box. isatty(2) returns TRUE anyway, thus we need to check the
+ * name to know we're not started from a terminal. */
+ if (gui.starting && (!isatty(2) || strcmp("/dev/console", ttyname(2)) == 0))
+ want_full_screen = FALSE;
+#endif
+
+ /*
+ * mch_init() sets up the terminal (window) for use. This must be
+ * done after resetting full_screen, otherwise it may move the cursor