2004-06-13 20:20:40 +00:00
|
|
|
/* vi:set ts=8 sts=4 sw=4:
|
|
|
|
*
|
|
|
|
* VIM - Vi IMproved by Bram Moolenaar
|
|
|
|
* GUI support by Robert Webb
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
* Windows GUI: main program (EXE) entry point:
|
|
|
|
*
|
|
|
|
* Ron Aaron <ronaharon@yahoo.com> wrote this and the DLL support code.
|
|
|
|
*/
|
|
|
|
#include "vim.h"
|
|
|
|
|
|
|
|
#ifdef __MINGW32__
|
|
|
|
# ifndef _cdecl
|
|
|
|
# define _cdecl
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* cproto doesn't create a prototype for main() */
|
|
|
|
int _cdecl
|
|
|
|
#if defined(FEAT_GUI_W32)
|
|
|
|
VimMain
|
|
|
|
#else
|
|
|
|
main
|
|
|
|
#endif
|
|
|
|
__ARGS((int argc, char **argv));
|
|
|
|
int (_cdecl *pmain)(int, char **);
|
|
|
|
|
2004-09-06 17:44:46 +00:00
|
|
|
#ifdef FEAT_MBYTE
|
|
|
|
/* The commandline arguments in UCS2. */
|
|
|
|
static DWORD nArgsW = 0;
|
|
|
|
static LPWSTR *ArglistW = NULL;
|
|
|
|
static int global_argc;
|
|
|
|
static char **global_argv;
|
|
|
|
|
|
|
|
static int used_file_argc = 0; /* last argument in global_argv[] used
|
|
|
|
for the argument list. */
|
|
|
|
static int *used_file_indexes = NULL; /* indexes in global_argv[] for
|
|
|
|
command line arguments added to
|
|
|
|
the argument list */
|
|
|
|
static int used_file_count = 0; /* nr of entries in used_file_indexes */
|
|
|
|
static int used_file_literal = FALSE; /* take file names literally */
|
|
|
|
static int used_file_full_path = FALSE; /* file name was full path */
|
|
|
|
static int used_alist_count = 0;
|
|
|
|
#endif
|
|
|
|
|
2004-06-13 20:20:40 +00:00
|
|
|
#ifndef PROTO
|
|
|
|
#ifdef FEAT_GUI
|
|
|
|
#ifndef VIMDLL
|
|
|
|
void _cdecl SaveInst(HINSTANCE hInst);
|
|
|
|
#endif
|
|
|
|
void (_cdecl *pSaveInst)(HINSTANCE);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
int WINAPI
|
|
|
|
WinMain(
|
|
|
|
HINSTANCE hInstance,
|
|
|
|
HINSTANCE hPrevInst,
|
|
|
|
LPSTR lpszCmdLine,
|
|
|
|
int nCmdShow)
|
|
|
|
{
|
2004-09-06 17:44:46 +00:00
|
|
|
int argc = 0;
|
2004-06-13 20:20:40 +00:00
|
|
|
char **argv;
|
|
|
|
char *tofree;
|
|
|
|
char prog[256];
|
|
|
|
#ifdef VIMDLL
|
|
|
|
char *p;
|
|
|
|
HANDLE hLib;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Ron: added full path name so that the $VIM variable will get set to our
|
|
|
|
* startup path (so the .vimrc file can be found w/o a VIM env. var.) */
|
|
|
|
GetModuleFileName(NULL, prog, 255);
|
|
|
|
|
2004-09-06 17:44:46 +00:00
|
|
|
/* Separate the command line into arguments. Use the Unicode functions
|
|
|
|
* when possible. When 'encoding' is later changed these are used to
|
|
|
|
* recode the arguments. */
|
|
|
|
#ifdef FEAT_MBYTE
|
|
|
|
ArglistW = CommandLineToArgvW(GetCommandLineW(), &nArgsW);
|
|
|
|
if (ArglistW != NULL)
|
|
|
|
{
|
|
|
|
argv = malloc((nArgsW + 1) * sizeof(char *));
|
|
|
|
if (argv != NULL)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
argv[argc] = NULL;
|
|
|
|
argc = nArgsW;
|
|
|
|
for (i = 0; i < argc; ++i)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
|
|
|
|
WideCharToMultiByte_alloc(GetACP(), 0,
|
|
|
|
ArglistW[i], wcslen(ArglistW[i]) + 1,
|
|
|
|
(LPSTR *)&argv[i], &len, 0, 0);
|
|
|
|
if (argv[i] == NULL)
|
|
|
|
{
|
|
|
|
while (i > 0)
|
|
|
|
free(argv[--i]);
|
|
|
|
free(argv);
|
|
|
|
argc = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-06-13 20:20:40 +00:00
|
|
|
if (argc == 0)
|
2004-09-06 17:44:46 +00:00
|
|
|
#endif
|
2004-06-13 20:20:40 +00:00
|
|
|
{
|
2004-09-06 17:44:46 +00:00
|
|
|
argc = get_cmd_args(prog, (char *)lpszCmdLine, &argv, &tofree);
|
|
|
|
if (argc == 0)
|
|
|
|
{
|
|
|
|
MessageBox(0, "Could not allocate memory for command line.",
|
|
|
|
"VIM Error", 0);
|
|
|
|
return 0;
|
|
|
|
}
|
2004-06-13 20:20:40 +00:00
|
|
|
}
|
|
|
|
|
2004-09-06 17:44:46 +00:00
|
|
|
#ifdef FEAT_MBYTE
|
|
|
|
global_argc = argc;
|
|
|
|
global_argv = argv;
|
|
|
|
used_file_indexes = malloc(argc * sizeof(int));
|
|
|
|
#endif
|
|
|
|
|
2004-06-13 20:20:40 +00:00
|
|
|
#ifdef DYNAMIC_GETTEXT
|
|
|
|
/* Initialize gettext library */
|
|
|
|
dyn_libintl_init(NULL);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef VIMDLL
|
|
|
|
// LoadLibrary - get name of dll to load in here:
|
|
|
|
p = strrchr(prog, '\\');
|
|
|
|
if (p != NULL)
|
|
|
|
{
|
|
|
|
# ifdef DEBUG
|
|
|
|
strcpy(p+1, "vim32d.dll");
|
|
|
|
# else
|
|
|
|
strcpy(p+1, "vim32.dll");
|
|
|
|
# endif
|
|
|
|
}
|
|
|
|
hLib = LoadLibrary(prog);
|
|
|
|
if (hLib == NULL)
|
|
|
|
{
|
|
|
|
MessageBox(0, _("Could not load vim32.dll!"), _("VIM Error"), 0);
|
|
|
|
goto errout;
|
|
|
|
}
|
|
|
|
// fix up the function pointers
|
|
|
|
# ifdef FEAT_GUI
|
|
|
|
pSaveInst = GetProcAddress(hLib, (LPCSTR)2);
|
|
|
|
# endif
|
|
|
|
pmain = GetProcAddress(hLib, (LPCSTR)1);
|
|
|
|
if (pmain == NULL)
|
|
|
|
{
|
|
|
|
MessageBox(0, _("Could not fix up function pointers to the DLL!"),
|
|
|
|
_("VIM Error"),0);
|
|
|
|
goto errout;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
# ifdef FEAT_GUI
|
|
|
|
pSaveInst = SaveInst;
|
|
|
|
# endif
|
|
|
|
pmain =
|
|
|
|
# if defined(FEAT_GUI_W32)
|
|
|
|
//&& defined(__MINGW32__)
|
|
|
|
VimMain
|
|
|
|
# else
|
|
|
|
main
|
|
|
|
# endif
|
|
|
|
;
|
|
|
|
#endif
|
|
|
|
#ifdef FEAT_GUI
|
|
|
|
pSaveInst(
|
|
|
|
#ifdef __MINGW32__
|
|
|
|
GetModuleHandle(NULL)
|
|
|
|
#else
|
|
|
|
hInstance
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
#endif
|
|
|
|
pmain(argc, argv);
|
|
|
|
|
|
|
|
#ifdef VIMDLL
|
|
|
|
FreeLibrary(hLib);
|
|
|
|
errout:
|
|
|
|
#endif
|
|
|
|
free(argv);
|
|
|
|
free(tofree);
|
2004-09-06 17:44:46 +00:00
|
|
|
#ifdef FEAT_MBYTE
|
|
|
|
if (ArglistW != NULL)
|
|
|
|
GlobalFree(ArglistW);
|
|
|
|
#endif
|
2004-06-13 20:20:40 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
2004-09-06 17:44:46 +00:00
|
|
|
|
|
|
|
#ifdef FEAT_MBYTE
|
|
|
|
/*
|
|
|
|
* Remember "name" is an argument that was added to the argument list.
|
|
|
|
* This avoids that we have to re-parse the argument list when fix_arg_enc()
|
|
|
|
* is called.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
used_file_arg(name, literal, full_path)
|
|
|
|
char *name;
|
|
|
|
int literal;
|
|
|
|
int full_path;
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (used_file_indexes == NULL)
|
|
|
|
return;
|
|
|
|
for (i = used_file_argc + 1; i < global_argc; ++i)
|
|
|
|
if (STRCMP(global_argv[i], name) == 0)
|
|
|
|
{
|
|
|
|
used_file_argc = i;
|
|
|
|
used_file_indexes[used_file_count++] = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
used_file_literal = literal;
|
|
|
|
used_file_full_path = full_path;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Remember the length of the argument list as it was. If it changes then we
|
|
|
|
* leave it alone when 'encoding' is set.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
set_alist_count(void)
|
|
|
|
{
|
|
|
|
used_alist_count = GARGCOUNT;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Fix the encoding of the command line arguments. Invoked when 'encoding'
|
|
|
|
* has been changed while starting up. Use the UCS-2 command line arguments
|
|
|
|
* and convert them to 'encoding'.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
fix_arg_enc()
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int idx;
|
|
|
|
char_u *str;
|
|
|
|
|
|
|
|
/* Safety checks:
|
|
|
|
* - if argument count differs between the wide and non-wide argument
|
|
|
|
* list, something must be wrong.
|
|
|
|
* - the file name arguments must have been located.
|
|
|
|
* - the length of the argument list wasn't changed by the user.
|
|
|
|
*/
|
|
|
|
if (global_argc != (int)nArgsW
|
|
|
|
|| ArglistW == NULL
|
|
|
|
|| used_file_indexes == NULL
|
|
|
|
|| used_file_count == 0
|
|
|
|
|| used_alist_count != GARGCOUNT)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Clear the argument list. Make room for the new arguments. */
|
|
|
|
alist_clear(&global_alist);
|
|
|
|
if (ga_grow(&global_alist.al_ga, used_file_count) == FAIL)
|
|
|
|
return; /* out of memory */
|
|
|
|
|
|
|
|
for (i = 0; i < used_file_count; ++i)
|
|
|
|
{
|
|
|
|
idx = used_file_indexes[i];
|
|
|
|
str = ucs2_to_enc(ArglistW[idx], NULL);
|
|
|
|
if (str != NULL)
|
|
|
|
alist_add(&global_alist, str, used_file_literal ? 2 : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!used_file_literal)
|
|
|
|
{
|
|
|
|
/* Now expand wildcards in the arguments. */
|
|
|
|
/* 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 *)":let SaVe_ISF = &isf|set isf+=(,)");
|
|
|
|
alist_expand();
|
|
|
|
do_cmdline_cmd((char_u *)":let &isf = SaVe_ISF|unlet SaVe_ISF");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If wildcard expansion failed, we are editing the first file of the
|
|
|
|
* arglist and there is no file name: Edit the first argument now. */
|
|
|
|
if (curwin->w_arg_idx == 0 && curbuf->b_fname == NULL)
|
|
|
|
{
|
|
|
|
do_cmdline_cmd((char_u *)":rewind");
|
|
|
|
if (GARGCOUNT == 1 && used_file_full_path)
|
|
|
|
(void)vim_chdirfile(alist_name(&GARGLIST[0]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|