for (int i = 0; Context && i < Context->msgcount; i++)
Context->hdrs[i]->pair = 0;
}
- else if ((r = REGCOMP(&tmp->regex, s, (sensitive ? mutt_which_case(s) : REG_ICASE))) != 0)
+ else
{
- regerror(r, &tmp->regex, err->data, err->dsize);
- free_color_line(tmp, 1);
- return -1;
+ int flags = 0;
+ if (sensitive)
+ flags = mutt_mb_is_lower(s) ? REG_ICASE : 0;
+ else
+ flags = REG_ICASE;
+
+ r = REGCOMP(&tmp->regex, s, flags);
+ if (r != 0)
+ {
+ regerror(r, &tmp->regex, err->data, err->dsize);
+ free_color_line(tmp, 1);
+ return -1;
+ }
}
tmp->pattern = mutt_str_strdup(s);
tmp->match = match;
bool not = false;
/* $mask is case-sensitive */
- if (mutt_str_strcmp(MuttVars[idx].option, "mask") != 0)
- flags |= mutt_which_case(tmp->data);
+ if ((mutt_str_strcmp(MuttVars[idx].option, "mask") != 0) && mutt_mb_is_lower(tmp->data))
+ flags |= REG_ICASE;
p = tmp->data;
if (mutt_str_strcmp(MuttVars[idx].option, "mask") == 0)
pp->regex = mutt_mem_calloc(1, sizeof(regex_t));
pp->pattern = mutt_str_strdup((char *) p->init);
- if (mutt_str_strcmp(p->option, "mask") != 0)
- flags |= mutt_which_case((const char *) p->init);
+ if ((mutt_str_strcmp(p->option, "mask") != 0) &&
+ (mutt_mb_is_lower((const char *) p->init)))
+ {
+ flags |= REG_ICASE;
+ }
if ((mutt_str_strcmp(p->option, "mask") == 0) && *s == '!')
{
s++;
search_dir = -search_dir;
if (search_buf)
- r = REGCOMP(&re, search_buf, REG_NOSUB | mutt_which_case(search_buf));
+ {
+ int flags = mutt_mb_is_lower(search_buf) ? REG_ICASE : 0;
+ r = REGCOMP(&re, search_buf, REG_NOSUB | flags);
+ }
if (r != 0)
{
* | :---------------------- | :---------------------------------------------------------
* | mutt_mb_charlen() | Count the bytes in a (multibyte) character
* | mutt_mb_get_initials() | Turn a name into initials
+ * | mutt_mb_is_lower() | Does a multi-byte string contain only lowercase characters?
* | mutt_mb_is_shell_char() | Is character not typically part of a pathname
* | mutt_mb_mbstowcs() | Convert a string from multibyte to wide characters
* | mutt_mb_wcstombs() | Convert a string from wide to multibyte characters
static const wchar_t shell_chars[] = L"<>&()$?*;{}| "; /* ! not included because it can be part of a pathname in NeoMutt */
return wcschr(shell_chars, ch) != NULL;
}
+
+/**
+ * mutt_mb_is_lower - Does a multi-byte string contain only lowercase characters?
+ * @param s String to check
+ * @retval true String contains no uppercase characters
+ * @retval false Error, or contains some uppercase characters
+ *
+ * Non-alphabetic characters are considered lowercase.
+ */
+bool mutt_mb_is_lower(const char *s)
+{
+ wchar_t w;
+ mbstate_t mb;
+ size_t l;
+
+ memset(&mb, 0, sizeof(mb));
+
+ for (; (l = mbrtowc(&w, s, MB_CUR_MAX, &mb)) != 0; s += l)
+ {
+ if (l == (size_t) -2)
+ continue; /* shift sequences */
+ if (l == (size_t) -1)
+ return false;
+ if (iswalpha((wint_t) w) && iswupper((wint_t) w))
+ return false;
+ }
+
+ return true;
+}
int mutt_mb_charlen(const char *s, int *width);
bool mutt_mb_get_initials(const char *name, char *buf, int buflen);
+bool mutt_mb_is_lower(const char *s);
bool mutt_mb_is_shell_char(wchar_t ch);
size_t mutt_mb_mbstowcs(wchar_t **pwbuf, size_t *pwbuflen, size_t i, char *buf);
void mutt_mb_wcstombs(char *dest, size_t dlen, const wchar_t *src, size_t slen);
}
else if (check_sig(buf, line_info, n - 1) == 0)
line_info[n].type = MT_COLOR_SIGNATURE;
- else if (regexec((regex_t *) QuoteRegexp.regex, buf, 1, pmatch, 0) == 0)
+ else if (regexec(QuoteRegexp.regex, buf, 1, pmatch, 0) == 0)
{
- if (regexec((regex_t *) Smileys.regex, buf, 1, smatch, 0) == 0)
+ if ((regexec(Smileys.regex, buf, 1, smatch, 0) == 0))
{
if (smatch[0].rm_so > 0)
{
c = buf[smatch[0].rm_so];
buf[smatch[0].rm_so] = 0;
- if (regexec((regex_t *) QuoteRegexp.regex, buf, 1, pmatch, 0) == 0)
+ if (regexec(QuoteRegexp.regex, buf, 1, pmatch, 0) == 0)
{
if (q_classify && line_info[n].quote == NULL)
line_info[n].quote = classify_quote(quote_list, buf + pmatch[0].rm_so,
(*last)--;
goto out;
}
- if (regexec((regex_t *) QuoteRegexp.regex, (char *) fmt, 1, pmatch, 0) != 0)
+ if (regexec(QuoteRegexp.regex, (char *) fmt, 1, pmatch, 0) != 0)
goto out;
(*line_info)[n].quote =
classify_quote(quote_list, (char *) fmt + pmatch[0].rm_so,
rd->search_compiled = Resize->search_compiled;
if (rd->search_compiled)
{
- err = REGCOMP(&rd->search_re, rd->searchbuf,
- REG_NEWLINE | mutt_which_case(rd->searchbuf));
+ int flags = mutt_mb_is_lower(rd->searchbuf) ? REG_ICASE : 0;
+ err = REGCOMP(&rd->search_re, rd->searchbuf, REG_NEWLINE | flags);
if (err != 0)
{
regerror(err, &rd->search_re, buffer, sizeof(buffer));
}
}
- err = REGCOMP(&rd.search_re, searchbuf, REG_NEWLINE | mutt_which_case(searchbuf));
+ int rflags = mutt_mb_is_lower(searchbuf) ? REG_ICASE : 0;
+ err = REGCOMP(&rd.search_re, searchbuf, REG_NEWLINE | rflags);
if (err != 0)
{
regerror(err, &rd.search_re, buffer, sizeof(buffer));
if (pat->stringmatch)
{
pat->p.str = mutt_str_strdup(buf.data);
- pat->ign_case = mutt_which_case(buf.data) == REG_ICASE;
+ pat->ign_case = mutt_mb_is_lower(buf.data);
FREE(&buf.data);
}
else if (pat->groupmatch)
else
{
pat->p.regex = mutt_mem_malloc(sizeof(regex_t));
- r = REGCOMP(pat->p.regex, buf.data,
- REG_NEWLINE | REG_NOSUB | mutt_which_case(buf.data));
+ int flags = mutt_mb_is_lower(buf.data) ? REG_ICASE : 0;
+ r = REGCOMP(pat->p.regex, buf.data, REG_NEWLINE | REG_NOSUB | flags);
if (r != 0)
{
regerror(r, pat->p.regex, errmsg, sizeof(errmsg));
{ 0, 0, 0, NULL },
};
-static struct Pattern *SearchPattern = NULL; /* current search pattern */
-static char LastSearch[STRING] = { 0 }; /* last pattern searched for */
-static char LastSearchExpn[LONG_STRING] = { 0 }; /* expanded version of
- LastSearch */
-
-/**
- * mutt_which_case - Smart-case searching
- *
- * if no uppercase letters are given, do a case-insensitive search
- */
-int mutt_which_case(const char *s)
-{
- wchar_t w;
- mbstate_t mb;
- size_t l;
-
- memset(&mb, 0, sizeof(mb));
-
- for (; (l = mbrtowc(&w, s, MB_CUR_MAX, &mb)) != 0; s += l)
- {
- if (l == (size_t) -2)
- continue; /* shift sequences */
- if (l == (size_t) -1)
- return 0; /* error; assume case-sensitive */
- if (iswalpha((wint_t) w) && iswupper((wint_t) w))
- return 0; /* case-sensitive */
- }
-
- return REG_ICASE; /* case-insensitive */
-}
+static struct Pattern *SearchPattern = NULL; /**< current search pattern */
+static char LastSearch[STRING] = { 0 }; /**< last pattern searched for */
+static char LastSearchExpn[LONG_STRING] = { 0 }; /**< expanded version of LastSearch */
static int patmatch(const struct Pattern *pat, const char *buf)
{