Thread: Autoconf'd test for int64

Autoconf'd test for int64

From
Tom Lane
Date:
Attached is a patch that uses autoconf to determine whether there is
a working 64-bit-int type available.

In playing around with it on my machine, I found that gcc provides
perfectly fine support for "long long" arithmetic ... but sprintf()
and sscanf(), which are system-supplied, don't work :-(.  So the
autoconf test program does a cursory test on them too.

If we find that a lot of systems are like this, it might be worth
the trouble to implement binary<->ASCII conversion of int64 ourselves
rather than relying on sprintf/sscanf to handle the data type.

            regards, tom lane


*** src/configure.in.orig    Sat Aug 15 11:52:03 1998
--- src/configure.in    Sun Aug 16 16:41:24 1998
***************
*** 522,528 ****
  #endif
  main() { double d = DBL_MIN; if (d != DBL_MIN) exit(-1); else exit(0); }],
      AC_MSG_RESULT(yes),
!     [AC_MSG_RESULT(no) AC_DEFINE(HAVE_DBL_MIN_PROBLEM)])

  dnl Checks for library functions.
  AC_PROG_GCC_TRADITIONAL
--- 522,604 ----
  #endif
  main() { double d = DBL_MIN; if (d != DBL_MIN) exit(-1); else exit(0); }],
      AC_MSG_RESULT(yes),
!     [AC_MSG_RESULT(no) AC_DEFINE(HAVE_DBL_MIN_PROBLEM)],
!     AC_MSG_RESULT(assuming ok on target machine))
!
! dnl Check to see if we have a working 64-bit integer type.
! AC_MSG_CHECKING(whether 'long int' is 64 bits)
! AC_TRY_RUN([#include <stdio.h>
! typedef long int int64;
! #define INT64_FORMAT "%ld"
!
! int64 a = 20000001;
! int64 b = 40000005;
!
! int does_int64_work()
! {
!   int64 c,d,e;
!   char buf[100];
!
!   if (sizeof(int64) != 8)
!     return 0;            /* doesn't look like the right size */
!
!   /* we do perfunctory checks on multiply, divide, sprintf, sscanf */
!   c = a * b;
!   sprintf(buf, INT64_FORMAT, c);
!   if (strcmp(buf, "800000140000005") != 0)
!     return 0;            /* either multiply or sprintf is busted */
!   if (sscanf(buf, INT64_FORMAT, &d) != 1)
!     return 0;
!   if (d != c)
!     return 0;
!   e = d / b;
!   if (e != a)
!     return 0;
!   return 1;
! }
! main() {
!   exit(! does_int64_work());
! }],
!     [AC_MSG_RESULT(yes) AC_DEFINE(HAVE_LONG_INT_64)],
!     AC_MSG_RESULT(no),
!     AC_MSG_RESULT(assuming not on target machine))
!
! AC_MSG_CHECKING(whether 'long long int' is 64 bits)
! AC_TRY_RUN([#include <stdio.h>
! typedef long long int int64;
! #define INT64_FORMAT "%Ld"
!
! int64 a = 20000001;
! int64 b = 40000005;
!
! int does_int64_work()
! {
!   int64 c,d,e;
!   char buf[100];
!
!   if (sizeof(int64) != 8)
!     return 0;            /* doesn't look like the right size */
!
!   /* we do perfunctory checks on multiply, divide, sprintf, sscanf */
!   c = a * b;
!   sprintf(buf, INT64_FORMAT, c);
!   if (strcmp(buf, "800000140000005") != 0)
!     return 0;            /* either multiply or sprintf is busted */
!   if (sscanf(buf, INT64_FORMAT, &d) != 1)
!     return 0;
!   if (d != c)
!     return 0;
!   e = d / b;
!   if (e != a)
!     return 0;
!   return 1;
! }
! main() {
!   exit(! does_int64_work());
! }],
!     [AC_MSG_RESULT(yes) AC_DEFINE(HAVE_LONG_LONG_INT_64)],
!     AC_MSG_RESULT(no),
!     AC_MSG_RESULT(assuming not on target machine))

  dnl Checks for library functions.
  AC_PROG_GCC_TRADITIONAL
*** src/include/config.h.in.orig    Sat Aug 15 11:54:54 1998
--- src/include/config.h.in    Sun Aug 16 16:33:22 1998
***************
*** 219,224 ****
--- 219,230 ----
  /* Set to 1 if your DBL_MIN is problematic */
  #undef HAVE_DBL_MIN_PROBLEM

+ /* Set to 1 if type "long int" works and is 64 bits */
+ #undef HAVE_LONG_INT_64
+
+ /* Set to 1 if type "long long int" works and is 64 bits */
+ #undef HAVE_LONG_LONG_INT_64
+
  /*
   * Code below this point should not require changes
   */
*** src/include/utils/int8.h.orig    Wed Jul  8 10:10:30 1998
--- src/include/utils/int8.h    Sun Aug 16 16:37:51 1998
***************
*** 23,51 ****
  #ifndef INT8_H
  #define INT8_H

! #if defined(__alpha) || defined(PPC)
  typedef long int int64;
-
  #define INT64_FORMAT "%ld"
!
! #elif defined(__GNUC__) && defined(i386)
  typedef long long int int64;
-
  #define INT64_FORMAT "%Ld"
-
  #else
  typedef long int int64;
-
  #define INT64_FORMAT "%ld"
  #endif
-
-
- /*
- #if sizeof(int64) == 8
- #define HAVE_64BIT_INTS 1
  #endif
- */
-

  extern int64 *int8in(char *str);
  extern char *int8out(int64 * val);
--- 23,44 ----
  #ifndef INT8_H
  #define INT8_H

! #ifdef HAVE_LONG_INT_64
! /* Plain "long int" fits, use it */
  typedef long int int64;
  #define INT64_FORMAT "%ld"
! #else
! #ifdef HAVE_LONG_LONG_INT_64
! /* We have working support for "long long int", use that */
  typedef long long int int64;
  #define INT64_FORMAT "%Ld"
  #else
+ /* Won't actually work, but fall back to long int so that int8.c compiles */
  typedef long int int64;
  #define INT64_FORMAT "%ld"
+ #define INT64_IS_BUSTED
  #endif
  #endif

  extern int64 *int8in(char *str);
  extern char *int8out(int64 * val);

Re: [HACKERS] Autoconf'd test for int64

From
"Thomas G. Lockhart"
Date:
> Attached is a patch that uses autoconf to determine whether there is
> a working 64-bit-int type available.

Using autoconf for things sounds great. I've been relying on scrappy for
that stuff, and find it a mystery myself. Marc or someone, would you be
willing to write a few sentences on how to make incremental changes to
the Postgres autoconfig system? I'll put it into the Developer's Guide,
and could make a stab at using it elsewhere.

> In playing around with it on my machine, I found that gcc provides
> perfectly fine support for "long long" arithmetic ... but sprintf()
> and sscanf(), which are system-supplied, don't work :-(.  So the
> autoconf test program does a cursory test on them too.

Sorry to hear the formatting routines are broken. sprintf() and sscanf()
are HP supplied? Doesn't gcc have its own library also??

> If we find that a lot of systems are like this, it might be worth
> the trouble to implement binary<->ASCII conversion of int64 ourselves
> rather than relying on sprintf/sscanf to handle the data type.

Yuck. Whaddya mean "we"; *my* system works fine :)

                       - Tom

Re: [HACKERS] Autoconf'd test for int64

From
The Hermit Hacker
Date:
On Sun, 16 Aug 1998, Thomas G. Lockhart wrote:

> > Attached is a patch that uses autoconf to determine whether there is
> > a working 64-bit-int type available.
>
> Using autoconf for things sounds great. I've been relying on scrappy for
> that stuff, and find it a mystery myself. Marc or someone, would you be
> willing to write a few sentences on how to make incremental changes to
> the Postgres autoconfig system? I'll put it into the Developer's Guide,
> and could make a stab at using it elsewhere.

    Sorry to say, but from my perspective as well its "funky
magic"...I cheat alot by looking at autoconf from other packages to try
and recreate what I want to do, as well as spend alot of time in the info
pages...

    I don't think this is something that can be easily explained in "a
few sentences" :(

Marc G. Fournier
Systems Administrator @ hub.org
primary: scrappy@hub.org           secondary: scrappy@{freebsd|postgresql}.org


Re: [HACKERS] Autoconf'd test for int64

From
"Thomas G. Lockhart"
Date:
> Sorry to say, but from my perspective as well its "funky
> magic"...
> I don't think this is something that can be easily explained in "a
> few sentences" :(

Well, no harm in asking :)

                    - Tom^H^H^HThomas

Quick cut at an autoconf tutorial

From
Tom Lane
Date:
"Thomas G. Lockhart" <lockhart@alumni.caltech.edu> writes:
> Using autoconf for things sounds great. I've been relying on scrappy for
> that stuff, and find it a mystery myself. Marc or someone, would you be
> willing to write a few sentences on how to make incremental changes to
> the Postgres autoconfig system?

Well, there's really no substitute for reading the autoconf manual ;-)

But basically the idea is that you don't want to have your code
#ifdef'ing on system ID symbols except in very specific circumstances.
Usually what you really want to know is "does feature X exist here?",
and the right way to handle that is to have a direct test for feature X.
If you take that approach your code is a lot more likely to work
out-of-the-box on a new system.  Not to mention the fact that some systems
like HPUX and Linux come in a lot of flavors --- testing the system ID
symbols isn't good enough there anyway.

What autoconf does is provide a system whereby you can make exactly the
tests you need during configuration, and have the results available when
your code is being compiled.  The results are usually expressed in the
form of configuration symbols that get defined (or not) in config.h.
You can also have autoconf apply system-specific edits to other places
like makefiles, but config.h is most often the file to tweak.

To take the particular example at hand, I had to go through the
following steps:

1. Ask myself what we really wanted to know.  What we wanted to know,
it seemed like, was whether either "long int" or "long long int" could
be used as a 64-bit integer type.  So I invented some configuration
symbol names that would carry this info from autoconf to the
compile-time tests needed in int8.h:

/* Set to 1 if type "long int" works and is 64 bits */
#undef HAVE_LONG_INT_64

/* Set to 1 if type "long long int" works and is 64 bits */
#undef HAVE_LONG_LONG_INT_64

2. I put the above lines into src/include/config.h.in, which is the
master file that autoconf will edit during configuration to create the
localized version src/include/config.h (.in is the usual convention for
indicating an autoconf master file).  Autoconf provides automatic
support for changing "#undef X" into "#define X something" when
appropriate, so we start with the "#undef" format.

3. Then I needed to figure out how to test these conditions.  Basically
what autoconf can do is to (try to) compile and run little test
programs; if it succeeds then it figures that particular feature is
there.  So I wrote a little program that checks sizeof(long long int)
(to make sure it's 8) and also tries to do some simple arithmetic to
make sure the answers come out right.  You can see the details in the
patch, but the important point is that if long long isn't OK, the
program will either fail to compile at all, or will exit with a nonzero
return status (which is program failure by Unix convention).  Autoconf
will only believe the test succeeded if the program compiles and exits
with zero status when run.

4. After I'd tested the test program to my satisfaction, I wrapped it
into this autoconf code:

AC_MSG_CHECKING(whether 'long long int' is 64 bits)
AC_TRY_RUN([
... test program code here ...
],
    [AC_MSG_RESULT(yes) AC_DEFINE(HAVE_LONG_LONG_INT_64)],
    AC_MSG_RESULT(no),
    AC_MSG_RESULT(assuming not on target machine))

AC_TRY_RUN is a macro that's basically like an if-then-else structure.
If the test program (whose text is the first argument) succeeds, the
second argument is executed; if the test fails, the third argument
is executed; and if autoconf knows it is cross-compiling for another
machine and therefore can't run a test program at all, it doesn't try
but just executes the fourth argument.  Usually that last alternative
should be the most conservative assumption.

The AC_MSG macros are just user interface aids (they generate all that
junk that the configure script prints as it runs).  The important aspect
is the AC_DEFINE() macro --- if that gets executed, it cues Autoconf
to convert "#undef HAVE_LONG_LONG_INT_64" to
"#define HAVE_LONG_LONG_INT_64 1" later on when it's generating config.h
from config.h.in.  (I could give AC_DEFINE a second argument if I wanted
to define the symbol as some particular string instead of "1".)  In the
other cases, AC_DEFINE is not executed so that line of config.h.in will
be left unmodified.

The other thing to know to read this is that square brackets are m4's
quoting convention.

I made another copy that was exactly the same but it works on "long int"
and defines HAVE_LONG_INT_64 if it wins.

5. Then I ran autoconf to generate a configure shell script from the
configure.in source code, and I was done.

6. AC_TRY_RUN is the sledgehammer of Autoconf programming --- you only
need it if you need to verify some unusual detail of a system's run-time
behavior.  Most of the standard sorts of problems can be dealt with
using simpler Autoconf macros.  For example, if I had been satisfied
just to test whether the declaration "long long int" would compile, I
could've just done
     AC_TRY_COMPILE(, [ long long int x; ],
            [success action], [fail action])
which would compile the code but not try to run it.  There are even
simpler macros that handle most of the really common cases.  For
example, PostgreSQL's configure.in includes
    AC_CHECK_HEADERS(limits.h)
which tries to compile a program that says "#include <limits.h>",
and if it succeeds then it automatically defines HAVE_LIMITS_H.
(We still have to remember to put #undef HAVE_LIMITS_H into
config.h.in, however, or the AC_DEFINE would have no visible effect.)

BTW this last example should cue you that there are conventions for
choosing configuration symbol names in Autoconf --- a symbol that
indicates that <stdlib.h> exists should be called HAVE_STDLIB_H,
and not anything else; if you violate these conventions you risk
confusing autoconf experts, or even breaking some other part of
configuration.  (A while back we had a configuration bug because
HAVE_HISTORY was getting used for two different purposes: both to
indicate whether <history.h> exists and whether libhistory exists
to be linked with.  Following the convention prevents this error,
since HAVE_HISTORY_H refers to the include file and HAVE_LIBHISTORY
to the library.)

7. The configure script generated by Autoconf is a self-contained
shell script that will run on darn near any Unix platform.  But to generate
configure from configure.in, you need to have Autoconf itself installed,
and you also need GNU m4 because Autoconf is really just a script in
the m4 macro processing language.  You can find these at any GNU archive
site if you don't have 'em already.  Both are painless to install.

8. There's really no substitute for reading the autoconf manual ;-).
But maybe this will motivate you to go do that.

            regards, tom lane

Re: [HACKERS] Autoconf'd test for int64

From
Tom Lane
Date:
"Thomas G. Lockhart" <lockhart@alumni.caltech.edu> writes:
>> In playing around with it on my machine, I found that gcc provides
>> perfectly fine support for "long long" arithmetic ... but sprintf()
>> and sscanf(), which are system-supplied, don't work :-(.  So the
>> autoconf test program does a cursory test on them too.

> Sorry to hear the formatting routines are broken. sprintf() and sscanf()
> are HP supplied? Doesn't gcc have its own library also??

gcc supplies low-level routines that implement doubleword arithmetic,
but it doesn't attempt to supplant the local libc.

>> If we find that a lot of systems are like this, it might be worth
>> the trouble to implement binary<->ASCII conversion of int64 ourselves
>> rather than relying on sprintf/sscanf to handle the data type.

> Yuck. Whaddya mean "we"; *my* system works fine :)

I'm not eager to do it either --- I hope to have upgraded to HPUX 10
before I actually need to do anything with int8.  I was just throwing
that idea out in case someone else needed int8 bad enough to want to
make it happen.

            regards, tom lane

Re: [HACKERS] Autoconf'd test for int64

From
"Thomas G. Lockhart"
Date:
> I'm not eager to do it either --- I hope to have upgraded to HPUX 10
> before I actually need to do anything with int8.  I was just throwing
> that idea out in case someone else needed int8 bad enough to want to
> make it happen.

The fact that machines need to provide their own i/o means that those
relying on gcc for compiling but non-gnu i/o libraries aren't likely to
succeed on 32-bit machines without rolling your own :(

                        - Tom

Re: Quick cut at an autoconf tutorial

From
"Thomas G. Lockhart"
Date:
> 8. There's really no substitute for reading the autoconf manual ;-).
> But maybe this will motivate you to go do that.

Sure, didn't even know one existed. Don't know if it is shipped on my
machine, and don't know where to look for one.

Oh boy, maybe I'll get to use GNU info! Not. Is there a hardcopy or html
version somewhere? *sigh*

                    - Tom

Re: Quick cut at an autoconf tutorial

From
Tom Lane
Date:
"Thomas G. Lockhart" <lockhart@alumni.caltech.edu> writes:
>> 8. There's really no substitute for reading the autoconf manual ;-).

> Sure, didn't even know one existed. Don't know if it is shipped on my
> machine, and don't know where to look for one.
> Oh boy, maybe I'll get to use GNU info! Not. Is there a hardcopy or html
> version somewhere? *sigh*

Picky picky.  The manual comes with the autoconf distribution tarball.
The master copy is in GNU "texinfo" format, looks like.  I always use
the GNU-info-format version of it, which gets installed automatically
by autoconf's install script.  But this is convenient for me because
I use the One True Editor, Emacs ;-) ;-).  If you don't live in Emacs
then I agree info format is less than convenient.

It is possible to generate html or latex (hence PostScript, hence nice-
looking hardcopy) from texinfo sources.  (Basically texinfo is the same
idea as SGML but a few years before its time.)  I'm not an expert on
how to do either process, not having ever felt the need.  If you look
around the net you can certainly get the tools for this, and possibly
even find the autoconf manual already converted to a format you like.

Or you can just read the texinfo source file.  It's certainly no less
legible than sgml source.

            regards, tom lane

Re: [HACKERS] Re: Quick cut at an autoconf tutorial

From
The Hermit Hacker
Date:
On Sun, 16 Aug 1998, Tom Lane wrote:

> "Thomas G. Lockhart" <lockhart@alumni.caltech.edu> writes:
> >> 8. There's really no substitute for reading the autoconf manual ;-).
>
> > Sure, didn't even know one existed. Don't know if it is shipped on my
> > machine, and don't know where to look for one.
> > Oh boy, maybe I'll get to use GNU info! Not. Is there a hardcopy or html
> > version somewhere? *sigh*
>
> Picky picky.  The manual comes with the autoconf distribution tarball.
> The master copy is in GNU "texinfo" format, looks like.  I always use
> the GNU-info-format version of it, which gets installed automatically
> by autoconf's install script.  But this is convenient for me because
> I use the One True Editor, Emacs ;-) ;-).  If you don't live in Emacs
> then I agree info format is less than convenient.

    Actually, I just type 'info autoconf' on my machine(s) to read
it...I don't use emacs myself, and don't find that 'info' requires
fore-knowledge of it

Marc G. Fournier
Systems Administrator @ hub.org
primary: scrappy@hub.org           secondary: scrappy@{freebsd|postgresql}.org


Re: [HACKERS] Re: Quick cut at an autoconf tutorial

From
"Thomas G. Lockhart"
Date:
> Actually, I just type 'info autoconf' on my machine(s) to read
> it...I don't use emacs myself, and don't find that 'info' requires
> fore-knowledge of it

I'm info-impaired. Never used it enough to remember how to traverse it,
and never managed to find what I needed without just running through the
entire document.

I'd like to learn emacs (I've got a new project using lisp) but haven't
found it useful yet. 15 years of vi is tough to break. I suppose I
should buy a book for it...

                - Tom

Re: [HACKERS] Re: Quick cut at an autoconf tutorial

From
dg@informix.com (David Gould)
Date:
>
> "Thomas G. Lockhart" <lockhart@alumni.caltech.edu> writes:
> >> 8. There's really no substitute for reading the autoconf manual ;-).
>
> > Sure, didn't even know one existed. Don't know if it is shipped on my
> > machine, and don't know where to look for one.
> > Oh boy, maybe I'll get to use GNU info! Not. Is there a hardcopy or html
> > version somewhere? *sigh*
>
> Picky picky.  The manual comes with the autoconf distribution tarball.
> The master copy is in GNU "texinfo" format, looks like.  I always use
> the GNU-info-format version of it, which gets installed automatically
> by autoconf's install script.  But this is convenient for me because
> I use the One True Editor, Emacs ;-) ;-).  If you don't live in Emacs
> then I agree info format is less than convenient.

There is also 'tkinfo' which makes reading info files fairly painless.

-dg

David Gould            dg@illustra.com           510.628.3783 or 510.305.9468
Informix Software  (No, really)         300 Lakeside Drive  Oakland, CA 94612
 - If simplicity worked, the world would be overrun with insects. -

Re: [HACKERS] Autoconf'd test for int64

From
Bruce Momjian
Date:
Applied.  Autoconf run.

> Attached is a patch that uses autoconf to determine whether there is
> a working 64-bit-int type available.
>
> In playing around with it on my machine, I found that gcc provides
> perfectly fine support for "long long" arithmetic ... but sprintf()
> and sscanf(), which are system-supplied, don't work :-(.  So the
> autoconf test program does a cursory test on them too.
>
> If we find that a lot of systems are like this, it might be worth
> the trouble to implement binary<->ASCII conversion of int64 ourselves
> rather than relying on sprintf/sscanf to handle the data type.
>
>             regards, tom lane

--
Bruce Momjian                          |  830 Blythe Avenue
maillist@candle.pha.pa.us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)