# HG changeset patch # User Bram Moolenaar # Date 1547846104 -3600 # Node ID 233e2c585e0343fece8a88673e140a55e7f02d82 # Parent a8f924ee004bb68a86f171366cb2031e3d0ad071 patch 8.1.0772: the sign_define_by_name() function is too long commit https://github.com/vim/vim/commit/0314236aabcb2ca9d0b74074dadecf68d7c7ed5f Author: Bram Moolenaar Date: Fri Jan 18 22:01:42 2019 +0100 patch 8.1.0772: the sign_define_by_name() function is too long Problem: The sign_define_by_name() function is too long. Solution: Split it into smaller functions. (Yegappan Lakshmanan, closes #3819) diff --git a/src/sign.c b/src/sign.c --- a/src/sign.c +++ b/src/sign.c @@ -727,6 +727,140 @@ sign_find(char_u *name, sign_T **sp_prev } /* + * Allocate a new sign + */ + static sign_T * +alloc_new_sign(char_u *name) +{ + sign_T *sp; + sign_T *lp; + int start = next_sign_typenr; + + // Allocate a new sign. + sp = (sign_T *)alloc_clear_id((unsigned)sizeof(sign_T), + aid_sign_define_by_name); + if (sp == NULL) + return NULL; + + // Check that next_sign_typenr is not already being used. + // This only happens after wrapping around. Hopefully + // another one got deleted and we can use its number. + for (lp = first_sign; lp != NULL; ) + { + if (lp->sn_typenr == next_sign_typenr) + { + ++next_sign_typenr; + if (next_sign_typenr == MAX_TYPENR) + next_sign_typenr = 1; + if (next_sign_typenr == start) + { + vim_free(sp); + emsg(_("E612: Too many signs defined")); + return NULL; + } + lp = first_sign; // start all over + continue; + } + lp = lp->sn_next; + } + + sp->sn_typenr = next_sign_typenr; + if (++next_sign_typenr == MAX_TYPENR) + next_sign_typenr = 1; // wrap around + + sp->sn_name = vim_strsave(name); + if (sp->sn_name == NULL) // out of memory + { + vim_free(sp); + return NULL; + } + + return sp; +} + +/* + * Initialize the icon information for a new sign + */ + static void +sign_define_init_icon(sign_T *sp, char_u *icon) +{ + vim_free(sp->sn_icon); + sp->sn_icon = vim_strsave(icon); + backslash_halve(sp->sn_icon); +# ifdef FEAT_SIGN_ICONS + if (gui.in_use) + { + out_flush(); + if (sp->sn_image != NULL) + gui_mch_destroy_sign(sp->sn_image); + sp->sn_image = gui_mch_register_sign(sp->sn_icon); + } +# endif +} + +/* + * Initialize the text for a new sign + */ + static int +sign_define_init_text(sign_T *sp, char_u *text) +{ + char_u *s; + char_u *endp; + int cells; + int len; + + endp = text + (int)STRLEN(text); + + // Remove backslashes so that it is possible to use a space. + for (s = text; s + 1 < endp; ++s) + if (*s == '\\') + { + STRMOVE(s, s + 1); + --endp; + } + + // Count cells and check for non-printable chars +# ifdef FEAT_MBYTE + if (has_mbyte) + { + cells = 0; + for (s = text; s < endp; s += (*mb_ptr2len)(s)) + { + if (!vim_isprintc((*mb_ptr2char)(s))) + break; + cells += (*mb_ptr2cells)(s); + } + } + else +# endif + { + for (s = text; s < endp; ++s) + if (!vim_isprintc(*s)) + break; + cells = (int)(s - text); + } + + // Currently sign text must be one or two display cells + if (s != endp || cells < 1 || cells > 2) + { + semsg(_("E239: Invalid sign text: %s"), text); + return FAIL; + } + + vim_free(sp->sn_text); + // Allocate one byte more if we need to pad up + // with a space. + len = (int)(endp - text + ((cells == 1) ? 1 : 0)); + sp->sn_text = vim_strnsave(text, len); + + // For single character sign text, pad with a space. + if (sp->sn_text != NULL && cells == 1) + STRCPY(sp->sn_text + len - 1, " "); + + return OK; +} + +/* * Define a new sign or update an existing sign */ int @@ -743,48 +877,10 @@ sign_define_by_name( sp = sign_find(name, &sp_prev); if (sp == NULL) { - sign_T *lp; - int start = next_sign_typenr; - - // Allocate a new sign. - sp = (sign_T *)alloc_clear_id((unsigned)sizeof(sign_T), - aid_sign_define_by_name); + sp = alloc_new_sign(name); if (sp == NULL) return FAIL; - // Check that next_sign_typenr is not already being used. - // This only happens after wrapping around. Hopefully - // another one got deleted and we can use its number. - for (lp = first_sign; lp != NULL; ) - { - if (lp->sn_typenr == next_sign_typenr) - { - ++next_sign_typenr; - if (next_sign_typenr == MAX_TYPENR) - next_sign_typenr = 1; - if (next_sign_typenr == start) - { - vim_free(sp); - emsg(_("E612: Too many signs defined")); - return FAIL; - } - lp = first_sign; // start all over - continue; - } - lp = lp->sn_next; - } - - sp->sn_typenr = next_sign_typenr; - if (++next_sign_typenr == MAX_TYPENR) - next_sign_typenr = 1; // wrap around - - sp->sn_name = vim_strsave(name); - if (sp->sn_name == NULL) // out of memory - { - vim_free(sp); - return FAIL; - } - // add the new sign to the list of signs if (sp_prev == NULL) first_sign = sp; @@ -794,73 +890,10 @@ sign_define_by_name( // set values for a defined sign. if (icon != NULL) - { - vim_free(sp->sn_icon); - sp->sn_icon = vim_strsave(icon); - backslash_halve(sp->sn_icon); -# ifdef FEAT_SIGN_ICONS - if (gui.in_use) - { - out_flush(); - if (sp->sn_image != NULL) - gui_mch_destroy_sign(sp->sn_image); - sp->sn_image = gui_mch_register_sign(sp->sn_icon); - } -# endif - } - - if (text != NULL) - { - char_u *s; - char_u *endp; - int cells; - int len; + sign_define_init_icon(sp, icon); - endp = text + (int)STRLEN(text); - for (s = text; s + 1 < endp; ++s) - if (*s == '\\') - { - // Remove a backslash, so that it is possible - // to use a space. - STRMOVE(s, s + 1); - --endp; - } -# ifdef FEAT_MBYTE - // Count cells and check for non-printable chars - if (has_mbyte) - { - cells = 0; - for (s = text; s < endp; s += (*mb_ptr2len)(s)) - { - if (!vim_isprintc((*mb_ptr2char)(s))) - break; - cells += (*mb_ptr2cells)(s); - } - } - else -# endif - { - for (s = text; s < endp; ++s) - if (!vim_isprintc(*s)) - break; - cells = (int)(s - text); - } - // Currently must be one or two display cells - if (s != endp || cells < 1 || cells > 2) - { - semsg(_("E239: Invalid sign text: %s"), text); - return FAIL; - } - - vim_free(sp->sn_text); - // Allocate one byte more if we need to pad up - // with a space. - len = (int)(endp - text + ((cells == 1) ? 1 : 0)); - sp->sn_text = vim_strnsave(text, len); - - if (sp->sn_text != NULL && cells == 1) - STRCPY(sp->sn_text + len - 1, " "); - } + if (text != NULL && (sign_define_init_text(sp, text) == FAIL)) + return FAIL; if (linehl != NULL) sp->sn_line_hl = syn_check_group(linehl, (int)STRLEN(linehl)); diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -792,6 +792,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 772, +/**/ 771, /**/ 770,