It may work to symlink gm4 to ${WRKDIR}/bin/m4 in post-extract. But this has come up in other places too so it would be helpful to have support in base m4.

--
 Sent from a phone, apologies for poor formatting.

On 4 December 2021 12:47:30 Christopher Zimmermann <[email protected]> wrote:

Hi,

current ocaml uses %02d format specifier in its autoconf. This is not
supported by our base m4. I had no idea how to force autoconf to use
devel/m4. So I added support for this flag to base m4. OK?
Alternatively suggestions are welcome how to force use of
/usr/local/bin/gm4 instead of /usr/bin/m4.

Christopher


Index: gnum4.c
===================================================================
RCS file: /cvs/src/usr.bin/m4/gnum4.c,v
retrieving revision 1.52
diff -u -p -r1.52 gnum4.c
--- gnum4.c     21 Aug 2017 21:41:13 -0000      1.52
+++ gnum4.c     4 Dec 2021 12:41:43 -0000
@@ -542,12 +542,12 @@ doformat(const char *argv[], int argc)
 {
        const char *format = argv[2];
        int pos = 3;
-       int left_padded;
-       long width;
+       int left_padded, fill_0 = 0;
+       int width;
        size_t l;
        const char *thisarg;
-       char temp[2];
-       long extra;
+       char temp[32];
+       long extra, number;

        while (*format != 0) {
                if (*format != '%') {
@@ -564,15 +564,19 @@ doformat(const char *argv[], int argc)
                        addchar('%');
                        break;
                }
+               if (*format == '0') {
+                       format++;
+                       fill_0 = 1;
+               }

                if (*format == '*') {
                        format++;
                        if (pos >= argc)
                                m4errx(1,
                                    "Format with too many format specifiers.");
-                       width = strtol(argv[pos++], NULL, 10);
+                       width = (int)strtol(argv[pos++], NULL, 10);
                } else {
-                       width = strtol(format, (char **)&format, 10);
+                       width = (int)strtol(format, (char **)&format, 10);
                }
                if (width < 0) {
                        left_padded = 1;
@@ -599,6 +603,18 @@ doformat(const char *argv[], int argc)
                switch(*format) {
                case 's':
                        thisarg = argv[pos++];
+                       break;
+               case 'd':
+                       number = strtol(argv[pos], (char **)&thisarg, 0);
+                       if (*argv[pos] == '\0' || *thisarg != '\0')
+                               m4errx(1,
+                                   "Unexpected argument to %%d format specifier: 
%s.",
+                                   argv[pos]);
+                       pos ++;
+                       snprintf(temp, sizeof(temp),
+                           fill_0 ? "%0*ld" : "%*ld",
+                           left_padded ? -width : width, number);
+                       thisarg = temp;
                        break;
                case 'c':
                        temp[0] = strtoul(argv[pos++], NULL, 10);
Index: m4.1
===================================================================
RCS file: /cvs/src/usr.bin/m4/m4.1,v
retrieving revision 1.65
diff -u -p -r1.65 m4.1
--- m4.1        8 Mar 2021 02:47:28 -0000       1.65
+++ m4.1        4 Dec 2021 12:41:43 -0000
@@ -290,8 +290,8 @@ and following arguments, in a way simila
 .Xr printf 3 .
 This built-in is only available in GNU-m4 compatibility mode, and the only
 parameters implemented are there for autoconf compatibility:
-left-padding flag, an optional field width, a maximum field width,
-*-specified field widths, and the %s and %c data type.
+left-padding flag, pad with leading zeros flag, an optional field width, a
+maximum field width, *-specified field widths, and the %d, %s and %c data type.
 .It Fn ifdef name yes no
 If the macro named by the first argument is defined then return the second
 argument, otherwise the third.

Reply via email to