To: vim_dev@googlegroups.com Subject: Patch 8.2.4989 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.4989 Problem: Cannot specify a function name for :defcompile. Solution: Implement a function name argument for :defcompile. Files: runtime/doc/vim9.txt, src/userfunc.c, src/proto/userfunc.pro, src/vim9execute.c, src/ex_cmds.h, src/testdir/test_vim9_cmd.vim, src/testdir/test_vim9_disassemble.vim *** ../vim-8.2.4988/runtime/doc/vim9.txt 2022-04-14 12:58:19.604895030 +0100 --- runtime/doc/vim9.txt 2022-05-21 15:19:15.069829376 +0100 *************** *** 1167,1177 **** *:defc* *:defcompile* :defc[ompile] Compile functions defined in the current script that were not compiled yet. ! This will report errors found during the compilation. *:disa* *:disassemble* :disa[ssemble] {func} Show the instructions generated for {func}. ! This is for debugging and testing. Note that for command line completion of {func} you can prepend "s:" to find script-local functions. --- 1210,1227 ---- *:defc* *:defcompile* :defc[ompile] Compile functions defined in the current script that were not compiled yet. ! This will report any errors found during compilation. ! ! :defc[ompile] {func} ! :defc[ompile] debug {func} ! :defc[ompile] profile {func} ! Compile function {func}, if needed. Use "debug" and ! "profile" to specify the compilation mode. ! This will report any errors found during compilation. *:disa* *:disassemble* :disa[ssemble] {func} Show the instructions generated for {func}. ! This is for debugging and testing. *E1061* Note that for command line completion of {func} you can prepend "s:" to find script-local functions. *** ../vim-8.2.4988/src/userfunc.c 2022-05-13 13:50:32.815012765 +0100 --- src/userfunc.c 2022-05-21 15:07:41.701381219 +0100 *************** *** 4997,5032 **** } /* * :defcompile - compile all :def functions in the current script that need to ! * be compiled. Except dead functions. Doesn't do profiling. */ void ! ex_defcompile(exarg_T *eap UNUSED) { - long todo = (long)func_hashtab.ht_used; - int changed = func_hashtab.ht_changed; - hashitem_T *hi; ufunc_T *ufunc; ! for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) { ! if (!HASHITEM_EMPTY(hi)) { ! --todo; ! ufunc = HI2UF(hi); ! if (ufunc->uf_script_ctx.sc_sid == current_sctx.sc_sid ! && ufunc->uf_def_status == UF_TO_BE_COMPILED ! && (ufunc->uf_flags & FC_DEAD) == 0) ! { ! (void)compile_def_function(ufunc, FALSE, CT_NONE, NULL); ! if (func_hashtab.ht_changed != changed) { ! // a function has been added or removed, need to start over ! todo = (long)func_hashtab.ht_used; ! changed = func_hashtab.ht_changed; ! hi = func_hashtab.ht_array; ! --hi; } } } --- 4997,5111 ---- } /* + * Find a function by name, including "123". + * Check for "profile" and "debug" arguments and set"compile_type". + * Return NULL if not found. + */ + ufunc_T * + find_func_by_name(char_u *name, compiletype_T *compile_type) + { + char_u *arg = name; + char_u *fname; + ufunc_T *ufunc; + int is_global = FALSE; + + *compile_type = CT_NONE; + if (STRNCMP(arg, "profile", 7) == 0 && VIM_ISWHITE(arg[7])) + { + *compile_type = CT_PROFILE; + arg = skipwhite(arg + 7); + } + else if (STRNCMP(arg, "debug", 5) == 0 && VIM_ISWHITE(arg[5])) + { + *compile_type = CT_DEBUG; + arg = skipwhite(arg + 5); + } + + if (STRNCMP(arg, "", 8) == 0) + { + arg += 8; + (void)getdigits(&arg); + fname = vim_strnsave(name, arg - name); + } + else + fname = trans_function_name(&arg, &is_global, FALSE, + TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD, NULL, NULL, NULL); + if (fname == NULL) + { + semsg(_(e_invalid_argument_str), name); + return NULL; + } + if (!ends_excmd2(name, arg)) + { + emsg(ex_errmsg(e_trailing_characters_str, arg)); + return NULL; + } + + ufunc = find_func(fname, is_global); + if (ufunc == NULL) + { + char_u *p = untrans_function_name(fname); + + if (p != NULL) + // Try again without making it script-local. + ufunc = find_func(p, FALSE); + } + vim_free(fname); + if (ufunc == NULL) + semsg(_(e_cannot_find_function_str), name); + return ufunc; + } + + /* * :defcompile - compile all :def functions in the current script that need to ! * be compiled or the one specified by the argument. ! * Skips dead functions. Doesn't do profiling. */ void ! ex_defcompile(exarg_T *eap) { ufunc_T *ufunc; ! if (*eap->arg != NUL) { ! compiletype_T compile_type; ! ! ufunc = find_func_by_name(eap->arg, &compile_type); ! if (ufunc != NULL) { ! if (func_needs_compiling(ufunc, compile_type)) ! (void)compile_def_function(ufunc, FALSE, compile_type, NULL); ! else ! smsg(_("Function %s does not need compiling"), eap->arg); ! } ! } ! else ! { ! long todo = (long)func_hashtab.ht_used; ! int changed = func_hashtab.ht_changed; ! hashitem_T *hi; ! for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) ! { ! if (!HASHITEM_EMPTY(hi)) ! { ! --todo; ! ufunc = HI2UF(hi); ! if (ufunc->uf_script_ctx.sc_sid == current_sctx.sc_sid ! && ufunc->uf_def_status == UF_TO_BE_COMPILED ! && (ufunc->uf_flags & FC_DEAD) == 0) { ! (void)compile_def_function(ufunc, FALSE, CT_NONE, NULL); ! ! if (func_hashtab.ht_changed != changed) ! { ! // a function has been added or removed, need to start ! // over ! todo = (long)func_hashtab.ht_used; ! changed = func_hashtab.ht_changed; ! hi = func_hashtab.ht_array; ! --hi; ! } } } } *** ../vim-8.2.4988/src/proto/userfunc.pro 2022-03-31 20:02:52.422045605 +0100 --- src/proto/userfunc.pro 2022-05-21 14:25:55.757001488 +0100 *************** *** 45,50 **** --- 45,51 ---- void list_functions(regmatch_T *regmatch); ufunc_T *define_function(exarg_T *eap, char_u *name_arg, garray_T *lines_to_free); void ex_function(exarg_T *eap); + ufunc_T *find_func_by_name(char_u *name, compiletype_T *compile_type); void ex_defcompile(exarg_T *eap); int eval_fname_script(char_u *p); int translated_function_exists(char_u *name, int is_global); *** ../vim-8.2.4988/src/vim9execute.c 2022-05-18 11:00:44.295519512 +0100 --- src/vim9execute.c 2022-05-21 14:24:16.605069858 +0100 *************** *** 6277,6331 **** ex_disassemble(exarg_T *eap) { char_u *arg = eap->arg; - char_u *fname; ufunc_T *ufunc; dfunc_T *dfunc; isn_T *instr; int instr_count; ! int is_global = FALSE; ! compiletype_T compile_type = CT_NONE; ! if (STRNCMP(arg, "profile", 7) == 0 && VIM_ISWHITE(arg[7])) ! { ! compile_type = CT_PROFILE; ! arg = skipwhite(arg + 7); ! } ! else if (STRNCMP(arg, "debug", 5) == 0 && VIM_ISWHITE(arg[5])) ! { ! compile_type = CT_DEBUG; ! arg = skipwhite(arg + 5); ! } ! ! if (STRNCMP(arg, "", 8) == 0) ! { ! arg += 8; ! (void)getdigits(&arg); ! fname = vim_strnsave(eap->arg, arg - eap->arg); ! } ! else ! fname = trans_function_name(&arg, &is_global, FALSE, ! TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD, NULL, NULL, NULL); ! if (fname == NULL) ! { ! semsg(_(e_invalid_argument_str), eap->arg); ! return; ! } ! ! ufunc = find_func(fname, is_global); ! if (ufunc == NULL) ! { ! char_u *p = untrans_function_name(fname); ! ! if (p != NULL) ! // Try again without making it script-local. ! ufunc = find_func(p, FALSE); ! } ! vim_free(fname); if (ufunc == NULL) - { - semsg(_(e_cannot_find_function_str), eap->arg); return; - } if (func_needs_compiling(ufunc, compile_type) && compile_def_function(ufunc, FALSE, compile_type, NULL) == FAIL) return; --- 6277,6291 ---- ex_disassemble(exarg_T *eap) { char_u *arg = eap->arg; ufunc_T *ufunc; dfunc_T *dfunc; isn_T *instr; int instr_count; ! compiletype_T compile_type; ! ufunc = find_func_by_name(arg, &compile_type); if (ufunc == NULL) return; if (func_needs_compiling(ufunc, compile_type) && compile_def_function(ufunc, FALSE, compile_type, NULL) == FAIL) return; *** ../vim-8.2.4988/src/ex_cmds.h 2022-03-24 11:22:07.215294108 +0000 --- src/ex_cmds.h 2022-05-21 15:13:35.921471148 +0100 *************** *** 465,471 **** EX_EXTRA|EX_BANG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), EXCMD(CMD_defcompile, "defcompile", ex_defcompile, ! EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_TRLBAR, ADDR_NONE), EXCMD(CMD_delcommand, "delcommand", ex_delcommand, EX_NEEDARG|EX_WORD1|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, --- 465,471 ---- EX_EXTRA|EX_BANG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), EXCMD(CMD_defcompile, "defcompile", ex_defcompile, ! EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_TRLBAR|EX_EXTRA, ADDR_NONE), EXCMD(CMD_delcommand, "delcommand", ex_delcommand, EX_NEEDARG|EX_WORD1|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, *** ../vim-8.2.4988/src/testdir/test_vim9_cmd.vim 2022-05-17 12:45:11.789423526 +0100 --- src/testdir/test_vim9_cmd.vim 2022-05-21 15:15:44.369638126 +0100 *************** *** 83,88 **** --- 83,98 ---- v9.CheckScriptSuccess(lines) enddef + def Test_defcompile_fails() + assert_fails('defcompile NotExists', 'E1061:') + assert_fails('defcompile debug debug Test_defcompile_fails', 'E488:') + assert_fails('defcompile profile profile Test_defcompile_fails', 'E488:') + enddef + + defcompile Test_defcompile_fails + defcompile debug Test_defcompile_fails + defcompile profile Test_defcompile_fails + def Test_cmdmod_execute() # "legacy" applies not only to the "exe" argument but also to the commands var lines =<< trim END *** ../vim-8.2.4988/src/testdir/test_vim9_disassemble.vim 2022-05-17 16:12:35.712086412 +0100 --- src/testdir/test_vim9_disassemble.vim 2022-05-21 15:09:29.405340070 +0100 *************** *** 43,48 **** --- 43,51 ---- assert_fails('disass [', 'E475:') assert_fails('disass 234', 'E129:') assert_fails('disass foo', 'E129:') + assert_fails('disass Test_disassemble_load burp', 'E488:') + assert_fails('disass debug debug Test_disassemble_load', 'E488:') + assert_fails('disass profile profile Test_disassemble_load', 'E488:') var res = execute('disass s:ScriptFuncLoad') assert_match('\d*_ScriptFuncLoad.*' .. *** ../vim-8.2.4988/src/version.c 2022-05-21 11:20:38.102070988 +0100 --- src/version.c 2022-05-21 14:20:10.761214621 +0100 *************** *** 748,749 **** --- 748,751 ---- { /* Add new patch number below this line */ + /**/ + 4989, /**/ -- hundred-and-one symptoms of being an internet addict: 243. You unsuccessfully try to download a pizza from www.dominos.com. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///