diff --git a/runtime/doc/channel.txt b/runtime/doc/channel.txt index 7938087b1b..a52c739ad7 100644 --- a/runtime/doc/channel.txt +++ b/runtime/doc/channel.txt @@ -1,4 +1,4 @@ -*channel.txt* For Vim version 7.4. Last change: 2016 Feb 15 +*channel.txt* For Vim version 7.4. Last change: 2016 Feb 16 VIM REFERENCE MANUAL by Bram Moolenaar @@ -117,7 +117,7 @@ Use |ch_status()| to see if the channel could be opened. "mode" can be: *channel-mode* "json" - Use JSON, see below; most convenient way. Default. - "js" - Use JavaScript encoding, more efficient than JSON. + "js" - Use JS (JavaScript) encoding, more efficient than JSON. "nl" - Use messages that end in a NL character "raw" - Use raw messages @@ -188,11 +188,11 @@ If there is an error reading or writing a channel it will be closed. ============================================================================== 4. Using a JSON or JS channel *channel-use* -If {mode} is "json" then a message can be sent synchronously like this: > +If mode is JSON then a message can be sent synchronously like this: > let response = ch_sendexpr(channel, {expr}) This awaits a response from the other side. -When {mode} is "js" this works the same, except that the messages use +When mode is JS this works the same, except that the messages use JavaScript encoding. See |js_encode()| for the difference. To send a message, without handling a response: > @@ -242,7 +242,7 @@ is then completely responsible for correct encoding and decoding. ============================================================================== 5. Channel commands *channel-commands* -With a "json" channel the process can send commands to Vim that will be +With a JSON channel the process can send commands to Vim that will be handled by Vim internally, it does not require a handler for the channel. Possible commands are: *E903* *E904* *E905* @@ -316,14 +316,15 @@ Example: ============================================================================== 6. Using a RAW or NL channel *channel-raw* -If {mode} is "raw" then a message can be send like this: > +If mode is RAW or NL then a message can be send like this: > let response = ch_sendraw(channel, {string}) + The {string} is sent as-is. The response will be what can be read from the channel right away. Since Vim doesn't know how to recognize the end of the message you need to take care of it yourself. The timeout applies for reading the first byte, after that it will not wait for anything more. -If {mode} is "nl" you can send a message in a similar way. You are expected +If mode is "nl" you can send a message in a similar way. You are expected to put in the NL after each message. Thus you can also send several messages ending in a NL at once. The response will be the text up to and including the first NL. This can also be just the NL for an empty response. @@ -450,6 +451,7 @@ The {options} argument in job_start() is a dictionary. All entries are optional. The same options can be used with job_setoptions(job, {options}). TODO: *job-out-cb* +"callback": handler "out-cb": handler Callback for when there is something to read on stdout. TODO: *job-err-cb* @@ -484,7 +486,7 @@ TODO: *job-out-io* "out-buffer": "name" buffer to append to TODO: *job-err-io* -"err-io": "out" same as stdout (default) +"err-io": "out" same type as stdout (default) "err-io": "null" disconnect stderr "err-io": "pipe" stderr is connected to the channel "err-io": "file" stderr writes to a file diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 0f8cab1254..1012989588 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 7.4. Last change: 2016 Feb 13 +*eval.txt* For Vim version 7.4. Last change: 2016 Feb 16 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1821,9 +1821,9 @@ ch_close( {handle}) none close a channel ch_logfile( {fname} [, {mode}]) none start logging channel activity ch_open( {address} [, {argdict})] Number open a channel to {address} ch_readraw( {handle}) String read from channel {handle} -ch_sendexpr( {handle}, {expr} [, {callback}]) +ch_sendexpr( {handle}, {expr} [, {options}]) any send {expr} over JSON channel {handle} -ch_sendraw( {handle}, {string} [, {callback}]) +ch_sendraw( {handle}, {string} [, {options}]) any send {string} over raw channel {handle} ch_status( {handle}) String status of channel {handle} changenr() Number current change number @@ -2725,28 +2725,32 @@ ch_readraw({handle}) *ch_readraw()* within that time an empty string is returned. TODO: depends on channel mode. -ch_sendexpr({handle}, {expr} [, {callback}]) *ch_sendexpr()* +ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()* Send {expr} over channel {handle}. The {expr} is encoded according to the type of channel. The function cannot be used with a raw channel. See |channel-use|. *E912* - When {callback} is given returns immediately. Without - {callback} waits for a response and returns the decoded - expression. When there is an error or timeout returns an - empty string. + {options} must be a Dictionary. + When "callback" is a Funcref or the name of a function, + ch_sendexpr() returns immediately. The callback is invoked + when the response is received. See |channel-callback|. - When {callback} is zero no response is expected. - Otherwise {callback} must be a Funcref or the name of a - function. It is called when the response is received. See - |channel-callback|. + Without "callback" ch_sendexpr() waits for a response and + returns the decoded expression. When there is an error or + timeout it returns an empty string. + + When "callback" is zero no response is expected. {only available when compiled with the |+channel| feature} -ch_sendraw({handle}, {string} [, {callback}]) *ch_sendraw()* +ch_sendraw({handle}, {string} [, {options}]) *ch_sendraw()* Send {string} over channel {handle}. Works like |ch_sendexpr()|, but does not encode the request or decode the response. The caller is responsible for the - correct contents. See |channel-use|. + correct contents. Also does not add a newline for a channel + in NL mode, the caller must do that. The NL in the response + is removed. + See |channel-use|. {only available when compiled with the |+channel| feature} @@ -7276,8 +7280,9 @@ listcmds Compiled with commands for the buffer list |:files| and the argument list |arglist|. localmap Compiled with local mappings and abbr. |:map-local| lua Compiled with Lua interface |Lua|. -mac Macintosh version of Vim. -macunix Macintosh version of Vim, using Unix files (OS-X). +mac Any Macintosh version of Vim. +macunix Compiled for OS X, with darwin +osx Compiled for OS X, with or without darwin menu Compiled with support for |:menu|. mksession Compiled with support for |:mksession|. modify_fname Compiled with file name modifiers. |filename-modifiers| diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak index 1c1ee8c649..6a2b91f6cf 100644 --- a/src/Make_cyg_ming.mak +++ b/src/Make_cyg_ming.mak @@ -264,7 +264,7 @@ ifndef DYNAMIC_PYTHON3_DLL DYNAMIC_PYTHON3_DLL=python$(PYTHON3_VER).dll endif ifdef PYTHON3_HOME -PYTHON3_HOME_DEF=-DPYTHON3_HOME=\"$(PYTHON3_HOME)\" +PYTHON3_HOME_DEF=-DPYTHON3_HOME=L\"$(PYTHON3_HOME)\" endif ifeq (no,$(DYNAMIC_PYTHON3)) diff --git a/src/channel.c b/src/channel.c index 468fbbc6cf..eaf644895a 100644 --- a/src/channel.c +++ b/src/channel.c @@ -47,7 +47,7 @@ # define sock_write(sd, buf, len) write(sd, buf, len) # define sock_read(sd, buf, len) read(sd, buf, len) # define sock_close(sd) close(sd) -# define fd_read(fd, buf, len, timeout) read(fd, buf, len) +# define fd_read(fd, buf, len) read(fd, buf, len) # define fd_write(sd, buf, len) write(sd, buf, len) # define fd_close(sd) close(sd) #endif @@ -58,7 +58,7 @@ extern HWND s_hwnd; /* Gvim's Window handle */ #ifdef WIN32 static int -fd_read(sock_T fd, char_u *buf, size_t len, int timeout) +fd_read(sock_T fd, char *buf, size_t len) { HANDLE h = (HANDLE)fd; DWORD nread; @@ -69,7 +69,7 @@ fd_read(sock_T fd, char_u *buf, size_t len, int timeout) } static int -fd_write(sock_T fd, char_u *buf, size_t len) +fd_write(sock_T fd, char *buf, size_t len) { HANDLE h = (HANDLE)fd; DWORD nwrite; @@ -253,7 +253,7 @@ add_channel(void) return NULL; channel->ch_id = next_ch_id++; - ch_log(channel, "Opening channel\n"); + ch_log(channel, "Created channel\n"); #ifdef CHANNEL_PIPES for (which = CHAN_SOCK; which <= CHAN_IN; ++which) @@ -477,8 +477,12 @@ channel_gui_unregister(channel_T *channel) #endif +static char *e_cannot_connect = N_("E902: Cannot connect to port"); + /* * Open a socket channel to "hostname":"port". + * "waittime" is the time in msec to wait for the connection. + * When negative wait forever. * Returns the channel for success. * Returns NULL for failure. */ @@ -511,7 +515,7 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void)) if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - ch_error(NULL, "in socket() in channel_open().\n"); + ch_error(channel, "in socket() in channel_open().\n"); PERROR("E898: socket() in channel_open()"); channel_free(channel); return NULL; @@ -524,7 +528,7 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void)) server.sin_port = htons(port); if ((host = gethostbyname(hostname)) == NULL) { - ch_error(NULL, "in gethostbyname() in channel_open()\n"); + ch_error(channel, "in gethostbyname() in channel_open()\n"); PERROR("E901: gethostbyname() in channel_open()"); sock_close(sd); channel_free(channel); @@ -544,7 +548,7 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void)) ) { SOCK_ERRNO; - ch_errorn(NULL, "channel_open: Connect failed with errno %d\n", + ch_errorn(channel, "channel_open: Connect failed with errno %d\n", errno); sock_close(sd); channel_free(channel); @@ -553,7 +557,7 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void)) } /* Try connecting to the server. */ - ch_logsn(NULL, "Connecting to %s port %d", hostname, port); + ch_logsn(channel, "Connecting to %s port %d\n", hostname, port); ret = connect(sd, (struct sockaddr *)&server, sizeof(server)); SOCK_ERRNO; if (ret < 0) @@ -564,9 +568,9 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void)) #endif ) { - ch_errorn(NULL, "channel_open: Connect failed with errno %d\n", + ch_errorn(channel, "channel_open: Connect failed with errno %d\n", errno); - PERROR(_("E902: Cannot connect to port")); + PERROR(_(e_cannot_connect)); sock_close(sd); channel_free(channel); return NULL; @@ -577,29 +581,62 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void)) { struct timeval tv; fd_set wfds; +#if defined(__APPLE__) && __APPLE__ == 1 +# define PASS_RFDS + fd_set rfds; + FD_ZERO(&rfds); + FD_SET(sd, &rfds); + /* On Mac a zero timeout almost never works. At least wait one + * millisecond. */ + if (waittime == 0) + waittime = 1; +#endif FD_ZERO(&wfds); FD_SET(sd, &wfds); tv.tv_sec = waittime / 1000; tv.tv_usec = (waittime % 1000) * 1000; - ret = select((int)sd + 1, NULL, &wfds, NULL, &tv); + + ch_logn(channel, "Waiting for connection (timeout %d msec)...\n", + waittime); + ret = select((int)sd + 1, +#ifdef PASS_RFDS + &rfds, +#else + NULL, +#endif + &wfds, NULL, &tv); + if (ret < 0) { SOCK_ERRNO; - ch_errorn(NULL, "channel_open: Connect failed with errno %d\n", + ch_errorn(channel, "channel_open: Connect failed with errno %d\n", errno); - PERROR(_("E902: Cannot connect to port")); + PERROR(_(e_cannot_connect)); sock_close(sd); channel_free(channel); return NULL; } +#ifdef PASS_RFDS + if (ret == 0 && FD_ISSET(sd, &rfds) && FD_ISSET(sd, &wfds)) + { + /* For OS X, this implies error. See tcp(4). */ + ch_error(channel, "channel_open: Connect failed\n"); + EMSG(_(e_cannot_connect)); + sock_close(sd); + channel_free(channel); + return NULL; + } +#endif if (!FD_ISSET(sd, &wfds)) { /* don't give an error, we just timed out. */ + ch_error(channel, "Connection timed out\n"); sock_close(sd); channel_free(channel); return NULL; } + ch_log(channel, "Connection made\n"); } if (waittime >= 0) @@ -619,7 +656,7 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void)) if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { SOCK_ERRNO; - ch_log(NULL, "socket() retry in channel_open()\n"); + ch_log(channel, "socket() retry in channel_open()\n"); PERROR("E900: socket() retry in channel_open()"); channel_free(channel); return NULL; @@ -633,7 +670,7 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void)) while (retries-- && ((errno == ECONNREFUSED) || (errno == EINTR))) { - ch_log(NULL, "retrying...\n"); + ch_log(channel, "retrying...\n"); mch_delay(3000L, TRUE); ui_breakcheck(); if (got_int) @@ -652,8 +689,8 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void)) if (!success) { /* Get here when the server can't be found. */ - ch_error(NULL, "Cannot connect to port after retry\n"); - PERROR(_("E899: Cannot connect to port after retry2")); + ch_error(channel, "Cannot connect to port after retry\n"); + PERROR(_("E899: Cannot connect to port after retry")); sock_close(sd); channel_free(channel); return NULL; @@ -688,12 +725,12 @@ channel_set_job(channel_T *channel, job_T *job) } /* - * Set the json mode of channel "channel" to "ch_mode". + * Set the mode of channel "channel" to "mode". */ void -channel_set_json_mode(channel_T *channel, ch_mode_T ch_mode) +channel_set_mode(channel_T *channel, ch_mode_T mode) { - channel->ch_mode = ch_mode; + channel->ch_mode = mode; } /* @@ -715,6 +752,18 @@ channel_set_callback(channel_T *channel, char_u *callback) channel->ch_callback = vim_strsave(callback); } +/* + * Set various properties from an "options" argument. + */ + void +channel_set_options(channel_T *channel, jobopt_T *options) +{ + channel_set_mode(channel, options->jo_mode); + + if (options->jo_callback != NULL && *options->jo_callback != NUL) + channel_set_callback(channel, options->jo_callback); +} + /* * Set the callback for channel "channel" for the response with "id". */ @@ -907,8 +956,7 @@ channel_parse_json(channel_T *channel) } /* - * Remove "node" from the queue that it is in and free it. - * Also frees the contained callback name. + * Remove "node" from the queue that it is in. Does not free it. */ static void remove_cb_node(cbq_T *head, cbq_T *node) @@ -921,8 +969,6 @@ remove_cb_node(cbq_T *head, cbq_T *node) head->cq_prev = node->cq_prev; else node->cq_next->cq_prev = node->cq_prev; - vim_free(node->cq_callback); - vim_free(node); } /* @@ -1079,7 +1125,8 @@ channel_exe_cmd(channel_T *channel, char_u *cmd, typval_T *arg2, typval_T *arg3) /* * Invoke a callback for channel "channel" if needed. - * Return OK when a message was handled, there might be another one. + * TODO: add "which" argument, read stderr. + * Return TRUE when a message was handled, there might be another one. */ static int may_invoke_callback(channel_T *channel) @@ -1096,7 +1143,7 @@ may_invoke_callback(channel_T *channel) /* this channel is handled elsewhere (netbeans) */ return FALSE; - if (ch_mode != MODE_RAW) + if (ch_mode == MODE_JSON || ch_mode == MODE_JS) { /* Get any json message in the queue. */ if (channel_get_json(channel, -1, &listtv) == FAIL) @@ -1135,18 +1182,51 @@ may_invoke_callback(channel_T *channel) } else if (channel_peek(channel) == NULL) { - /* nothing to read on raw channel */ + /* nothing to read on RAW or NL channel */ return FALSE; } else { - /* If there is no callback, don't do anything. */ + /* If there is no callback drop the message. */ if (channel->ch_callback == NULL) + { + while ((msg = channel_get(channel)) != NULL) + vim_free(msg); return FALSE; + } + + if (ch_mode == MODE_NL) + { + char_u *nl; + char_u *buf; + + /* See if we have a message ending in NL in the first buffer. If + * not try to concatenate the first and the second buffer. */ + while (TRUE) + { + buf = channel_peek(channel); + nl = vim_strchr(buf, NL); + if (nl != NULL) + break; + if (channel_collapse(channel) == FAIL) + return FALSE; /* incomplete message */ + } + if (nl[1] == NUL) + /* get the whole buffer */ + msg = channel_get(channel); + else + { + /* Copy the message into allocated memory and remove it from + * the buffer. */ + msg = vim_strnsave(buf, (int)(nl - buf)); + mch_memmove(buf, nl + 1, STRLEN(nl + 1) + 1); + } + } + else + /* For a raw channel we don't know where the message ends, just + * get everything we have. */ + msg = channel_get_all(channel); - /* For a raw channel we don't know where the message ends, just get - * everything. */ - msg = channel_get_all(channel); argv[1].v_type = VAR_STRING; argv[1].vval.v_string = msg; } @@ -1163,8 +1243,12 @@ may_invoke_callback(channel_T *channel) if (item->cq_seq_nr == seq_nr) { ch_log(channel, "Invoking one-time callback\n"); - invoke_callback(channel, item->cq_callback, argv); + /* Remove the item from the list first, if the callback + * invokes ch_close() the list will be cleared. */ remove_cb_node(head, item); + invoke_callback(channel, item->cq_callback, argv); + vim_free(item->cq_callback); + vim_free(item); done = TRUE; break; } @@ -1239,7 +1323,7 @@ channel_status(channel_T *channel) void channel_close(channel_T *channel) { - ch_log(channel, "Closing channel"); + ch_log(channel, "Closing channel\n"); #ifdef FEAT_GUI channel_gui_unregister(channel); @@ -1294,12 +1378,20 @@ channel_save(channel_T *channel, char_u *buf, int len) return FAIL; /* out of memory */ } - /* TODO: don't strip CR when channel is in raw mode */ - p = node->rq_buffer; - for (i = 0; i < len; ++i) - if (buf[i] != CAR || i + 1 >= len || buf[i + 1] != NL) - *p++ = buf[i]; - *p = NUL; + if (channel->ch_mode == MODE_NL) + { + /* Drop any CR before a NL. */ + p = node->rq_buffer; + for (i = 0; i < len; ++i) + if (buf[i] != CAR || i + 1 >= len || buf[i + 1] != NL) + *p++ = buf[i]; + *p = NUL; + } + else + { + mch_memmove(node->rq_buffer, buf, len); + node->rq_buffer[len] = NUL; + } /* append node to the tail of the queue */ node->rq_next = NULL; @@ -1348,7 +1440,13 @@ channel_clear(channel_T *channel) vim_free(channel_get(channel)); while (cb_head->cq_next != NULL) - remove_cb_node(cb_head, cb_head->cq_next); + { + cbq_T *node = cb_head->cq_next; + + remove_cb_node(cb_head, node); + vim_free(node->cq_callback); + vim_free(node); + } while (json_head->jq_next != NULL) { @@ -1392,7 +1490,7 @@ channel_wait(channel_T *channel, sock_T fd, int timeout) int ret; if (timeout > 0) - ch_logn(channel, "Waiting for %d msec\n", timeout); + ch_logn(channel, "Waiting for up to %d msec\n", timeout); # ifdef WIN32 @@ -1405,7 +1503,8 @@ channel_wait(channel_T *channel, sock_T fd, int timeout) /* reading from a pipe, not a socket */ while (TRUE) { - if (PeekNamedPipe(fd, NULL, 0, NULL, &nread, NULL) && nread > 0) + if (PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nread, NULL) + && nread > 0) return OK; diff = deadline - GetTickCount(); if (diff < 0) @@ -1521,9 +1620,9 @@ channel_read(channel_T *channel, int which, char *func) if (channel_wait(channel, fd, 0) == FAIL) break; if (use_socket) - len = sock_read(fd, buf, MAXMSGSIZE); + len = sock_read(fd, (char *)buf, MAXMSGSIZE); else - len = fd_read(fd, buf, MAXMSGSIZE, channel->ch_timeout); + len = fd_read(fd, (char *)buf, MAXMSGSIZE); if (len <= 0) break; /* error or nothing more to read */ @@ -1582,21 +1681,33 @@ channel_read(channel_T *channel, int which, char *func) } /* - * Read from raw channel "channel". Blocks until there is something to read or - * the timeout expires. + * Read from RAW or NL channel "channel". Blocks until there is something to + * read or the timeout expires. + * TODO: add "which" argument and read from stderr. * Returns what was read in allocated memory. * Returns NULL in case of error or timeout. */ char_u * channel_read_block(channel_T *channel) { - ch_log(channel, "Reading raw\n"); - if (channel_peek(channel) == NULL) - { - sock_T fd = get_read_fd(channel); + char_u *buf; + char_u *msg; + ch_mode_T mode = channel->ch_mode; + sock_T fd = get_read_fd(channel); + char_u *nl; + + ch_logsn(channel, "Blocking %s read, timeout: %d msec\n", + mode == MODE_RAW ? "RAW" : "NL", channel->ch_timeout); + + while (TRUE) + { + buf = channel_peek(channel); + if (buf != NULL && (mode == MODE_RAW + || (mode == MODE_NL && vim_strchr(buf, NL) != NULL))) + break; + if (buf != NULL && channel_collapse(channel) == OK) + continue; - /* TODO: read both out and err if they are different */ - ch_log(channel, "No readahead\n"); /* Wait for up to the channel timeout. */ if (fd == CHAN_FD_INVALID || channel_wait(channel, fd, channel->ch_timeout) == FAIL) @@ -1604,9 +1715,30 @@ channel_read_block(channel_T *channel) channel_read(channel, -1, "channel_read_block"); } - /* TODO: only get the first message */ - ch_log(channel, "Returning readahead\n"); - return channel_get_all(channel); + if (mode == MODE_RAW) + { + msg = channel_get_all(channel); + } + else + { + nl = vim_strchr(buf, NL); + if (nl[1] == NUL) + { + /* get the whole buffer */ + msg = channel_get(channel); + *nl = NUL; + } + else + { + /* Copy the message into allocated memory and remove it from the + * buffer. */ + msg = vim_strnsave(buf, (int)(nl - buf)); + mch_memmove(buf, nl + 1, STRLEN(nl + 1) + 1); + } + } + if (log_fd != NULL) + ch_logn(channel, "Returning %d bytes\n", (int)STRLEN(msg)); + return msg; } /* @@ -1725,9 +1857,9 @@ channel_send(channel_T *channel, char_u *buf, char *fun) } if (use_socket) - res = sock_write(fd, buf, len); + res = sock_write(fd, (char *)buf, len); else - res = fd_write(fd, buf, len); + res = fd_write(fd, (char *)buf, len); if (res != len) { if (!channel->ch_error && fun != NULL) diff --git a/src/dosinst.h b/src/dosinst.h index b33426ad78..97d83d9700 100644 --- a/src/dosinst.h +++ b/src/dosinst.h @@ -452,7 +452,7 @@ run_command(char *cmd) /* * Append a backslash to "name" if there isn't one yet. */ - static void + void add_pathsep(char *name) { int len = strlen(name); diff --git a/src/edit.c b/src/edit.c index 762c515d8e..bd0677fe05 100644 --- a/src/edit.c +++ b/src/edit.c @@ -328,7 +328,7 @@ edit( { int c = 0; char_u *ptr; - int lastc; + int lastc = 0; int mincol; static linenr_T o_lnum = 0; int i; diff --git a/src/eval.c b/src/eval.c index 970ce2b586..9c49808426 100644 --- a/src/eval.c +++ b/src/eval.c @@ -7535,7 +7535,7 @@ get_dict_string(dict_T *d, char_u *key, int save) /* * Get a number item from a dictionary. - * Returns 0 if the entry doesn't exist or out of memory. + * Returns 0 if the entry doesn't exist. */ long get_dict_number(dict_T *d, char_u *key) @@ -9929,6 +9929,50 @@ f_ch_logfile(typval_T *argvars, typval_T *rettv UNUSED) ch_logfile(file); } +/* + * Get the option entries from "dict", and parse them. + * If an option value is invalid return FAIL. + */ + static int +get_job_options(dict_T *dict, jobopt_T *opt) +{ + dictitem_T *item; + char_u *mode; + + if (dict == NULL) + return OK; + + if ((item = dict_find(dict, (char_u *)"mode", -1)) != NULL) + { + mode = get_tv_string(&item->di_tv); + if (STRCMP(mode, "nl") == 0) + opt->jo_mode = MODE_NL; + else if (STRCMP(mode, "raw") == 0) + opt->jo_mode = MODE_RAW; + else if (STRCMP(mode, "js") == 0) + opt->jo_mode = MODE_JS; + else if (STRCMP(mode, "json") == 0) + opt->jo_mode = MODE_JSON; + else + { + EMSG2(_(e_invarg2), mode); + return FAIL; + } + } + + if ((item = dict_find(dict, (char_u *)"callback", -1)) != NULL) + { + opt->jo_callback = get_callback(&item->di_tv); + if (opt->jo_callback == NULL) + { + EMSG2(_(e_invarg2), "callback"); + return FAIL; + } + } + + return OK; +} + /* * "ch_open()" function */ @@ -9936,14 +9980,12 @@ f_ch_logfile(typval_T *argvars, typval_T *rettv UNUSED) f_ch_open(typval_T *argvars, typval_T *rettv) { char_u *address; - char_u *mode; - char_u *callback = NULL; char_u *p; char *rest; int port; int waittime = 0; int timeout = 2000; - ch_mode_T ch_mode = MODE_JSON; + jobopt_T options; channel_T *channel; /* default: fail */ @@ -9974,35 +10016,22 @@ f_ch_open(typval_T *argvars, typval_T *rettv) return; } + options.jo_mode = MODE_JSON; + options.jo_callback = NULL; if (argvars[1].v_type == VAR_DICT) { dict_T *dict = argvars[1].vval.v_dict; dictitem_T *item; /* parse argdict */ - if ((item = dict_find(dict, (char_u *)"mode", -1)) != NULL) - { - mode = get_tv_string(&item->di_tv); - if (STRCMP(mode, "raw") == 0) - ch_mode = MODE_RAW; - else if (STRCMP(mode, "js") == 0) - ch_mode = MODE_JS; - else if (STRCMP(mode, "json") == 0) - ch_mode = MODE_JSON; - else - { - EMSG2(_(e_invarg2), mode); - return; - } - } + if (get_job_options(dict, &options) == FAIL) + return; if ((item = dict_find(dict, (char_u *)"waittime", -1)) != NULL) waittime = get_tv_number(&item->di_tv); if ((item = dict_find(dict, (char_u *)"timeout", -1)) != NULL) timeout = get_tv_number(&item->di_tv); - if ((item = dict_find(dict, (char_u *)"callback", -1)) != NULL) - callback = get_callback(&item->di_tv); } - if (waittime < 0 || timeout < 0) + if (timeout < 0) { EMSG(_(e_invarg)); return; @@ -10012,10 +10041,8 @@ f_ch_open(typval_T *argvars, typval_T *rettv) if (channel != NULL) { rettv->vval.v_channel = channel; - channel_set_json_mode(channel, ch_mode); + channel_set_options(channel, &options); channel_set_timeout(channel, timeout); - if (callback != NULL && *callback != NUL) - channel_set_callback(channel, callback); } } @@ -10065,6 +10092,7 @@ send_common(typval_T *argvars, char_u *text, int id, char *fun) { channel_T *channel; char_u *callback = NULL; + jobopt_T options; channel = get_channel_arg(&argvars[0]); if (channel == NULL) @@ -10072,9 +10100,15 @@ send_common(typval_T *argvars, char_u *text, int id, char *fun) if (argvars[2].v_type != VAR_UNKNOWN) { - callback = get_callback(&argvars[2]); - if (callback == NULL) + if (argvars[2].v_type != VAR_DICT) + { + EMSG(_(e_invarg)); return NULL; + } + options.jo_callback = NULL; + if (get_job_options(argvars[2].vval.v_dict, &options) == FAIL) + return NULL; + callback = options.jo_callback; } /* Set the callback. An empty callback means no callback and not reading * the response. */ @@ -13124,7 +13158,10 @@ f_has(typval_T *argvars, typval_T *rettv) "mac", #endif #if defined(MACOS_X_UNIX) - "macunix", + "macunix", /* built with 'darwin' enabled */ +#endif +#if defined(__APPLE__) && __APPLE__ == 1 + "osx", /* built with or without 'darwin' enabled */ #endif #ifdef __QNX__ "qnx", @@ -14489,15 +14526,16 @@ f_job_getchannel(typval_T *argvars, typval_T *rettv) static void f_job_start(typval_T *argvars UNUSED, typval_T *rettv) { - job_T *job; - char_u *cmd = NULL; + job_T *job; + char_u *cmd = NULL; #if defined(UNIX) # define USE_ARGV - char **argv = NULL; - int argc = 0; + char **argv = NULL; + int argc = 0; #else - garray_T ga; + garray_T ga; #endif + jobopt_T options; rettv->v_type = VAR_JOB; job = job_alloc(); @@ -14506,6 +14544,21 @@ f_job_start(typval_T *argvars UNUSED, typval_T *rettv) return; rettv->vval.v_job->jv_status = JOB_FAILED; + + /* Default mode is NL. */ + options.jo_mode = MODE_NL; + options.jo_callback = NULL; + if (argvars[1].v_type != VAR_UNKNOWN) + { + if (argvars[1].v_type != VAR_DICT) + { + EMSG(_(e_invarg)); + return; + } + if (get_job_options(argvars[1].vval.v_dict, &options) == FAIL) + return; + } + #ifndef USE_ARGV ga_init2(&ga, (int)sizeof(char*), 20); #endif @@ -14568,9 +14621,9 @@ f_job_start(typval_T *argvars UNUSED, typval_T *rettv) #endif } #ifdef USE_ARGV - mch_start_job(argv, job); + mch_start_job(argv, job, &options); #else - mch_start_job(cmd, job); + mch_start_job((char *)cmd, job, &options); #endif theend: @@ -16430,7 +16483,7 @@ f_remote_peek(typval_T *argvars UNUSED, typval_T *rettv) return; /* type error; errmsg already given */ } # ifdef WIN32 - sscanf(serverid, SCANF_HEX_LONG_U, &n); + sscanf((const char *)serverid, SCANF_HEX_LONG_U, &n); if (n == 0) rettv->vval.v_number = -1; else @@ -16478,7 +16531,7 @@ f_remote_read(typval_T *argvars UNUSED, typval_T *rettv) /* The server's HWND is encoded in the 'id' parameter */ long_u n = 0; - sscanf(serverid, SCANF_HEX_LONG_U, &n); + sscanf((char *)serverid, SCANF_HEX_LONG_U, &n); if (n != 0) r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); if (r == NULL) @@ -21855,7 +21908,10 @@ get_tv_string_buf_chk(typval_T *varp, char_u *buf) channel_T *channel = varp->vval.v_channel; char *status = channel_status(channel); - vim_snprintf((char *)buf, NUMBUFLEN, + if (channel == NULL) + vim_snprintf((char *)buf, NUMBUFLEN, "channel %s", status); + else + vim_snprintf((char *)buf, NUMBUFLEN, "channel %d %s", channel->ch_id, status); return buf; } @@ -22494,7 +22550,8 @@ copy_tv(typval_T *from, typval_T *to) case VAR_CHANNEL: #ifdef FEAT_CHANNEL to->vval.v_channel = from->vval.v_channel; - ++to->vval.v_channel->ch_refcount; + if (to->vval.v_channel != NULL) + ++to->vval.v_channel->ch_refcount; break; #endif case VAR_STRING: @@ -25435,7 +25492,7 @@ get_short_pathname(char_u **fnamep, char_u **bufp, int *fnamelen) char_u *newbuf; len = *fnamelen; - l = GetShortPathName(*fnamep, *fnamep, len); + l = GetShortPathName((LPSTR)*fnamep, (LPSTR)*fnamep, len); if (l > len - 1) { /* If that doesn't work (not enough space), then save the string @@ -25448,7 +25505,7 @@ get_short_pathname(char_u **fnamep, char_u **bufp, int *fnamelen) *fnamep = *bufp = newbuf; /* Really should always succeed, as the buffer is big enough. */ - l = GetShortPathName(*fnamep, *fnamep, l+1); + l = GetShortPathName((LPSTR)*fnamep, (LPSTR)*fnamep, l+1); } *fnamelen = l; @@ -25740,7 +25797,7 @@ repeat: p = alloc(_MAX_PATH + 1); if (p != NULL) { - if (GetLongPathName(*fnamep, p, _MAX_PATH)) + if (GetLongPathName((LPSTR)*fnamep, (LPSTR)p, _MAX_PATH)) { vim_free(*bufp); *bufp = *fnamep = p; diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c index 84fe946818..5f86e9b532 100644 --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -4222,16 +4222,16 @@ ex_checktime(exarg_T *eap) #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \ && (defined(FEAT_EVAL) || defined(FEAT_MULTI_LANG)) # define HAVE_GET_LOCALE_VAL -static char *get_locale_val(int what); +static char_u *get_locale_val(int what); - static char * + static char_u * get_locale_val(int what) { - char *loc; + char_u *loc; /* Obtain the locale value from the libraries. For DJGPP this is * redefined and it doesn't use the arguments. */ - loc = setlocale(what, NULL); + loc = (char_u *)setlocale(what, NULL); # ifdef WIN32 if (loc != NULL) @@ -4295,7 +4295,7 @@ gettext_lang(char_u *name) for (i = 0; mtable[i] != NULL; i += 2) if (STRNICMP(mtable[i], name, STRLEN(mtable[i])) == 0) - return mtable[i + 1]; + return (char_u *)mtable[i + 1]; return name; } #endif @@ -4312,13 +4312,13 @@ get_mess_lang(void) # ifdef HAVE_GET_LOCALE_VAL # if defined(LC_MESSAGES) - p = (char_u *)get_locale_val(LC_MESSAGES); + p = get_locale_val(LC_MESSAGES); # else /* This is necessary for Win32, where LC_MESSAGES is not defined and $LANG * may be set to the LCID number. LC_COLLATE is the best guess, LC_TIME * and LC_MONETARY may be set differently for a Japanese working in the * US. */ - p = (char_u *)get_locale_val(LC_COLLATE); + p = get_locale_val(LC_COLLATE); # endif # else p = mch_getenv((char_u *)"LC_ALL"); @@ -4363,7 +4363,7 @@ get_mess_env(void) p = NULL; /* ignore something like "1043" */ # ifdef HAVE_GET_LOCALE_VAL if (p == NULL || *p == NUL) - p = (char_u *)get_locale_val(LC_CTYPE); + p = get_locale_val(LC_CTYPE); # endif } } @@ -4383,7 +4383,7 @@ set_lang_var(void) char_u *loc; # ifdef HAVE_GET_LOCALE_VAL - loc = (char_u *)get_locale_val(LC_CTYPE); + loc = get_locale_val(LC_CTYPE); # else /* setlocale() not supported: use the default value */ loc = (char_u *)"C"; @@ -4393,14 +4393,14 @@ set_lang_var(void) /* When LC_MESSAGES isn't defined use the value from $LC_MESSAGES, fall * back to LC_CTYPE if it's empty. */ # if defined(HAVE_GET_LOCALE_VAL) && defined(LC_MESSAGES) - loc = (char_u *)get_locale_val(LC_MESSAGES); + loc = get_locale_val(LC_MESSAGES); # else loc = get_mess_env(); # endif set_vim_var_string(VV_LANG, loc, -1); # ifdef HAVE_GET_LOCALE_VAL - loc = (char_u *)get_locale_val(LC_TIME); + loc = get_locale_val(LC_TIME); # endif set_vim_var_string(VV_LC_TIME, loc, -1); } diff --git a/src/ex_getln.c b/src/ex_getln.c index 372e958cfd..ed886af478 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -626,8 +626,8 @@ getcmdline( #endif if (vim_ispathsep(ccline.cmdbuff[j]) #ifdef BACKSLASH_IN_FILENAME - && vim_strchr(" *?[{`$%#", ccline.cmdbuff[j + 1]) - == NULL + && vim_strchr((char_u *)" *?[{`$%#", + ccline.cmdbuff[j + 1]) == NULL #endif ) { diff --git a/src/fileio.c b/src/fileio.c index b77d6fedb9..44c6efc22e 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -7518,11 +7518,11 @@ vim_tempname( } strcpy(buf4, "VIM"); buf4[2] = extra_char; /* make it "VIa", "VIb", etc. */ - if (GetTempFileName(szTempFile, buf4, 0, itmp) == 0) + if (GetTempFileName(szTempFile, buf4, 0, (LPSTR)itmp) == 0) return NULL; if (!keep) /* GetTempFileName() will create the file, we don't want that */ - (void)DeleteFile(itmp); + (void)DeleteFile((LPSTR)itmp); /* Backslashes in a temp file name cause problems when filtering with * "sh". NOTE: This also checks 'shellcmdflag' to help those people who diff --git a/src/gui_w32.c b/src/gui_w32.c index 05d8e3005e..70dd9b593e 100644 --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -1131,7 +1131,7 @@ _WndProc( if (STRLEN(str) < sizeof(lpdi->szText) || ((tt_text = vim_strsave(str)) == NULL)) - vim_strncpy(lpdi->szText, str, + vim_strncpy((char_u *)lpdi->szText, str, sizeof(lpdi->szText) - 1); else lpdi->lpszText = tt_text; @@ -1747,9 +1747,9 @@ gui_mch_init(void) /* Initialise the struct */ s_findrep_struct.lStructSize = sizeof(s_findrep_struct); - s_findrep_struct.lpstrFindWhat = alloc(MSWIN_FR_BUFSIZE); + s_findrep_struct.lpstrFindWhat = (LPSTR)alloc(MSWIN_FR_BUFSIZE); s_findrep_struct.lpstrFindWhat[0] = NUL; - s_findrep_struct.lpstrReplaceWith = alloc(MSWIN_FR_BUFSIZE); + s_findrep_struct.lpstrReplaceWith = (LPSTR)alloc(MSWIN_FR_BUFSIZE); s_findrep_struct.lpstrReplaceWith[0] = NUL; s_findrep_struct.wFindWhatLen = MSWIN_FR_BUFSIZE; s_findrep_struct.wReplaceWithLen = MSWIN_FR_BUFSIZE; @@ -2099,7 +2099,7 @@ GetCompositionString_inUCS2(HIMC hIMC, DWORD GCS, int *lenp) pImmGetCompositionStringA(hIMC, GCS, buf, ret); /* convert from codepage to UCS-2 */ - MultiByteToWideChar_alloc(GetACP(), 0, buf, ret, &wbuf, lenp); + MultiByteToWideChar_alloc(GetACP(), 0, (LPCSTR)buf, ret, &wbuf, lenp); vim_free(buf); return (short_u *)wbuf; @@ -3028,7 +3028,7 @@ rebuild_tearoff(vimmenu_T *menu) HWND thwnd = menu->tearoff_handle; - GetWindowText(thwnd, tbuf, 127); + GetWindowText(thwnd, (LPSTR)tbuf, 127); if (GetWindowRect(thwnd, &trect) && GetWindowRect(s_hwnd, &rct) && GetClientRect(s_hwnd, &roct)) @@ -3174,7 +3174,7 @@ dialog_callback( else # endif GetDlgItemText(hwnd, DLG_NONBUTTON_CONTROL + 2, - s_textfield, IOSIZE); + (LPSTR)s_textfield, IOSIZE); } /* @@ -3216,7 +3216,7 @@ dialog_callback( * If stubbing out this fn, return 1. */ -static const char_u *dlg_icons[] = /* must match names in resource file */ +static const char *dlg_icons[] = /* must match names in resource file */ { "IDR_VIM", "IDR_VIM_ERROR", @@ -3353,7 +3353,7 @@ gui_mch_dialog( fontHeight = fontInfo.tmHeight; /* Minimum width for horizontal button */ - minButtonWidth = GetTextWidth(hdc, "Cancel", 6); + minButtonWidth = GetTextWidth(hdc, (char_u *)"Cancel", 6); /* Maximum width of a dialog, if possible */ if (s_hwnd == NULL) @@ -3617,7 +3617,7 @@ gui_mch_dialog( + 2 * fontHeight * i), PixelToDialogX(dlgwidth - 2 * DLG_VERT_PADDING_X), (WORD)(PixelToDialogY(2 * fontHeight) - 1), - (WORD)(IDCANCEL + 1 + i), (WORD)0x0080, pstart); + (WORD)(IDCANCEL + 1 + i), (WORD)0x0080, (char *)pstart); } else { @@ -3628,7 +3628,7 @@ gui_mch_dialog( PixelToDialogY(buttonYpos), /* TBK */ PixelToDialogX(buttonWidths[i]), (WORD)(PixelToDialogY(2 * fontHeight) - 1), - (WORD)(IDCANCEL + 1 + i), (WORD)0x0080, pstart); + (WORD)(IDCANCEL + 1 + i), (WORD)0x0080, (char *)pstart); } pstart = pend + 1; /*next button*/ } @@ -3649,7 +3649,7 @@ gui_mch_dialog( PixelToDialogY(dlgPaddingY), (WORD)(PixelToDialogX(messageWidth) + 1), PixelToDialogY(msgheight), - DLG_NONBUTTON_CONTROL + 1, (WORD)0x0081, message); + DLG_NONBUTTON_CONTROL + 1, (WORD)0x0081, (char *)message); /* Edit box */ if (textfield != NULL) @@ -3659,7 +3659,7 @@ gui_mch_dialog( PixelToDialogY(2 * dlgPaddingY + msgheight), PixelToDialogX(dlgwidth - 4 * dlgPaddingX), PixelToDialogY(fontHeight + dlgPaddingY), - DLG_NONBUTTON_CONTROL + 2, (WORD)0x0081, textfield); + DLG_NONBUTTON_CONTROL + 2, (WORD)0x0081, (char *)textfield); *pnumitems += 1; } @@ -3798,7 +3798,7 @@ nCopyAnsiToWideChar( if (enc_codepage == 0 && (int)GetACP() != enc_codepage) { /* Not a codepage, use our own conversion function. */ - wn = enc_to_utf16(lpAnsiIn, NULL); + wn = enc_to_utf16((char_u *)lpAnsiIn, NULL); if (wn != NULL) { wcscpy(lpWCStr, wn); @@ -4043,7 +4043,7 @@ gui_mch_tearoff( /* Calculate width of a single space. Used for padding columns to the * right width. */ - spaceWidth = GetTextWidth(hdc, " ", 1); + spaceWidth = GetTextWidth(hdc, (char_u *)" ", 1); /* Figure out max width of the text column, the accelerator column and the * optional submenu column. */ @@ -4086,7 +4086,7 @@ gui_mch_tearoff( textWidth = columnWidths[0] + columnWidths[1]; if (submenuWidth != 0) { - submenuWidth = GetTextWidth(hdc, TEAROFF_SUBMENU_LABEL, + submenuWidth = GetTextWidth(hdc, (char_u *)TEAROFF_SUBMENU_LABEL, (int)STRLEN(TEAROFF_SUBMENU_LABEL)); textWidth += submenuWidth; } @@ -4262,7 +4262,7 @@ gui_mch_tearoff( (WORD)(sepPadding + 1 + 13 * (*pnumitems)), (WORD)PixelToDialogX(dlgwidth - 2 * TEAROFF_PADDING_X), (WORD)12, - menuID, (WORD)0x0080, label); + menuID, (WORD)0x0080, (char *)label); vim_free(label); (*pnumitems)++; } @@ -4360,7 +4360,7 @@ get_toolbar_bitmap(vimmenu_T *menu) gui_find_iconfile(menu->iconfile, fname, "bmp"); hbitmap = LoadImage( NULL, - fname, + (LPCSTR)fname, IMAGE_BITMAP, TOOLBAR_BUTTON_WIDTH, TOOLBAR_BUTTON_HEIGHT, @@ -4381,7 +4381,7 @@ get_toolbar_bitmap(vimmenu_T *menu) menu->dname, fname, "bmp") == OK)) hbitmap = LoadImage( NULL, - fname, + (LPCSTR)fname, IMAGE_BITMAP, TOOLBAR_BUTTON_WIDTH, TOOLBAR_BUTTON_HEIGHT, @@ -4629,14 +4629,15 @@ gui_mch_register_sign(char_u *signfile) do_load = 0; if (do_load) - sign.hImage = (HANDLE)LoadImage(NULL, signfile, sign.uType, + sign.hImage = (HANDLE)LoadImage(NULL, (LPCSTR)signfile, sign.uType, gui.char_width * 2, gui.char_height, LR_LOADFROMFILE | LR_CREATEDIBSECTION); #ifdef FEAT_XPM_W32 if (!STRICMP(ext, ".xpm")) { sign.uType = IMAGE_XPM; - LoadXpmImage(signfile, (HBITMAP *)&sign.hImage, (HBITMAP *)&sign.hShape); + LoadXpmImage((char *)signfile, (HBITMAP *)&sign.hImage, + (HBITMAP *)&sign.hShape); } #endif } @@ -4740,13 +4741,13 @@ multiline_balloon_available(void) UINT vlen = 0; void *data = alloc(len); - if (data != NULL + if ((data != NULL && GetFileVersionInfo(comctl_dll, 0, len, data) && VerQueryValue(data, "\\", (void **)&ver, &vlen) && vlen - && HIWORD(ver->dwFileVersionMS) > 4 - || (HIWORD(ver->dwFileVersionMS) == 4 - && LOWORD(ver->dwFileVersionMS) >= 70)) + && HIWORD(ver->dwFileVersionMS) > 4) + || ((HIWORD(ver->dwFileVersionMS) == 4 + && LOWORD(ver->dwFileVersionMS) >= 70))) { vim_free(data); multiline_tip = TRUE; @@ -4908,7 +4909,7 @@ gui_mch_post_balloon(BalloonEval *beval, char_u *mesg) { gui_mch_disable_beval_area(cur_beval); beval->showState = ShS_SHOWING; - make_tooltip(beval, mesg, pt); + make_tooltip(beval, (char *)mesg, pt); } // TRACE0("gui_mch_post_balloon }}}"); } diff --git a/src/gui_w48.c b/src/gui_w48.c index 6bafa8e0e4..5896dcddad 100644 --- a/src/gui_w48.c +++ b/src/gui_w48.c @@ -534,7 +534,8 @@ char_to_string(int ch, char_u *string, int slen, int had_alt) else { string[0] = ch; - len = MultiByteToWideChar(GetACP(), 0, string, 1, wstring, 2); + len = MultiByteToWideChar(GetACP(), 0, (LPCSTR)string, + 1, wstring, 2); } } else @@ -551,7 +552,7 @@ char_to_string(int ch, char_u *string, int slen, int had_alt) if (enc_codepage > 0) { len = WideCharToMultiByte(enc_codepage, 0, wstring, len, - string, slen, 0, NULL); + (LPSTR)string, slen, 0, NULL); /* If we had included the ALT key into the character but now the * upper bit is no longer set, that probably means the conversion * failed. Convert the original character and set the upper bit @@ -560,7 +561,7 @@ char_to_string(int ch, char_u *string, int slen, int had_alt) { wstring[0] = ch & 0x7f; len = WideCharToMultiByte(enc_codepage, 0, wstring, len, - string, slen, 0, NULL); + (LPSTR)string, slen, 0, NULL); if (len == 1) /* safety check */ string[0] |= 0x80; } @@ -921,7 +922,7 @@ findrep_atow(LPFINDREPLACEW lpfrw, LPFINDREPLACE lpfr) lpfrw->hwndOwner = lpfr->hwndOwner; lpfrw->Flags = lpfr->Flags; - wp = enc_to_utf16(lpfr->lpstrFindWhat, NULL); + wp = enc_to_utf16((char_u *)lpfr->lpstrFindWhat, NULL); wcsncpy(lpfrw->lpstrFindWhat, wp, lpfrw->wFindWhatLen - 1); vim_free(wp); @@ -938,12 +939,12 @@ findrep_wtoa(LPFINDREPLACE lpfr, LPFINDREPLACEW lpfrw) lpfr->Flags = lpfrw->Flags; - p = utf16_to_enc(lpfrw->lpstrFindWhat, NULL); - vim_strncpy(lpfr->lpstrFindWhat, p, lpfr->wFindWhatLen - 1); + p = utf16_to_enc((short_u*)lpfrw->lpstrFindWhat, NULL); + vim_strncpy((char_u *)lpfr->lpstrFindWhat, p, lpfr->wFindWhatLen - 1); vim_free(p); - p = utf16_to_enc(lpfrw->lpstrReplaceWith, NULL); - vim_strncpy(lpfr->lpstrReplaceWith, p, lpfr->wReplaceWithLen - 1); + p = utf16_to_enc((short_u*)lpfrw->lpstrReplaceWith, NULL); + vim_strncpy((char_u *)lpfr->lpstrReplaceWith, p, lpfr->wReplaceWithLen - 1); vim_free(p); } # endif @@ -1000,8 +1001,8 @@ _OnFindRepl(void) if (s_findrep_struct.Flags & FR_MATCHCASE) flags |= FRD_MATCH_CASE; down = (s_findrep_struct.Flags & FR_DOWN) != 0; - gui_do_findrepl(flags, s_findrep_struct.lpstrFindWhat, - s_findrep_struct.lpstrReplaceWith, down); + gui_do_findrepl(flags, (char_u *)s_findrep_struct.lpstrFindWhat, + (char_u *)s_findrep_struct.lpstrReplaceWith, down); } } #endif @@ -1530,7 +1531,7 @@ gui_mch_get_color(char_u *name) int r, g, b; int i; - if (name[0] == '#' && strlen(name) == 7) + if (name[0] == '#' && STRLEN(name) == 7) { /* Name is in "#rrggbb" format */ r = hex_digit(name[1]) * 16 + hex_digit(name[2]); @@ -2268,7 +2269,7 @@ GetTextWidth(HDC hdc, char_u *str, int len) { SIZE size; - GetTextExtentPoint(hdc, str, len, &size); + GetTextExtentPoint(hdc, (LPCSTR)str, len, &size); return size.cx; } @@ -2468,10 +2469,11 @@ show_tabline_popup_menu(void) if (first_tabpage->tp_next != NULL) add_tabline_popup_menu_entry(tab_pmenu, - TABLINE_MENU_CLOSE, _("Close tab")); - add_tabline_popup_menu_entry(tab_pmenu, TABLINE_MENU_NEW, _("New tab")); - add_tabline_popup_menu_entry(tab_pmenu, TABLINE_MENU_OPEN, - _("Open tab...")); + TABLINE_MENU_CLOSE, (char_u *)_("Close tab")); + add_tabline_popup_menu_entry(tab_pmenu, + TABLINE_MENU_NEW, (char_u *)_("New tab")); + add_tabline_popup_menu_entry(tab_pmenu, + TABLINE_MENU_OPEN, (char_u *)_("Open tab...")); GetCursorPos(&pt); rval = TrackPopupMenuEx(tab_pmenu, TPM_RETURNCMD, pt.x, pt.y, s_tabhwnd, @@ -2583,7 +2585,7 @@ gui_mch_update_tabline(void) } get_tabline_label(tp, FALSE); - tie.pszText = NameBuff; + tie.pszText = (LPSTR)NameBuff; #ifdef FEAT_MBYTE wstr = NULL; if (use_unicode) @@ -2680,7 +2682,7 @@ initialise_findrep(char_u *initial_string) if (wword) s_findrep_struct.Flags |= FR_WHOLEWORD; if (entry_text != NULL && *entry_text != NUL) - vim_strncpy(s_findrep_struct.lpstrFindWhat, entry_text, + vim_strncpy((char_u *)s_findrep_struct.lpstrFindWhat, entry_text, s_findrep_struct.wFindWhatLen - 1); vim_free(entry_text); } @@ -3194,11 +3196,11 @@ logfont2name(LOGFONT lf) if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) { int len; - acp_to_enc(lf.lfFaceName, (int)strlen(lf.lfFaceName), + acp_to_enc((char_u *)lf.lfFaceName, (int)strlen(lf.lfFaceName), (char_u **)&font_name, &len); } #endif - res = alloc((unsigned)(strlen(font_name) + 20 + res = (char *)alloc((unsigned)(strlen(font_name) + 20 + (charset_name == NULL ? 0 : strlen(charset_name) + 2))); if (res != NULL) { @@ -3233,7 +3235,7 @@ logfont2name(LOGFONT lf) if (font_name != lf.lfFaceName) vim_free(font_name); #endif - return res; + return (char_u *)res; } @@ -3323,7 +3325,7 @@ gui_mch_init_font(char_u *font_name, int fontset) return FAIL; if (font_name == NULL) - font_name = lf.lfFaceName; + font_name = (char_u *)lf.lfFaceName; #if defined(FEAT_MBYTE_IME) || defined(GLOBAL_IME) norm_logfont = lf; sub_logfont = lf; @@ -3753,12 +3755,12 @@ gui_mch_browse( fileStruct.lStructSize = sizeof(fileStruct); #endif - fileStruct.lpstrTitle = title; - fileStruct.lpstrDefExt = ext; + fileStruct.lpstrTitle = (LPSTR)title; + fileStruct.lpstrDefExt = (LPSTR)ext; - fileStruct.lpstrFile = fileBuf; + fileStruct.lpstrFile = (LPSTR)fileBuf; fileStruct.nMaxFile = MAXPATHL; - fileStruct.lpstrFilter = filterp; + fileStruct.lpstrFilter = (LPSTR)filterp; fileStruct.hwndOwner = s_hwnd; /* main Vim window is owner*/ /* has an initial dir been specified? */ if (initdir != NULL && *initdir != NUL) @@ -3769,7 +3771,7 @@ gui_mch_browse( for (p = initdirp; *p != NUL; ++p) if (*p == '/') *p = '\\'; - fileStruct.lpstrInitialDir = initdirp; + fileStruct.lpstrInitialDir = (LPSTR)initdirp; } /* @@ -3851,7 +3853,7 @@ _OnDropFiles( #endif { DragQueryFile(hDrop, i, szFile, BUFPATHLEN); - fnames[i] = vim_strsave(szFile); + fnames[i] = vim_strsave((char_u *)szFile); } } diff --git a/src/if_cscope.c b/src/if_cscope.c index 4a7290713e..c135fe5bbc 100644 --- a/src/if_cscope.c +++ b/src/if_cscope.c @@ -839,7 +839,7 @@ cs_create_connection(int i) # ifdef __BORLANDC__ # define OPEN_OH_ARGTYPE long # else -# if (_MSC_VER >= 1300) +# if (_MSC_VER >= 1300) || defined(__MINGW32__) # define OPEN_OH_ARGTYPE intptr_t # else # define OPEN_OH_ARGTYPE long @@ -1423,7 +1423,7 @@ cs_insert_filelist( /* On windows 9x GetFileInformationByHandle doesn't work, so skip it */ if (!mch_windows95()) { - switch (win32_fileinfo(fname, &bhfi)) + switch (win32_fileinfo((char_u *)fname, &bhfi)) { case FILEINFO_ENC_FAIL: /* enc_to_utf16() failed */ case FILEINFO_READ_FAIL: /* CreateFile() failed */ @@ -1459,7 +1459,8 @@ cs_insert_filelist( && csinfo[j].st_dev == sb->st_dev && csinfo[j].st_ino == sb->st_ino #else /* compare pathnames first */ - && ((fullpathcmp(csinfo[j].fname, fname, FALSE) & FPC_SAME) + && ((fullpathcmp((char_u *)csinfo[j].fname, + (char_u *)fname, FALSE) & FPC_SAME) /* if not Windows 9x, test index file attributes too */ || (!mch_windows95() && csinfo[j].nVolume == bhfi.dwVolumeSerialNumber diff --git a/src/if_perl.xs b/src/if_perl.xs index b723dcbe5b..47c944039c 100644 --- a/src/if_perl.xs +++ b/src/if_perl.xs @@ -49,6 +49,12 @@ # define __inline__ __inline #endif +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-variable" +# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + #include #include #include @@ -1730,3 +1736,6 @@ Append(vimbuf, ...) } } +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif diff --git a/src/if_python.c b/src/if_python.c index 04b614aded..63fe3e2e3e 100644 --- a/src/if_python.c +++ b/src/if_python.c @@ -43,6 +43,15 @@ # undef _DEBUG #endif +#ifdef HAVE_STRFTIME +# undef HAVE_STRFTIME +#endif +#ifdef HAVE_STRING_H +# undef HAVE_STRING_H +#endif +#ifdef HAVE_PUTENV +# undef HAVE_PUTENV +#endif #ifdef HAVE_STDARG_H # undef HAVE_STDARG_H /* Python's config.h defines it as well. */ #endif diff --git a/src/if_python3.c b/src/if_python3.c index 7d69b0c81f..84302bd636 100644 --- a/src/if_python3.c +++ b/src/if_python3.c @@ -51,6 +51,15 @@ # undef F_BLANK #endif +#ifdef HAVE_STRFTIME +# undef HAVE_STRFTIME +#endif +#ifdef HAVE_STRING_H +# undef HAVE_STRING_H +#endif +#ifdef HAVE_PUTENV +# undef HAVE_PUTENV +#endif #ifdef HAVE_STDARG_H # undef HAVE_STDARG_H /* Python's config.h defines it as well. */ #endif diff --git a/src/if_ruby.c b/src/if_ruby.c index a8c3229927..218ea4b584 100644 --- a/src/if_ruby.c +++ b/src/if_ruby.c @@ -166,6 +166,10 @@ # define RSTRING_PTR(s) RSTRING(s)->ptr #endif +#ifdef HAVE_DUP +# undef HAVE_DUP +#endif + #include "vim.h" #include "version.h" @@ -261,6 +265,7 @@ static void ruby_vim_init(void); # define rb_raise dll_rb_raise # define rb_str_cat dll_rb_str_cat # define rb_str_concat dll_rb_str_concat +# undef rb_str_new # define rb_str_new dll_rb_str_new # ifdef rb_str_new2 /* Ruby may #define rb_str_new2 to use rb_str_new_cstr. */ @@ -308,7 +313,8 @@ static void ruby_vim_init(void); # define ruby_script dll_ruby_script # define rb_enc_find_index dll_rb_enc_find_index # define rb_enc_find dll_rb_enc_find -# define rb_enc_str_new dll_rb_enc_str_new +# undef rb_enc_str_new +# define rb_enc_str_new dll_rb_enc_str_new # define rb_sprintf dll_rb_sprintf # define rb_require dll_rb_require # define ruby_options dll_ruby_options diff --git a/src/main.c b/src/main.c index c16f93d359..b80053dac4 100644 --- a/src/main.c +++ b/src/main.c @@ -4027,7 +4027,7 @@ build_drop_cmd( } cdp = vim_strsave_escaped_ext(cwd, #ifdef BACKSLASH_IN_FILENAME - "", /* rem_backslash() will tell what chars to escape */ + (char_u *)"", /* rem_backslash() will tell what chars to escape */ #else PATH_ESC_CHARS, #endif diff --git a/src/mbyte.c b/src/mbyte.c index 0cde567e50..5c87d374f5 100644 --- a/src/mbyte.c +++ b/src/mbyte.c @@ -473,7 +473,7 @@ enc_canon_props(char_u *name) CPINFO cpinfo; /* Get info on this codepage to find out what it is. */ - if (GetCPInfo(atoi(name + 2), &cpinfo) != 0) + if (GetCPInfo(atoi((char *)name + 2), &cpinfo) != 0) { if (cpinfo.MaxCharSize == 1) /* some single-byte encoding */ return ENC_8BIT; @@ -535,7 +535,7 @@ mb_init(void) CPINFO cpinfo; /* Get info on this codepage to find out what it is. */ - if (GetCPInfo(atoi(p_enc + 2), &cpinfo) != 0) + if (GetCPInfo(atoi((char *)p_enc + 2), &cpinfo) != 0) { if (cpinfo.MaxCharSize == 1) { @@ -547,7 +547,7 @@ mb_init(void) && (cpinfo.LeadByte[0] != 0 || cpinfo.LeadByte[1] != 0)) { /* must be a DBCS encoding, check below */ - enc_dbcs_new = atoi(p_enc + 2); + enc_dbcs_new = atoi((char *)p_enc + 2); } else goto codepage_invalid; @@ -571,7 +571,7 @@ codepage_invalid: #ifdef WIN3264 /* Windows: accept only valid codepage numbers, check below. */ if (p_enc[6] != 'c' || p_enc[7] != 'p' - || (enc_dbcs_new = atoi(p_enc + 8)) == 0) + || (enc_dbcs_new = atoi((char *)p_enc + 8)) == 0) return e_invarg; #else /* Unix: accept any "2byte-" name, assume current locale. */ @@ -4420,7 +4420,7 @@ get_iconv_import_func(HINSTANCE hInst, const char *funcname) continue; pImpName = (PIMAGE_IMPORT_BY_NAME)(pImage + (UINT_PTR)(pINT->u1.AddressOfData)); - if (strcmp(pImpName->Name, funcname) == 0) + if (strcmp((char *)pImpName->Name, funcname) == 0) return (void *)pIAT->u1.Function; } } @@ -6422,7 +6422,7 @@ string_convert_ext( { tmp_len = MultiByteToWideChar(vcp->vc_cpfrom, unconvlenp ? MB_ERR_INVALID_CHARS : 0, - ptr, len, 0, 0); + (char *)ptr, len, 0, 0); if (tmp_len == 0 && GetLastError() == ERROR_NO_UNICODE_TRANSLATION) { @@ -6442,7 +6442,8 @@ string_convert_ext( if (vcp->vc_cpfrom == 0) utf8_to_utf16(ptr, len, tmp, unconvlenp); else - MultiByteToWideChar(vcp->vc_cpfrom, 0, ptr, len, tmp, tmp_len); + MultiByteToWideChar(vcp->vc_cpfrom, 0, + (char *)ptr, len, tmp, tmp_len); /* 2. ucs-2 -> codepage/UTF-8. */ if (vcp->vc_cpto == 0) @@ -6457,7 +6458,8 @@ string_convert_ext( utf16_to_utf8(tmp, tmp_len, retval); else WideCharToMultiByte(vcp->vc_cpto, 0, - tmp, tmp_len, retval, retlen, 0, 0); + tmp, tmp_len, + (char *)retval, retlen, 0, 0); retval[retlen] = NUL; if (lenp != NULL) *lenp = retlen; diff --git a/src/misc1.c b/src/misc1.c index 97c91a5a99..49fa47562e 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -3785,7 +3785,7 @@ init_homedir(void) homedrive = mch_getenv((char_u *)"HOMEDRIVE"); homepath = mch_getenv((char_u *)"HOMEPATH"); if (homepath == NULL || *homepath == NUL) - homepath = "\\"; + homepath = (char_u *)"\\"; if (homedrive != NULL && STRLEN(homedrive) + STRLEN(homepath) < MAXPATHL) { @@ -3823,7 +3823,7 @@ init_homedir(void) * Best assumption we can make in such a situation. */ if (var == NULL) - var = "C:/"; + var = (char_u *)"C:/"; #endif if (var != NULL) { @@ -9950,7 +9950,7 @@ dos_expandpath( if (wn == NULL) # endif - hFind = FindFirstFile(buf, &fb); + hFind = FindFirstFile((LPCSTR)buf, &fb); ok = (hFind != INVALID_HANDLE_VALUE); #else /* If we are expanding wildcards we try both files and directories */ @@ -10048,7 +10048,7 @@ dos_expandpath( } if (wn == NULL) # endif - hFind = FindFirstFile(buf, &fb); + hFind = FindFirstFile((LPCSTR)buf, &fb); ok = (hFind != INVALID_HANDLE_VALUE); #else ok = (findfirst((char *)buf, &fb, diff --git a/src/option.c b/src/option.c index c76ab133a4..73480db0ab 100644 --- a/src/option.c +++ b/src/option.c @@ -3257,7 +3257,7 @@ set_init_1(void) # endif || ((p = mch_getenv((char_u *)"COMSPEC")) != NULL && *p != NUL) # ifdef WIN3264 - || ((p = default_shell()) != NULL && *p != NUL) + || ((p = (char_u *)default_shell()) != NULL && *p != NUL) # endif #endif ) @@ -3540,7 +3540,7 @@ set_init_1(void) STRCPY(buf, "ja"); else buf[2] = NUL; /* truncate to two-letter code */ - vim_setenv("LANG", buf); + vim_setenv((char_u *)"LANG", (char_u *)buf); } } # else diff --git a/src/os_mswin.c b/src/os_mswin.c index b7e3b5e5ec..3a5922b452 100644 --- a/src/os_mswin.c +++ b/src/os_mswin.c @@ -273,11 +273,11 @@ mch_early_init(void) for (i = 0; i < 256; ++i) toupper_tab[i] = tolower_tab[i] = i; #ifdef WIN3264 - CharUpperBuff(toupper_tab, 256); - CharLowerBuff(tolower_tab, 256); + CharUpperBuff((LPSTR)toupper_tab, 256); + CharLowerBuff((LPSTR)tolower_tab, 256); #else - AnsiUpperBuff(toupper_tab, 256); - AnsiLowerBuff(tolower_tab, 256); + AnsiUpperBuff((LPSTR)toupper_tab, 256); + AnsiLowerBuff((LPSTR)tolower_tab, 256); #endif } @@ -327,7 +327,7 @@ mch_settitle( } } # endif - SetConsoleTitle(title); + SetConsoleTitle((LPCSTR)title); } # endif } @@ -428,7 +428,7 @@ mch_FullName( if (nResult == FAIL) /* fall back to non-wide function */ #endif { - if (_fullpath(buf, fname, len - 1) == NULL) + if (_fullpath((char *)buf, (const char *)fname, len - 1) == NULL) { /* failed, use relative path name */ vim_strncpy(buf, fname, len - 1); @@ -469,10 +469,10 @@ mch_isFullName(char_u *fname) return TRUE; /* A name that can't be made absolute probably isn't absolute. */ - if (mch_FullName(fname, szName, sizeof(szName) - 1, FALSE) == FAIL) + if (mch_FullName(fname, (char_u *)szName, sizeof(szName) - 1, FALSE) == FAIL) return FALSE; - return pathcmp(fname, szName, -1) == 0; + return pathcmp((const char *)fname, (const char *)szName, -1) == 0; } /* @@ -619,14 +619,14 @@ vim_stat(const char *name, struct stat *stp) /* WinNT and later can use _MAX_PATH wide characters for a pathname, which * means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is * UTF-8. */ - char buf[_MAX_PATH * 3 + 1]; + char_u buf[_MAX_PATH * 3 + 1]; #else - char buf[_MAX_PATH + 1]; + char_u buf[_MAX_PATH + 1]; #endif - char *p; + char_u *p; vim_strncpy((char_u *)buf, (char_u *)name, sizeof(buf) - 1); - p = buf + strlen(buf); + p = buf + STRLEN(buf); if (p > buf) mb_ptr_back(buf, p); @@ -637,10 +637,10 @@ vim_stat(const char *name, struct stat *stp) if ((buf[0] == '\\' && buf[1] == '\\') || (buf[0] == '/' && buf[1] == '/')) { /* UNC root path must be followed by '\\'. */ - p = vim_strpbrk(buf + 2, "\\/"); + p = vim_strpbrk(buf + 2, (char_u *)"\\/"); if (p != NULL) { - p = vim_strpbrk(p + 1, "\\/"); + p = vim_strpbrk(p + 1, (char_u *)"\\/"); if (p == NULL) STRCAT(buf, "\\"); } @@ -668,7 +668,7 @@ vim_stat(const char *name, struct stat *stp) } } #endif - return stat_symlink_aware(buf, stp); + return stat_symlink_aware((char *)buf, stp); } #if defined(FEAT_GUI_MSWIN) || defined(PROTO) @@ -741,7 +741,8 @@ display_errors(void) gui.starting ? (char_u *)_("Message") : #endif (char_u *)_("Error"), - p, (char_u *)_("&Ok"), 1, NULL, FALSE); + (char_u *)p, (char_u *)_("&Ok"), + 1, NULL, FALSE); break; } ga_clear(&error_ga); @@ -820,7 +821,7 @@ mch_chdir(char *path) #ifdef FEAT_MBYTE if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) { - WCHAR *p = enc_to_utf16(path, NULL); + WCHAR *p = enc_to_utf16((char_u *)path, NULL); int n; if (p != NULL) @@ -853,7 +854,8 @@ can_end_termcap_mode( if (g_PlatformId == VER_PLATFORM_WIN32_NT || Columns == 80) return TRUE; if (give_msg) - msg(_("'columns' is not 80, cannot execute external commands")); + msg((char_u *) + _("'columns' is not 80, cannot execute external commands")); return FALSE; #endif } @@ -915,7 +917,7 @@ check_str_len(char_u *str) MEMORY_BASIC_INFORMATION mbi; size_t length = 0; size_t i; - const char *p; + const char_u *p; /* get page size */ GetSystemInfo(&si); @@ -953,7 +955,7 @@ mch_icon_load_cb(char_u *fname, void *cookie) HANDLE *h = (HANDLE *)cookie; *h = LoadImage(NULL, - fname, + (LPSTR)fname, IMAGE_ICON, 64, 64, @@ -992,7 +994,7 @@ mch_libcall( # ifdef WIN16 hinstLib = LoadLibrary(libname); # else - hinstLib = vimLoadLib(libname); + hinstLib = vimLoadLib((char *)libname); # endif // If the handle is valid, try to get the function address. @@ -1005,25 +1007,25 @@ mch_libcall( if (argstring != NULL) { /* Call with string argument */ - ProcAdd = (MYSTRPROCSTR) GetProcAddress(hinstLib, funcname); + ProcAdd = (MYSTRPROCSTR)GetProcAddress(hinstLib, (LPCSTR)funcname); if ((fRunTimeLinkSuccess = (ProcAdd != NULL)) != 0) { if (string_result == NULL) - retval_int = ((MYSTRPROCINT)ProcAdd)(argstring); + retval_int = ((MYSTRPROCINT)ProcAdd)((LPSTR)argstring); else - retval_str = (ProcAdd)(argstring); + retval_str = (char_u *)(ProcAdd)((LPSTR)argstring); } } else { /* Call with number argument */ - ProcAddI = (MYINTPROCSTR) GetProcAddress(hinstLib, funcname); + ProcAddI = (MYINTPROCSTR) GetProcAddress(hinstLib, (LPCSTR)funcname); if ((fRunTimeLinkSuccess = (ProcAddI != NULL)) != 0) { if (string_result == NULL) retval_int = ((MYINTPROCINT)ProcAddI)(argint); else - retval_str = (ProcAddI)(argint); + retval_str = (char_u *)(ProcAddI)(argint); } } @@ -1228,7 +1230,7 @@ vimSetDlgItemText(HWND hDlg, int nIDDlgItem, char_u *s) vim_free(wp); return ret; } - return SetDlgItemText(hDlg, nIDDlgItem, s); + return SetDlgItemText(hDlg, nIDDlgItem, (LPCSTR)s); } #endif @@ -1283,18 +1285,18 @@ PrintDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { SendDlgItemMessage(hDlg, i, WM_SETFONT, (WPARAM)hfont, 1); if (GetDlgItemText(hDlg,i, buff, sizeof(buff))) - vimSetDlgItemText(hDlg,i, _(buff)); + vimSetDlgItemText(hDlg,i, (char_u *)_(buff)); } SendDlgItemMessage(hDlg, IDCANCEL, WM_SETFONT, (WPARAM)hfont, 1); if (GetDlgItemText(hDlg,IDCANCEL, buff, sizeof(buff))) - vimSetDlgItemText(hDlg,IDCANCEL, _(buff)); + vimSetDlgItemText(hDlg,IDCANCEL, (char_u *)_(buff)); } #endif - SetWindowText(hDlg, szAppName); + SetWindowText(hDlg, (LPCSTR)szAppName); if (prt_name != NULL) { - vimSetDlgItemText(hDlg, IDC_PRINTTEXT2, (LPSTR)prt_name); + vimSetDlgItemText(hDlg, IDC_PRINTTEXT2, (char_u *)prt_name); vim_free(prt_name); prt_name = NULL; } @@ -1585,7 +1587,7 @@ mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) * NT, but NULL appears to work just as well. */ if (*p_pdev != NUL) - prt_dlg.hDC = CreateDC(NULL, p_pdev, NULL, NULL); + prt_dlg.hDC = CreateDC(NULL, (LPCSTR)p_pdev, NULL, NULL); else #endif { @@ -1649,7 +1651,7 @@ mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) { char_u *printer_name = (char_u *)devname + devname->wDeviceOffset; char_u *port_name = (char_u *)devname +devname->wOutputOffset; - char_u *text = _("to %s on %s"); + char_u *text = (char_u *)_("to %s on %s"); #ifdef FEAT_MBYTE char_u *printer_name_orig = printer_name; char_u *port_name_orig = port_name; @@ -1671,7 +1673,8 @@ mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) prt_name = alloc((unsigned)(STRLEN(printer_name) + STRLEN(port_name) + STRLEN(text))); if (prt_name != NULL) - wsprintf(prt_name, text, printer_name, port_name); + wsprintf((char *)prt_name, (const char *)text, + printer_name, port_name); #ifdef FEAT_MBYTE if (printer_name != printer_name_orig) vim_free(printer_name); @@ -1781,11 +1784,11 @@ mch_print_begin(prt_settings_T *psettings) SetAbortProc(prt_dlg.hDC, AbortProc); #endif wsprintf(szBuffer, _("Printing '%s'"), gettail(psettings->jobname)); - vimSetDlgItemText(hDlgPrint, IDC_PRINTTEXT1, (LPSTR)szBuffer); + vimSetDlgItemText(hDlgPrint, IDC_PRINTTEXT1, (char_u *)szBuffer); vim_memset(&di, 0, sizeof(DOCINFO)); di.cbSize = sizeof(DOCINFO); - di.lpszDocName = psettings->jobname; + di.lpszDocName = (LPCSTR)psettings->jobname; ret = StartDoc(prt_dlg.hDC, &di); #ifdef FEAT_GUI @@ -1815,7 +1818,7 @@ mch_print_end_page(void) mch_print_begin_page(char_u *msg) { if (msg != NULL) - vimSetDlgItemText(hDlgPrint, IDC_PROGRESS, (LPSTR)msg); + vimSetDlgItemText(hDlgPrint, IDC_PROGRESS, msg); return (StartPage(prt_dlg.hDC) > 0); } @@ -1878,16 +1881,17 @@ mch_print_text_out(char_u *p, int len) } #endif TextOut(prt_dlg.hDC, prt_pos_x + prt_left_margin, - prt_pos_y + prt_top_margin, p, len); + prt_pos_y + prt_top_margin, + (LPCSTR)p, len); #ifndef FEAT_PROPORTIONAL_FONTS prt_pos_x += len * prt_tm.tmAveCharWidth; return (prt_pos_x + prt_left_margin + prt_tm.tmAveCharWidth + prt_tm.tmOverhang > prt_right_margin); #else # ifdef WIN16 - GetTextExtentPoint(prt_dlg.hDC, p, len, &sz); + GetTextExtentPoint(prt_dlg.hDC, (LPCSTR)p, len, &sz); # else - GetTextExtentPoint32(prt_dlg.hDC, p, len, &sz); + GetTextExtentPoint32(prt_dlg.hDC, (LPCSTR)p, len, &sz); # endif prt_pos_x += (sz.cx - prt_tm.tmOverhang); /* This is wrong when printing spaces for a TAB. */ @@ -2027,7 +2031,7 @@ shortcut_errorw: goto shortcut_end; // full path string must be in Unicode. - MultiByteToWideChar(CP_ACP, 0, fname, -1, wsz, MAX_PATH); + MultiByteToWideChar(CP_ACP, 0, (LPCSTR)fname, -1, wsz, MAX_PATH); // "load" the name and resolve the link hr = ppf->lpVtbl->Load(ppf, wsz, STGM_READ); @@ -2043,7 +2047,7 @@ shortcut_errorw: ZeroMemory(buf, MAX_PATH); hr = psl->lpVtbl->GetPath(psl, buf, MAX_PATH, &ffd, 0); if (hr == S_OK && buf[0] != NUL) - rfname = vim_strsave(buf); + rfname = vim_strsave((char_u *)buf); shortcut_end: // Release all interface pointers (both belong to the same object) @@ -2234,7 +2238,7 @@ Messaging_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) if (res == NULL) { - res = vim_strsave(_(e_invexprmsg)); + res = vim_strsave((char_u *)_(e_invexprmsg)); reply.dwData = COPYDATA_ERROR_RESULT; } else @@ -2399,8 +2403,8 @@ enumWindowsGetNames(HWND hwnd, LPARAM lparam) return TRUE; /* Add the name to the list */ - ga_concat(ga, server); - ga_concat(ga, "\n"); + ga_concat(ga, (char_u *)server); + ga_concat(ga, (char_u *)"\n"); return TRUE; } @@ -2459,7 +2463,7 @@ serverSetName(char_u *name) #endif /* Update the message window title */ - SetWindowText(message_window, ok_name); + SetWindowText(message_window, (LPCSTR)ok_name); #ifdef FEAT_EVAL /* Set the servername variable */ @@ -2948,7 +2952,7 @@ get_logfont( if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) { int len; - enc_to_acp(name, (int)strlen(name), &acpname, &len); + enc_to_acp(name, (int)STRLEN(name), &acpname, &len); name = acpname; } #endif diff --git a/src/os_unix.c b/src/os_unix.c index 742c43a832..0f87d92110 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5059,7 +5059,7 @@ error: #if defined(FEAT_JOB) || defined(PROTO) void -mch_start_job(char **argv, job_T *job) +mch_start_job(char **argv, job_T *job, jobopt_T *options) { pid_t pid; int fd_in[2]; /* for stdin */ @@ -5149,6 +5149,7 @@ mch_start_job(char **argv, job_T *job) # ifdef FEAT_CHANNEL channel_set_pipes(channel, fd_in[1], fd_out[0], fd_err[0]); channel_set_job(channel, job); + channel_set_options(channel, options); # ifdef FEAT_GUI channel_gui_register(channel); # endif diff --git a/src/os_win32.c b/src/os_win32.c index e05be4b8bb..63d7d60cb5 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -91,7 +91,6 @@ FILE* fdDump = NULL; */ #ifdef PROTO #define WINAPI -#define WINBASEAPI typedef char * LPCSTR; typedef char * LPWSTR; typedef int ACCESS_MASK; @@ -148,14 +147,14 @@ typedef int PROCESS_INFORMATION; * and Michael Dietrich for helping me figure out this workaround. */ -/* WINBASEAPI BOOL WINAPI GetConsoleKeyboardLayoutNameA(LPSTR); */ -#ifndef WINBASEAPI -# define WINBASEAPI __stdcall +/* WINAPI BOOL WINAPI GetConsoleKeyboardLayoutNameA(LPSTR); */ +#ifndef WINAPI +# define WINAPI __stdcall #endif #if defined(__BORLANDC__) typedef BOOL (__stdcall *PFNGCKLN)(LPSTR); #else -typedef WINBASEAPI BOOL (WINAPI *PFNGCKLN)(LPSTR); +typedef BOOL (WINAPI *PFNGCKLN)(LPSTR); #endif static PFNGCKLN s_pfnGetConsoleKeyboardLayoutName = NULL; #endif @@ -237,6 +236,7 @@ static char_u *exe_path = NULL; static BOOL win8_or_later = FALSE; +#ifndef FEAT_GUI_W32 /* * Version of ReadConsoleInput() that works with IME. * Works around problems on Windows 8. @@ -326,6 +326,7 @@ peek_console_input( return read_console_input(hInput, lpBuffer, -1, lpEvents); } +# ifdef FEAT_CLIENTSERVER static DWORD msg_wait_for_multiple_objects( DWORD nCount, @@ -339,7 +340,9 @@ msg_wait_for_multiple_objects( return MsgWaitForMultipleObjects(nCount, pHandles, fWaitAll, dwMilliseconds, dwWakeMask); } +# endif +# ifndef FEAT_CLIENTSERVER static DWORD wait_for_single_object( HANDLE hHandle, @@ -349,6 +352,8 @@ wait_for_single_object( return WAIT_OBJECT_0; return WaitForSingleObject(hHandle, dwMilliseconds); } +# endif +#endif static void get_exe_name(void) @@ -388,7 +393,7 @@ get_exe_name(void) STRCAT(temp, ";"); } STRCAT(temp, exe_path); - vim_setenv((char_u *)"PATH", temp); + vim_setenv((char_u *)"PATH", (char_u *)temp); } } } @@ -440,7 +445,7 @@ vimLoadLib(char *name) /* Change directory to where the executable is, both to make * sure we find a .dll there and to avoid looking for a .dll * in the current directory. */ - SetCurrentDirectory(exe_path); + SetCurrentDirectory((LPCSTR)exe_path); dll = LoadLibrary(name); SetCurrentDirectoryW(old_dirw); return dll; @@ -453,7 +458,7 @@ vimLoadLib(char *name) /* Change directory to where the executable is, both to make * sure we find a .dll there and to avoid looking for a .dll * in the current directory. */ - SetCurrentDirectory(exe_path); + SetCurrentDirectory((LPCSTR)exe_path); dll = LoadLibrary(name); SetCurrentDirectory(old_dir); } @@ -1961,7 +1966,7 @@ executable_exists(char *name, char_u **path) #ifdef FEAT_MBYTE if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) { - WCHAR *p = enc_to_utf16(name, NULL); + WCHAR *p = enc_to_utf16((char_u *)name, NULL); WCHAR fnamew[_MAX_PATH]; WCHAR *dumw; WCHAR *wcurpath, *wnewpath; @@ -2003,10 +2008,10 @@ executable_exists(char *name, char_u **path) vim_free(newpath); if (n == 0) return FALSE; - if (mch_isdir(fname)) + if (mch_isdir((char_u *)fname)) return FALSE; if (path != NULL) - *path = vim_strsave(fname); + *path = vim_strsave((char_u *)fname); return TRUE; } @@ -2383,7 +2388,7 @@ static ConsoleBuffer g_cbTermcap = { 0 }; #ifdef __BORLANDC__ typedef HWND (__stdcall *GETCONSOLEWINDOWPROC)(VOID); #else -typedef WINBASEAPI HWND (WINAPI *GETCONSOLEWINDOWPROC)(VOID); +typedef HWND (WINAPI *GETCONSOLEWINDOWPROC)(VOID); #endif char g_szOrigTitle[256] = { 0 }; HWND g_hWnd = NULL; /* also used in os_mswin.c */ @@ -2439,18 +2444,15 @@ SetConsoleIcon( HICON hIconSmall, HICON hIcon) { - HICON hPrevIconSmall; - HICON hPrevIcon; - if (hWnd == NULL) return FALSE; if (hIconSmall != NULL) - hPrevIconSmall = (HICON)SendMessage(hWnd, WM_SETICON, - (WPARAM)ICON_SMALL, (LPARAM)hIconSmall); + SendMessage(hWnd, WM_SETICON, + (WPARAM)ICON_SMALL, (LPARAM)hIconSmall); if (hIcon != NULL) - hPrevIcon = (HICON)SendMessage(hWnd, WM_SETICON, - (WPARAM)ICON_BIG,(LPARAM) hIcon); + SendMessage(hWnd, WM_SETICON, + (WPARAM)ICON_BIG, (LPARAM) hIcon); return TRUE; } @@ -2496,7 +2498,7 @@ SaveConsoleTitleAndIcon(void) /* Extract the first icon contained in the Vim executable. */ if (mch_icon_load((HANDLE *)&g_hVimIcon) == FAIL || g_hVimIcon == NULL) - g_hVimIcon = ExtractIcon(NULL, exe_name, 0); + g_hVimIcon = ExtractIcon(NULL, (LPCSTR)exe_name, 0); if (g_hVimIcon != NULL) g_fCanChangeIcon = TRUE; } @@ -2851,7 +2853,7 @@ fname_case( return; /* Build the new name in szTrueName[] one component at a time. */ - porig = name; + porig = (char *)name; ptrue = szTrueName; if (isalpha(porig[0]) && porig[1] == ':') @@ -2877,7 +2879,7 @@ fname_case( if (enc_dbcs) { - l = (*mb_ptr2len)(porig); + l = (*mb_ptr2len)((char_u *)porig); while (--l >= 0) *ptrue++ = *porig++; } @@ -2978,7 +2980,7 @@ mch_get_user_name( #endif if (GetUserName(szUserName, &cch)) { - vim_strncpy(s, szUserName, len - 1); + vim_strncpy(s, (char_u *)szUserName, len - 1); return OK; } s[0] = NUL; @@ -3018,8 +3020,8 @@ mch_get_host_name( /* Retry with non-wide function (for Windows 98). */ } #endif - if (!GetComputerName(s, &cch)) - vim_strncpy(s, "PC (Win32 Vim)", len - 1); + if (!GetComputerName((LPSTR)s, &cch)) + vim_strncpy(s, (char_u *)"PC (Win32 Vim)", len - 1); } @@ -3069,7 +3071,7 @@ mch_dirname( /* Retry with non-wide function (for Windows 98). */ } #endif - return (GetCurrentDirectory(len, buf) != 0 ? OK : FAIL); + return (GetCurrentDirectory(len, (LPSTR)buf) != 0 ? OK : FAIL); } /* @@ -3082,7 +3084,7 @@ mch_getperm(char_u *name) struct stat st; int n; - n = mch_stat(name, &st); + n = mch_stat((char *)name, &st); return n == 0 ? (long)(unsigned short)st.st_mode : -1L; } @@ -3113,7 +3115,7 @@ mch_setperm(char_u *name, long perm) } if (n == -1) #endif - n = _chmod(name, perm); + n = _chmod((const char *)name, perm); if (n == -1) return FAIL; @@ -3197,7 +3199,7 @@ mch_mkdir(char_u *name) return retval; } #endif - return _mkdir(name); + return _mkdir((const char *)name); } /* @@ -3221,7 +3223,7 @@ mch_rmdir(char_u *name) return retval; } #endif - return _rmdir(name); + return _rmdir((const char *)name); } /* @@ -3260,7 +3262,7 @@ mch_is_symbolic_link(char_u *name) && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { /* Retry with non-wide function (for Windows 98). */ - hFind = FindFirstFile(name, &findDataA); + hFind = FindFirstFile((LPCSTR)name, &findDataA); if (hFind != INVALID_HANDLE_VALUE) { fileFlags = findDataA.dwFileAttributes; @@ -3276,7 +3278,7 @@ mch_is_symbolic_link(char_u *name) else #endif { - hFind = FindFirstFile(name, &findDataA); + hFind = FindFirstFile((LPCSTR)name, &findDataA); if (hFind != INVALID_HANDLE_VALUE) { fileFlags = findDataA.dwFileAttributes; @@ -3347,8 +3349,8 @@ win32_fileinfo(char_u *fname, BY_HANDLE_FILE_INFORMATION *info) } if (wn == NULL) #endif - hFile = CreateFile(fname, /* file name */ - GENERIC_READ, /* access mode */ + hFile = CreateFile((LPCSTR)fname, /* file name */ + GENERIC_READ, /* access mode */ FILE_SHARE_READ | FILE_SHARE_WRITE, /* share mode */ NULL, /* security descriptor */ OPEN_EXISTING, /* creation disposition */ @@ -3566,13 +3568,13 @@ mch_nodetype(char_u *name) } if (wn == NULL) #endif - hFile = CreateFile(name, /* file name */ - GENERIC_WRITE, /* access mode */ - 0, /* share mode */ - NULL, /* security descriptor */ - OPEN_EXISTING, /* creation disposition */ - 0, /* file attributes */ - NULL); /* handle to template file */ + hFile = CreateFile((LPCSTR)name, /* file name */ + GENERIC_WRITE, /* access mode */ + 0, /* share mode */ + NULL, /* security descriptor */ + OPEN_EXISTING, /* creation disposition */ + 0, /* file attributes */ + NULL); /* handle to template file */ #ifdef FEAT_MBYTE vim_free(wn); @@ -4084,7 +4086,7 @@ vim_create_process( # ifdef FEAT_MBYTE if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) { - WCHAR *wcmd = enc_to_utf16(cmd, NULL); + WCHAR *wcmd = enc_to_utf16((char_u *)cmd, NULL); if (wcmd != NULL) { @@ -4725,7 +4727,7 @@ mch_system(char *cmd, int options) { if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) { - WCHAR *wcmd = enc_to_utf16(cmd, NULL); + WCHAR *wcmd = enc_to_utf16((char_u *)cmd, NULL); if (wcmd != NULL) { int ret = _wsystem(wcmd); @@ -4768,7 +4770,7 @@ mch_call_shell( wcscat(szShellTitle, L" :sh"); else { - WCHAR *wn = enc_to_utf16(cmd, NULL); + WCHAR *wn = enc_to_utf16((char_u *)cmd, NULL); if (wn != NULL) { @@ -4793,8 +4795,9 @@ mch_call_shell( else { strcat(szShellTitle, " - !"); - if ((strlen(szShellTitle) + strlen(cmd) < sizeof(szShellTitle))) - strcat(szShellTitle, cmd); + if ((strlen(szShellTitle) + strlen((char *)cmd) + < sizeof(szShellTitle))) + strcat(szShellTitle, (char *)cmd); } SetConsoleTitle(szShellTitle); } @@ -4831,7 +4834,7 @@ mch_call_shell( if (cmd == NULL) { - x = mch_system(p_sh, options); + x = mch_system((char *)p_sh, options); } else { @@ -4915,9 +4918,10 @@ mch_call_shell( char_u *cmd_shell = mch_getenv("COMSPEC"); if (cmd_shell == NULL || *cmd_shell == NUL) - cmd_shell = default_shell(); + cmd_shell = (char_u *)default_shell(); - subcmd = vim_strsave_escaped_ext(cmdbase, "|", '^', FALSE); + subcmd = vim_strsave_escaped_ext(cmdbase, + (char_u *)"|", '^', FALSE); if (subcmd != NULL) { /* make "cmd.exe /c arguments" */ @@ -4937,7 +4941,7 @@ mch_call_shell( * inherit our handles which causes unpleasant dangling swap * files if we exit before the spawned process */ - if (vim_create_process(newcmd, FALSE, flags, &si, &pi)) + if (vim_create_process((char *)newcmd, FALSE, flags, &si, &pi)) x = 0; else { @@ -5010,7 +5014,7 @@ mch_call_shell( #endif ) { - smsg(_("shell returned %d"), x); + smsg((char_u *)_("shell returned %d"), x); msg_putchar('\n'); } #ifdef FEAT_TITLE @@ -5034,7 +5038,7 @@ mch_call_shell( #if defined(FEAT_JOB) || defined(PROTO) void -mch_start_job(char *cmd, job_T *job) +mch_start_job(char *cmd, job_T *job, jobopt_T *options) { STARTUPINFO si; PROCESS_INFORMATION pi; @@ -5071,6 +5075,7 @@ mch_start_job(char *cmd, job_T *job) si.dwFlags |= STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; +# ifdef FEAT_CHANNEL saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; @@ -5085,6 +5090,7 @@ mch_start_job(char *cmd, job_T *job) si.hStdInput = ifd[0]; si.hStdOutput = ofd[1]; si.hStdError = efd[1]; +# endif if (!vim_create_process(cmd, TRUE, CREATE_SUSPENDED | @@ -5111,14 +5117,15 @@ mch_start_job(char *cmd, job_T *job) job->jv_job_object = jo; job->jv_status = JOB_STARTED; +# ifdef FEAT_CHANNEL CloseHandle(ifd[0]); CloseHandle(ofd[1]); CloseHandle(efd[1]); -# ifdef FEAT_CHANNEL job->jv_channel = channel; channel_set_pipes(channel, (sock_T)ifd[1], (sock_T)ofd[0], (sock_T)efd[0]); channel_set_job(channel, job); + channel_set_options(channel, options); # ifdef FEAT_GUI channel_gui_register(channel); @@ -5745,7 +5752,7 @@ mch_write( { /* optimization: use one single write_chars for runs of text, * rather than once per character It ain't curses, but it helps. */ - DWORD prefix = (DWORD)strcspn(s, "\n\r\b\a\033"); + DWORD prefix = (DWORD)strcspn((char *)s, "\n\r\b\a\033"); if (p_wd) { @@ -6083,7 +6090,7 @@ mch_remove(char_u *name) } } #endif - return DeleteFile(name) ? 0 : -1; + return DeleteFile((LPCSTR)name) ? 0 : -1; } @@ -6368,10 +6375,10 @@ mch_access(char *n, int p) WCHAR *wn = NULL; if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) - wn = enc_to_utf16(n, NULL); + wn = enc_to_utf16((char_u *)n, NULL); #endif - if (mch_isdir(n)) + if (mch_isdir((char_u *)n)) { char TempName[_MAX_PATH + 16] = ""; #ifdef FEAT_MBYTE @@ -6414,7 +6421,7 @@ mch_access(char *n, int p) char *pch; WIN32_FIND_DATA d; - vim_strncpy(TempName, n, _MAX_PATH); + vim_strncpy((char_u *)TempName, (char_u *)n, _MAX_PATH); pch = TempName + STRLEN(TempName) - 1; if (*pch != '\\' && *pch != '/') *++pch = '\\'; @@ -6506,7 +6513,7 @@ mch_open(char *name, int flags, int mode) if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) { - wn = enc_to_utf16(name, NULL); + wn = enc_to_utf16((char_u *)name, NULL); if (wn != NULL) { f = _wopen(wn, flags, mode); @@ -6558,8 +6565,8 @@ mch_fopen(char *name, char *mode) else if (newMode == 'b') _set_fmode(_O_BINARY); # endif - wn = enc_to_utf16(name, NULL); - wm = enc_to_utf16(mode, NULL); + wn = enc_to_utf16((char_u *)name, NULL); + wm = enc_to_utf16((char_u *)mode, NULL); if (wn != NULL && wm != NULL) f = _wfopen(wn, wm); vim_free(wn); diff --git a/src/proto/channel.pro b/src/proto/channel.pro index c5e61be5c5..a4acfe6d1b 100644 --- a/src/proto/channel.pro +++ b/src/proto/channel.pro @@ -7,9 +7,10 @@ void channel_gui_register_all(void); channel_T *channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void)); void channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err); void channel_set_job(channel_T *channel, job_T *job); -void channel_set_json_mode(channel_T *channel, ch_mode_T ch_mode); +void channel_set_mode(channel_T *channel, ch_mode_T mode); void channel_set_timeout(channel_T *channel, int timeout); void channel_set_callback(channel_T *channel, char_u *callback); +void channel_set_options(channel_T *channel, jobopt_T *options); void channel_set_req_callback(channel_T *channel, char_u *callback, int id); char_u *channel_get(channel_T *channel); int channel_collapse(channel_T *channel); diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro index c97f7fecf9..25d25797e1 100644 --- a/src/proto/os_unix.pro +++ b/src/proto/os_unix.pro @@ -57,7 +57,7 @@ void mch_set_shellsize(void); void mch_new_shellsize(void); int mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc); int mch_call_shell(char_u *cmd, int options); -void mch_start_job(char **argv, job_T *job); +void mch_start_job(char **argv, job_T *job, jobopt_T *options); char *mch_job_status(job_T *job); int mch_stop_job(job_T *job, char_u *how); void mch_clear_job(job_T *job); diff --git a/src/proto/os_win32.pro b/src/proto/os_win32.pro index 2fa6e10246..19c59ec961 100644 --- a/src/proto/os_win32.pro +++ b/src/proto/os_win32.pro @@ -40,7 +40,7 @@ void mch_set_shellsize(void); void mch_new_shellsize(void); void mch_set_winsize_now(void); int mch_call_shell(char_u *cmd, int options); -void mch_start_job(char *cmd, job_T *job); +void mch_start_job(char *cmd, job_T *job, jobopt_T *options); char *mch_job_status(job_T *job); int mch_stop_job(job_T *job, char_u *how); void mch_clear_job(job_T *job); diff --git a/src/structs.h b/src/structs.h index 8e4b10232b..e33cd4035a 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1375,6 +1375,15 @@ struct channel_S { int ch_refcount; /* reference count */ }; +/* + * Options for job and channel commands. + */ +typedef struct +{ + ch_mode_T jo_mode; /* "mode" */ + char_u *jo_callback; /* "callback", not allocated! */ +} jobopt_T; + /* structure used for explicit stack while garbage collecting hash tables */ typedef struct ht_stack_S diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index e7448faf09..85a257ac2e 100644 --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -28,7 +28,7 @@ else finish endif -let s:chopt = has('macunix') ? {'waittime' : 1} : {} +let s:chopt = {} " Run "testfunc" after sarting the server and stop the server afterwards. func s:run_server(testfunc) @@ -117,7 +117,7 @@ func s:communicate(port) call assert_equal('added more', getline('$')) " Send a request with a specific handler. - call ch_sendexpr(handle, 'hello!', 's:RequestHandler') + call ch_sendexpr(handle, 'hello!', {'callback': 's:RequestHandler'}) sleep 10m if !exists('s:responseHandle') call assert_false(1, 's:responseHandle was not set') @@ -128,7 +128,7 @@ func s:communicate(port) unlet s:responseHandle let s:responseMsg = '' - call ch_sendexpr(handle, 'hello!', function('s:RequestHandler')) + call ch_sendexpr(handle, 'hello!', {'callback': function('s:RequestHandler')}) sleep 10m if !exists('s:responseHandle') call assert_false(1, 's:responseHandle was not set') @@ -171,7 +171,7 @@ func s:communicate(port) call assert_equal('ok', ch_sendexpr(handle, 'empty-request')) " make the server quit, can't check if this works, should not hang. - call ch_sendexpr(handle, '!quit!', 0) + call ch_sendexpr(handle, '!quit!', {'callback': 0}) endfunc func Test_communicate() @@ -242,7 +242,7 @@ func s:channel_handler(port) call assert_equal('we called you', s:reply) " Test that it works while not waiting on a numbered message. - call ch_sendexpr(handle, 'call me again', 0) + call ch_sendexpr(handle, 'call me again', {'callback': 0}) sleep 10m call assert_equal('we did call you', s:reply) endfunc @@ -284,7 +284,30 @@ func Test_connect_waittime() endif endfunc -func Test_pipe() +func Test_raw_pipe() + if !has('job') + return + endif + let job = job_start(s:python . " test_channel_pipe.py", {'mode': 'raw'}) + call assert_equal("run", job_status(job)) + try + let handle = job_getchannel(job) + call ch_sendraw(handle, "echo something\n", {'callback': 0}) + let msg = ch_readraw(handle) + call assert_equal("something\n", substitute(msg, "\r", "", 'g')) + + call ch_sendraw(handle, "double this\n", {'callback': 0}) + let msg = ch_readraw(handle) + call assert_equal("this\nAND this\n", substitute(msg, "\r", "", 'g')) + + let reply = ch_sendraw(handle, "quit\n") + call assert_equal("Goodbye!\n", substitute(reply, "\r", "", 'g')) + finally + call job_stop(job) + endtry +endfunc + +func Test_nl_pipe() if !has('job') return endif @@ -292,15 +315,22 @@ func Test_pipe() call assert_equal("run", job_status(job)) try let handle = job_getchannel(job) - call ch_sendraw(handle, "echo something\n", 0) - call assert_equal("something\n", ch_readraw(handle)) + call ch_sendraw(handle, "echo something\n", {'callback': 0}) + call assert_equal("something", ch_readraw(handle)) + + call ch_sendraw(handle, "double this\n", {'callback': 0}) + call assert_equal("this", ch_readraw(handle)) + call assert_equal("AND this", ch_readraw(handle)) + let reply = ch_sendraw(handle, "quit\n") - call assert_equal("Goodbye!\n", reply) + call assert_equal("Goodbye!", reply) finally call job_stop(job) endtry endfunc +"""""""""" + let s:unletResponse = '' func s:UnletHandler(handle, msg) let s:unletResponse = a:msg @@ -310,7 +340,7 @@ endfunc " Test that "unlet handle" in a handler doesn't crash Vim. func s:unlet_handle(port) let s:channelfd = ch_open('localhost:' . a:port, s:chopt) - call ch_sendexpr(s:channelfd, "test", function('s:UnletHandler')) + call ch_sendexpr(s:channelfd, "test", {'callback': function('s:UnletHandler')}) sleep 10m call assert_equal('what?', s:unletResponse) endfunc @@ -318,3 +348,31 @@ endfunc func Test_unlet_handle() call s:run_server('s:unlet_handle') endfunc + +"""""""""" + +let s:unletResponse = '' +func s:CloseHandler(handle, msg) + let s:unletResponse = a:msg + call ch_close(s:channelfd) +endfunc + +" Test that "unlet handle" in a handler doesn't crash Vim. +func s:close_handle(port) + let s:channelfd = ch_open('localhost:' . a:port, s:chopt) + call ch_sendexpr(s:channelfd, "test", {'callback': function('s:CloseHandler')}) + sleep 10m + call assert_equal('what?', s:unletResponse) +endfunc + +func Test_close_handle() + call s:run_server('s:close_handle') +endfunc + +"""""""""" + +func Test_open_fail() + silent! let ch = ch_open("noserver") + echo ch + let d = ch +endfunc diff --git a/src/testdir/test_channel_pipe.py b/src/testdir/test_channel_pipe.py index 495fa80124..5994d27ffd 100644 --- a/src/testdir/test_channel_pipe.py +++ b/src/testdir/test_channel_pipe.py @@ -21,4 +21,7 @@ if __name__ == "__main__": if typed.startswith("echo"): print(typed[5:-1]) sys.stdout.flush() + if typed.startswith("double"): + print(typed[7:-1] + "\nAND " + typed[7:-1]) + sys.stdout.flush() diff --git a/src/version.c b/src/version.c index 6c0b2ac0a1..a4af4c7da8 100644 --- a/src/version.c +++ b/src/version.c @@ -762,6 +762,34 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1342, +/**/ + 1341, +/**/ + 1340, +/**/ + 1339, +/**/ + 1338, +/**/ + 1337, +/**/ + 1336, +/**/ + 1335, +/**/ + 1334, +/**/ + 1333, +/**/ + 1332, +/**/ + 1331, +/**/ + 1330, +/**/ + 1329, /**/ 1328, /**/