Re: bug formatting a .h function extern declaration with attribute macros

Simon Josefsson via "GNU indent discussion, bug reports, suggestions." <[email protected]> Fri, 04 Apr 2025 12:23:55 +0200
Newsgroups gmane.comp.gnu.indent.bugs,gmane.comp.gnu.m4.bugs
Message-ID <[email protected]>
--=-=-=
Content-Type: text/plain

Eric Blake <[email protected]> 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;

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* */

/Simon

--=-=-=
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQNoBAEWCAMQFiEEo8ychwudMQq61M8vUXIrCP5HRaIFAmfvszwUHHNpbW9uQGpv
c2Vmc3Nvbi5vcmfCHCYAmDMEXJLOtBYJKwYBBAHaRw8BAQdACIcrZIvhrxDBkK9f
V+QlTmXxo2naObDuGtw58YaxlOu0JVNpbW9uIEpvc2Vmc3NvbiA8c2ltb25Aam9z
ZWZzc29uLm9yZz6IlgQTFggAPgIbAwULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgBYh
BLHSvRN1vst4TPT4xNc89jjFPAa+BQJn0XQkBQkNZGbwAAoJENc89jjFPAa+BtIA
/iR73CfBurG9y8pASh3cbGOMHpDZfMAtosu6jbpO69GHAP4p7l57d+iVty2VQMsx
+3TCSAvZkpr4P/FuTzZ8JZe8BrgzBFySz4EWCSsGAQQB2kcPAQEHQOxTCIOaeXAx
I2hIX4HK9bQTpNVei708oNr1Klm8qCGKiPUEGBYIACYCGwIWIQSx0r0Tdb7LeEz0
+MTXPPY4xTwGvgUCZ9F0SgUJDWRmSQCBdiAEGRYIAB0WIQSjzJyHC50xCrrUzy9R
cisI/kdFogUCXJLPgQAKCRBRcisI/kdFoqdMAQCgH45aseZgIrwKOvUOA9QfsmeE
8GZHYNuFHmM9FEQS6AD6A4x5aYvoY6lo98pgtw2HPDhmcCXFItjXCrV4A0GmJA4J
ENc89jjFPAa+wUUBAO64fbZek6FPlRK0DrlWsrjCXuLi6PUxyzCAY6lG2nhUAQC6
qobB9mkZlZ0qihy1x4JRtflqFcqqT9n7iUZkCDIiDbg4BFySz2oSCisGAQQBl1UB
BQEBB0AxlRumDW6nZY7A+VCfek9VpEx6PJmdJyYPt3lNHMd6HAMBCAeIfgQYFggA
JgIbDBYhBLHSvRN1vst4TPT4xNc89jjFPAa+BQJn0XTSBQkNZGboAAoJENc89jjF
PAa+0M0BAPPRq73kLnHYNDMniVBOzUdi2XeF32idjEWWfjvyIJUOAP4wZ+ALxIeh
is3Uw2BzGZE6ttXQ2Q+DeCJO3TPpIqaXDAAKCRBRcisI/kdFopHcAP0aUa+nkRKb
xYanLanh6rv+iHb0ewXMRQ3TPFTUs+C3NwEAu/o5oJlWAO/Q9UgPLHG7z00ZzIYe
zxt1OOIweHi0zg0=
=xmU5
-----END PGP SIGNATURE-----
--=-=-=--