To: vim_dev@googlegroups.com Subject: Patch 8.1.1989 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.1989 Problem: The evalfunc.c file is still too big. Solution: Move f_pathshorten() to filepath.c. Move f_cscope_connection() to if_cscope.c. Move diff_ functions to diff.c. Move timer_ functions to ex_cmds2.c. move callback functions to evalvars.c. Files: src/evalfunc.c, src/proto/evalfunc.pro, src/filepath.c, src/proto/filepath.pro, src/if_cscope.c, src/proto/if_cscope.pro, src/diff.c, src/proto/diff.pro, src/ex_cmds2.c, src/proto/ex_cmds2.pro, src/evalvars.c, src/proto/evalvars.pro *** ../vim-8.1.1988/src/evalfunc.c 2019-09-04 22:28:53.061026888 +0200 --- src/evalfunc.c 2019-09-05 22:18:06.320368819 +0200 *************** *** 70,76 **** static void f_cos(typval_T *argvars, typval_T *rettv); static void f_cosh(typval_T *argvars, typval_T *rettv); #endif - static void f_cscope_connection(typval_T *argvars, typval_T *rettv); static void f_cursor(typval_T *argsvars, typval_T *rettv); #ifdef MSWIN static void f_debugbreak(typval_T *argvars, typval_T *rettv); --- 70,75 ---- *************** *** 78,85 **** static void f_deepcopy(typval_T *argvars, typval_T *rettv); static void f_deletebufline(typval_T *argvars, typval_T *rettv); static void f_did_filetype(typval_T *argvars, typval_T *rettv); - static void f_diff_filler(typval_T *argvars, typval_T *rettv); - static void f_diff_hlID(typval_T *argvars, typval_T *rettv); static void f_empty(typval_T *argvars, typval_T *rettv); static void f_environ(typval_T *argvars, typval_T *rettv); static void f_escape(typval_T *argvars, typval_T *rettv); --- 77,82 ---- *************** *** 178,184 **** static void f_nextnonblank(typval_T *argvars, typval_T *rettv); static void f_nr2char(typval_T *argvars, typval_T *rettv); static void f_or(typval_T *argvars, typval_T *rettv); - static void f_pathshorten(typval_T *argvars, typval_T *rettv); #ifdef FEAT_PERL static void f_perleval(typval_T *argvars, typval_T *rettv); #endif --- 175,180 ---- *************** *** 291,303 **** static void f_tan(typval_T *argvars, typval_T *rettv); static void f_tanh(typval_T *argvars, typval_T *rettv); #endif - #ifdef FEAT_TIMERS - static void f_timer_info(typval_T *argvars, typval_T *rettv); - static void f_timer_pause(typval_T *argvars, typval_T *rettv); - static void f_timer_start(typval_T *argvars, typval_T *rettv); - static void f_timer_stop(typval_T *argvars, typval_T *rettv); - static void f_timer_stopall(typval_T *argvars, typval_T *rettv); - #endif static void f_tolower(typval_T *argvars, typval_T *rettv); static void f_toupper(typval_T *argvars, typval_T *rettv); static void f_tr(typval_T *argvars, typval_T *rettv); --- 287,292 ---- *************** *** 2095,2127 **** #endif /* - * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function - * - * Checks the existence of a cscope connection. - */ - static void - f_cscope_connection(typval_T *argvars UNUSED, typval_T *rettv UNUSED) - { - #ifdef FEAT_CSCOPE - int num = 0; - char_u *dbpath = NULL; - char_u *prepend = NULL; - char_u buf[NUMBUFLEN]; - - if (argvars[0].v_type != VAR_UNKNOWN - && argvars[1].v_type != VAR_UNKNOWN) - { - num = (int)tv_get_number(&argvars[0]); - dbpath = tv_get_string(&argvars[1]); - if (argvars[2].v_type != VAR_UNKNOWN) - prepend = tv_get_string_buf(&argvars[2], buf); - } - - rettv->vval.v_number = cs_connection(num, dbpath, prepend); - #endif - } - - /* * "cursor(lnum, col)" function, or * "cursor(list)" * --- 2084,2089 ---- *************** *** 2322,2396 **** } /* - * "diff_filler()" function - */ - static void - f_diff_filler(typval_T *argvars UNUSED, typval_T *rettv UNUSED) - { - #ifdef FEAT_DIFF - rettv->vval.v_number = diff_check_fill(curwin, tv_get_lnum(argvars)); - #endif - } - - /* - * "diff_hlID()" function - */ - static void - f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED) - { - #ifdef FEAT_DIFF - linenr_T lnum = tv_get_lnum(argvars); - static linenr_T prev_lnum = 0; - static varnumber_T changedtick = 0; - static int fnum = 0; - static int change_start = 0; - static int change_end = 0; - static hlf_T hlID = (hlf_T)0; - int filler_lines; - int col; - - if (lnum < 0) /* ignore type error in {lnum} arg */ - lnum = 0; - if (lnum != prev_lnum - || changedtick != CHANGEDTICK(curbuf) - || fnum != curbuf->b_fnum) - { - /* New line, buffer, change: need to get the values. */ - filler_lines = diff_check(curwin, lnum); - if (filler_lines < 0) - { - if (filler_lines == -1) - { - change_start = MAXCOL; - change_end = -1; - if (diff_find_change(curwin, lnum, &change_start, &change_end)) - hlID = HLF_ADD; /* added line */ - else - hlID = HLF_CHD; /* changed line */ - } - else - hlID = HLF_ADD; /* added line */ - } - else - hlID = (hlf_T)0; - prev_lnum = lnum; - changedtick = CHANGEDTICK(curbuf); - fnum = curbuf->b_fnum; - } - - if (hlID == HLF_CHD || hlID == HLF_TXD) - { - col = tv_get_number(&argvars[1]) - 1; /* ignore type error in {col} */ - if (col >= change_start && col <= change_end) - hlID = HLF_TXD; /* changed text */ - else - hlID = HLF_CHD; /* changed line */ - } - rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID; - #endif - } - - /* * "empty({expr})" function */ static void --- 2284,2289 ---- *************** *** 6358,6384 **** | tv_get_number_chk(&argvars[1], NULL); } - /* - * "pathshorten()" function - */ - static void - f_pathshorten(typval_T *argvars, typval_T *rettv) - { - char_u *p; - - rettv->v_type = VAR_STRING; - p = tv_get_string_chk(&argvars[0]); - if (p == NULL) - rettv->vval.v_string = NULL; - else - { - p = vim_strsave(p); - rettv->vval.v_string = p; - if (p != NULL) - shorten_dir(p); - } - } - #ifdef FEAT_PERL /* * "perleval()" function --- 6251,6256 ---- *************** *** 9472,9694 **** } #endif - /* - * Get a callback from "arg". It can be a Funcref or a function name. - * When "arg" is zero return an empty string. - * "cb_name" is not allocated. - * "cb_name" is set to NULL for an invalid argument. - */ - callback_T - get_callback(typval_T *arg) - { - callback_T res; - - res.cb_free_name = FALSE; - if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL) - { - res.cb_partial = arg->vval.v_partial; - ++res.cb_partial->pt_refcount; - res.cb_name = partial_name(res.cb_partial); - } - else - { - res.cb_partial = NULL; - if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING) - { - // Note that we don't make a copy of the string. - res.cb_name = arg->vval.v_string; - func_ref(res.cb_name); - } - else if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0) - { - res.cb_name = (char_u *)""; - } - else - { - emsg(_("E921: Invalid callback argument")); - res.cb_name = NULL; - } - } - return res; - } - - /* - * Copy a callback into a typval_T. - */ - void - put_callback(callback_T *cb, typval_T *tv) - { - if (cb->cb_partial != NULL) - { - tv->v_type = VAR_PARTIAL; - tv->vval.v_partial = cb->cb_partial; - ++tv->vval.v_partial->pt_refcount; - } - else - { - tv->v_type = VAR_FUNC; - tv->vval.v_string = vim_strsave(cb->cb_name); - func_ref(cb->cb_name); - } - } - - /* - * Make a copy of "src" into "dest", allocating the function name if needed, - * without incrementing the refcount. - */ - void - set_callback(callback_T *dest, callback_T *src) - { - if (src->cb_partial == NULL) - { - // just a function name, make a copy - dest->cb_name = vim_strsave(src->cb_name); - dest->cb_free_name = TRUE; - } - else - { - // cb_name is a pointer into cb_partial - dest->cb_name = src->cb_name; - dest->cb_free_name = FALSE; - } - dest->cb_partial = src->cb_partial; - } - - /* - * Unref/free "callback" returned by get_callback() or set_callback(). - */ - void - free_callback(callback_T *callback) - { - if (callback->cb_partial != NULL) - { - partial_unref(callback->cb_partial); - callback->cb_partial = NULL; - } - else if (callback->cb_name != NULL) - func_unref(callback->cb_name); - if (callback->cb_free_name) - { - vim_free(callback->cb_name); - callback->cb_free_name = FALSE; - } - callback->cb_name = NULL; - } - - #ifdef FEAT_TIMERS - /* - * "timer_info([timer])" function - */ - static void - f_timer_info(typval_T *argvars, typval_T *rettv) - { - timer_T *timer = NULL; - - if (rettv_list_alloc(rettv) != OK) - return; - if (argvars[0].v_type != VAR_UNKNOWN) - { - if (argvars[0].v_type != VAR_NUMBER) - emsg(_(e_number_exp)); - else - { - timer = find_timer((int)tv_get_number(&argvars[0])); - if (timer != NULL) - add_timer_info(rettv, timer); - } - } - else - add_timer_info_all(rettv); - } - - /* - * "timer_pause(timer, paused)" function - */ - static void - f_timer_pause(typval_T *argvars, typval_T *rettv UNUSED) - { - timer_T *timer = NULL; - int paused = (int)tv_get_number(&argvars[1]); - - if (argvars[0].v_type != VAR_NUMBER) - emsg(_(e_number_exp)); - else - { - timer = find_timer((int)tv_get_number(&argvars[0])); - if (timer != NULL) - timer->tr_paused = paused; - } - } - - /* - * "timer_start(time, callback [, options])" function - */ - static void - f_timer_start(typval_T *argvars, typval_T *rettv) - { - long msec = (long)tv_get_number(&argvars[0]); - timer_T *timer; - int repeat = 0; - callback_T callback; - dict_T *dict; - - rettv->vval.v_number = -1; - if (check_secure()) - return; - if (argvars[2].v_type != VAR_UNKNOWN) - { - if (argvars[2].v_type != VAR_DICT - || (dict = argvars[2].vval.v_dict) == NULL) - { - semsg(_(e_invarg2), tv_get_string(&argvars[2])); - return; - } - if (dict_find(dict, (char_u *)"repeat", -1) != NULL) - repeat = dict_get_number(dict, (char_u *)"repeat"); - } - - callback = get_callback(&argvars[1]); - if (callback.cb_name == NULL) - return; - - timer = create_timer(msec, repeat); - if (timer == NULL) - free_callback(&callback); - else - { - set_callback(&timer->tr_callback, &callback); - rettv->vval.v_number = (varnumber_T)timer->tr_id; - } - } - - /* - * "timer_stop(timer)" function - */ - static void - f_timer_stop(typval_T *argvars, typval_T *rettv UNUSED) - { - timer_T *timer; - - if (argvars[0].v_type != VAR_NUMBER) - { - emsg(_(e_number_exp)); - return; - } - timer = find_timer((int)tv_get_number(&argvars[0])); - if (timer != NULL) - stop_timer(timer); - } - - /* - * "timer_stopall()" function - */ - static void - f_timer_stopall(typval_T *argvars UNUSED, typval_T *rettv UNUSED) - { - stop_all_timers(); - } - #endif - /* * "tolower(string)" function */ --- 9344,9349 ---- *** ../vim-8.1.1988/src/proto/evalfunc.pro 2019-08-03 21:58:17.753476626 +0200 --- src/proto/evalfunc.pro 2019-09-05 22:18:47.576212519 +0200 *************** *** 14,21 **** float_T vim_round(float_T f); long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit); void f_string(typval_T *argvars, typval_T *rettv); - callback_T get_callback(typval_T *arg); - void put_callback(callback_T *cb, typval_T *tv); - void set_callback(callback_T *dest, callback_T *src); - void free_callback(callback_T *callback); /* vim: set ft=c : */ --- 14,17 ---- *** ../vim-8.1.1988/src/filepath.c 2019-09-04 20:59:10.487410001 +0200 --- src/filepath.c 2019-09-05 21:58:40.449130391 +0200 *************** *** 1311,1316 **** --- 1311,1337 ---- } /* + * "pathshorten()" function + */ + void + f_pathshorten(typval_T *argvars, typval_T *rettv) + { + char_u *p; + + rettv->v_type = VAR_STRING; + p = tv_get_string_chk(&argvars[0]); + if (p == NULL) + rettv->vval.v_string = NULL; + else + { + p = vim_strsave(p); + rettv->vval.v_string = p; + if (p != NULL) + shorten_dir(p); + } + } + + /* * "readdir()" function */ void *** ../vim-8.1.1988/src/proto/filepath.pro 2019-09-04 20:59:10.491409987 +0200 --- src/proto/filepath.pro 2019-09-05 21:59:36.936933760 +0200 *************** *** 20,25 **** --- 20,26 ---- void f_globpath(typval_T *argvars, typval_T *rettv); void f_isdirectory(typval_T *argvars, typval_T *rettv); void f_mkdir(typval_T *argvars, typval_T *rettv); + void f_pathshorten(typval_T *argvars, typval_T *rettv); void f_readdir(typval_T *argvars, typval_T *rettv); void f_readfile(typval_T *argvars, typval_T *rettv); void f_resolve(typval_T *argvars, typval_T *rettv); *** ../vim-8.1.1988/src/if_cscope.c 2019-09-04 15:54:23.916359692 +0200 --- src/if_cscope.c 2019-09-05 22:06:27.459142131 +0200 *************** *** 384,390 **** * Note: All string comparisons are case sensitive! */ #if defined(FEAT_EVAL) || defined(PROTO) ! int cs_connection(int num, char_u *dbpath, char_u *ppath) { int i; --- 384,390 ---- * Note: All string comparisons are case sensitive! */ #if defined(FEAT_EVAL) || defined(PROTO) ! static int cs_connection(int num, char_u *dbpath, char_u *ppath) { int i; *************** *** 430,436 **** } return FALSE; ! } /* cs_connection */ #endif --- 430,464 ---- } return FALSE; ! } ! ! /* ! * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function ! * ! * Checks the existence of a cscope connection. ! */ ! void ! f_cscope_connection(typval_T *argvars UNUSED, typval_T *rettv UNUSED) ! { ! #ifdef FEAT_CSCOPE ! int num = 0; ! char_u *dbpath = NULL; ! char_u *prepend = NULL; ! char_u buf[NUMBUFLEN]; ! ! if (argvars[0].v_type != VAR_UNKNOWN ! && argvars[1].v_type != VAR_UNKNOWN) ! { ! num = (int)tv_get_number(&argvars[0]); ! dbpath = tv_get_string(&argvars[1]); ! if (argvars[2].v_type != VAR_UNKNOWN) ! prepend = tv_get_string_buf(&argvars[2], buf); ! } ! ! rettv->vval.v_number = cs_connection(num, dbpath, prepend); ! #endif ! } ! #endif *** ../vim-8.1.1988/src/proto/if_cscope.pro 2018-05-17 13:52:38.000000000 +0200 --- src/proto/if_cscope.pro 2019-09-05 22:06:29.231134618 +0200 *************** *** 7,12 **** int cs_fgets(char_u *buf, int size); void cs_free_tags(void); void cs_print_tags(void); ! int cs_connection(int num, char_u *dbpath, char_u *ppath); void cs_end(void); /* vim: set ft=c : */ --- 7,12 ---- int cs_fgets(char_u *buf, int size); void cs_free_tags(void); void cs_print_tags(void); ! void f_cscope_connection(typval_T *argvars, typval_T *rettv); void cs_end(void); /* vim: set ft=c : */ *** ../vim-8.1.1988/src/diff.c 2019-08-24 20:54:15.979845564 +0200 --- src/diff.c 2019-09-05 22:09:21.998417515 +0200 *************** *** 3215,3218 **** return 0; } ! #endif /* FEAT_DIFF */ --- 3215,3291 ---- return 0; } ! #endif // FEAT_DIFF ! ! #if defined(FEAT_EVAL) || defined(PROTO) ! ! /* ! * "diff_filler()" function ! */ ! void ! f_diff_filler(typval_T *argvars UNUSED, typval_T *rettv UNUSED) ! { ! #ifdef FEAT_DIFF ! rettv->vval.v_number = diff_check_fill(curwin, tv_get_lnum(argvars)); ! #endif ! } ! ! /* ! * "diff_hlID()" function ! */ ! void ! f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED) ! { ! #ifdef FEAT_DIFF ! linenr_T lnum = tv_get_lnum(argvars); ! static linenr_T prev_lnum = 0; ! static varnumber_T changedtick = 0; ! static int fnum = 0; ! static int change_start = 0; ! static int change_end = 0; ! static hlf_T hlID = (hlf_T)0; ! int filler_lines; ! int col; ! ! if (lnum < 0) /* ignore type error in {lnum} arg */ ! lnum = 0; ! if (lnum != prev_lnum ! || changedtick != CHANGEDTICK(curbuf) ! || fnum != curbuf->b_fnum) ! { ! /* New line, buffer, change: need to get the values. */ ! filler_lines = diff_check(curwin, lnum); ! if (filler_lines < 0) ! { ! if (filler_lines == -1) ! { ! change_start = MAXCOL; ! change_end = -1; ! if (diff_find_change(curwin, lnum, &change_start, &change_end)) ! hlID = HLF_ADD; /* added line */ ! else ! hlID = HLF_CHD; /* changed line */ ! } ! else ! hlID = HLF_ADD; /* added line */ ! } ! else ! hlID = (hlf_T)0; ! prev_lnum = lnum; ! changedtick = CHANGEDTICK(curbuf); ! fnum = curbuf->b_fnum; ! } ! ! if (hlID == HLF_CHD || hlID == HLF_TXD) ! { ! col = tv_get_number(&argvars[1]) - 1; /* ignore type error in {col} */ ! if (col >= change_start && col <= change_end) ! hlID = HLF_TXD; /* changed text */ ! else ! hlID = HLF_CHD; /* changed line */ ! } ! rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID; ! #endif ! } ! ! #endif *** ../vim-8.1.1988/src/proto/diff.pro 2019-08-24 20:54:15.979845564 +0200 --- src/proto/diff.pro 2019-09-05 22:09:26.050401044 +0200 *************** *** 27,30 **** --- 27,32 ---- int diff_move_to(int dir, long count); linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1); linenr_T diff_lnum_win(linenr_T lnum, win_T *wp); + void f_diff_filler(typval_T *argvars, typval_T *rettv); + void f_diff_hlID(typval_T *argvars, typval_T *rettv); /* vim: set ft=c : */ *** ../vim-8.1.1988/src/ex_cmds2.c 2019-08-25 15:40:39.662739502 +0200 --- src/ex_cmds2.c 2019-09-05 22:14:37.377168986 +0200 *************** *** 375,381 **** return abort; } ! # if defined(EXITFREE) || defined(PROTO) void timer_free_all() { --- 375,381 ---- return abort; } ! # if defined(EXITFREE) || defined(PROTO) void timer_free_all() { *************** *** 388,397 **** free_timer(timer); } } - # endif # endif ! #endif /* * If 'autowrite' option set, try to write the file. --- 388,510 ---- free_timer(timer); } } # endif ! /* ! * "timer_info([timer])" function ! */ ! void ! f_timer_info(typval_T *argvars, typval_T *rettv) ! { ! timer_T *timer = NULL; ! ! if (rettv_list_alloc(rettv) != OK) ! return; ! if (argvars[0].v_type != VAR_UNKNOWN) ! { ! if (argvars[0].v_type != VAR_NUMBER) ! emsg(_(e_number_exp)); ! else ! { ! timer = find_timer((int)tv_get_number(&argvars[0])); ! if (timer != NULL) ! add_timer_info(rettv, timer); ! } ! } ! else ! add_timer_info_all(rettv); ! } ! ! /* ! * "timer_pause(timer, paused)" function ! */ ! void ! f_timer_pause(typval_T *argvars, typval_T *rettv UNUSED) ! { ! timer_T *timer = NULL; ! int paused = (int)tv_get_number(&argvars[1]); ! ! if (argvars[0].v_type != VAR_NUMBER) ! emsg(_(e_number_exp)); ! else ! { ! timer = find_timer((int)tv_get_number(&argvars[0])); ! if (timer != NULL) ! timer->tr_paused = paused; ! } ! } ! ! /* ! * "timer_start(time, callback [, options])" function ! */ ! void ! f_timer_start(typval_T *argvars, typval_T *rettv) ! { ! long msec = (long)tv_get_number(&argvars[0]); ! timer_T *timer; ! int repeat = 0; ! callback_T callback; ! dict_T *dict; ! ! rettv->vval.v_number = -1; ! if (check_secure()) ! return; ! if (argvars[2].v_type != VAR_UNKNOWN) ! { ! if (argvars[2].v_type != VAR_DICT ! || (dict = argvars[2].vval.v_dict) == NULL) ! { ! semsg(_(e_invarg2), tv_get_string(&argvars[2])); ! return; ! } ! if (dict_find(dict, (char_u *)"repeat", -1) != NULL) ! repeat = dict_get_number(dict, (char_u *)"repeat"); ! } ! ! callback = get_callback(&argvars[1]); ! if (callback.cb_name == NULL) ! return; ! ! timer = create_timer(msec, repeat); ! if (timer == NULL) ! free_callback(&callback); ! else ! { ! set_callback(&timer->tr_callback, &callback); ! rettv->vval.v_number = (varnumber_T)timer->tr_id; ! } ! } ! ! /* ! * "timer_stop(timer)" function ! */ ! void ! f_timer_stop(typval_T *argvars, typval_T *rettv UNUSED) ! { ! timer_T *timer; ! ! if (argvars[0].v_type != VAR_NUMBER) ! { ! emsg(_(e_number_exp)); ! return; ! } ! timer = find_timer((int)tv_get_number(&argvars[0])); ! if (timer != NULL) ! stop_timer(timer); ! } ! ! /* ! * "timer_stopall()" function ! */ ! void ! f_timer_stopall(typval_T *argvars UNUSED, typval_T *rettv UNUSED) ! { ! stop_all_timers(); ! } ! ! # endif // FEAT_TIMERS ! ! #endif // FEAT_EVAL /* * If 'autowrite' option set, try to write the file. *** ../vim-8.1.1988/src/proto/ex_cmds2.pro 2019-08-25 15:40:39.662739502 +0200 --- src/proto/ex_cmds2.pro 2019-09-05 22:15:08.777047668 +0200 *************** *** 9,14 **** --- 9,19 ---- void add_timer_info_all(typval_T *rettv); int set_ref_in_timer(int copyID); void timer_free_all(void); + void f_timer_info(typval_T *argvars, typval_T *rettv); + void f_timer_pause(typval_T *argvars, typval_T *rettv); + void f_timer_start(typval_T *argvars, typval_T *rettv); + void f_timer_stop(typval_T *argvars, typval_T *rettv); + void f_timer_stopall(typval_T *argvars, typval_T *rettv); int autowrite(buf_T *buf, int forceit); void autowrite_all(void); int check_changed(buf_T *buf, int flags); *** ../vim-8.1.1988/src/evalvars.c 2019-09-03 17:13:32.040528491 +0200 --- src/evalvars.c 2019-09-05 22:18:11.476349258 +0200 *************** *** 3467,3470 **** --- 3467,3573 ---- } } + /* + * Get a callback from "arg". It can be a Funcref or a function name. + * When "arg" is zero return an empty string. + * "cb_name" is not allocated. + * "cb_name" is set to NULL for an invalid argument. + */ + callback_T + get_callback(typval_T *arg) + { + callback_T res; + + res.cb_free_name = FALSE; + if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL) + { + res.cb_partial = arg->vval.v_partial; + ++res.cb_partial->pt_refcount; + res.cb_name = partial_name(res.cb_partial); + } + else + { + res.cb_partial = NULL; + if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING) + { + // Note that we don't make a copy of the string. + res.cb_name = arg->vval.v_string; + func_ref(res.cb_name); + } + else if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0) + { + res.cb_name = (char_u *)""; + } + else + { + emsg(_("E921: Invalid callback argument")); + res.cb_name = NULL; + } + } + return res; + } + + /* + * Copy a callback into a typval_T. + */ + void + put_callback(callback_T *cb, typval_T *tv) + { + if (cb->cb_partial != NULL) + { + tv->v_type = VAR_PARTIAL; + tv->vval.v_partial = cb->cb_partial; + ++tv->vval.v_partial->pt_refcount; + } + else + { + tv->v_type = VAR_FUNC; + tv->vval.v_string = vim_strsave(cb->cb_name); + func_ref(cb->cb_name); + } + } + + /* + * Make a copy of "src" into "dest", allocating the function name if needed, + * without incrementing the refcount. + */ + void + set_callback(callback_T *dest, callback_T *src) + { + if (src->cb_partial == NULL) + { + // just a function name, make a copy + dest->cb_name = vim_strsave(src->cb_name); + dest->cb_free_name = TRUE; + } + else + { + // cb_name is a pointer into cb_partial + dest->cb_name = src->cb_name; + dest->cb_free_name = FALSE; + } + dest->cb_partial = src->cb_partial; + } + + /* + * Unref/free "callback" returned by get_callback() or set_callback(). + */ + void + free_callback(callback_T *callback) + { + if (callback->cb_partial != NULL) + { + partial_unref(callback->cb_partial); + callback->cb_partial = NULL; + } + else if (callback->cb_name != NULL) + func_unref(callback->cb_name); + if (callback->cb_free_name) + { + vim_free(callback->cb_name); + callback->cb_free_name = FALSE; + } + callback->cb_name = NULL; + } + #endif // FEAT_EVAL *** ../vim-8.1.1988/src/proto/evalvars.pro 2019-09-04 15:54:23.916359692 +0200 --- src/proto/evalvars.pro 2019-09-05 22:18:39.884241622 +0200 *************** *** 77,80 **** --- 77,84 ---- void f_settabwinvar(typval_T *argvars, typval_T *rettv); void f_setwinvar(typval_T *argvars, typval_T *rettv); void f_setbufvar(typval_T *argvars, typval_T *rettv); + callback_T get_callback(typval_T *arg); + void put_callback(callback_T *cb, typval_T *tv); + void set_callback(callback_T *dest, callback_T *src); + void free_callback(callback_T *callback); /* vim: set ft=c : */ *** ../vim-8.1.1988/src/version.c 2019-09-05 21:28:58.495157310 +0200 --- src/version.c 2019-09-05 22:33:04.925030754 +0200 *************** *** 759,760 **** --- 759,762 ---- { /* Add new patch number below this line */ + /**/ + 1989, /**/ -- hundred-and-one symptoms of being an internet addict: 194. Your business cards contain your e-mail and home page address. /// 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 ///