bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Beta release of gawk 3.1.6 now available - MinGW build [long]


From: Eli Zaretskii
Subject: Re: Beta release of gawk 3.1.6 now available - MinGW build [long]
Date: Sun, 03 Jun 2007 23:54:59 +0300

> Date: Sun, 03 Jun 2007 19:02:42 +0200
> From: Manuel Collado <address@hidden>
> 
> >>>> --------------------------------
> >>>> #if defined(__MINGW32__)
> >>>> #undef HAVE_ALLOCA
> >>>> #define HAVE_TMPFILE 1
> >>>> #define restrict    /* nothing */
> >>>> #endif
> >>>> -------------------------------
> >>> ??? Can you explain why you need to undef HAVE_TMPFILE and define away
> >>> `restrict'?  You _are_ using GCC, right?  If so, GCC supports both of
> >>> these features.
> 
> Please correct me if I'm wrong. To my knowledge, gcc is just a compiler. 
> It supports language-related features, like the 'restrict' keyword. 
> Support for features related to HAVE_ALLOCA or HAVE_TMPFILE are 
> supported by the underlying runtime (libc?), which is a separate 
> package/tool. Different platforms (DJGPP, MinGW, Cygwin,...) may have 
> the same compiler (the same version of gcc), but really different 
> runtime support.

That's true for library functions in general, but alloca is a special
case, since it is implemented in the compiler itself.  GCC emits
inline assembly for it.  Thus, any x86 target supports it in the same
way.

> gcc -c -O2 -gdwarf-2 -g3 -DGAWK -I. -DHAVE_CONFIG_H  array.c
> In file included from array.c:43:
> awk.h:230: error: syntax error before "buf"
> awk.h:230: error: conflicting types for 'snprintf'

This happens because config.h does not declare HAVE_SNPRINTF, and
awk.h has this around line 230:

  #ifndef HAVE_SNPRINTF
  /* will use replacement version */
  extern int snprintf P((char *restrict buf, size_t len, const char *restrict 
fmt, ...));
  #endif

I think a better solution is to define HAVE_SNPRINTF, since MinGW does
have it.

> In file included from gawkmisc.c:49:
> posix/gawkmisc.c: In function `optimal_bufsize':
> posix/gawkmisc.c:136: error: structure has no member named `st_blksize'

The MinGW build is not supposed to compile posix/gawkmisc.c, since the
MinGW runtime is not Posix enough.  In particular `struct stat' does
not have a member named `st_blksize'.

> 4.- Restore the original Makefile (from ./pc). Add '#define restrict 
> /*nothing*/' at the end of config.h and remake

I attach at the end of this message a series of patches I sent to the
Gawk maintainer that are supposed to fix a few problems with the MinGW
build.  You will see that I fixed this problem by defining
HAVE_SNPRINTF.

> In file included from replace.c:83:
> missing_d/snprintf.c:58:2: #error Neither mkstemp() nor tmpfile() is 
> available on this platform.
> In file included from replace.c:83:
> missing_d/snprintf.c: In function `vsnprintf':
> missing_d/snprintf.c:82: warning: assignment makes pointer from integer 
> without a cast
> mingw32-make[1]: *** [replace.o] Error 1
> mingw32-make[1]: Leaving directory `C:/Temp/gawk-3.1.5g'
> mingw32-make: *** [mingw32] Error 2
> 
> 
> 5.- Add '#define HAVE_TMPFILE 1' at the end of config.h and remake

This happened because, when HAVE_SNPRINTF is not defined, Gawk uses a
replacement snprintf that uses temporary files (yuk!).  Again,
defining HAVE_SNPRINTF is a better solution, IMO.

> In file included from regex.c:69:
> regex_internal.h:442:22: alloca.h: No such file or directory
> mingw32-make[1]: *** [regex.o] Error 1
> mingw32-make[1]: Leaving directory `C:/Temp/gawk-3.1.5g'
> mingw32-make: *** [mingw32] Error 2
> 
> 
> 6.- Add '#undef HAVE_ALLOCA' at the end of config.h and remake

Yes, this is indeed needed, since regex_internal.h assumes that if
HAVE_ALLOCA is defined, the header alloca.h is available, which is
false.  But using alloca in regex is not a good idea anyway, since
some complex regular expressions are known to cause stack overflow.

Thanks again for reporting the problems.

Here are the patches I used for my build:

2007-06-01  Eli Zaretskii  <address@hidden>

        * builtin.c (format_tree): Handle non-standard snprintf that
        return negative value when the buffer is too small.

--- builtin.c~0 2007-04-30 01:25:09.000000000 +0300
+++ builtin.c   2007-06-01 22:28:30.551000000 +0300
@@ -1000,8 +1000,12 @@ check_pos:
                               cpbufs[1].bufsize) {
                                if (cpbufs[1].buf == cpbufs[1].stackbuf)
                                        cpbufs[1].buf = NULL;
-                               cpbufs[1].bufsize += ((i > cpbufs[1].bufsize) ?
-                                                     i : cpbufs[1].bufsize);
+                               if (i > 0) {
+                                       cpbufs[1].bufsize += ((i > 
cpbufs[1].bufsize) ?
+                                                             i : 
cpbufs[1].bufsize);
+                               }
+                               else
+                                       cpbufs[1].bufsize *= 2;
                                assert(cpbufs[1].bufsize > 0);
                                erealloc(cpbufs[1].buf, char *,
                                         cpbufs[1].bufsize, "format_tree");

2007-06-01  Eli Zaretskii  <address@hidden>

        * Makefile.tst (msg): Use $(CMP) instead a literal "cmp".
        (nonl): Use NUL instead of /dev/null.
        (devfd, pid, fmtspcl, nofile, rstest4, rstest5, getlnhd, clos1way):
        Expect to fail on MinGW.
        (fmtspcl.ok): Depend on Makefile, not Makefile.tst.
        (pipeio2, hsprint, fmttest): Expect formatting or whitespace
        differences.
        (exitval2): Use exitval2.w32 instead of exitval2.awk.

        * config.h (HAVE_DECL_TZNAME) [__MINGW32__]: Define.
        (HAVE_ALLOCA) [__MINGW32__]: Don't define.
        (HAVE_SNPRINTF) [__MINGW32__]: Remove _MSC_VER condition.


--- pc/config.h~0       2007-05-21 08:46:38.000000000 +0300
+++ pc/config.h 2007-06-01 17:11:50.379125000 +0300
@@ -61,6 +61,10 @@
 #endif
 
 #ifdef __MINGW32__
+/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't.
+   */
+#define HAVE_DECL_TZNAME 1
+
 /* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
 #define HAVE_INTMAX_T 1
 
@@ -131,9 +135,6 @@
 /* Define to `int' if <sys/types.h> doesn't define.  */
 /* #undef gid_t */
 
-/* Define if you have alloca, as a function or macro.  */
-#define HAVE_ALLOCA 1
-
 /* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
 /* #undef HAVE_ALLOCA_H */
 
@@ -169,6 +170,8 @@
 
 #ifdef __GNUC__
 #define inline __inline__
+/* Define to 1 if you have the <stddef.h> header file. */
+#define HAVE_STDDEF_H 1
 #endif
 
 /* Define if on MINIX.  */
@@ -274,9 +277,7 @@
 #define HAVE_LOCALE_H 1
 
 /* Define to 1 if you have the `snprintf' function. */
-#if defined (_MSC_VER)
-# define HAVE_SNPRINTF 1
-#endif
+#define HAVE_SNPRINTF 1
 
 /* Define if you have the strcasecmp function.  */
 #define HAVE_STRCASECMP 1

--- pc/Makefile.tst~0   2007-05-17 01:12:36.000000000 +0300
+++ pc/Makefile.tst     2007-06-01 23:11:09.312500000 +0300
@@ -181,11 +181,11 @@
 inet:  inetmesg $(INET_TESTS)
 
 msg::
-       @echo ''
-       @echo 'Any output from "cmp" is bad news, although some differences'
-       @echo 'in floating point values are probably benign -- in particular,'
-       @echo 'some systems may omit a leading zero and the floating point'
-       @echo 'precision may lead to slightly different output in a few cases.'
+       @echo ""
+       @echo "Any output from $(CMP) is bad news, although some differences"
+       @echo "in floating point values are probably benign -- in particular,"
+       @echo "some systems may omit a leading zero and the floating point"
+       @echo "precision may lead to slightly different output in a few cases."
 
 printlang::
        @$(AWK) -f $(srcdir)/printlang.awk
@@ -294,7 +294,7 @@
 
 nonl::
        @echo $@
-       @-AWKPATH=$(srcdir) $(AWK) --lint -f nonl.awk /dev/null >_$@ 2>&1
+       @-AWKPATH=$(srcdir) $(AWK) --lint -f nonl.awk NUL >_$@ 2>&1
        @-$(CMP) $(srcdir)/nonl.ok _$@ && rm -f _$@
 
 strftime::
@@ -316,6 +316,7 @@
 
 devfd::
        @echo $@
+       @echo Expect devfd to fail in MinGW
        @$(AWK) 1 /dev/fd/4 /dev/fd/5 4<$(srcdir)/devfd.in4 
5<$(srcdir)/devfd.in5 >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
        @-$(CMP) $(srcdir)/address@hidden _$@ && rm -f _$@
 
@@ -344,7 +345,7 @@
 # command so that pid.sh is fork'ed as a child before being exec'ed.
 pid::
        @echo pid
-       @echo Expect pid to fail with DJGPP.
+       @echo Expect pid to fail with DJGPP and MinGW.
        @AWKPATH=$(srcdir) AWK=$(AWKPROG) $(SHELL) $(srcdir)/pid.sh $$$$ > 
_`basename address@hidden ; :
        @-$(CMP) $(srcdir)/pid.ok _`basename address@hidden && rm -f _`basename 
address@hidden
 
@@ -361,12 +362,12 @@
        @echo A B C D E | tr -d '\12\15' | $(AWK) '{ print $$NF }' - 
$(srcdir)/nors.in > _$@
        @-$(CMP) $(srcdir)/nors.ok _$@ && rm -f _$@
 
-#fmtspcl.ok: fmtspcl.tok Makefile
-fmtspcl.ok: fmtspcl.tok Makefile.tst
+fmtspcl.ok: fmtspcl.tok Makefile
        @$(AWK) -v "sd=$(srcdir)" 'BEGIN {pnan = sprintf("%g",sqrt(-1)); nnan = 
sprintf("%g",-sqrt(-1)); pinf = sprintf("%g",-log(0)); ninf = 
sprintf("%g",log(0))} {sub(/positive_nan/,pnan); sub(/negative_nan/,nnan); 
sub(/positive_infinity/,pinf); sub(/negative_infinity/,ninf); 
sub(/fmtspcl/,(sd"/fmtspcl")); print}' < $(srcdir)/fmtspcl.tok > $@ 2>/dev/null
 
 fmtspcl: fmtspcl.ok
        @echo fmtspcl
+       @echo Expect $@ to fail with MinGW
        @$(AWK) -f $(srcdir)/fmtspcl.awk  --lint >_$@ 2>&1 || echo EXIT CODE: 
$$? >>_$@
        @-$(CMP) address@hidden _$@ && rm -f _$@
 
@@ -383,6 +384,7 @@
 
 pipeio2::
        @echo $@
+       @echo Expect $@ to produce insignificant whitespace differences
        @$(AWK) -v SRCDIR=$(srcdir) -f $(srcdir)/pipeio2.awk >_$@
        @-$(CMP) $(srcdir)/pipeio2.ok _$@ && rm -f _$@
 
@@ -545,8 +547,9 @@
 
 rsstart3::
        @echo $@
-       @head $(srcdir)/rsstart1.in | $(AWK) -f $(srcdir)/rsstart2.awk >_$@
-       @-$(CMP) $(srcdir)/address@hidden _$@ && rm -f _$@
+       @head $(srcdir)/rsstart1.in > rsstart3.in
+       $(AWK) -f $(srcdir)/rsstart2.awk < rsstart3.in >_$@
+       @-$(CMP) $(srcdir)/address@hidden _$@ && rm -f _$@ rsstart3.in
 
 nondec2::
        @echo $@
@@ -575,6 +578,7 @@
 
 devfd1::
        @echo $@
+       @echo Expect devfd1 to fail in MinGW
        @$(AWK) -f $(srcdir)/address@hidden 4< $(srcdir)/devfd.in1 5< 
$(srcdir)/devfd.in2 >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
        @-$(CMP) $(srcdir)/address@hidden _$@ && rm -f _$@
 
@@ -794,7 +798,7 @@
 
 exitval2:
        @echo exitval2
-       @AWKPATH=$(srcdir) $(AWK) -f address@hidden  >_$@ 2>&1 || echo EXIT 
CODE: $$? >>_$@
+       @AWKPATH=$(srcdir) $(AWK) -f address@hidden  >_$@ 2>&1 || echo EXIT 
CODE: $$? >>_$@
        @-$(CMP) $(srcdir)/address@hidden _$@ && rm -f _$@
 
 fldchg:
@@ -809,7 +813,8 @@
 
 fmttest:
        @echo fmttest
-       @AWKPATH=$(srcdir) $(AWK) -f address@hidden  >_$@ 2>&1 || echo EXIT 
CODE: $$? >>_$@
+       @echo Expect $@ to prodiuce insignificant formatting differences
+       @AWKPATH=$(srcdir) $(AWK) -f address@hidden | sed -e 
"s/\([0-9]e[-+]\)0\([0-9]\)/\1\2/g" >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
        @-$(CMP) $(srcdir)/address@hidden _$@ && rm -f _$@
 
 fnamedat:
@@ -944,7 +949,7 @@
 
 hsprint:
        @echo hsprint
-       @echo Expect hsprint to produce insignificant differences
+       @echo Expect hsprint to produce insignificant formatting differences
        @AWKPATH=$(srcdir) $(AWK) -f address@hidden | sed -e 
"s/\([0-9]e[-+]\)0\([0-9]\)/\1\2/g" -e "s/| 1/|  1/" >_$@ 2>&1 || echo EXIT 
CODE: $$? >>_$@
 #      @AWKPATH=$(srcdir) $(AWK) -f address@hidden  >_$@ 2>&1 || echo EXIT 
CODE: $$? >>_$@
        @-$(CMP) $(srcdir)/address@hidden _$@ && rm -f _$@
@@ -1277,11 +1282,13 @@
 
 rstest4:
        @echo rstest4
+       @echo Expect $@ to fail on DOS/Windows
        @AWKPATH=$(srcdir) $(AWK) -f address@hidden  >_$@ 2>&1 || echo EXIT 
CODE: $$? >>_$@
        @-$(CMP) $(srcdir)/address@hidden _$@ && rm -f _$@
 
 rstest5:
        @echo rstest5
+       @echo Expect $@ to fail on DOS/Windows
        @AWKPATH=$(srcdir) $(AWK) -f address@hidden  >_$@ 2>&1 || echo EXIT 
CODE: $$? >>_$@
        @-$(CMP) $(srcdir)/address@hidden _$@ && rm -f _$@
 
@@ -1433,6 +1440,7 @@
 
 getlnhd:
        @echo getlnhd
+       @echo Expect getlnhd to fail if pipe does not use a Unixy shell
        @AWKPATH=$(srcdir) $(AWK) -f address@hidden  >_$@ 2>&1 || echo EXIT 
CODE: $$? >>_$@
        @-$(CMP) $(srcdir)/address@hidden _$@ && rm -f _$@
 
@@ -1453,7 +1461,7 @@
 
 clos1way:
        @echo clos1way
-       @echo Expect clos1way to fail with DJGPP.
+       @echo Expect clos1way to fail with DJGPP and MinGW.
        @AWKPATH=$(srcdir) $(AWK) -f address@hidden  >_$@ 2>&1 || echo EXIT 
CODE: $$? >>_$@
        @-$(CMP) $(srcdir)/address@hidden _$@ && rm -f _$@
 
@@ -1564,7 +1572,7 @@
 
 posix:
        @echo posix
-       @AWKPATH=$(srcdir) $(AWK) -f address@hidden  < $(srcdir)/address@hidden 
>_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+       @AWKPATH=$(srcdir) $(AWK) -f address@hidden  < $(srcdir)/address@hidden 
| sed -e "s/e+000/e+00/" >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
        @-$(CMP) $(srcdir)/address@hidden _$@ && rm -f _$@
 
 procinfs:


2007-06-01  Eli Zaretskii  <address@hidden>

        * exitval2.w32: New file, a Windows version for exitval2.awk.


--- /dev/null   1970-01-01 02:00:00.000000000 +0200
+++ test/exitval2.w32   2007-01-13 14:16:38.984375000 +0200
@@ -0,0 +1,3 @@
+BEGIN { print "foo" | "sh -c \"read x ; echo $x ; exit 12\"" }
+# this should still exit 0, as pointed out by kenny mccormack in
+# comp.lang.awk on 2 feb 2005

--- test/Makefile.am~0  2007-05-16 01:04:29.000000000 +0300
+++ test/Makefile.am    2007-06-01 23:24:28.109375000 +0300
@@ -157,6 +157,7 @@
        exitval1.awk \
        exitval1.ok \
        exitval2.awk \
+       exitval2.w32 \
        exitval2.ok \
        fflush.ok \
        fflush.sh \




reply via email to

[Prev in Thread] Current Thread [Next in Thread]