On 09-02-2026 00:51:00 +0100, Gero Treuner wrote:
[...]
> I generalized the patch to cover subpaths of different lengths and also
> applied the optimization to mx_is_mh() .
> 
> IMO code clarity is sufficient. The array declarations could be moved
> inside the function, if that might further improve it. Repeated function
> calls are avoided, CPU cycles probably similar, and size of binary
> slightly reduced: ~100 Bytes for stripped mh.o and also affecting the
> final binary (not stripped) on my Debian Linux amd64 machine. But I
> assume that with different compilers, optimization flags and machines
> results vary.
> I decided against the proposed fstatat(), because most likely there are
> some mutt users on machines not supporting it. Adding detection and
> alternative code should be overengineering.
> 
> The code is custom-made to fit to the current buffer code. (Extending it
> would not be an option in an exercise to minimize code.)

I like this a lot.  It's clear and easily extendable.

Fabian


> This is low priority. I felt like having some diversion.
> 
> Here is the patch:
> 
> diff --git a/buffer.h b/buffer.h
> index e16c11db..dc8ffa7f 100644
> --- a/buffer.h
> +++ b/buffer.h
> @@ -31,6 +31,10 @@ typedef struct
>  /* Convert a buffer to a const char * "string" */
>  #define mutt_b2s(b) (b->data ? (const char *)b->data : "")
>  
> +/* For probing of base paths with varying sub parts (or similar) */
> +#define mutt_buffer_path_prepare(buf, path, saved_pos) (saved_pos = 
> mutt_buffer_printf (buf, "%s/", path))
> +#define mutt_buffer_path_add(buf, s, saved_pos) (buf->dptr = buf->data + 
> saved_pos, mutt_buffer_addstr (buf, s))
> +
>  BUFFER *mutt_buffer_new (void);
>  BUFFER *mutt_buffer_init (BUFFER *);
>  void mutt_buffer_free (BUFFER **);
> diff --git a/mh.c b/mh.c
> index b048a791..f03028df 100644
> --- a/mh.c
> +++ b/mh.c
> @@ -2742,26 +2742,25 @@ int mh_check_empty (const char *path)
>    return r;
>  }
>  
> +static const char * const maildir_subdirs[] = { "cur", "new", "tmp" };
> +
>  int mx_is_maildir (const char *path)
>  {
>    BUFFER *tmp = NULL;
>    struct stat st;
>    int rc = 0;
> +  int saved_pos;
> +  int i;
>  
>    tmp = mutt_buffer_pool_get ();
>  
> -  mutt_buffer_printf (tmp, "%s/cur", path);
> -  if (stat (mutt_b2s (tmp), &st) != 0 || !S_ISDIR (st.st_mode))
> -    goto out;
> -
> -  mutt_buffer_printf (tmp, "%s/new", path);
> -  if (stat (mutt_b2s (tmp), &st) != 0 || !S_ISDIR (st.st_mode))
> -    goto out;
> -
> -  mutt_buffer_printf (tmp, "%s/tmp", path);
> -  if (stat (mutt_b2s (tmp), &st) != 0 || !S_ISDIR (st.st_mode))
> -    goto out;
> -
> +  mutt_buffer_path_prepare (tmp, path, saved_pos);
> +  for (i = 0; i < mutt_array_size (maildir_subdirs); i++)
> +  {
> +    mutt_buffer_path_add(tmp, maildir_subdirs[i], saved_pos);
> +    if (stat (mutt_b2s (tmp), &st) != 0 || !S_ISDIR (st.st_mode))
> +      goto out;
> +  }
>    rc = 1;
>  
>  out:
> @@ -2769,42 +2768,35 @@ out:
>    return rc;
>  }
>  
> +static const char * const mh_files[] = {
> +  ".mh_sequences",
> +  ".xmhcache",
> +  ".mew_cache",
> +  ".mew-cache",
> +  ".sylpheed_cache",
> +  /*
> +   * ok, this isn't an mh folder, but mh mode can be used to read
> +   * Usenet news from the spool. ;-)
> +   */
> +  ".overview"
> +};
> +
>  int mx_is_mh (const char *path)
>  {
>    BUFFER *tmp = NULL;
>    int rc = 1;
> +  int saved_pos;
> +  int i;
>  
>    tmp = mutt_buffer_pool_get ();
>  
> -  mutt_buffer_printf (tmp, "%s/.mh_sequences", path);
> -  if (access (mutt_b2s (tmp), F_OK) == 0)
> -    goto out;
> -
> -  mutt_buffer_printf (tmp, "%s/.xmhcache", path);
> -  if (access (mutt_b2s (tmp), F_OK) == 0)
> -    goto out;
> -
> -  mutt_buffer_printf (tmp, "%s/.mew_cache", path);
> -  if (access (mutt_b2s (tmp), F_OK) == 0)
> -    goto out;
> -
> -  mutt_buffer_printf (tmp, "%s/.mew-cache", path);
> -  if (access (mutt_b2s (tmp), F_OK) == 0)
> -    goto out;
> -
> -  mutt_buffer_printf (tmp, "%s/.sylpheed_cache", path);
> -  if (access (mutt_b2s (tmp), F_OK) == 0)
> -    goto out;
> -
> -  /*
> -   * ok, this isn't an mh folder, but mh mode can be used to read
> -   * Usenet news from the spool. ;-)
> -   */
> -
> -  mutt_buffer_printf (tmp, "%s/.overview", path);
> -  if (access (mutt_b2s (tmp), F_OK) == 0)
> -    goto out;
> -
> +  mutt_buffer_path_prepare (tmp, path, saved_pos);
> +  for (i = 0; i < mutt_array_size (mh_files); i++)
> +  {
> +    mutt_buffer_path_add(tmp, mh_files[i], saved_pos);
> +    if (access (mutt_b2s (tmp), F_OK) == 0)
> +      goto out;
> +  }
>    rc = 0;
>  
>  out:
> 
> 
> 
> 
> Kind regards,
>    Gero

Attachment: signature.asc
Description: PGP signature

Reply via email to