On Fri, Jun 19, 2026 at 02:27:15AM -0400, Kurt Hackenberg wrote:
On Fri, Jun 19, 2026 at 13:37 +0800, Kevin J. McCarthy wrote:

Ah, sorry, that's right.  I meant to propose ascii_strncasecmp()

I assumed that. Question is, do we have to call some external function to do that caseless compare, or can we code it directly in this function?

   int match;

   for (i = 0; ; i++)
       if ( !(match = (toupper(a[i]) == toupper(b[i])))
            || b[i] == '\0' || isspace(b[i]))
           break;

   return match;

Just whomped up, and untested.

Mutt uses its own ascii_* functions because the built-in ones are problematic for some locales. The isspace() has weird issues too, and I just spent some time recently removing it throughout the code. See 4fb4575a4bc23a739a16db810c13f2a4942786f8 for instance.

However, I realized this function was confusing me too, because it's not just checking if "a" matches the first word in the "b" list. It's returning the comparison value. :-) My brain was thinking it was similar to mechlist_contains() in gsasl.c

We could change the retval of the function to true/false and use the ascii_toupper() and IS_ASCII_WS() function in your loop above. Or keep the comparison and just do something like:

  size_t a_len, b_len;

  a_len = mutt_strlen(a);
  b_len = b ? strcspn(b, " \t\n\v\f\r") : 0;
  return ascii_strncasecmp(a, b, MAX(a_len, b_len));

(Also untested)

--
Kevin J. McCarthy
GPG Fingerprint: 8975 A9B3 3AA3 7910 385C  5308 ADEF 7684 8031 6BDA

Attachment: signature.asc
Description: PGP signature

Reply via email to