Next: , Previous: Header Portability, Up: Header Files


5.6.2 特定のヘッダの調査

これらのマクロは,特定のシステムヘッダファイルを調査します — それらが 存在しているか,そして場合によっては,特定のシンボルを宣言しているかを調 査します.

— Macro: AC_HEADER_DIRENT

以下のヘッダファイルを調査します.最初に見つかった‘DIR’を定義してい るものに対して,リストアップされているCプリプロセッサマクロを定義します.

dirent.h HAVE_DIRENT_H
sys/ndir.h HAVE_SYS_NDIR_H
sys/dir.h HAVE_SYS_DIR_H
ndir.h HAVE_NDIR_H

ソースコード内のディレクトリライブラリの宣言は,以下のようにすべきでしょ う.

          #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
          #endif

上記の宣言を使用している場合,プログラムは型をstruct directではな くstruct direntとして変数を宣言し,struct direntへのポイン タを渡すことによって,NAMLENマクロまでのディレクトリエントリ名の 長さにアクセスします.

このマクロは,SCO Xenix dirxライブラリも調査します.

— Macro: AC_HEADER_MAJOR

sys/types.hmajorminor,そしてmakedevを定 義していないが,sys/mkdev.hが定義している場合, MAJOR_IN_MKDEVを定義します.それ以外の場合で, sys/sysmacros.hが定義している場合は,MAJOR_IN_SYSMACROS を 定義します.

— Macro: AC_HEADER_STAT

sys/stat.hで定義されているS_ISDIRS_ISREG等のマク ロが正確に動作しない(間違った正の値を返す)場合, STAT_MACROS_BROKEN を定義します.Tektronix UTekV,Amdahl UTS,そ してMotorola System V/88の場合がそうです.

— Macro: AC_HEADER_STDBOOL

stdbool.hが存在し,それがC99に準拠している場合, HAVE_STDBOOL_Hを1に定義します.型_Boolが定義されている場合, HAVE__BOOLを1に定義します.C99の要求を満たすため,system.h には以下のコードを含めるべきです.

     
     #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

— Macro: AC_HEADER_STDC

システムにANSI Cヘッダファイルが存在する場合, STDC_HEADERSを定義します.特にこのマクロは,stdlib.hstdarg.hstring.h,そしてfloat.hを調査し,システム にそれらが存在している場合は,おそらくANSI Cヘッダーファイルの 残りも存在します.同様に,このマクロはstring.hmemchrを宣 言(他のmem関数もおそらく存在)しているかどうか,stdlib.hfreeを宣言(mallocや他の関連する関数もおそらく存在)している かどうか,そして,ctype.hマクロが,ANSI Cが要求するハイ ビットセット文字でも動作するかどうかを調査します.

GCCがあるシステムの多くはANSI Cヘッダファイルが存在していない ので,システムにANSI対応のヘッダファイル(そして,おそらくC ラ イブラリ関数) が存在していることを決定するために,__STDC__の代わ りにSTDC_HEADERSを使用してください.

ANSI Cヘッダが無いシステムには多くの変種が存在していて,そこで は,システムヘッダファイルが宣言しているものを正確に理解するより,使用す る関数を宣言する方がより容易でしょう.ANSIBSDの関 数が混在しているシステムもあります.ほとんどANSIだが ‘memmove’が無いものもあります.BSD関数がstring.hstrings.h でマクロで定義されているものもあります.BSD関 数しか持っていないが string.hが存在するものもあります.メモリ関数 がmemory.hで定義されていて,string.hでも定義されているもの もあります.等々いろいろなシステムがあります.一つの文字列関数と一つのメ モリ関数を調査すれば恐らく十分です.ライブラリにANSIバージョン のものが存在する場合,他のものもほとんど存在します.以下を configure.acに書き込む場合を考えます.

          AC_HEADER_STDC
          AC_CHECK_FUNCS(strchr memcpy)

コード内に,以下のような宣言を使用することが可能です.

          #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
          #endif

BSDとは異なるmemchrmemsetstrtok,また は strspnの様な関数を使用する場合,マクロは不十分でしょう.それぞ れの関数を実装する必要があります.(システムのCライブラリのものが,手動で 最適化されているかもしれないので)必要なときだけ実装を組み込む簡単な方法 として,例えばmemchrを使用する場合は,それをmemchr.cに書き 込み,‘AC_REPLACE_FUNCS(memchr)’を使用することです.

— Macro: AC_HEADER_SYS_WAIT

sys/wait.hが存在して,POSIXと互換性がある場合, HAVE_SYS_WAIT_Hを定義します.非互換性は,sys/wait.hが存在 しない場合や,ステータスの値を保存するため,intの代わりに古い BSDunion wait使用する場合に生じます. sys/wait.hPOSIXと互換性がない場合,それをインクルード する代わりに,それらの通常の解釈を用いてPOSIXのマクロを定義し てください.例えば以下のようにします.

          #include <sys/types.h>
          #if HAVE_SYS_WAIT_H
          # include <sys/wait.h>
          #endif
          #ifndef WEXITSTATUS
          # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
          #endif
          #ifndef WIFEXITED
          # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
          #endif

unistd.hPOSIXシステムに含まれている場合, _POSIX_VERSIONが定義されます.unistd.hが無い場合,明らかに POSIXシステムではありません.しかし,unistd.hを持つ POSIXではないシステムもあります.

システムがPOSIXをサポートしているかどうか調査する方法は以下の ようにします.

     #if HAVE_UNISTD_H
     # include <sys/types.h>
     # include <unistd.h>
     #endif
     
     #ifdef _POSIX_VERSION
     /* Code for POSIX systems.  */
     #endif
— Macro: AC_HEADER_TIME

プログラムが,time.hsys/time.hの両方をインクルードする可 能性がある場合,TIME_WITH_SYS_TIMEを定義します.古いシステムでは, sys/time.htime.hをインクルードするものもありますが, time.hは複数回のインクルードに対して保護されていないので,プログ ラムで明示的に両方のファイルをインクルードすべきではありません.このマク ロは,例えば,struct tmと同様,struct timevalを使用するプ ログラムで役に立ちます. AC_CHECK_HEADERS(sys/time.h) を使用して いることを調査可能にするHAVE_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
— Macro: AC_HEADER_TIOCGWINSZ

TIOCGWINSZの使用が<sys/ioctl.h>を要求する場合, GWINSZ_IN_SYS_IOCTLを定義します.それ以外では,TIOCGWINSZ<termios.h>で見つかるはずです.

以下のようにして使用します.

          #if HAVE_TERMIOS_H
          # include <termios.h>
          #endif
          
          #if GWINSZ_IN_SYS_IOCTL
          # include <sys/ioctl.h>
          #endif