summaryrefslogtreecommitdiff
path: root/src/sign.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-01-18 22:01:42 +0100
committerBram Moolenaar <Bram@vim.org>2019-01-18 22:01:42 +0100
commit0314236aabcb2ca9d0b74074dadecf68d7c7ed5f (patch)
tree9126c287fb11749a7264796a8d405e871b08dfe9 /src/sign.c
parent147e7d0caba8b66ff11622e514142bcc3d24403a (diff)
downloadvim-git-0314236aabcb2ca9d0b74074dadecf68d7c7ed5f.tar.gz
patch 8.1.0772: the sign_define_by_name() function is too longv8.1.0772
Problem: The sign_define_by_name() function is too long. Solution: Split it into smaller functions. (Yegappan Lakshmanan, closes #3819)
Diffstat (limited to 'src/sign.c')
-rw-r--r--src/sign.c243
1 files changed, 138 insertions, 105 deletions
diff --git a/src/sign.c b/src/sign.c
index 75f41235e..bab93ff08 100644
--- 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;
-
- 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;
- }
+ sign_define_init_icon(sp, icon);
- 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));