/*
+ * Copyright notice from original mutt:
* Copyright (C) 1996-2002 Michael R. Elkins <me@mutt.org>
* Copyright (C) 2004 g10 Code GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- */
+ *
+ * Parts were written/modified by:
+ * Nico Golde <nico@ngolde.de>
+ *
+ * This file is part of mutt-ng, see http://www.muttng.org/.
+ * It's licensed under the GNU General Public License,
+ * please see the file GPL in the top level source directory.
+ */
#if HAVE_CONFIG_H
# include "config.h"
#include "pager.h"
#include "mbyte.h"
+#include "lib/mem.h"
+#include "lib/intl.h"
+#include "lib/str.h"
+
#include <termios.h>
#include <sys/types.h>
#include <fcntl.h>
customize this is of course the Mutt way. */
void mutt_need_hard_redraw (void)
{
- if (!getenv ("DISPLAY"))
- {
+ if (!getenv ("DISPLAY")) {
keypad (stdscr, TRUE);
clearok (stdscr, TRUE);
set_option (OPTNEEDREDRAW);
event_t mutt_getch (void)
{
int ch;
- event_t err = {-1, OP_NULL }, ret;
+ event_t err = { -1, OP_NULL }, ret;
- if (!option(OPTUNBUFFEREDINPUT) && UngetCount)
+ if (!option (OPTUNBUFFEREDINPUT) && UngetCount)
return (KeyEvent[--UngetCount]);
SigInt = 0;
if (SigInt)
mutt_query_exit ();
- if(ch == ERR)
+ if (ch == ERR)
return err;
-
- if ((ch & 0x80) && option (OPTMETAKEY))
- {
+
+ if ((ch & 0x80) && option (OPTMETAKEY)) {
/* send ALT-x as ESC-x */
ch &= ~0x80;
mutt_ungetch (ch, 0);
return (ch == ctrl ('G') ? err : ret);
}
-int _mutt_get_field (/* const */ char *field, char *buf, size_t buflen, int complete, int multiple, char ***files, int *numfiles)
+int _mutt_get_field ( /* const */ char *field, char *buf, size_t buflen,
+ int complete, int multiple, char ***files, int *numfiles)
{
int ret;
int x, y;
- ENTER_STATE *es = mutt_new_enter_state();
-
- do
- {
- CLEARLINE (LINES-1);
+ ENTER_STATE *es = mutt_new_enter_state ();
+
+ do {
+ CLEARLINE (LINES - 1);
addstr (field);
mutt_refresh ();
getyx (stdscr, y, x);
- ret = _mutt_enter_string (buf, buflen, y, x, complete, multiple, files, numfiles, es);
+ ret =
+ _mutt_enter_string (buf, buflen, y, x, complete, multiple, files,
+ numfiles, es);
}
while (ret == 1);
- CLEARLINE (LINES-1);
+ CLEARLINE (LINES - 1);
mutt_free_enter_state (&es);
-
+
return (ret);
}
int mutt_get_password (char *msg, char *buf, size_t buflen)
{
int rc;
-
- CLEARLINE (LINES-1);
+
+ CLEARLINE (LINES - 1);
addstr (msg);
set_option (OPTUNBUFFEREDINPUT);
- rc = mutt_enter_string (buf, buflen, LINES - 1, mutt_strlen (msg), M_PASS);
+ rc = mutt_enter_string (buf, buflen, LINES - 1, safe_strlen (msg), M_PASS);
unset_option (OPTUNBUFFEREDINPUT);
- CLEARLINE (LINES-1);
+ CLEARLINE (LINES - 1);
return (rc);
}
void mutt_clear_error (void)
{
Errorbuf[0] = 0;
- if (!option(OPTNOCURSES))
- CLEARLINE (LINES-1);
+ if (!option (OPTNOCURSES))
+ CLEARLINE (LINES - 1);
}
static void fix_end_of_file (const char *data)
{
FILE *fp;
int c;
-
+
if ((fp = safe_fopen (data, "a+")) == NULL)
return;
- fseek (fp,-1,SEEK_END);
- if ((c = fgetc(fp)) != '\n')
+ fseek (fp, -1, SEEK_END);
+ if ((c = fgetc (fp)) != '\n')
fputc ('\n', fp);
safe_fclose (&fp);
}
void mutt_edit_file (const char *editor, const char *data)
{
char cmd[LONG_STRING];
-
+
mutt_endwin (NULL);
mutt_expand_file_fmt (cmd, sizeof (cmd), editor, data);
if (mutt_system (cmd) == -1)
char answer[2];
answer[1] = 0;
-
+
reyes_ok = (expr = nl_langinfo (YESEXPR)) && expr[0] == '^' &&
- !regcomp (&reyes, expr, REG_NOSUB|REG_EXTENDED);
+ !regcomp (&reyes, expr, REG_NOSUB | REG_EXTENDED);
reno_ok = (expr = nl_langinfo (NOEXPR)) && expr[0] == '^' &&
- !regcomp (&reno, expr, REG_NOSUB|REG_EXTENDED);
+ !regcomp (&reno, expr, REG_NOSUB | REG_EXTENDED);
#endif
- CLEARLINE(LINES-1);
+ CLEARLINE (LINES - 1);
/*
* In order to prevent the default answer to the question to wrapped
* to fit.
*/
answer_string = safe_malloc (COLS + 1);
- snprintf (answer_string, COLS + 1, " ([%s]/%s): ", def == M_YES ? yes : no, def == M_YES ? no : yes);
- answer_string_len = strlen (answer_string);
+ snprintf (answer_string, COLS + 1, " ([%s]/%s): ", def == M_YES ? yes : no,
+ def == M_YES ? no : yes);
+ answer_string_len = safe_strlen (answer_string);
printw ("%.*s%s", COLS - answer_string_len, msg, answer_string);
FREE (&answer_string);
- FOREVER
- {
+ FOREVER {
mutt_refresh ();
ch = mutt_getch ();
if (CI_is_return (ch.ch))
break;
- if (ch.ch == -1)
- {
+ if (ch.ch == -1) {
def = -1;
break;
}
#ifdef HAVE_LANGINFO_YESEXPR
answer[0] = ch.ch;
- if (reyes_ok ?
- (regexec (& reyes, answer, 0, 0, 0) == 0) :
+ if (reyes_ok ? (regexec (&reyes, answer, 0, 0, 0) == 0) :
#else
if (
#endif
- (tolower (ch.ch) == 'y'))
- {
+ (tolower (ch.ch) == 'y')) {
def = M_YES;
break;
}
else if (
#ifdef HAVE_LANGINFO_YESEXPR
- reno_ok ?
- (regexec (& reno, answer, 0, 0, 0) == 0) :
+ reno_ok ? (regexec (&reno, answer, 0, 0, 0) == 0) :
#endif
- (tolower (ch.ch) == 'n'))
- {
+ (tolower (ch.ch) == 'n')) {
def = M_NO;
break;
}
- else
- {
- BEEP();
+ else {
+ BEEP ();
}
}
-#ifdef HAVE_LANGINFO_YESEXPR
+#ifdef HAVE_LANGINFO_YESEXPR
if (reyes_ok)
- regfree (& reyes);
+ regfree (&reyes);
if (reno_ok)
- regfree (& reno);
+ regfree (&reno);
#endif
- if (def != -1)
- {
+ if (def != -1) {
addstr ((char *) (def == M_YES ? yes : no));
mutt_refresh ();
}
mutt_flushinp ();
curs_set (1);
if (Timeout)
- timeout (-1); /* restore blocking operation */
- if (mutt_yesorno (_("Exit Mutt?"), M_YES) == M_YES)
- {
+ timeout (-1); /* restore blocking operation */
+ if (mutt_yesorno (_("Exit Mutt-ng?"), M_YES) == M_YES) {
endwin ();
exit (1);
}
- mutt_clear_error();
+ mutt_clear_error ();
mutt_curs_set (-1);
SigInt = 0;
}
void mutt_curses_error (const char *fmt, ...)
{
+ char TmpErrorbuf[STRING];
va_list ap;
va_start (ap, fmt);
vsnprintf (Errorbuf, sizeof (Errorbuf), fmt, ap);
va_end (ap);
-
+
dprint (1, (debugfile, "%s\n", Errorbuf));
- mutt_format_string (Errorbuf, sizeof (Errorbuf),
- 0, COLS-2, 0, 0, Errorbuf, sizeof (Errorbuf), 0);
+ mutt_format_string (TmpErrorbuf, sizeof (TmpErrorbuf),
+ 0, COLS - 2, 0, 0, Errorbuf, sizeof (Errorbuf), 0);
+ snprintf (Errorbuf, sizeof (Errorbuf), "%s", TmpErrorbuf); /* overkill */
- if (!option (OPTKEEPQUIET))
- {
+ if (!option (OPTKEEPQUIET)) {
BEEP ();
SETCOLOR (MT_COLOR_ERROR);
- mvaddstr (LINES-1, 0, Errorbuf);
+ mvaddstr (LINES - 1, 0, Errorbuf);
clrtoeol ();
SETCOLOR (MT_COLOR_NORMAL);
mutt_refresh ();
void mutt_curses_message (const char *fmt, ...)
{
+ char TmpErrorbuf[STRING];
va_list ap;
va_start (ap, fmt);
vsnprintf (Errorbuf, sizeof (Errorbuf), fmt, ap);
va_end (ap);
- mutt_format_string (Errorbuf, sizeof (Errorbuf),
- 0, COLS-2, 0, 0, Errorbuf, sizeof (Errorbuf), 0);
+ mutt_format_string (TmpErrorbuf, sizeof (TmpErrorbuf),
+ 0, COLS - 2, 0, 0, Errorbuf, sizeof (Errorbuf), 0);
+ snprintf (Errorbuf, sizeof (Errorbuf), "%s", TmpErrorbuf); /* overkill */
- if (!option (OPTKEEPQUIET))
- {
+ if (!option (OPTKEEPQUIET)) {
SETCOLOR (MT_COLOR_MESSAGE);
mvaddstr (LINES - 1, 0, Errorbuf);
clrtoeol ();
{
if (option (OPTKEEPQUIET))
return;
-
+
SETCOLOR (option (OPTMSGERR) ? MT_COLOR_ERROR : MT_COLOR_MESSAGE);
- CLEARLINE (LINES-1);
+ CLEARLINE (LINES - 1);
addstr (Errorbuf);
SETCOLOR (MT_COLOR_NORMAL);
}
void mutt_endwin (const char *msg)
{
- if (!option (OPTNOCURSES))
- {
+ if (!option (OPTNOCURSES)) {
CLEARLINE (LINES - 1);
-
+
attrset (A_NORMAL);
mutt_refresh ();
endwin ();
}
-
- if (msg && *msg)
- {
+
+ if (msg && *msg) {
puts (msg);
fflush (stdout);
}
{
char *p = strerror (errno);
- dprint (1, (debugfile, "%s: %s (errno = %d)\n", s,
- p ? p : "unknown error", errno));
+ dprint (1, (debugfile, "%s: %s (errno = %d)\n", s,
+ p ? p : "unknown error", errno));
mutt_error ("%s: %s (errno = %d)", s, p ? p : _("unknown error"), errno);
}
f = open ("/dev/tty", O_RDONLY);
tcgetattr (f, &t);
- memcpy ((void *)&old, (void *)&t, sizeof(struct termios)); /* save original state */
+ memcpy ((void *) &old, (void *) &t, sizeof (struct termios)); /* save original state */
t.c_lflag &= ~(ICANON | ECHO);
t.c_cc[VMIN] = 1;
t.c_cc[VTIME] = 0;
}
int mutt_do_pager (const char *banner,
- const char *tempfile,
- int do_color,
- pager_t *info)
+ const char *tempfile, int do_color, pager_t * info)
{
int rc;
-
- if (!Pager || mutt_strcmp (Pager, "builtin") == 0)
+
+ if (!Pager || safe_strcmp (Pager, "builtin") == 0)
rc = mutt_pager (banner, tempfile, do_color, info);
- else
- {
+ else {
char cmd[STRING];
-
+
mutt_endwin (NULL);
- mutt_expand_file_fmt (cmd, sizeof(cmd), Pager, tempfile);
- if (mutt_system (cmd) == -1)
- {
+ mutt_expand_file_fmt (cmd, sizeof (cmd), Pager, tempfile);
+ if (mutt_system (cmd) == -1) {
mutt_error (_("Error running \"%s\"!"), cmd);
rc = -1;
}
return rc;
}
-int _mutt_enter_fname (const char *prompt, char *buf, size_t blen, int *redraw, int buffy, int multiple, char ***files, int *numfiles)
+int _mutt_enter_fname (const char *prompt, char *buf, size_t blen,
+ int *redraw, int buffy, int multiple, char ***files,
+ int *numfiles)
{
event_t ch;
- mvaddstr (LINES-1, 0, (char *) prompt);
+ mvaddstr (LINES - 1, 0, (char *) prompt);
addstr (_(" ('?' for list): "));
if (buf[0])
addstr (buf);
clrtoeol ();
mutt_refresh ();
- ch = mutt_getch();
- if (ch.ch == -1)
- {
- CLEARLINE (LINES-1);
+ ch = mutt_getch ();
+ if (ch.ch == -1) {
+ CLEARLINE (LINES - 1);
return (-1);
}
- else if (ch.ch == '?')
- {
+ else if (ch.ch == '?') {
mutt_refresh ();
buf[0] = 0;
- _mutt_select_file (buf, blen, M_SEL_FOLDER | (multiple ? M_SEL_MULTI : 0),
+ _mutt_select_file (buf, blen, M_SEL_FOLDER | (multiple ? M_SEL_MULTI : 0),
files, numfiles);
*redraw = REDRAW_FULL;
}
- else
- {
- char *pc = safe_malloc (mutt_strlen (prompt) + 3);
+ else {
+ char *pc = safe_malloc (safe_strlen (prompt) + 3);
- sprintf (pc, "%s: ", prompt); /* __SPRINTF_CHECKED__ */
+ sprintf (pc, "%s: ", prompt); /* __SPRINTF_CHECKED__ */
mutt_ungetch (ch.op ? 0 : ch.ch, ch.op ? ch.op : 0);
- if (_mutt_get_field (pc, buf, blen, (buffy ? M_EFILE : M_FILE) | M_CLEAR, multiple, files, numfiles)
+ if (_mutt_get_field
+ (pc, buf, blen, (buffy ? M_EFILE : M_FILE) | M_CLEAR, multiple, files,
+ numfiles)
!= 0)
buf[0] = 0;
MAYBE_REDRAW (*redraw);
tmp.op = op;
if (UngetCount >= UngetBufLen)
- safe_realloc (&KeyEvent, (UngetBufLen += 128) * sizeof(event_t));
+ safe_realloc (&KeyEvent, (UngetBufLen += 128) * sizeof (event_t));
KeyEvent[UngetCount++] = tmp;
}
void mutt_curs_set (int cursor)
{
static int SavedCursor = 1;
-
+
if (cursor < 0)
cursor = SavedCursor;
else
SavedCursor = cursor;
-
+
if (curs_set (cursor) == ERR) {
- if (cursor == 1) /* cnorm */
- curs_set (2); /* cvvis */
+ if (cursor == 1) /* cnorm */
+ curs_set (2); /* cvvis */
}
}
#endif
mvaddstr (LINES - 1, 0, prompt);
clrtoeol ();
- FOREVER
- {
+ FOREVER {
mutt_refresh ();
- ch = mutt_getch ();
- if (ch.ch == -1 || CI_is_return (ch.ch))
- {
+ ch = mutt_getch ();
+ if (ch.ch == -1 || CI_is_return (ch.ch)) {
choice = -1;
break;
}
- else
- {
+ else {
p = strchr (letters, ch.ch);
- if (p)
- {
+ if (p) {
choice = p - letters + 1;
break;
}
- else if (ch.ch <= '9' && ch.ch > '0')
- {
+ else if (ch.ch <= '9' && ch.ch > '0') {
choice = ch.ch - '0';
- if (choice <= mutt_strlen (letters))
+ if (choice <= safe_strlen (letters))
break;
}
}
int mutt_addwch (wchar_t wc)
{
- char buf[MB_LEN_MAX*2];
+ char buf[MB_LEN_MAX * 2];
mbstate_t mbstate;
size_t n1, n2;
memset (&mbstate, 0, sizeof (mbstate));
- if ((n1 = wcrtomb (buf, wc, &mbstate)) == (size_t)(-1) ||
- (n2 = wcrtomb (buf + n1, 0, &mbstate)) == (size_t)(-1))
- return -1; /* ERR */
+ if ((n1 = wcrtomb (buf, wc, &mbstate)) == (size_t) (-1) ||
+ (n2 = wcrtomb (buf + n1, 0, &mbstate)) == (size_t) (-1))
+ return -1; /* ERR */
else
return addstr (buf);
}
void mutt_format_string (char *dest, size_t destlen,
int min_width, int max_width,
int right_justify, char m_pad_char,
- const char *s, size_t n,
- int arboreal)
+ const char *s, size_t n, int arboreal)
{
char *p;
+ wchar_t wc;
int w;
size_t k, k2;
char scratch[MB_LEN_MAX];
+ mbstate_t mbstate1, mbstate2;
+ memset (&mbstate1, 0, sizeof (mbstate1));
+ memset (&mbstate2, 0, sizeof (mbstate2));
--destlen;
p = dest;
- for (; n; s+=1, n-=1)
- {
- w = 1;
- k2 = 1;
- if (w > max_width)
+ for (; n && (k = mbrtowc (&wc, s, n, &mbstate1)); s += k, n -= k) {
+ if (k == (size_t) (-1) || k == (size_t) (-2)) {
+ k = (k == (size_t) (-1)) ? 1 : n;
+ wc = replacement_char ();
+ }
+ if (arboreal && wc < M_TREE_MAX)
+ w = 1; /* hack */
+ else {
+ if (!IsWPrint (wc))
+ wc = '?';
+ w = wcwidth (wc);
+ }
+ if (w >= 0) {
+ if (w > max_width || (k2 = wcrtomb (scratch, wc, &mbstate2)) > destlen)
break;
- min_width -= w;
- max_width -= w;
- strncpy (p, s, k2);
- p += k2;
- destlen -= k2;
+ min_width -= w;
+ max_width -= w;
+ strncpy (p, scratch, k2);
+ p += k2;
+ destlen -= k2;
+ }
}
- w = (int)destlen < min_width ? destlen : min_width;
+ w = (int) destlen < min_width ? destlen : min_width;
if (w <= 0)
*p = '\0';
- else if (right_justify)
- {
+ else if (right_justify) {
p[w] = '\0';
while (--p >= dest)
p[w] = *p;
while (--w >= 0)
dest[w] = m_pad_char;
}
- else
- {
+ else {
while (--w >= 0)
*p++ = m_pad_char;
*p = '\0';
static void mutt_format_s_x (char *dest,
size_t destlen,
- const char *prefix,
- const char *s,
- int arboreal)
+ const char *prefix, const char *s, int arboreal)
{
int right_justify = 1;
char *p;
if (*prefix == '-')
++prefix, right_justify = 0;
min_width = strtol (prefix, &p, 10);
- if (*p == '.')
- {
+ if (*p == '.') {
prefix = p + 1;
max_width = strtol (prefix, &p, 10);
if (p <= prefix)
}
mutt_format_string (dest, destlen, min_width, max_width,
- right_justify, ' ', s, mutt_strlen (s), arboreal);
+ right_justify, ' ', s, safe_strlen (s), arboreal);
}
void mutt_format_s (char *dest,
- size_t destlen,
- const char *prefix,
- const char *s)
+ size_t destlen, const char *prefix, const char *s)
{
mutt_format_s_x (dest, destlen, prefix, s, 0);
}
void mutt_format_s_tree (char *dest,
- size_t destlen,
- const char *prefix,
- const char *s)
+ size_t destlen, const char *prefix, const char *s)
{
mutt_format_s_x (dest, destlen, prefix, s, 1);
}
void mutt_paddstr (int n, const char *s)
{
- size_t len = mutt_strlen (s);
+ wchar_t wc;
+ int w;
+ size_t k;
+ size_t len = safe_strlen (s);
+ mbstate_t mbstate;
- for (; len && *s; s += 1, len -= 1)
- {
- if (1 > n)
- break;
- addnstr ((char *)s, 1);
- n -= 1;
+ memset (&mbstate, 0, sizeof (mbstate));
+ for (; len && (k = mbrtowc (&wc, s, len, &mbstate)); s += k, len -= k) {
+ if (k == (size_t) (-1) || k == (size_t) (-2)) {
+ k = (k == (size_t) (-1)) ? 1 : len;
+ wc = replacement_char ();
+ }
+ if (!IsWPrint (wc))
+ wc = '?';
+ w = wcwidth (wc);
+ if (w >= 0) {
+ if (w > n)
+ break;
+ addnstr ((char *) s, k);
+ n -= w;
+ }
}
while (n-- > 0)
addch (' ');
}
/*
- * mutt_strwidth is like mutt_strlen except that it returns the width
+ * mutt_strwidth is like safe_strlen except that it returns the width
* refering to the number of characters cells.
- * AK: since we remove all that multibyte-character-stuff, it is equal to mutt_strlen
*/
int mutt_strwidth (const char *s)
{
- return mutt_strlen(s);
+ wchar_t wc;
+ int w;
+ size_t k, n;
+ mbstate_t mbstate;
+
+ if (!s)
+ return 0;
+
+ n = safe_strlen (s);
+
+ memset (&mbstate, 0, sizeof (mbstate));
+ for (w = 0; n && (k = mbrtowc (&wc, s, n, &mbstate)); s += k, n -= k) {
+ if (k == (size_t) (-1) || k == (size_t) (-2)) {
+ k = (k == (size_t) (-1)) ? 1 : n;
+ wc = replacement_char ();
+ }
+ if (!IsWPrint (wc))
+ wc = '?';
+ w += wcwidth (wc);
+ }
+ return w;
}