Next: Generic Headers, Previous: Header Portability, Up: Header Files
These macros check for particular system header files—whether they exist, and in some cases whether they declare certain symbols.
Check for the following header files. For the first one that is found and defines `DIR', define the listed C preprocessor macro:
dirent.h HAVE_DIRENT_Hsys/ndir.h HAVE_SYS_NDIR_Hsys/dir.h HAVE_SYS_DIR_Hndir.h HAVE_NDIR_HThe directory-library declarations in your source code should look something like the following:
#if HAVE_DIRENT_H # include <dirent.h> # define NAMLEN(dirent) strlen((dirent)->d_name) #else # define dirent direct # define NAMLEN(dirent) (dirent)->d_namlen # if HAVE_SYS_NDIR_H # include <sys/ndir.h> # endif # if HAVE_SYS_DIR_H # include <sys/dir.h> # endif # if HAVE_NDIR_H # include <ndir.h> # endif #endifUsing the above declarations, the program would declare variables to be of type
struct dirent, notstruct direct, and would access the length of a directory entry name by passing a pointer to astruct direntto theNAMLENmacro.This macro also checks for the SCO Xenix dir and x libraries.
If sys/types.h does not define
major,minor, andmakedev, but sys/mkdev.h does, defineMAJOR_IN_MKDEV; otherwise, if sys/sysmacros.h does, defineMAJOR_IN_SYSMACROS.
If the macros
S_ISDIR,S_ISREG, etc. defined in sys/stat.h do not work properly (returning false positives), defineSTAT_MACROS_BROKEN. This is the case on Tektronix UTekV, Amdahl UTS and Motorola System V/88.
If stdbool.h exists and is conformant to C99, define
HAVE_STDBOOL_Hto 1; if the type_Boolis defined, defineHAVE__BOOLto 1. To fulfill the C99 requirements, your system.h should contain the following code:#if HAVE_STDBOOL_H # include <stdbool.h> #else # if ! HAVE__BOOL # ifdef __cplusplus typedef bool _Bool; # else typedef unsigned char _Bool; # endif # endif # define bool _Bool # define false 0 # define true 1 # define __bool_true_false_are_defined 1 #endif
Define
STDC_HEADERSif the system has ANSI C header files. Specifically, this macro checks for stdlib.h, stdarg.h, string.h, and float.h; if the system has those, it probably has the rest of the ANSI C header files. This macro also checks whether string.h declaresmemchr(and thus presumably the othermemfunctions), whether stdlib.h declarefree(and thus presumablymallocand other related functions), and whether the ctype.h macros work on characters with the high bit set, as ANSI C requires.Use
STDC_HEADERSinstead of__STDC__to determine whether the system has ANSI-compliant header files (and probably C library functions) because many systems that have GCC do not have ANSI C header files.On systems without ANSI C headers, there is so much variation that it is probably easier to declare the functions you use than to figure out exactly what the system header files declare. Some systems contain a mix of functions from ANSI and BSD; some are mostly ANSI but lack `memmove'; some define the BSD functions as macros in string.h or strings.h; some have only the BSD functions but string.h; some declare the memory functions in memory.h, some in string.h; etc. It is probably sufficient to check for one string function and one memory function; if the library has the ANSI versions of those then it probably has most of the others. If you put the following in configure.ac:
AC_HEADER_STDC AC_CHECK_FUNCS(strchr memcpy)then, in your code, you can use declarations like this:
#if STDC_HEADERS # include <string.h> #else # if !HAVE_STRCHR # define strchr index # define strrchr rindex # endif char *strchr (), *strrchr (); # if !HAVE_MEMCPY # define memcpy(d, s, n) bcopy ((s), (d), (n)) # define memmove(d, s, n) bcopy ((s), (d), (n)) # endif #endifIf you use a function like
memchr,memset,strtok, orstrspn, which have no BSD equivalent, then macros won't suffice; you must provide an implementation of each function. An easy way to incorporate your implementations only when needed (since the ones in system C libraries may be hand optimized) is to, takingmemchrfor example, put it in memchr.c and use `AC_REPLACE_FUNCS(memchr)'.
If sys/wait.h exists and is compatible with POSIX, define
HAVE_SYS_WAIT_H. Incompatibility can occur if sys/wait.h does not exist, or if it uses the old BSDunion waitinstead ofintto store a status value. If sys/wait.h is not POSIX compatible, then instead of including it, define the POSIX macros with their usual interpretations. Here is an example:#include <sys/types.h> #if HAVE_SYS_WAIT_H # include <sys/wait.h> #endif #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif
_POSIX_VERSION is defined when unistd.h is included on
POSIX systems. If there is no unistd.h, it is definitely
not a POSIX system. However, some non-POSIX systems do
have unistd.h.
The way to check if the system supports POSIX is:
#if HAVE_UNISTD_H
# include <sys/types.h>
# include <unistd.h>
#endif
#ifdef _POSIX_VERSION
/* Code for POSIX systems. */
#endif
If a program may include both time.h and sys/time.h, define
TIME_WITH_SYS_TIME. On some older systems, sys/time.h includes time.h, but time.h is not protected against multiple inclusion, so programs should not explicitly include both files. This macro is useful in programs that use, for example,struct timevalas well asstruct tm. It is best used in conjunction withHAVE_SYS_TIME_H, which can be checked for usingAC_CHECK_HEADERS(sys/time.h).#if TIME_WITH_SYS_TIME # include <sys/time.h> # include <time.h> #else # if HAVE_SYS_TIME_H # include <sys/time.h> # else # include <time.h> # endif #endif