Hi all,

On Fri, Feb 06, 2026 at 09:41:04AM +0800, Kevin J. McCarthy wrote:
> > Out of curiosity I rewrote it to iterate over the three subdirectory
> > names and compared the difference in size of the binaries. In this
> > case it apparently is dominated by (debug) symbols and not hitting a
> > threshold for reduced size of a fully stripped binary on my system.
> [...]
> Thanks Gero!  I certainly agree it's more optimized. :D
> 
> However, I personally argue for code clarity except when optimization is
> called for.  In this case, I don't think it's worth the trade off.  See just
> below the function in mh.c, mx_is_mh(), for similar code, also called by
> mx_get_magic().

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.)

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

Reply via email to