aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/message.c258
1 files changed, 150 insertions, 108 deletions
diff --git a/src/message.c b/src/message.c
index 402b899dd8..feb1226e6d 100644
--- a/src/message.c
+++ b/src/message.c
@@ -61,6 +61,35 @@ static int do_more_prompt(int typed_char);
static void msg_screen_putchar(int c, int attr);
static int msg_check_screen(void);
static void redir_write(char_u *s, int maxlen);
+
+/// Allocates memory for dialog string & for storing hotkeys
+///
+/// Finds the size of memory required for the confirm_msg & for storing hotkeys
+/// and then allocates the memory for them.
+/// has_hotkey array is also filled-up.
+///
+/// @param message Message which will be part of the confirm_msg
+/// @param buttons String containing button names
+/// @param[out] has_hotkey A element in this array is set to true if
+/// corresponding button has a hotkey
+///
+/// @return Pointer to memory allocated for storing hotkeys
+static char_u * console_dialog_alloc(const char_u *message,
+ char_u *buttons,
+ bool has_hotkey[]);
+
+/// Copies hotkeys & dialog message into the memory allocated for it
+///
+/// @param message Message which will be part of the confirm_msg
+/// @param buttons String containing button names
+/// @param default_button_idx Number of default button
+/// @param has_hotkey A element in this array is true if corresponding button
+/// has a hotkey
+/// @param[out] hotkeys_ptr Pointer to the memory location where hotkeys will be copied
+static void copy_hotkeys_and_msg(const char_u *message, char_u *buttons,
+ int default_button_idx, const bool has_hotkey[],
+ char_u *hotkeys_ptr);
+
static char_u *msg_show_console_dialog(char_u *message, char_u *buttons,
int dfltbutton);
static int confirm_msg_used = FALSE; /* displaying confirm_msg */
@@ -2828,6 +2857,59 @@ copy_char (
}
}
+#define HAS_HOTKEY_LEN 30
+#define HOTK_LEN (has_mbyte ? MB_MAXBYTES : 1)
+
+static char_u * console_dialog_alloc(const char_u *message,
+ char_u *buttons,
+ bool has_hotkey[])
+{
+ int lenhotkey = HOTK_LEN; // count first button
+ has_hotkey[0] = false;
+
+ // Compute the size of memory to allocate.
+ int len = 0;
+ int idx = 0;
+ char_u *r = buttons;
+ while (*r) {
+ if (*r == DLG_BUTTON_SEP) {
+ len += 3; // '\n' -> ', '; 'x' -> '(x)'
+ lenhotkey += HOTK_LEN; // each button needs a hotkey
+ if (idx < HAS_HOTKEY_LEN - 1) {
+ has_hotkey[++idx] = false;
+ }
+ } else if (*r == DLG_HOTKEY_CHAR) {
+ r++;
+ len++; // '&a' -> '[a]'
+ if (idx < HAS_HOTKEY_LEN - 1) {
+ has_hotkey[idx] = true;
+ }
+ }
+
+ // Advance to the next character
+ mb_ptr_adv(r);
+ }
+
+ len += (int)(STRLEN(message)
+ + 2 // for the NL's
+ + STRLEN(buttons)
+ + 3); // for the ": " and NUL
+ lenhotkey++; // for the NUL
+
+ // If no hotkey is specified, first char is used.
+ if (!has_hotkey[0]) {
+ len += 2; // "x" -> "[x]"
+ }
+
+
+ // Now allocate space for the strings
+ free(confirm_msg);
+ confirm_msg = xmalloc(len);
+ *confirm_msg = NUL;
+
+ return xmalloc(lenhotkey);
+}
+
/*
* Format the dialog string, and display it at the bottom of
* the screen. Return a string of hotkey chars (if defined) for
@@ -2839,127 +2921,87 @@ copy_char (
*/
static char_u *msg_show_console_dialog(char_u *message, char_u *buttons, int dfltbutton)
{
- int len = 0;
-# define HOTK_LEN (has_mbyte ? MB_MAXBYTES : 1)
- int lenhotkey = HOTK_LEN; /* count first button */
- char_u *hotk = NULL;
- char_u *msgp = NULL;
- char_u *hotkp = NULL;
- char_u *r;
- int copy;
-#define HAS_HOTKEY_LEN 30
- char_u has_hotkey[HAS_HOTKEY_LEN];
- int first_hotkey = FALSE; /* first char of button is hotkey */
- int idx;
+ bool has_hotkey[HAS_HOTKEY_LEN];
+ char_u *hotk = console_dialog_alloc(message, buttons, has_hotkey);
- has_hotkey[0] = FALSE;
+ copy_hotkeys_and_msg(message, buttons, dfltbutton, has_hotkey, hotk);
- /*
- * First loop: compute the size of memory to allocate.
- * Second loop: copy to the allocated memory.
- */
- for (copy = 0; copy <= 1; ++copy) {
- r = buttons;
- idx = 0;
- while (*r) {
- if (*r == DLG_BUTTON_SEP) {
- if (copy) {
- *msgp++ = ',';
- *msgp++ = ' '; /* '\n' -> ', ' */
-
- /* advance to next hotkey and set default hotkey */
- if (has_mbyte)
- hotkp += STRLEN(hotkp);
- else
- ++hotkp;
- hotkp[copy_char(r + 1, hotkp, TRUE)] = NUL;
- if (dfltbutton)
- --dfltbutton;
-
- /* If no hotkey is specified first char is used. */
- if (idx < HAS_HOTKEY_LEN - 1 && !has_hotkey[++idx])
- first_hotkey = TRUE;
- } else {
- len += 3; /* '\n' -> ', '; 'x' -> '(x)' */
- lenhotkey += HOTK_LEN; /* each button needs a hotkey */
- if (idx < HAS_HOTKEY_LEN - 1)
- has_hotkey[++idx] = FALSE;
- }
- } else if (*r == DLG_HOTKEY_CHAR || first_hotkey) {
- if (*r == DLG_HOTKEY_CHAR)
- ++r;
- first_hotkey = FALSE;
- if (copy) {
- if (*r == DLG_HOTKEY_CHAR) /* '&&a' -> '&a' */
- *msgp++ = *r;
- else {
- /* '&a' -> '[a]' */
- *msgp++ = (dfltbutton == 1) ? '[' : '(';
- msgp += copy_char(r, msgp, FALSE);
- *msgp++ = (dfltbutton == 1) ? ']' : ')';
+ display_confirm_msg();
+ return hotk;
+}
- /* redefine hotkey */
- hotkp[copy_char(r, hotkp, TRUE)] = NUL;
- }
- } else {
- ++len; /* '&a' -> '[a]' */
- if (idx < HAS_HOTKEY_LEN - 1)
- has_hotkey[idx] = TRUE;
- }
- } else {
- /* everything else copy literally */
- if (copy)
- msgp += copy_char(r, msgp, FALSE);
- }
+static void copy_hotkeys_and_msg(const char_u *message, char_u *buttons,
+ int default_button_idx, const bool has_hotkey[],
+ char_u *hotkeys_ptr)
+{
+ *confirm_msg = '\n';
+ STRCPY(confirm_msg + 1, message);
- /* advance to the next character */
- mb_ptr_adv(r);
- }
+ char_u *msgp = confirm_msg + 1 + STRLEN(message);
- if (copy) {
- *msgp++ = ':';
- *msgp++ = ' ';
- *msgp = NUL;
- } else {
- len += (int)(STRLEN(message)
- + 2 /* for the NL's */
- + STRLEN(buttons)
- + 3); /* for the ": " and NUL */
- lenhotkey++; /* for the NUL */
-
- /* If no hotkey is specified first char is used. */
- if (!has_hotkey[0]) {
- first_hotkey = TRUE;
- len += 2; /* "x" -> "[x]" */
- }
+ // Define first default hotkey. Keep the hotkey string NUL
+ // terminated to avoid reading past the end.
+ hotkeys_ptr[copy_char(buttons, hotkeys_ptr, TRUE)] = NUL;
- /*
- * Now allocate and load the strings
- */
- free(confirm_msg);
- confirm_msg = alloc(len);
- *confirm_msg = NUL;
- hotk = alloc(lenhotkey);
+ // Remember where the choices start, displaying starts here when
+ // "hotkeys_ptr" typed at the more prompt.
+ confirm_msg_tail = msgp;
+ *msgp++ = '\n';
- *confirm_msg = '\n';
- STRCPY(confirm_msg + 1, message);
+ bool first_hotkey = false; // Is the first char of button a hotkey
+ if (!has_hotkey[0]) {
+ first_hotkey = true; // If no hotkey is specified, first char is used
+ }
+
+ int idx = 0;
+ char_u *r = buttons;
+ while (*r) {
+ if (*r == DLG_BUTTON_SEP) {
+ *msgp++ = ',';
+ *msgp++ = ' '; // '\n' -> ', '
+
+ // Advance to next hotkey and set default hotkey
+ hotkeys_ptr += (has_mbyte) ? STRLEN(hotkeys_ptr): 1;
+ hotkeys_ptr[copy_char(r + 1, hotkeys_ptr, TRUE)] = NUL;
+
+ if (default_button_idx) {
+ default_button_idx--;
+ }
+
+ // If no hotkey is specified, first char is used.
+ if (idx < HAS_HOTKEY_LEN - 1 && !has_hotkey[++idx]) {
+ first_hotkey = true;
+ }
- msgp = confirm_msg + 1 + STRLEN(message);
- hotkp = hotk;
+ } else if (*r == DLG_HOTKEY_CHAR || first_hotkey) {
+ if (*r == DLG_HOTKEY_CHAR) {
+ ++r;
+ }
- /* Define first default hotkey. Keep the hotkey string NUL
- * terminated to avoid reading past the end. */
- hotkp[copy_char(buttons, hotkp, TRUE)] = NUL;
+ first_hotkey = false;
+ if (*r == DLG_HOTKEY_CHAR) { // '&&a' -> '&a'
+ *msgp++ = *r;
+ } else {
+ // '&a' -> '[a]'
+ *msgp++ = (default_button_idx == 1) ? '[' : '(';
+ msgp += copy_char(r, msgp, FALSE);
+ *msgp++ = (default_button_idx == 1) ? ']' : ')';
- /* Remember where the choices start, displaying starts here when
- * "hotkp" typed at the more prompt. */
- confirm_msg_tail = msgp;
- *msgp++ = '\n';
+ // redefine hotkey
+ hotkeys_ptr[copy_char(r, hotkeys_ptr, TRUE)] = NUL;
+ }
+ } else {
+ // everything else copy literally
+ msgp += copy_char(r, msgp, FALSE);
}
+
+ // advance to the next character
+ mb_ptr_adv(r);
}
- display_confirm_msg();
- return hotk;
+ *msgp++ = ':';
+ *msgp++ = ' ';
+ *msgp = NUL;
}
/*