From: Bram Moolenaar Date: Sun, 6 Jun 2010 13:21:10 +0000 (+0200) Subject: Fixed memory leak in ":ownsyntax". X-Git-Tag: v7.3~320 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1950c3529b16acd21ee5770b422d633f24d192a3;p=vim Fixed memory leak in ":ownsyntax". --- diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index fda756fbb..c57b8d4cd 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1163,13 +1163,6 @@ b:changedtick The total number of changes to the current buffer. It is A variable name that is preceded with "w:" is local to the current window. It is deleted when the window is closed. -One local window variable is predefined: - *w:ownsyntax-variable* *ownsyntax* -w:ownsyntax Set to 1 if the window has an independent syntax installed - via the |:ownsyntax| command. The default for a window is - 0. Syntax scripts can use this to determine whether they - should set b:current_syntax or w:current_syntax. - *tabpage-variable* *t:var* A variable name that is preceded with "t:" is local to the current tab page, It is deleted when the tab page is closed. {not available when compiled diff --git a/src/eval.c b/src/eval.c index ca9389fb3..2e5b8766c 100644 --- a/src/eval.c +++ b/src/eval.c @@ -3884,11 +3884,6 @@ get_user_var_name(xp, idx) ++hi; return cat_prefix_varname('w', hi->hi_key); } - if (wdone == ht->ht_used) - { - ++wdone; - return (char_u *)"w:ownsyntax"; - } #ifdef FEAT_WINDOWS /* t: variables */ @@ -18758,18 +18753,6 @@ get_var_tv(name, len, rettv, verbose) tv = &atv; } - if (STRCMP(name, "w:ownsyntax") == 0) - { - atv.v_type = VAR_NUMBER; -#ifdef FEAT_SYN_HL - atv.vval.v_number = (curwin->w_s != &curwin->w_buffer->b_s) ? 1 : 0; -#else - atv.vval.v_number = 0; -#endif - tv = &atv; - } - - /* * Check for user-defined variables. */ @@ -19292,6 +19275,7 @@ find_var_ht(name, varname) /* * Get the string value of a (global/local) variable. + * Note: see get_tv_string() for how long the pointer remains valid. * Returns NULL when it doesn't exist. */ char_u * diff --git a/src/syntax.c b/src/syntax.c index 370bc761b..2b70c6d45 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -3537,8 +3537,7 @@ syn_cmd_clear(eap, syncing) syntax_clear(curwin->w_s); if (curwin->w_s == &curwin->w_buffer->b_s) do_unlet((char_u *)"b:current_syntax", TRUE); - else - do_unlet((char_u *)"w:current_syntax", TRUE); + do_unlet((char_u *)"w:current_syntax", TRUE); } } @@ -6157,6 +6156,9 @@ ex_syntax(eap) ex_ownsyntax(eap) exarg_T *eap; { + char_u *old_value; + char_u *new_value; + if (curwin->w_s == &curwin->w_buffer->b_s) { curwin->w_s = (synblock_T *)alloc(sizeof(synblock_T)); @@ -6170,7 +6172,26 @@ ex_ownsyntax(eap) clear_string_option(&curwin->w_s->b_p_spl); #endif } + + /* save value of b:current_syntax */ + old_value = get_var_value((char_u *)"b:current_syntax"); + if (old_value != NULL) + old_value = vim_strsave(old_value); + + /* Apply the "syntax" autocommand event, this finds and loads the syntax + * file. */ apply_autocmds(EVENT_SYNTAX, eap->arg, curbuf->b_fname, TRUE, curbuf); + + /* move value of b:current_syntax to w:current_syntax */ + new_value = get_var_value((char_u *)"b:current_syntax"); + set_internal_string_var((char_u *)"w:current_syntax", new_value); + + /* restore value of b:current_syntax */ + if (old_value != NULL) + { + set_internal_string_var((char_u *)"b:current_syntax", old_value); + vim_free(old_value); + } } int diff --git a/src/window.c b/src/window.c index d6aae7c0f..e878d9fab 100644 --- a/src/window.c +++ b/src/window.c @@ -4410,7 +4410,10 @@ win_free(wp, tp) #ifdef FEAT_SYN_HL /* free independent synblock */ if (wp->w_s != &wp->w_buffer->b_s) + { + syntax_clear(wp->w_s); vim_free(wp->w_s); + } #endif #ifdef FEAT_AUTOCMD