]> granicus.if.org Git - neomutt/commitdiff
Add mutt_mb_is_lower() to muttlib
authorRichard Russon <rich@flatcap.org>
Wed, 6 Dec 2017 01:03:32 +0000 (01:03 +0000)
committerRichard Russon <rich@flatcap.org>
Thu, 28 Dec 2017 14:44:51 +0000 (14:44 +0000)
This is based on mutt_which_case() which had a unnecessary Regex
constant embedded in it.

color.c
init.c
menu.c
mutt/mbyte.c
mutt/mbyte.h
pager.c
pattern.c

diff --git a/color.c b/color.c
index a0961686036ddaf69a196116f4fb03862df981e5..708bf5277c9272601de17be1382d2b16a57d7579 100644 (file)
--- a/color.c
+++ b/color.c
@@ -653,11 +653,21 @@ static int add_pattern(struct ColorLineHead *top, const char *s, int sensitive,
       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;
diff --git a/init.c b/init.c
index 36075906a4f14c1f38238e439e32b304a5ed24dc..2ab74487d593c339a17e50a7e9ff1d82c5de31f4 100644 (file)
--- a/init.c
+++ b/init.c
@@ -183,8 +183,8 @@ static int parse_regex(int idx, struct Buffer *tmp, struct Buffer *err)
     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)
@@ -2187,8 +2187,11 @@ static void restore_default(struct Option *p)
 
         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++;
diff --git a/menu.c b/menu.c
index 91ea41d72b40daaf4d9bf16d3faae89f63f20c69..76a111d7471ec2f537f06907d9203669b216a8a8 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -959,7 +959,10 @@ static int menu_search(struct Menu *menu, int op)
     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)
   {
index 55e4e2a8a6f08f0c6fdcdda56e9da7dbad5ca148..e164517e6ae1483e34162d0144994e45f48131bf 100644 (file)
@@ -33,6 +33,7 @@
  * | :---------------------- | :---------------------------------------------------------
  * | 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
@@ -355,3 +356,32 @@ bool mutt_mb_is_shell_char(wchar_t ch)
   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;
+}
index fad6d6d15dbdbebe85a8dac24e3b22559f0dab57..9fc4e0ff23ea44d4ede21bd4827c78b33e488ae9 100644 (file)
@@ -43,6 +43,7 @@ extern wchar_t ReplacementChar;
 
 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);
diff --git a/pager.c b/pager.c
index 482c451eee98cde1f6c9e2f84c8f8bd12a4b5809..3b06494e00cf7a7d0bbc00ef17e55491793a3832 100644 (file)
--- a/pager.c
+++ b/pager.c
@@ -847,9 +847,9 @@ static void resolve_types(char *buf, char *raw, struct Line *line_info, int n,
   }
   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)
       {
@@ -859,7 +859,7 @@ static void resolve_types(char *buf, char *raw, struct Line *line_info, int n,
         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,
@@ -1491,7 +1491,7 @@ static int display_line(FILE *f, LOFF_T *last_pos, struct Line **line_info,
         (*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,
@@ -1810,8 +1810,8 @@ static void pager_menu_redraw(struct Menu *pager_menu)
       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));
@@ -2501,7 +2501,8 @@ int mutt_pager(const char *banner, const char *fname, int flags, struct Pager *e
           }
         }
 
-        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));
index ca83f682e41428da40eb10b8828a3cace79f8d86..936257f011a69088dc027ca27154a0809d3525b7 100644 (file)
--- a/pattern.c
+++ b/pattern.c
@@ -101,7 +101,7 @@ static bool eat_regex(struct Pattern *pat, struct Buffer *s, struct Buffer *err)
   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)
@@ -112,8 +112,8 @@ static bool eat_regex(struct Pattern *pat, struct Buffer *s, struct Buffer *err)
   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));
@@ -881,36 +881,9 @@ static const struct PatternFlags
   { 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)
 {