On Fri, Apr 04, 2025 at 12:23:55PM +0200, Simon Josefsson wrote: > Eric Blake <ebl...@redhat.com> writes: > > > I'm trying to run indent on the GNU M4 source code base before a > > release (it looks like gnulib added the ability to run make indent > > since the last time I made an m4 release). But one change that indent > > is insisting on is wrong: > > > > -extern void m4_error (int, int, const char *, ...) > > - ATTRIBUTE_COLD ATTRIBUTE_FORMAT ((__printf__, 3, 4)); > > -extern void m4_error_at_line (int, int, const char *, int, const char *, > > ...) > > - ATTRIBUTE_COLD ATTRIBUTE_FORMAT ((__printf__, 5, 6)); > > -extern _Noreturn void m4_failure (int, const char *, ...) > > +extern void > > +m4_error (int, int, const char *, ...) > > + ATTRIBUTE_COLD ATTRIBUTE_FORMAT ((__printf__, 3, 4)); > > + extern void m4_error_at_line (int, int, const char *, int, const char > > *, > > + ...) > > + ATTRIBUTE_COLD ATTRIBUTE_FORMAT ((__printf__, 5, 6)); > > + extern _Noreturn void m4_failure (int, const char *, ...) > > > > The old format may be awkward for starting the function name after the > > return type, but even if I break that up, emacs still recommends: > > > > extern void > > m4_error (int, int, const char *, ...) > > ATTRIBUTE_COLD ATTRIBUTE_FORMAT ((__printf__, 3, 4)); > > > > And once indent gets messed up by the double attribute (both > > ATTRIBUTE_COLD and ATTRIBUTE_FORMAT are macros that expand to > > __attribute__ magic; the former without parameters), then the rest of > > the file is messed up (as seen by the four-space indent before the > > next extern function line). Any ideas on how to tell indent about > > ALL_CAPS macros that fit in attribute positions of declarations? > > In GNU Libidn2's idn2.h I do it like this: > > # if defined __GNUC__ && defined __GNUC_MINOR__ > # define GCC_VERSION_AT_LEAST(major, minor) ((__GNUC__ > (major)) || > (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) > # else > # define GCC_VERSION_AT_LEAST(major, minor) 0 > # endif > # if GCC_VERSION_AT_LEAST(2,96) > # define G_GNUC_IDN2_ATTRIBUTE_PURE __attribute__ ((pure)) > # else > # define G_GNUC_IDN2_ATTRIBUTE_PURE > # endif > > extern _IDN2_API const char *idn2_check_version (const char *req_version) > G_GNUC_IDN2_ATTRIBUTE_PURE;
Figuring out how to write the __attribute__-hiding macros conditional on compiler version wasn't the issue (the m4 definitions for ATTRIBUTE_PURE come from gnulib, and are under a similar ladder of #if); rather, it's that an all-caps macro that takes no arguments and appears after the func(params) but before the trailing ; of an extern function declaration confuse indent. > > GNU Libtasn1 libtasn1.h has some similar usages too. > > Not sure if this helps, but maybe this approach could be explored? > > I suppose you are familiar with the hack to just disable indent for a > small piece of code too: > > /* *INDENT-OFF* */ > > extern void > m4_error (int, int, const char *, ...) > ATTRIBUTE_COLD ATTRIBUTE_FORMAT ((__printf__, 3, 4)); > > /* *INDENT-ON* */ Yep, that's what I resorted to in the short term: https://git.savannah.gnu.org/cgit/m4.git/diff/src/m4.h?h=branch-1.4 -- Eric Blake, Principal Software Engineer Red Hat, Inc. Virtualization: qemu.org | libguestfs.org