Mercurial > vim
annotate src/if_sniff.c @ 7825:7898da204b98 v7.4.1209
commit https://github.com/vim/vim/commit/02fdaeaa697fb5af4ba7fee6e209b3c2c825bb4f
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Jan 30 18:13:55 2016 +0100
patch 7.4.1209
Problem: Can't build with Athena.
Solution: Fix function declarations.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 30 Jan 2016 18:15:04 +0100 |
parents | bcef391c101c |
children |
rev | line source |
---|---|
7 | 1 /* vi:set ts=8 sts=4 sw=4: |
2 * | |
3 * if_sniff.c Interface between Vim and SNiFF+ | |
4 * | |
5 * See README.txt for an overview of the Vim source code. | |
6 */ | |
7 | |
8 #include "vim.h" | |
9 | |
10 #ifdef WIN32 | |
11 # include <stdio.h> | |
12 # include <process.h> | |
13 # include <string.h> | |
14 # include <assert.h> | |
15 #else | |
16 # ifdef FEAT_GUI_X11 | |
17 # include "gui_x11.pro" | |
18 # endif | |
19 # include "os_unixx.h" | |
20 #endif | |
21 | |
22 static int sniffemacs_pid; | |
23 | |
24 int fd_from_sniff; | |
25 int sniff_connected = 0; | |
26 int sniff_request_waiting = 0; | |
27 int want_sniff_request = 0; | |
28 | |
29 #define MAX_REQUEST_LEN 512 | |
30 | |
31 #define NEED_SYMBOL 2 | |
32 #define EMPTY_SYMBOL 4 | |
33 #define NEED_FILE 8 | |
34 #define SILENT 16 | |
35 #define DISCONNECT 32 | |
36 #define CONNECT 64 | |
37 | |
38 #define RQ_NONE 0 | |
39 #define RQ_SIMPLE 1 | |
40 #define RQ_CONTEXT NEED_FILE + NEED_SYMBOL | |
41 #define RQ_SCONTEXT NEED_FILE + NEED_SYMBOL + EMPTY_SYMBOL | |
42 #define RQ_NOSYMBOL NEED_FILE | |
43 #define RQ_SILENT RQ_NOSYMBOL + SILENT | |
44 #define RQ_CONNECT RQ_NONE + CONNECT | |
45 #define RQ_DISCONNECT RQ_SIMPLE + DISCONNECT | |
46 | |
47 struct sn_cmd | |
48 { | |
49 char *cmd_name; | |
50 char cmd_code; | |
51 char *cmd_msg; | |
52 int cmd_type; | |
53 }; | |
54 | |
55 struct sn_cmd_list | |
56 { | |
57 struct sn_cmd* sniff_cmd; | |
58 struct sn_cmd_list* next_cmd; | |
59 }; | |
60 | |
61 static struct sn_cmd sniff_cmds[] = | |
62 { | |
63 { "toggle", 'e', N_("Toggle implementation/definition"),RQ_SCONTEXT }, | |
64 { "superclass", 's', N_("Show base class of"), RQ_CONTEXT }, | |
65 { "overridden", 'm', N_("Show overridden member function"),RQ_SCONTEXT }, | |
66 { "retrieve-file", 'r', N_("Retrieve from file"), RQ_CONTEXT }, | |
67 { "retrieve-project",'p', N_("Retrieve from project"), RQ_CONTEXT }, | |
68 { "retrieve-all-projects", | |
69 'P', N_("Retrieve from all projects"), RQ_CONTEXT }, | |
70 { "retrieve-next", 'R', N_("Retrieve"), RQ_CONTEXT }, | |
71 { "goto-symbol", 'g', N_("Show source of"), RQ_CONTEXT }, | |
72 { "find-symbol", 'f', N_("Find symbol"), RQ_CONTEXT }, | |
73 { "browse-class", 'w', N_("Browse class"), RQ_CONTEXT }, | |
74 { "hierarchy", 't', N_("Show class in hierarchy"), RQ_CONTEXT }, | |
75 { "restr-hier", 'T', N_("Show class in restricted hierarchy"),RQ_CONTEXT }, | |
76 { "xref-to", 'x', N_("Xref refers to"), RQ_CONTEXT }, | |
77 { "xref-by", 'X', N_("Xref referred by"), RQ_CONTEXT }, | |
78 { "xref-has", 'c', N_("Xref has a"), RQ_CONTEXT }, | |
79 { "xref-used-by", 'C', N_("Xref used by"), RQ_CONTEXT }, | |
80 { "show-docu", 'd', N_("Show docu of"), RQ_CONTEXT }, | |
81 { "gen-docu", 'D', N_("Generate docu for"), RQ_CONTEXT }, | |
82 { "connect", 'y', NULL, RQ_CONNECT }, | |
83 { "disconnect", 'q', NULL, RQ_DISCONNECT }, | |
84 { "font-info", 'z', NULL, RQ_SILENT }, | |
85 { "update", 'u', NULL, RQ_SILENT }, | |
86 { NULL, '\0', NULL, 0} | |
87 }; | |
88 | |
89 | |
90 static char *SniffEmacs[2] = {"sniffemacs", (char *)NULL}; /* Yes, Emacs! */ | |
91 static int fd_to_sniff; | |
92 static int sniff_will_disconnect = 0; | |
93 static char msg_sniff_disconnect[] = N_("Cannot connect to SNiFF+. Check environment (sniffemacs must be found in $PATH).\n"); | |
94 static char sniff_rq_sep[] = " "; | |
95 static struct sn_cmd_list *sniff_cmd_ext = NULL; | |
96 | |
97 /* Initializing vim commands | |
98 * executed each time vim connects to Sniff | |
99 */ | |
100 static char *init_cmds[]= { | |
101 "augroup sniff", | |
102 "autocmd BufWritePost * sniff update", | |
103 "autocmd BufReadPost * sniff font-info", | |
104 "autocmd VimLeave * sniff disconnect", | |
105 "augroup END", | |
106 | |
107 "let g:sniff_connected = 1", | |
108 | |
109 "if ! exists('g:sniff_mappings_sourced')|" | |
110 "if ! exists('g:sniff_mappings')|" | |
111 "if exists('$SNIFF_DIR4')|" | |
112 "let g:sniff_mappings='$SNIFF_DIR4/config/integrations/vim/sniff.vim'|" | |
113 "else|" | |
114 "let g:sniff_mappings='$SNIFF_DIR/config/sniff.vim'|" | |
115 "endif|" | |
116 "endif|" | |
117 "let g:sniff_mappings=expand(g:sniff_mappings)|" | |
118 "if filereadable(g:sniff_mappings)|" | |
119 "execute 'source' g:sniff_mappings|" | |
120 "let g:sniff_mappings_sourced=1|" | |
121 "endif|" | |
122 "endif", | |
123 | |
124 NULL | |
125 }; | |
126 | |
127 /*-------- Function Prototypes ----------------------------------*/ | |
128 | |
7803
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7049
diff
changeset
|
129 static int ConnectToSniffEmacs(void); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7049
diff
changeset
|
130 static void sniff_connect(void); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7049
diff
changeset
|
131 static void HandleSniffRequest(char* buffer); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7049
diff
changeset
|
132 static int get_request(int fd, char *buf, int maxlen); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7049
diff
changeset
|
133 static void WriteToSniff(char *str); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7049
diff
changeset
|
134 static void SendRequest(struct sn_cmd *command, char* symbol); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7049
diff
changeset
|
135 static void vi_msg(char *); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7049
diff
changeset
|
136 static void vi_error_msg(char *); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7049
diff
changeset
|
137 static char *vi_symbol_under_cursor(void); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7049
diff
changeset
|
138 static void vi_open_file(char *); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7049
diff
changeset
|
139 static char *vi_buffer_name(void); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7049
diff
changeset
|
140 static buf_T *vi_find_buffer(char *); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7049
diff
changeset
|
141 static void vi_exec_cmd(char *); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7049
diff
changeset
|
142 static void vi_set_cursor_pos(long char_nr); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7049
diff
changeset
|
143 static long vi_cursor_pos(void); |
7 | 144 |
145 /* debug trace */ | |
146 #if 0 | |
147 static FILE* _tracefile = NULL; | |
148 #define SNIFF_TRACE_OPEN(file) if (!_tracefile) _tracefile = fopen(file, "w") | |
149 #define SNIFF_TRACE(msg) fprintf(_tracefile, msg); fflush(_tracefile); | |
150 #define SNIFF_TRACE1(msg, arg) fprintf(_tracefile, msg,arg); fflush(_tracefile); | |
151 #define SNIFF_TRACE_CLOSE fclose(_tracefile); _tracefile=NULL; | |
152 #else | |
153 #define SNIFF_TRACE_OPEN(file) | |
154 #define SNIFF_TRACE(msg) | |
155 #define SNIFF_TRACE1(msg, arg) | |
156 #define SNIFF_TRACE_CLOSE | |
157 #endif | |
158 | |
159 /*-------- Windows Only Declarations -----------------------------*/ | |
160 #ifdef WIN32 | |
161 | |
162 static int sniff_request_processed=1; | |
163 static HANDLE sniffemacs_handle=NULL; | |
164 static HANDLE readthread_handle=NULL; | |
165 static HANDLE handle_to_sniff=NULL; | |
166 static HANDLE handle_from_sniff=NULL; | |
167 | |
168 struct sniffBufNode | |
169 { | |
170 struct sniffBufNode *next; | |
171 int bufLen; | |
172 char buf[MAX_REQUEST_LEN]; | |
173 }; | |
174 static struct sniffBufNode *sniffBufStart=NULL; | |
175 static struct sniffBufNode *sniffBufEnd=NULL; | |
176 static HANDLE hBufferMutex=NULL; | |
177 | |
178 # ifdef FEAT_GUI_W32 | |
179 extern HWND s_hwnd; /* gvim's Window handle */ | |
180 # endif | |
181 /* | |
182 * some helper functions for Windows port only | |
183 */ | |
184 | |
185 static HANDLE | |
186 ExecuteDetachedProgram(char *szBinary, char *szCmdLine, | |
187 HANDLE hStdInput, HANDLE hStdOutput) | |
188 { | |
189 BOOL bResult; | |
190 DWORD nError; | |
191 PROCESS_INFORMATION aProcessInformation; | |
192 PROCESS_INFORMATION *pProcessInformation= &aProcessInformation; | |
193 STARTUPINFO aStartupInfo; | |
194 STARTUPINFO *pStartupInfo= &aStartupInfo; | |
195 DWORD dwCreationFlags= 0; | |
196 char szPath[512]; | |
197 HINSTANCE hResult; | |
198 | |
199 hResult = FindExecutable(szBinary, ".", szPath); | |
200 if ((int)hResult <= 32) | |
201 { | |
202 /* can't find the exe file */ | |
203 return NULL; | |
204 } | |
205 | |
206 ZeroMemory(pStartupInfo, sizeof(*pStartupInfo)); | |
207 pStartupInfo->dwFlags= STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES; | |
208 pStartupInfo->hStdInput = hStdInput; | |
209 pStartupInfo->hStdOutput = hStdOutput; | |
210 pStartupInfo->wShowWindow= SW_HIDE; | |
211 pStartupInfo->cb = sizeof(STARTUPINFO); | |
212 | |
213 bResult= CreateProcess( | |
214 szPath, | |
215 szCmdLine, | |
216 NULL, /* security attr for process */ | |
217 NULL, /* security attr for primary thread */ | |
218 TRUE, /* DO inherit stdin and stdout */ | |
219 dwCreationFlags, /* creation flags */ | |
220 NULL, /* environment */ | |
221 ".", /* current directory */ | |
222 pStartupInfo, /* startup info: NULL crashes */ | |
223 pProcessInformation /* process information: NULL crashes */ | |
224 ); | |
225 nError= GetLastError(); | |
226 if (bResult) | |
227 { | |
228 CloseHandle(pProcessInformation->hThread); | |
229 CloseHandle(hStdInput); | |
230 CloseHandle(hStdOutput); | |
231 return(pProcessInformation->hProcess); | |
232 } | |
233 else | |
234 return(NULL); | |
235 } | |
236 | |
237 /* | |
238 * write to the internal Thread / Thread communications buffer. | |
239 * Return TRUE if successful, FALSE else. | |
240 */ | |
241 static BOOL | |
242 writeToBuffer(char *msg, int len) | |
243 { | |
244 DWORD dwWaitResult; /* Request ownership of mutex. */ | |
245 struct sniffBufNode *bn; | |
246 int bnSize; | |
247 | |
248 SNIFF_TRACE1("writeToBuffer %d\n", len); | |
249 bnSize = sizeof(struct sniffBufNode) - MAX_REQUEST_LEN + len + 1; | |
250 if (bnSize < 128) bnSize = 128; /* minimum length to avoid fragmentation */ | |
251 bn = (struct sniffBufNode *)malloc(bnSize); | |
252 if (!bn) | |
253 return FALSE; | |
254 | |
255 memcpy(bn->buf, msg, len); | |
256 bn->buf[len]='\0'; /* terminate CString for added safety */ | |
257 bn->next = NULL; | |
258 bn->bufLen = len; | |
259 /* now, acquire a Mutex for adding the string to our linked list */ | |
260 dwWaitResult = WaitForSingleObject( | |
261 hBufferMutex, /* handle of mutex */ | |
262 1000L); /* one-second time-out interval */ | |
263 if (dwWaitResult == WAIT_OBJECT_0) | |
264 { | |
265 /* The thread got mutex ownership. */ | |
266 if (sniffBufEnd) | |
267 { | |
268 sniffBufEnd->next = bn; | |
269 sniffBufEnd = bn; | |
270 } | |
271 else | |
272 sniffBufStart = sniffBufEnd = bn; | |
273 /* Release ownership of the mutex object. */ | |
274 if (! ReleaseMutex(hBufferMutex)) | |
275 { | |
276 /* Deal with error. */ | |
277 } | |
278 return TRUE; | |
279 } | |
280 | |
281 /* Cannot get mutex ownership due to time-out or mutex object abandoned. */ | |
282 free(bn); | |
283 return FALSE; | |
284 } | |
285 | |
286 /* | |
287 * read from the internal Thread / Thread communications buffer. | |
288 * Return TRUE if successful, FALSE else. | |
289 */ | |
290 static int | |
291 ReadFromBuffer(char *buf, int maxlen) | |
292 { | |
293 DWORD dwWaitResult; /* Request ownership of mutex. */ | |
294 int theLen; | |
295 struct sniffBufNode *bn; | |
296 | |
297 dwWaitResult = WaitForSingleObject( | |
298 hBufferMutex, /* handle of mutex */ | |
299 1000L); /* one-second time-out interval */ | |
300 if (dwWaitResult == WAIT_OBJECT_0) | |
301 { | |
302 if (!sniffBufStart) | |
303 { | |
304 /* all pending Requests Processed */ | |
305 theLen = 0; | |
306 } | |
307 else | |
308 { | |
309 bn = sniffBufStart; | |
310 theLen = bn->bufLen; | |
311 SNIFF_TRACE1("ReadFromBuffer %d\n", theLen); | |
312 if (theLen >= maxlen) | |
313 { | |
314 /* notify the user of buffer overflow? */ | |
315 theLen = maxlen-1; | |
316 } | |
317 memcpy(buf, bn->buf, theLen); | |
318 buf[theLen] = '\0'; | |
319 if (! (sniffBufStart = bn->next)) | |
320 { | |
321 sniffBufEnd = NULL; | |
322 sniff_request_processed = 1; | |
323 } | |
324 free(bn); | |
325 } | |
326 if (! ReleaseMutex(hBufferMutex)) | |
327 { | |
328 /* Deal with error. */ | |
329 } | |
330 return theLen; | |
331 } | |
332 | |
333 /* Cannot get mutex ownership due to time-out or mutex object abandoned. */ | |
334 return -1; | |
335 } | |
336 | |
337 /* on Win32, a separate Thread reads the input pipe. get_request is not needed here. */ | |
338 static void __cdecl | |
339 SniffEmacsReadThread(void *dummy) | |
340 { | |
341 static char ReadThreadBuffer[MAX_REQUEST_LEN]; | |
342 int ReadThreadLen=0; | |
343 int result=0; | |
344 int msgLen=0; | |
345 char *msgStart, *msgCur; | |
346 | |
347 SNIFF_TRACE("begin thread\n"); | |
348 /* Read from the pipe to SniffEmacs */ | |
349 while (sniff_connected) | |
350 { | |
351 if (!ReadFile(handle_from_sniff, | |
352 ReadThreadBuffer + ReadThreadLen, /* acknowledge rest in buffer */ | |
353 MAX_REQUEST_LEN - ReadThreadLen, | |
354 &result, | |
355 NULL)) | |
356 { | |
357 DWORD err = GetLastError(); | |
358 result = -1; | |
359 } | |
360 | |
361 if (result < 0) | |
362 { | |
363 /* probably sniffemacs died... log the Error? */ | |
364 sniff_disconnect(1); | |
365 } | |
366 else if (result > 0) | |
367 { | |
368 ReadThreadLen += result-1; /* total length of valid chars */ | |
369 for(msgCur=msgStart=ReadThreadBuffer; ReadThreadLen > 0; msgCur++, ReadThreadLen--) | |
370 { | |
371 if (*msgCur == '\0' || *msgCur == '\r' || *msgCur == '\n') | |
372 { | |
373 msgLen = msgCur-msgStart; /* don't add the CR/LF chars */ | |
374 if (msgLen > 0) | |
375 writeToBuffer(msgStart, msgLen); | |
376 msgStart = msgCur + 1; /* over-read single CR/LF chars */ | |
377 } | |
378 } | |
379 | |
380 /* move incomplete message to beginning of buffer */ | |
381 ReadThreadLen = msgCur - msgStart; | |
382 if (ReadThreadLen > 0) | |
383 mch_memmove(ReadThreadBuffer, msgStart, ReadThreadLen); | |
384 | |
385 if (sniff_request_processed) | |
386 { | |
387 /* notify others that new data has arrived */ | |
388 sniff_request_processed = 0; | |
389 sniff_request_waiting = 1; | |
390 #ifdef FEAT_GUI_W32 | |
391 PostMessage(s_hwnd, WM_USER, (WPARAM)0, (LPARAM)0); | |
392 #endif | |
393 } | |
394 } | |
395 } | |
396 SNIFF_TRACE("end thread\n"); | |
397 } | |
398 #endif /* WIN32 */ | |
399 /*-------- End of Windows Only Declarations ------------------------*/ | |
400 | |
401 | |
402 /* ProcessSniffRequests | |
403 * Function that should be called from outside | |
404 * to process the waiting sniff requests | |
405 */ | |
406 void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
407 ProcessSniffRequests(void) |
7 | 408 { |
409 static char buf[MAX_REQUEST_LEN]; | |
410 int len; | |
411 | |
412 while (sniff_connected) | |
413 { | |
414 #ifdef WIN32 | |
415 len = ReadFromBuffer(buf, sizeof(buf)); | |
416 #else | |
417 len = get_request(fd_from_sniff, buf, sizeof(buf)); | |
418 #endif | |
419 if (len < 0) | |
420 { | |
421 vi_error_msg(_("E274: Sniff: Error during read. Disconnected")); | |
422 sniff_disconnect(1); | |
423 break; | |
424 } | |
425 else if (len > 0) | |
426 HandleSniffRequest( buf ); | |
427 else | |
428 break; | |
429 } | |
430 | |
431 if (sniff_will_disconnect) /* Now the last msg has been processed */ | |
432 sniff_disconnect(1); | |
433 } | |
434 | |
435 static struct sn_cmd * | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
436 find_sniff_cmd(char *cmd) |
7 | 437 { |
438 struct sn_cmd *sniff_cmd = NULL; | |
439 int i; | |
440 for(i=0; sniff_cmds[i].cmd_name; i++) | |
441 { | |
442 if (!strcmp(cmd, sniff_cmds[i].cmd_name)) | |
443 { | |
444 sniff_cmd = &sniff_cmds[i]; | |
445 break; | |
446 } | |
447 } | |
448 if (!sniff_cmd) | |
449 { | |
450 struct sn_cmd_list *list = sniff_cmd_ext; | |
3935 | 451 while (list) |
7 | 452 { |
453 if (!strcmp(cmd, list->sniff_cmd->cmd_name)) | |
454 { | |
455 sniff_cmd = list->sniff_cmd; | |
456 break; | |
457 } | |
458 list = list->next_cmd; | |
459 } | |
460 } | |
461 return sniff_cmd; | |
462 } | |
463 | |
464 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
465 add_sniff_cmd(char *cmd, char *def, char *msg) |
7 | 466 { |
467 int rc = 0; | |
468 if (def != NULL && def[0] != NUL && find_sniff_cmd(cmd) == NULL) | |
469 { | |
470 struct sn_cmd_list *list = sniff_cmd_ext; | |
471 struct sn_cmd *sniff_cmd = (struct sn_cmd*)malloc(sizeof(struct sn_cmd)); | |
472 struct sn_cmd_list *cmd_node = (struct sn_cmd_list*)malloc(sizeof(struct sn_cmd_list)); | |
473 int rq_type = 0; | |
474 | |
475 /* unescape message text */ | |
476 char *p = msg; | |
477 char *end = p+strlen(msg); | |
3935 | 478 while (*p) |
7 | 479 { |
480 if (*p == '\\') | |
481 mch_memmove(p,p+1,end-p); | |
482 p++; | |
483 } | |
484 SNIFF_TRACE1("request name = %s\n",cmd); | |
485 SNIFF_TRACE1("request def = %s\n",def); | |
486 SNIFF_TRACE1("request msg = %s\n",msg); | |
487 | |
3935 | 488 while (list && list->next_cmd) |
7 | 489 list = list->next_cmd; |
490 if (!list) | |
491 sniff_cmd_ext = cmd_node; | |
492 else | |
493 list->next_cmd = cmd_node; | |
494 | |
495 sniff_cmd->cmd_name = cmd; | |
496 sniff_cmd->cmd_code = def[0]; | |
497 sniff_cmd->cmd_msg = msg; | |
498 switch(def[1]) | |
499 { | |
500 case 'f': | |
501 rq_type = RQ_NOSYMBOL; | |
502 break; | |
503 case 's': | |
504 rq_type = RQ_CONTEXT; | |
505 break; | |
506 case 'S': | |
507 rq_type = RQ_SCONTEXT; | |
508 break; | |
509 default: | |
510 rq_type = RQ_SIMPLE; | |
511 break; | |
512 } | |
513 sniff_cmd->cmd_type = rq_type; | |
514 cmd_node->sniff_cmd = sniff_cmd; | |
515 cmd_node->next_cmd = NULL; | |
516 rc = 1; | |
517 } | |
518 return rc; | |
519 } | |
520 | |
521 /* ex_sniff | |
522 * Handle ":sniff" command | |
523 */ | |
524 void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
525 ex_sniff(exarg_T *eap) |
7 | 526 { |
527 char_u *arg = eap->arg; | |
528 char_u *symbol = NULL; | |
529 char_u *cmd = NULL; | |
530 | |
531 SNIFF_TRACE_OPEN("if_sniff.log"); | |
532 if (ends_excmd(*arg)) /* no request: print available commands */ | |
533 { | |
534 int i; | |
535 msg_start(); | |
536 msg_outtrans_attr((char_u *)"-- SNiFF+ commands --", hl_attr(HLF_T)); | |
537 for(i=0; sniff_cmds[i].cmd_name; i++) | |
538 { | |
539 msg_putchar('\n'); | |
540 msg_outtrans((char_u *)":sniff "); | |
541 msg_outtrans((char_u *)sniff_cmds[i].cmd_name); | |
542 } | |
543 msg_putchar('\n'); | |
544 msg_outtrans((char_u *)_("SNiFF+ is currently ")); | |
545 if (!sniff_connected) | |
546 msg_outtrans((char_u *)_("not ")); | |
547 msg_outtrans((char_u *)_("connected")); | |
548 msg_end(); | |
549 } | |
550 else /* extract command name and symbol if present */ | |
551 { | |
552 symbol = skiptowhite(arg); | |
553 cmd = vim_strnsave(arg, (int)(symbol-arg)); | |
554 symbol = skipwhite(symbol); | |
555 if (ends_excmd(*symbol)) | |
556 symbol = NULL; | |
557 if (!strcmp((char *)cmd, "addcmd")) | |
558 { | |
559 char_u *def = skiptowhite(symbol); | |
560 char_u *name = vim_strnsave(symbol, (int)(def-symbol)); | |
561 char_u *msg; | |
562 def = skipwhite(def); | |
563 msg = skiptowhite(def); | |
564 def = vim_strnsave(def, (int)(msg-def)); | |
565 msg = skipwhite(msg); | |
566 if (ends_excmd(*msg)) | |
567 msg = vim_strsave(name); | |
568 else | |
569 msg = vim_strnsave(msg, (int)(skiptowhite_esc(msg)-msg)); | |
570 if (!add_sniff_cmd((char*)name, (char*)def, (char*)msg)) | |
571 { | |
572 vim_free(msg); | |
573 vim_free(def); | |
574 vim_free(name); | |
575 } | |
576 } | |
577 else | |
578 { | |
579 struct sn_cmd* sniff_cmd = find_sniff_cmd((char*)cmd); | |
580 if (sniff_cmd) | |
581 SendRequest(sniff_cmd, (char *)symbol); | |
582 else | |
583 EMSG2(_("E275: Unknown SNiFF+ request: %s"), cmd); | |
584 } | |
585 vim_free(cmd); | |
586 } | |
587 } | |
588 | |
589 | |
590 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
591 sniff_connect(void) |
7 | 592 { |
593 if (sniff_connected) | |
594 return; | |
595 if (ConnectToSniffEmacs()) | |
596 vi_error_msg(_("E276: Error connecting to SNiFF+")); | |
597 else | |
598 { | |
599 int i; | |
600 | |
601 for (i = 0; init_cmds[i]; i++) | |
602 vi_exec_cmd(init_cmds[i]); | |
603 } | |
604 } | |
605 | |
606 void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
607 sniff_disconnect(int immediately) |
7 | 608 { |
609 if (!sniff_connected) | |
610 return; | |
611 if (immediately) | |
612 { | |
613 vi_exec_cmd("augroup sniff"); | |
614 vi_exec_cmd("au!"); | |
615 vi_exec_cmd("augroup END"); | |
616 vi_exec_cmd("unlet g:sniff_connected"); | |
617 sniff_connected = 0; | |
618 want_sniff_request = 0; | |
619 sniff_will_disconnect = 0; | |
620 #ifdef FEAT_GUI | |
621 if (gui.in_use) | |
622 gui_mch_wait_for_chars(0L); | |
623 #endif | |
624 #ifdef WIN32 | |
3935 | 625 while (sniffBufStart != NULL) |
7 | 626 { |
627 struct sniffBufNode *node = sniffBufStart; | |
628 sniffBufStart = sniffBufStart->next; | |
629 free(node); | |
630 } | |
631 sniffBufStart = sniffBufEnd = NULL; | |
632 sniff_request_processed = 1; | |
633 CloseHandle(handle_to_sniff); | |
634 CloseHandle(handle_from_sniff); | |
635 WaitForSingleObject(sniffemacs_handle, 1000L); | |
636 CloseHandle(sniffemacs_handle); | |
637 sniffemacs_handle = NULL; | |
638 WaitForSingleObject(readthread_handle, 1000L); | |
639 readthread_handle = NULL; | |
640 CloseHandle(hBufferMutex); | |
641 hBufferMutex = NULL; | |
642 SNIFF_TRACE_CLOSE; | |
643 #else | |
644 close(fd_to_sniff); | |
645 close(fd_from_sniff); | |
646 wait(NULL); | |
647 #endif | |
648 } | |
649 else | |
650 { | |
651 #ifdef WIN32 | |
7049
2ebc20378f68
commit https://github.com/vim/vim/commit/80ce282107849ef1a0e9b8a3be26c59c211b0957
Christian Brabandt <cb@256bit.org>
parents:
3935
diff
changeset
|
652 # if (defined(_MSC_VER) && _MSC_VER >= 1400) |
2ebc20378f68
commit https://github.com/vim/vim/commit/80ce282107849ef1a0e9b8a3be26c59c211b0957
Christian Brabandt <cb@256bit.org>
parents:
3935
diff
changeset
|
653 Sleep(2); |
2ebc20378f68
commit https://github.com/vim/vim/commit/80ce282107849ef1a0e9b8a3be26c59c211b0957
Christian Brabandt <cb@256bit.org>
parents:
3935
diff
changeset
|
654 # else |
7 | 655 _sleep(2); |
7049
2ebc20378f68
commit https://github.com/vim/vim/commit/80ce282107849ef1a0e9b8a3be26c59c211b0957
Christian Brabandt <cb@256bit.org>
parents:
3935
diff
changeset
|
656 # endif |
7 | 657 if (!sniff_request_processed) |
658 ProcessSniffRequests(); | |
659 #else | |
660 sleep(2); /* Incoming msg could disturb edit */ | |
661 #endif | |
662 sniff_will_disconnect = 1; /* We expect disconnect msg in 2 secs */ | |
663 } | |
664 } | |
665 | |
666 | |
667 /* ConnectToSniffEmacs | |
668 * Connect to Sniff: returns 1 on error | |
669 */ | |
670 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
671 ConnectToSniffEmacs(void) |
7 | 672 { |
673 #ifdef WIN32 /* Windows Version of the Code */ | |
674 HANDLE ToSniffEmacs[2], FromSniffEmacs[2]; | |
675 SECURITY_ATTRIBUTES sa; | |
676 | |
677 sa.nLength = sizeof(sa); | |
678 sa.lpSecurityDescriptor = NULL; | |
679 sa.bInheritHandle = TRUE; | |
680 | |
681 if (! CreatePipe(&ToSniffEmacs[0], &ToSniffEmacs[1], &sa, 0)) | |
682 return 1; | |
683 if (! CreatePipe(&FromSniffEmacs[0], &FromSniffEmacs[1], &sa, 0)) | |
684 return 1; | |
685 | |
686 sniffemacs_handle = ExecuteDetachedProgram(SniffEmacs[0], SniffEmacs[0], | |
687 ToSniffEmacs[0], FromSniffEmacs[1]); | |
688 | |
689 if (sniffemacs_handle) | |
690 { | |
691 handle_to_sniff = ToSniffEmacs[1]; | |
692 handle_from_sniff = FromSniffEmacs[0]; | |
693 sniff_connected = 1; | |
694 hBufferMutex = CreateMutex( | |
695 NULL, /* no security attributes */ | |
696 FALSE, /* initially not owned */ | |
697 "SniffReadBufferMutex"); /* name of mutex */ | |
698 if (hBufferMutex == NULL) | |
699 { | |
700 /* Check for error. */ | |
701 } | |
702 readthread_handle = (HANDLE)_beginthread(SniffEmacsReadThread, 0, NULL); | |
703 return 0; | |
704 } | |
705 else | |
706 { | |
707 /* error in spawn() */ | |
708 return 1; | |
709 } | |
710 | |
711 #else /* UNIX Version of the Code */ | |
712 int ToSniffEmacs[2], FromSniffEmacs[2]; | |
713 | |
1774 | 714 if (pipe(ToSniffEmacs) != 0) |
715 return 1; | |
716 if (pipe(FromSniffEmacs) != 0) | |
717 return 1; | |
7 | 718 |
719 /* fork */ | |
720 if ((sniffemacs_pid=fork()) == 0) | |
721 { | |
722 /* child */ | |
723 | |
724 /* prepare communication pipes */ | |
725 close(ToSniffEmacs[1]); | |
726 close(FromSniffEmacs[0]); | |
727 | |
728 dup2(ToSniffEmacs[0],fileno(stdin)); /* write to ToSniffEmacs[1] */ | |
729 dup2(FromSniffEmacs[1],fileno(stdout));/* read from FromSniffEmacs[0] */ | |
730 | |
731 close(ToSniffEmacs[0]); | |
732 close(FromSniffEmacs[1]); | |
733 | |
734 /* start sniffemacs */ | |
735 execvp (SniffEmacs[0], SniffEmacs); | |
736 { | |
737 /* FILE *out = fdopen(FromSniffEmacs[1], "w"); */ | |
738 sleep(1); | |
739 fputs(_(msg_sniff_disconnect), stdout); | |
740 fflush(stdout); | |
741 sleep(3); | |
742 #ifdef FEAT_GUI | |
743 if (gui.in_use) | |
744 gui_exit(1); | |
745 #endif | |
746 exit(1); | |
747 } | |
748 return 1; | |
749 } | |
750 else if (sniffemacs_pid > 0) | |
751 { | |
752 /* parent process */ | |
753 close(ToSniffEmacs[0]); | |
754 fd_to_sniff = ToSniffEmacs[1]; | |
755 close(FromSniffEmacs[1]); | |
756 fd_from_sniff = FromSniffEmacs[0]; | |
757 sniff_connected = 1; | |
758 return 0; | |
759 } | |
760 else /* error in fork() */ | |
761 return 1; | |
762 #endif /* UNIX Version of the Code */ | |
763 } | |
764 | |
765 | |
766 /* HandleSniffRequest | |
767 * Handle one request from SNiFF+ | |
768 */ | |
769 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
770 HandleSniffRequest(char *buffer) |
7 | 771 { |
772 char VICommand[MAX_REQUEST_LEN]; | |
773 char command; | |
774 char *arguments; | |
775 char *token; | |
776 char *argv[3]; | |
777 int argc = 0; | |
778 buf_T *buf; | |
779 | |
780 const char *SetTab = "set tabstop=%d"; | |
781 const char *SelectBuf = "buf %s"; | |
782 const char *DeleteBuf = "bd %s"; | |
783 const char *UnloadBuf = "bun %s"; | |
784 const char *GotoLine = "%d"; | |
785 | |
786 command = buffer[0]; | |
787 arguments = &buffer[1]; | |
788 token = strtok(arguments, sniff_rq_sep); | |
3935 | 789 while (argc <3) |
7 | 790 { |
791 if (token) | |
792 { | |
793 argv[argc] = (char*)vim_strsave((char_u *)token); | |
794 token = strtok(0, sniff_rq_sep); | |
795 } | |
796 else | |
797 argv[argc] = strdup(""); | |
798 argc++; | |
799 } | |
800 | |
801 switch (command) | |
802 { | |
803 case 'o' : /* visit file at char pos */ | |
804 case 'O' : /* visit file at line number */ | |
805 { | |
806 char *file = argv[0]; | |
807 int position = atoi(argv[1]); | |
808 | |
809 buf = vi_find_buffer(file); | |
810 setpcmark(); /* insert current pos in jump list [mark.c]*/ | |
811 if (!buf) | |
812 vi_open_file(file); | |
813 else if (buf!=curbuf) | |
814 { | |
426 | 815 vim_snprintf(VICommand, sizeof(VICommand), |
816 (char *)SelectBuf, file); | |
7 | 817 vi_exec_cmd(VICommand); |
818 } | |
819 if (command == 'o') | |
820 vi_set_cursor_pos((long)position); | |
821 else | |
822 { | |
426 | 823 vim_snprintf(VICommand, sizeof(VICommand), |
824 (char *)GotoLine, (int)position); | |
7 | 825 vi_exec_cmd(VICommand); |
826 } | |
827 checkpcmark(); /* [mark.c] */ | |
828 #if defined(FEAT_GUI_X11) || defined(FEAT_GUI_W32) | |
829 if (gui.in_use && !gui.in_focus) /* Raise Vim Window */ | |
830 { | |
831 # ifdef FEAT_GUI_W32 | |
832 SetForegroundWindow(s_hwnd); | |
833 # else | |
834 extern Widget vimShell; | |
835 | |
836 XSetInputFocus(gui.dpy, XtWindow(vimShell), RevertToNone, | |
837 CurrentTime); | |
838 XRaiseWindow(gui.dpy, XtWindow(vimShell)); | |
839 # endif | |
840 } | |
841 #endif | |
842 break; | |
843 } | |
844 case 'p' : /* path of file has changed */ | |
845 /* when changing from shared to private WS (checkout) */ | |
846 { | |
847 char *file = argv[0]; | |
848 char *new_path = argv[1]; | |
849 | |
850 buf = vi_find_buffer(file); | |
851 if (buf && !buf->b_changed) /* delete buffer only if not modified */ | |
852 { | |
426 | 853 vim_snprintf(VICommand, sizeof(VICommand), |
854 (char *)DeleteBuf, file); | |
7 | 855 vi_exec_cmd(VICommand); |
856 } | |
857 vi_open_file(new_path); | |
858 break; | |
859 } | |
860 case 'w' : /* writability has changed */ | |
861 /* Sniff sends request twice, | |
862 * but only the last one is the right one */ | |
863 { | |
864 char *file = argv[0]; | |
865 int writable = atoi(argv[1]); | |
866 | |
867 buf = vi_find_buffer(file); | |
868 if (buf) | |
869 { | |
870 buf->b_p_ro = !writable; | |
871 if (buf != curbuf) | |
872 { | |
873 buf->b_flags |= BF_CHECK_RO + BF_NEVERLOADED; | |
874 if (writable && !buf->b_changed) | |
875 { | |
426 | 876 vim_snprintf(VICommand, sizeof(VICommand), |
877 (char *)UnloadBuf, file); | |
7 | 878 vi_exec_cmd(VICommand); |
879 } | |
880 } | |
881 else if (writable && !buf->b_changed) | |
882 { | |
883 vi_exec_cmd("e"); | |
884 } | |
885 } | |
886 break; | |
887 } | |
888 case 'h' : /* highlight info */ | |
889 break; /* not implemented */ | |
890 | |
891 case 't' : /* Set tab width */ | |
892 { | |
893 int tab_width = atoi(argv[1]); | |
894 | |
895 if (tab_width > 0 && tab_width <= 16) | |
896 { | |
426 | 897 vim_snprintf(VICommand, sizeof(VICommand), |
898 (char *)SetTab, tab_width); | |
7 | 899 vi_exec_cmd(VICommand); |
900 } | |
901 break; | |
902 } | |
903 case '|': | |
904 { | |
905 /* change the request separator */ | |
906 sniff_rq_sep[0] = arguments[0]; | |
907 /* echo the request */ | |
908 WriteToSniff(buffer); | |
909 break; | |
910 } | |
911 case 'A' : /* Warning/Info msg */ | |
912 vi_msg(arguments); | |
426 | 913 if (!strncmp(arguments, "Disconnected", 12)) |
7 | 914 sniff_disconnect(1); /* unexpected disconnection */ |
915 break; | |
916 case 'a' : /* Error msg */ | |
917 vi_error_msg(arguments); | |
426 | 918 if (!strncmp(arguments, "Cannot connect", 14)) |
7 | 919 sniff_disconnect(1); |
920 break; | |
921 | |
922 default : | |
923 break; | |
924 } | |
3935 | 925 while (argc) |
7 | 926 vim_free(argv[--argc]); |
927 } | |
928 | |
929 | |
930 #ifndef WIN32 | |
931 /* get_request | |
932 * read string from fd up to next newline (excluding the nl), | |
933 * returns length of string | |
934 * 0 if no data available or no complete line | |
935 * <0 on error | |
936 */ | |
937 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
938 get_request(int fd, char *buf, int maxlen) |
7 | 939 { |
940 static char inbuf[1024]; | |
941 static int pos = 0, bytes = 0; | |
942 int len; | |
943 #ifdef HAVE_SELECT | |
944 struct timeval tval; | |
945 fd_set rfds; | |
946 | |
947 FD_ZERO(&rfds); | |
948 FD_SET(fd, &rfds); | |
949 tval.tv_sec = 0; | |
950 tval.tv_usec = 0; | |
951 #else | |
952 struct pollfd fds; | |
953 | |
954 fds.fd = fd; | |
955 fds.events = POLLIN; | |
956 #endif | |
957 | |
958 for (len = 0; len < maxlen; len++) | |
959 { | |
960 if (pos >= bytes) /* end of buffer reached? */ | |
961 { | |
962 #ifdef HAVE_SELECT | |
963 if (select(fd + 1, &rfds, NULL, NULL, &tval) > 0) | |
964 #else | |
2577
073ff46fe397
Fold Vim 7.2 default branch back to trunk to avoid two heads. (Tony
Bram Moolenaar <bram@vim.org>
parents:
2165
diff
changeset
|
965 if (poll(&fds, 1, 0) > 0) |
7 | 966 #endif |
2577
073ff46fe397
Fold Vim 7.2 default branch back to trunk to avoid two heads. (Tony
Bram Moolenaar <bram@vim.org>
parents:
2165
diff
changeset
|
967 { |
073ff46fe397
Fold Vim 7.2 default branch back to trunk to avoid two heads. (Tony
Bram Moolenaar <bram@vim.org>
parents:
2165
diff
changeset
|
968 pos = 0; |
073ff46fe397
Fold Vim 7.2 default branch back to trunk to avoid two heads. (Tony
Bram Moolenaar <bram@vim.org>
parents:
2165
diff
changeset
|
969 bytes = read(fd, inbuf, sizeof(inbuf)); |
073ff46fe397
Fold Vim 7.2 default branch back to trunk to avoid two heads. (Tony
Bram Moolenaar <bram@vim.org>
parents:
2165
diff
changeset
|
970 if (bytes <= 0) |
073ff46fe397
Fold Vim 7.2 default branch back to trunk to avoid two heads. (Tony
Bram Moolenaar <bram@vim.org>
parents:
2165
diff
changeset
|
971 return bytes; |
073ff46fe397
Fold Vim 7.2 default branch back to trunk to avoid two heads. (Tony
Bram Moolenaar <bram@vim.org>
parents:
2165
diff
changeset
|
972 } |
073ff46fe397
Fold Vim 7.2 default branch back to trunk to avoid two heads. (Tony
Bram Moolenaar <bram@vim.org>
parents:
2165
diff
changeset
|
973 else |
073ff46fe397
Fold Vim 7.2 default branch back to trunk to avoid two heads. (Tony
Bram Moolenaar <bram@vim.org>
parents:
2165
diff
changeset
|
974 { |
073ff46fe397
Fold Vim 7.2 default branch back to trunk to avoid two heads. (Tony
Bram Moolenaar <bram@vim.org>
parents:
2165
diff
changeset
|
975 pos = pos-len; |
073ff46fe397
Fold Vim 7.2 default branch back to trunk to avoid two heads. (Tony
Bram Moolenaar <bram@vim.org>
parents:
2165
diff
changeset
|
976 buf[0] = '\0'; |
073ff46fe397
Fold Vim 7.2 default branch back to trunk to avoid two heads. (Tony
Bram Moolenaar <bram@vim.org>
parents:
2165
diff
changeset
|
977 return 0; |
073ff46fe397
Fold Vim 7.2 default branch back to trunk to avoid two heads. (Tony
Bram Moolenaar <bram@vim.org>
parents:
2165
diff
changeset
|
978 } |
7 | 979 } |
980 if ((buf[len] = inbuf[pos++]) =='\n') | |
981 break; | |
982 } | |
983 buf[len] = '\0'; | |
984 return len; | |
985 } | |
986 #endif /* WIN32 */ | |
987 | |
988 | |
989 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
990 SendRequest(struct sn_cmd *command, char *symbol) |
7 | 991 { |
992 int cmd_type = command->cmd_type; | |
993 static char cmdstr[MAX_REQUEST_LEN]; | |
994 static char msgtxt[MAX_REQUEST_LEN]; | |
995 char *buffer_name = NULL; | |
996 | |
997 if (cmd_type == RQ_CONNECT) | |
998 { | |
999 sniff_connect(); | |
1000 return; | |
1001 } | |
1002 if (!sniff_connected && !(cmd_type & SILENT)) | |
1003 { | |
1004 vi_error_msg(_("E278: SNiFF+ not connected")); | |
1005 return; | |
1006 } | |
1007 | |
1008 if (cmd_type & NEED_FILE) | |
1009 { | |
1010 if (!curbuf->b_sniff) | |
1011 { | |
1012 if (!(cmd_type & SILENT)) | |
1013 vi_error_msg(_("E279: Not a SNiFF+ buffer")); | |
1014 return; | |
1015 } | |
1016 buffer_name = vi_buffer_name(); | |
1017 if (buffer_name == NULL) | |
1018 return; | |
1019 if (cmd_type & NEED_SYMBOL) | |
1020 { | |
1021 if (cmd_type & EMPTY_SYMBOL) | |
1022 symbol = " "; | |
1023 else if (!symbol && !(symbol = vi_symbol_under_cursor())) | |
1024 return; /* error msg already displayed */ | |
1025 } | |
1026 | |
1027 if (symbol) | |
272 | 1028 vim_snprintf(cmdstr, sizeof(cmdstr), "%c%s%s%ld%s%s\n", |
7 | 1029 command->cmd_code, |
1030 buffer_name, | |
1031 sniff_rq_sep, | |
1032 vi_cursor_pos(), | |
1033 sniff_rq_sep, | |
1034 symbol | |
1035 ); | |
1036 else | |
272 | 1037 vim_snprintf(cmdstr, sizeof(cmdstr), "%c%s\n", |
1038 command->cmd_code, buffer_name); | |
7 | 1039 } |
1040 else /* simple request */ | |
1041 { | |
1042 cmdstr[0] = command->cmd_code; | |
1043 cmdstr[1] = '\n'; | |
1044 cmdstr[2] = '\0'; | |
1045 } | |
1046 if (command->cmd_msg && !(cmd_type & SILENT)) | |
1047 { | |
1048 if ((cmd_type & NEED_SYMBOL) && !(cmd_type & EMPTY_SYMBOL)) | |
1049 { | |
272 | 1050 vim_snprintf(msgtxt, sizeof(msgtxt), "%s: %s", |
1051 _(command->cmd_msg), symbol); | |
7 | 1052 vi_msg(msgtxt); |
1053 } | |
1054 else | |
1055 vi_msg(_(command->cmd_msg)); | |
1056 } | |
1057 WriteToSniff(cmdstr); | |
1058 if (cmd_type & DISCONNECT) | |
1059 sniff_disconnect(0); | |
1060 } | |
1061 | |
1062 | |
1063 | |
1064 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1065 WriteToSniff(char *str) |
7 | 1066 { |
1067 int bytes; | |
1068 #ifdef WIN32 | |
1069 if (! WriteFile(handle_to_sniff, str, strlen(str), &bytes, NULL)) | |
1070 { | |
1071 DWORD err=GetLastError(); | |
1072 bytes = -1; | |
1073 } | |
1074 #else | |
1075 bytes = write(fd_to_sniff, str, strlen(str)); | |
1076 #endif | |
1077 if (bytes<0) | |
1078 { | |
1079 vi_msg(_("Sniff: Error during write. Disconnected")); | |
1080 sniff_disconnect(1); | |
1081 } | |
1082 } | |
1083 | |
1084 /*-------- vim helping functions --------------------------------*/ | |
1085 | |
1086 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1087 vi_msg(char *str) |
7 | 1088 { |
1089 if (str != NULL && *str != NUL) | |
1090 MSG((char_u *)str); | |
1091 } | |
1092 | |
1093 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1094 vi_error_msg(char *str) |
7 | 1095 { |
1096 if (str != NULL && *str != NUL) | |
1097 EMSG((char_u *)str); | |
1098 } | |
1099 | |
1100 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1101 vi_open_file(char *fname) |
7 | 1102 { |
1103 ++no_wait_return; | |
1743 | 1104 do_ecmd(0, (char_u *)fname, NULL, NULL, ECMD_ONE, ECMD_HIDE+ECMD_OLDBUF, |
1105 curwin); | |
7 | 1106 curbuf->b_sniff = TRUE; |
1107 --no_wait_return; /* [ex_docmd.c] */ | |
1108 } | |
1109 | |
1110 static buf_T * | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1111 vi_find_buffer(char *fname) |
7 | 1112 { /* derived from buflist_findname() [buffer.c] */ |
1113 buf_T *buf; | |
1114 | |
1115 for (buf = firstbuf; buf != NULL; buf = buf->b_next) | |
1116 if (buf->b_sfname != NULL && fnamecmp(fname, buf->b_sfname) == 0) | |
1117 return (buf); | |
1118 return NULL; | |
1119 } | |
1120 | |
1121 | |
1122 static char * | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1123 vi_symbol_under_cursor(void) |
7 | 1124 { |
1125 int len; | |
1126 char *symbolp; | |
1127 char *p; | |
1128 static char sniff_symbol[256]; | |
1129 | |
1130 len = find_ident_under_cursor((char_u **)&symbolp, FIND_IDENT); | |
1131 /* [normal.c] */ | |
1132 if (len <= 0) | |
1133 return NULL; | |
1134 for (p=sniff_symbol; len; len--) | |
1135 *p++ = *symbolp++; | |
1136 *p = '\0'; | |
1137 return sniff_symbol; | |
1138 } | |
1139 | |
1140 | |
1141 static char * | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1142 vi_buffer_name(void) |
7 | 1143 { |
1144 return (char *)curbuf->b_sfname; | |
1145 } | |
1146 | |
1147 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1148 vi_exec_cmd(char *vicmd) |
7 | 1149 { |
1150 do_cmdline_cmd((char_u *)vicmd); /* [ex_docmd.c] */ | |
1151 } | |
1152 | |
1153 /* | |
1154 * Set cursor on character position | |
1155 * derived from cursor_pos_info() [buffer.c] | |
1156 */ | |
1157 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1158 vi_set_cursor_pos(long char_pos) |
7 | 1159 { |
1160 linenr_T lnum; | |
1161 long char_count = 1; /* first position = 1 */ | |
1162 int line_size; | |
1163 int eol_size; | |
1164 | |
1165 if (char_pos == 0) | |
1166 { | |
1167 char_pos = 1; | |
1168 } | |
1169 if (get_fileformat(curbuf) == EOL_DOS) | |
1170 eol_size = 2; | |
1171 else | |
1172 eol_size = 1; | |
1173 for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) | |
1174 { | |
1175 line_size = STRLEN(ml_get(lnum)) + eol_size; | |
1176 if (char_count+line_size > char_pos) break; | |
1177 char_count += line_size; | |
1178 } | |
1179 curwin->w_cursor.lnum = lnum; | |
1180 curwin->w_cursor.col = char_pos - char_count; | |
1181 } | |
1182 | |
1183 static long | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1184 vi_cursor_pos(void) |
7 | 1185 { |
1186 linenr_T lnum; | |
1187 long char_count=1; /* sniff starts with pos 1 */ | |
1188 int line_size; | |
1189 int eol_size; | |
1190 | |
1191 if (curbuf->b_p_tx) | |
1192 eol_size = 2; | |
1193 else | |
1194 eol_size = 1; | |
1195 for (lnum = 1; lnum < curwin->w_cursor.lnum; ++lnum) | |
1196 { | |
1197 line_size = STRLEN(ml_get(lnum)) + eol_size; | |
1198 char_count += line_size; | |
1199 } | |
1200 return char_count + curwin->w_cursor.col; | |
1201 } |