7
|
1 /* vi:set ts=8 sts=4 sw=4:
|
|
2 *
|
|
3 * VIM - Vi IMproved by Bram Moolenaar
|
|
4 * GUI support by Robert Webb
|
|
5 *
|
|
6 * Do ":help uganda" in Vim to read copying and usage conditions.
|
|
7 * Do ":help credits" in Vim to see a list of people who contributed.
|
|
8 * See README.txt for an overview of the Vim source code.
|
|
9 */
|
|
10 /*
|
|
11 * Windows GUI: main program (EXE) entry point:
|
|
12 *
|
|
13 * Ron Aaron <ronaharon@yahoo.com> wrote this and the DLL support code.
|
|
14 */
|
|
15 #include "vim.h"
|
|
16
|
|
17 #ifdef __MINGW32__
|
|
18 # ifndef _cdecl
|
|
19 # define _cdecl
|
|
20 # endif
|
|
21 #endif
|
|
22
|
|
23 /* cproto doesn't create a prototype for main() */
|
|
24 int _cdecl
|
|
25 #if defined(FEAT_GUI_W32)
|
|
26 VimMain
|
|
27 #else
|
|
28 main
|
|
29 #endif
|
|
30 __ARGS((int argc, char **argv));
|
|
31 int (_cdecl *pmain)(int, char **);
|
|
32
|
23
|
33 #ifdef FEAT_MBYTE
|
|
34 /* The commandline arguments in UCS2. */
|
|
35 static DWORD nArgsW = 0;
|
|
36 static LPWSTR *ArglistW = NULL;
|
|
37 static int global_argc;
|
|
38 static char **global_argv;
|
|
39
|
|
40 static int used_file_argc = 0; /* last argument in global_argv[] used
|
|
41 for the argument list. */
|
|
42 static int *used_file_indexes = NULL; /* indexes in global_argv[] for
|
|
43 command line arguments added to
|
|
44 the argument list */
|
|
45 static int used_file_count = 0; /* nr of entries in used_file_indexes */
|
|
46 static int used_file_literal = FALSE; /* take file names literally */
|
|
47 static int used_file_full_path = FALSE; /* file name was full path */
|
|
48 static int used_alist_count = 0;
|
|
49 #endif
|
|
50
|
7
|
51 #ifndef PROTO
|
|
52 #ifdef FEAT_GUI
|
|
53 #ifndef VIMDLL
|
|
54 void _cdecl SaveInst(HINSTANCE hInst);
|
|
55 #endif
|
|
56 void (_cdecl *pSaveInst)(HINSTANCE);
|
|
57 #endif
|
|
58
|
|
59 int WINAPI
|
|
60 WinMain(
|
|
61 HINSTANCE hInstance,
|
|
62 HINSTANCE hPrevInst,
|
|
63 LPSTR lpszCmdLine,
|
|
64 int nCmdShow)
|
|
65 {
|
23
|
66 int argc = 0;
|
7
|
67 char **argv;
|
|
68 char *tofree;
|
|
69 char prog[256];
|
|
70 #ifdef VIMDLL
|
|
71 char *p;
|
|
72 HANDLE hLib;
|
|
73 #endif
|
|
74
|
|
75 /* Ron: added full path name so that the $VIM variable will get set to our
|
|
76 * startup path (so the .vimrc file can be found w/o a VIM env. var.) */
|
|
77 GetModuleFileName(NULL, prog, 255);
|
|
78
|
23
|
79 /* Separate the command line into arguments. Use the Unicode functions
|
|
80 * when possible. When 'encoding' is later changed these are used to
|
|
81 * recode the arguments. */
|
|
82 #ifdef FEAT_MBYTE
|
|
83 ArglistW = CommandLineToArgvW(GetCommandLineW(), &nArgsW);
|
|
84 if (ArglistW != NULL)
|
7
|
85 {
|
23
|
86 argv = malloc((nArgsW + 1) * sizeof(char *));
|
|
87 if (argv != NULL)
|
|
88 {
|
|
89 int i;
|
|
90
|
|
91 argv[argc] = NULL;
|
|
92 argc = nArgsW;
|
|
93 for (i = 0; i < argc; ++i)
|
|
94 {
|
|
95 int len;
|
|
96
|
|
97 WideCharToMultiByte_alloc(GetACP(), 0,
|
|
98 ArglistW[i], wcslen(ArglistW[i]) + 1,
|
|
99 (LPSTR *)&argv[i], &len, 0, 0);
|
|
100 if (argv[i] == NULL)
|
|
101 {
|
|
102 while (i > 0)
|
|
103 free(argv[--i]);
|
|
104 free(argv);
|
|
105 argc = 0;
|
|
106 }
|
|
107 }
|
|
108 }
|
7
|
109 }
|
|
110
|
23
|
111 if (argc == 0)
|
|
112 #endif
|
|
113 {
|
|
114 argc = get_cmd_args(prog, (char *)lpszCmdLine, &argv, &tofree);
|
|
115 if (argc == 0)
|
|
116 {
|
|
117 MessageBox(0, "Could not allocate memory for command line.",
|
|
118 "VIM Error", 0);
|
|
119 return 0;
|
|
120 }
|
|
121 }
|
|
122
|
|
123 #ifdef FEAT_MBYTE
|
|
124 global_argc = argc;
|
|
125 global_argv = argv;
|
|
126 used_file_indexes = malloc(argc * sizeof(int));
|
|
127 #endif
|
|
128
|
7
|
129 #ifdef DYNAMIC_GETTEXT
|
|
130 /* Initialize gettext library */
|
|
131 dyn_libintl_init(NULL);
|
|
132 #endif
|
|
133
|
|
134 #ifdef VIMDLL
|
|
135 // LoadLibrary - get name of dll to load in here:
|
|
136 p = strrchr(prog, '\\');
|
|
137 if (p != NULL)
|
|
138 {
|
|
139 # ifdef DEBUG
|
|
140 strcpy(p+1, "vim32d.dll");
|
|
141 # else
|
|
142 strcpy(p+1, "vim32.dll");
|
|
143 # endif
|
|
144 }
|
|
145 hLib = LoadLibrary(prog);
|
|
146 if (hLib == NULL)
|
|
147 {
|
|
148 MessageBox(0, _("Could not load vim32.dll!"), _("VIM Error"), 0);
|
|
149 goto errout;
|
|
150 }
|
|
151 // fix up the function pointers
|
|
152 # ifdef FEAT_GUI
|
|
153 pSaveInst = GetProcAddress(hLib, (LPCSTR)2);
|
|
154 # endif
|
|
155 pmain = GetProcAddress(hLib, (LPCSTR)1);
|
|
156 if (pmain == NULL)
|
|
157 {
|
|
158 MessageBox(0, _("Could not fix up function pointers to the DLL!"),
|
|
159 _("VIM Error"),0);
|
|
160 goto errout;
|
|
161 }
|
|
162 #else
|
|
163 # ifdef FEAT_GUI
|
|
164 pSaveInst = SaveInst;
|
|
165 # endif
|
|
166 pmain =
|
|
167 # if defined(FEAT_GUI_W32)
|
|
168 //&& defined(__MINGW32__)
|
|
169 VimMain
|
|
170 # else
|
|
171 main
|
|
172 # endif
|
|
173 ;
|
|
174 #endif
|
|
175 #ifdef FEAT_GUI
|
|
176 pSaveInst(
|
|
177 #ifdef __MINGW32__
|
|
178 GetModuleHandle(NULL)
|
|
179 #else
|
|
180 hInstance
|
|
181 #endif
|
|
182 );
|
|
183 #endif
|
|
184 pmain(argc, argv);
|
|
185
|
|
186 #ifdef VIMDLL
|
|
187 FreeLibrary(hLib);
|
|
188 errout:
|
|
189 #endif
|
|
190 free(argv);
|
|
191 free(tofree);
|
23
|
192 #ifdef FEAT_MBYTE
|
|
193 if (ArglistW != NULL)
|
|
194 GlobalFree(ArglistW);
|
|
195 #endif
|
7
|
196
|
|
197 return 0;
|
|
198 }
|
|
199 #endif
|
23
|
200
|
|
201 #ifdef FEAT_MBYTE
|
|
202 /*
|
|
203 * Remember "name" is an argument that was added to the argument list.
|
|
204 * This avoids that we have to re-parse the argument list when fix_arg_enc()
|
|
205 * is called.
|
|
206 */
|
|
207 void
|
|
208 used_file_arg(name, literal, full_path)
|
|
209 char *name;
|
|
210 int literal;
|
|
211 int full_path;
|
|
212 {
|
|
213 int i;
|
|
214
|
|
215 if (used_file_indexes == NULL)
|
|
216 return;
|
|
217 for (i = used_file_argc + 1; i < global_argc; ++i)
|
|
218 if (STRCMP(global_argv[i], name) == 0)
|
|
219 {
|
|
220 used_file_argc = i;
|
|
221 used_file_indexes[used_file_count++] = i;
|
|
222 break;
|
|
223 }
|
|
224 used_file_literal = literal;
|
|
225 used_file_full_path = full_path;
|
|
226 }
|
|
227
|
|
228 /*
|
|
229 * Remember the length of the argument list as it was. If it changes then we
|
|
230 * leave it alone when 'encoding' is set.
|
|
231 */
|
|
232 void
|
|
233 set_alist_count(void)
|
|
234 {
|
|
235 used_alist_count = GARGCOUNT;
|
|
236 }
|
|
237
|
|
238 /*
|
|
239 * Fix the encoding of the command line arguments. Invoked when 'encoding'
|
|
240 * has been changed while starting up. Use the UCS-2 command line arguments
|
|
241 * and convert them to 'encoding'.
|
|
242 */
|
|
243 void
|
|
244 fix_arg_enc()
|
|
245 {
|
|
246 int i;
|
|
247 int idx;
|
|
248 char_u *str;
|
|
249
|
|
250 /* Safety checks:
|
|
251 * - if argument count differs between the wide and non-wide argument
|
|
252 * list, something must be wrong.
|
|
253 * - the file name arguments must have been located.
|
|
254 * - the length of the argument list wasn't changed by the user.
|
|
255 */
|
|
256 if (global_argc != (int)nArgsW
|
|
257 || ArglistW == NULL
|
|
258 || used_file_indexes == NULL
|
|
259 || used_file_count == 0
|
|
260 || used_alist_count != GARGCOUNT)
|
|
261 return;
|
|
262
|
|
263 /* Clear the argument list. Make room for the new arguments. */
|
|
264 alist_clear(&global_alist);
|
|
265 if (ga_grow(&global_alist.al_ga, used_file_count) == FAIL)
|
|
266 return; /* out of memory */
|
|
267
|
|
268 for (i = 0; i < used_file_count; ++i)
|
|
269 {
|
|
270 idx = used_file_indexes[i];
|
|
271 str = ucs2_to_enc(ArglistW[idx], NULL);
|
|
272 if (str != NULL)
|
|
273 alist_add(&global_alist, str, used_file_literal ? 2 : 0);
|
|
274 }
|
|
275
|
|
276 if (!used_file_literal)
|
|
277 {
|
|
278 /* Now expand wildcards in the arguments. */
|
|
279 /* Temporarily add '(' and ')' to 'isfname'. These are valid
|
|
280 * filename characters but are excluded from 'isfname' to make
|
|
281 * "gf" work on a file name in parenthesis (e.g.: see vim.h). */
|
|
282 do_cmdline_cmd((char_u *)":let SaVe_ISF = &isf|set isf+=(,)");
|
|
283 alist_expand();
|
|
284 do_cmdline_cmd((char_u *)":let &isf = SaVe_ISF|unlet SaVe_ISF");
|
|
285 }
|
|
286
|
|
287 /* If wildcard expansion failed, we are editing the first file of the
|
|
288 * arglist and there is no file name: Edit the first argument now. */
|
|
289 if (curwin->w_arg_idx == 0 && curbuf->b_fname == NULL)
|
|
290 {
|
|
291 do_cmdline_cmd((char_u *)":rewind");
|
|
292 if (GARGCOUNT == 1 && used_file_full_path)
|
|
293 (void)vim_chdirfile(alist_name(&GARGLIST[0]));
|
|
294 }
|
|
295 }
|
|
296 #endif
|
|
297
|