To: vim_dev@googlegroups.com Subject: Patch 8.0.1745 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1745 Problem: Build failure on MS-Windows. Solution: Build job arguments for MS-Windows. Fix allocating job twice. Files: src/structs.h, src/channel.c, src/os_unix.c, src/misc2.c, src/terminal.c, src/proto/misc2.pro *** ../vim-8.0.1744/src/structs.h 2018-04-21 19:49:02.528104537 +0200 --- src/structs.h 2018-04-21 21:30:11.616228056 +0200 *************** *** 1488,1494 **** int jv_copyID; channel_T *jv_channel; /* channel for I/O, reference counted */ ! char_u **argv; /* command line used to start the job */ }; /* --- 1488,1494 ---- int jv_copyID; channel_T *jv_channel; /* channel for I/O, reference counted */ ! char_u **jv_argv; /* command line used to start the job */ }; /* *** ../vim-8.0.1744/src/channel.c 2018-04-21 19:49:02.524104569 +0200 --- src/channel.c 2018-04-21 22:27:55.648820716 +0200 *************** *** 5021,5031 **** vim_free(job->jv_tty_out); vim_free(job->jv_stoponexit); free_callback(job->jv_exit_cb, job->jv_exit_partial); ! if (job->argv != NULL) { ! for (i = 0; job->argv[i] != NULL; i++) ! vim_free(job->argv[i]); ! vim_free(job->argv); } } --- 5021,5031 ---- vim_free(job->jv_tty_out); vim_free(job->jv_stoponexit); free_callback(job->jv_exit_cb, job->jv_exit_partial); ! if (job->jv_argv != NULL) { ! for (i = 0; job->jv_argv[i] != NULL; i++) ! vim_free(job->jv_argv[i]); ! vim_free(job->jv_argv); } } *************** *** 5462,5477 **** { job_T *job; char_u *cmd = NULL; - #if defined(UNIX) - # define USE_ARGV char **argv = NULL; int argc = 0; #else garray_T ga; #endif jobopt_T opt; ch_part_T part; - int len; int i; job = job_alloc(); --- 5462,5476 ---- { job_T *job; char_u *cmd = NULL; char **argv = NULL; int argc = 0; + #if defined(UNIX) + # define USE_ARGV #else garray_T ga; #endif jobopt_T opt; ch_part_T part; int i; job = job_alloc(); *************** *** 5550,5556 **** #ifdef USE_ARGV if (argv_arg != NULL) { ! argv = argv_arg; } else #endif --- 5549,5563 ---- #ifdef USE_ARGV if (argv_arg != NULL) { ! /* Make a copy of argv_arg for job->jv_argv. */ ! for (i = 0; argv_arg[i] != NULL; i++) ! argc++; ! argv = (char **)alloc(sizeof(char_u *) * (argc + 1)); ! if (argv == NULL) ! goto theend; ! for (i = 0; i < argc; i++) ! argv[i] = (char *)vim_strsave((char_u *)argv_arg[i]); ! argv[argc] = NULL; } else #endif *************** *** 5563,5574 **** EMSG(_(e_invarg)); goto theend; } - #ifdef USE_ARGV /* This will modify "cmd". */ if (mch_parse_cmd(cmd, FALSE, &argv, &argc) == FAIL) goto theend; argv[argc] = NULL; - #endif } else if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL --- 5570,5581 ---- EMSG(_(e_invarg)); goto theend; } /* This will modify "cmd". */ if (mch_parse_cmd(cmd, FALSE, &argv, &argc) == FAIL) goto theend; + for (i = 0; i < argc; i++) + argv[i] = (char *)vim_strsave((char_u *)argv[i]); argv[argc] = NULL; } else if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL *************** *** 5580,5586 **** else { list_T *l = argvars[0].vval.v_list; - #ifdef USE_ARGV listitem_T *li; char_u *s; --- 5587,5592 ---- *************** *** 5592,5618 **** { s = get_tv_string_chk(&li->li_tv); if (s == NULL) goto theend; ! argv[argc++] = (char *)s; } argv[argc] = NULL; ! #else if (win32_build_cmd(l, &ga) == FAIL) goto theend; cmd = ga.ga_data; #endif } ! /* Save the command used to start the job */ ! len = 0; ! for (i = 0; argv[i] != NULL; i++) ! len++; ! job->argv = (char_u **)alloc(sizeof(char_u *) * (len + 1)); ! if (job->argv == NULL) ! goto theend; ! for (i = 0; argv[i] != NULL; i++) ! job->argv[i] = vim_strsave((char_u *)argv[i]); ! job->argv[i] = NULL; #ifdef USE_ARGV if (ch_log_active()) --- 5598,5621 ---- { s = get_tv_string_chk(&li->li_tv); if (s == NULL) + { + for (i = 0; i < argc; ++i) + vim_free(argv[i]); goto theend; ! } ! argv[argc++] = (char *)vim_strsave(s); } argv[argc] = NULL; ! ! #ifndef USE_ARGV if (win32_build_cmd(l, &ga) == FAIL) goto theend; cmd = ga.ga_data; #endif } ! /* Save the command used to start the job. */ ! job->jv_argv = (char_u **)argv; #ifdef USE_ARGV if (ch_log_active()) *************** *** 5640,5651 **** channel_write_in(job->jv_channel); theend: ! #ifdef USE_ARGV ! if (argv != argv_arg) ! vim_free(argv); ! #else vim_free(ga.ga_data); #endif free_job_options(&opt); return job; } --- 5643,5653 ---- channel_write_in(job->jv_channel); theend: ! #ifndef USE_ARGV vim_free(ga.ga_data); #endif + if ((char_u **)argv != job->jv_argv) + vim_free(argv); free_job_options(&opt); return job; } *************** *** 5716,5723 **** if (l != NULL) { dict_add_list(dict, "cmd", l); ! for (i = 0; job->argv[i] != NULL; i++) ! list_append_string(l, job->argv[i], -1); } } --- 5718,5726 ---- if (l != NULL) { dict_add_list(dict, "cmd", l); ! if (job->jv_argv != NULL) ! for (i = 0; job->jv_argv[i] != NULL; i++) ! list_append_string(l, job->jv_argv[i], -1); } } *** ../vim-8.0.1744/src/os_unix.c 2018-04-05 22:59:23.274681873 +0200 --- src/os_unix.c 2018-04-21 21:43:12.624614976 +0200 *************** *** 4154,4244 **** return wait_pid; } - #if defined(FEAT_JOB_CHANNEL) \ - || !defined(USE_SYSTEM) \ - || (defined(FEAT_GUI) && defined(FEAT_TERMINAL)) \ - || defined(PROTO) - /* - * Parse "cmd" and put the white-separated parts in "argv". - * "argv" is an allocated array with "argc" entries and room for 4 more. - * Returns FAIL when out of memory. - */ - int - mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc) - { - int i; - char_u *p, *d; - int inquote; - - /* - * Do this loop twice: - * 1: find number of arguments - * 2: separate them and build argv[] - */ - for (i = 0; i < 2; ++i) - { - p = skipwhite(cmd); - inquote = FALSE; - *argc = 0; - for (;;) - { - if (i == 1) - (*argv)[*argc] = (char *)p; - ++*argc; - d = p; - while (*p != NUL && (inquote || (*p != ' ' && *p != TAB))) - { - if (p[0] == '"') - /* quotes surrounding an argument and are dropped */ - inquote = !inquote; - else - { - if (p[0] == '\\' && p[1] != NUL) - { - /* First pass: skip over "\ " and "\"". - * Second pass: Remove the backslash. */ - ++p; - } - if (i == 1) - *d++ = *p; - } - ++p; - } - if (*p == NUL) - { - if (i == 1) - *d++ = NUL; - break; - } - if (i == 1) - *d++ = NUL; - p = skipwhite(p + 1); - } - if (*argv == NULL) - { - if (use_shcf) - { - /* Account for possible multiple args in p_shcf. */ - p = p_shcf; - for (;;) - { - p = skiptowhite(p); - if (*p == NUL) - break; - ++*argc; - p = skipwhite(p); - } - } - - *argv = (char **)alloc((unsigned)((*argc + 4) * sizeof(char *))); - if (*argv == NULL) /* out of memory */ - return FAIL; - } - } - return OK; - } - #endif - #if !defined(USE_SYSTEM) || defined(FEAT_JOB_CHANNEL) /* * Set the environment for a child process. --- 4154,4159 ---- *** ../vim-8.0.1744/src/misc2.c 2018-04-04 22:57:24.109853647 +0200 --- src/misc2.c 2018-04-21 21:44:12.916305731 +0200 *************** *** 6429,6431 **** --- 6429,6516 ---- } # endif #endif + + #if defined(FEAT_JOB_CHANNEL) \ + || (defined(UNIX) && (!defined(USE_SYSTEM) \ + || (defined(FEAT_GUI) && defined(FEAT_TERMINAL)))) \ + || defined(PROTO) + /* + * Parse "cmd" and put the white-separated parts in "argv". + * "argv" is an allocated array with "argc" entries and room for 4 more. + * Returns FAIL when out of memory. + */ + int + mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc) + { + int i; + char_u *p, *d; + int inquote; + + /* + * Do this loop twice: + * 1: find number of arguments + * 2: separate them and build argv[] + */ + for (i = 0; i < 2; ++i) + { + p = skipwhite(cmd); + inquote = FALSE; + *argc = 0; + for (;;) + { + if (i == 1) + (*argv)[*argc] = (char *)p; + ++*argc; + d = p; + while (*p != NUL && (inquote || (*p != ' ' && *p != TAB))) + { + if (p[0] == '"') + /* quotes surrounding an argument and are dropped */ + inquote = !inquote; + else + { + if (p[0] == '\\' && p[1] != NUL) + { + /* First pass: skip over "\ " and "\"". + * Second pass: Remove the backslash. */ + ++p; + } + if (i == 1) + *d++ = *p; + } + ++p; + } + if (*p == NUL) + { + if (i == 1) + *d++ = NUL; + break; + } + if (i == 1) + *d++ = NUL; + p = skipwhite(p + 1); + } + if (*argv == NULL) + { + if (use_shcf) + { + /* Account for possible multiple args in p_shcf. */ + p = p_shcf; + for (;;) + { + p = skiptowhite(p); + if (*p == NUL) + break; + ++*argc; + p = skipwhite(p); + } + } + + *argv = (char **)alloc((unsigned)((*argc + 4) * sizeof(char *))); + if (*argv == NULL) /* out of memory */ + return FAIL; + } + } + return OK; + } + #endif *** ../vim-8.0.1744/src/terminal.c 2018-04-21 20:02:32.738539943 +0200 --- src/terminal.c 2018-04-21 22:20:31.203479598 +0200 *************** *** 5312,5325 **** win32_build_env(opt->jo_env, &ga_env, TRUE); env_wchar = ga_env.ga_data; - job = job_alloc(); - if (job == NULL) - goto failed; - - channel = add_channel(); - if (channel == NULL) - goto failed; - term->tl_winpty_config = winpty_config_new(0, &winpty_err); if (term->tl_winpty_config == NULL) goto failed; --- 5312,5317 ---- *** ../vim-8.0.1744/src/proto/misc2.pro 2018-02-10 18:45:21.080822072 +0100 --- src/proto/misc2.pro 2018-04-21 21:44:28.440225549 +0200 *************** *** 110,113 **** --- 110,114 ---- void time_to_bytes(time_T the_time, char_u *buf); int has_non_ascii(char_u *s); void parse_queued_messages(void); + int mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc); /* vim: set ft=c : */ *** ../vim-8.0.1744/src/version.c 2018-04-21 20:12:31.978855879 +0200 --- src/version.c 2018-04-21 22:29:04.804411871 +0200 *************** *** 763,764 **** --- 763,766 ---- { /* Add new patch number below this line */ + /**/ + 1745, /**/ -- "Marriage is when a man and woman become as one; the trouble starts when they try to decide which one" /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///