man iffe (Commandes) - C compilation environment feature probe
NAME
iffe - C compilation environment feature probe
SYNOPSIS
iffe [-] op[,op...] [arg[,arg...]] [prereq ...] [: op ...]
DESCRIPTION
iffe is a command interpreter that probes the C compilation environment for features. A feature is any file, option or symbol that controls or is controlled by the C compiler. iffe tests features by generating and compiling C programs and observing the behavior of the C compiler.
iffe commands are line oriented. Command lines may be iffe command arguments with the argument : as the line delimiter or they may be newline terminated lines from input files. The command syntax is op[,op...] [arg[,arg...]] [prereq ...] [block{ ... }end ...] ops and args may be combined, separated by commas, to perform a set of operations on a set of arguments. prerequisites are compiler options (-D* -L*) and library (-l*) and header (*.h) references to be used when applying the feature tests. A - arg by itself groups prerequisites into separate feature tests. The prerequisites before the first - be passed to the compiler for all feature tests; the groups after the first - will be attempted in left-to-right order, and the first group that provides a successful feature test result terminates the test. blocks are multi-line code blocks that override or augment the default code provided by iffe. User supplied code blocks should be compatible with the K&R, ANSI, and C++ C language dialects. All generated code contains the following at the top to hide dialect differences: #if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus) #define _STD_ 1 #define _ARG_(x) x #define _VOID_ void #else #define _STD_ 0 #define _ARG_(x) () #define _VOID_ char #endif #if defined(__cplusplus) #define _BEGIN_EXTERNS_ extern "C" { #define _END_EXTERNS_ } #else #define _BEGIN_EXTERNS_ #define _END_EXTERNS_ #endif #define _NIL_(x) ((x)0) Also included at the top are macro defintions for tests already performed.
The output file is a C language header that contains macro defintions, comments, and other text corresponding to the feature test commands. #ifndef _def_name_directory ... #endif guards the header from multiple where name is determined by either the input file name from the command, if any, or the first op of the first command, and directory is basname component of either the command, if any, or the current working directory. The output file name is determined in this order:
- - option
- Output is stdout.
- set out file
- Output is file.
- run [directory/]base[.suffix]
- Output is FEATURE/base.
Generated iffe headers are often referenced in C source as: #include "FEATURE/file" The nmake(1) base rules contain metarules for generating from where suffix may be omitted, or (see the feature test op below). Because prerequisites are automatically detected, nmake(1) ensures that all prerequisite iffe headers are generated before compilation. Note that the directories are deliberately named and to keep case-insensitive file systems happy.
The feature test ops are:
- # comment
- Comment line.
- cmd name
- Defines _cmd_name if name is an executable in one of the standard system directories (/bin, /etc, /usr/bin, /usr/etc, /usr/ucb). _directory_name is defined for directory in which name is found (with translated to
- dat name
- Defines _dat_name if name is a data symbol in the C library.
- def name
- Equivalent to cmd,dat,hdr,key,lib,mth,sys,typ name.
- hdr name
- Defines _hdr_name if the header <name.h> exists.
- iff name
- The generated header #ifndef-#endif macro guard is _name_H.
- key name
- Defines _key_name if name is a reserved word (keyword).
- lcl name
- Generates a statement for the local version of either the header <name.h> if it exists or the header <sys/name.h> if it exists. Defines _lcl_name on success.
- lib name
- Defines _lib_name if name is an external symbol in the C library.
- mac name
- Defines _mac_name if name is a macro.
- mem struct.member
- Defines _mem_member_struct if member is a member of the structure struct.
- mth name
- Defines _mth_name if name is an external symbol in the math library.
- nop name
- No-op.
- npt name
- Defines _npt_name if the name function requires a prototype.
- one header ...
- Generates a statement for the first header found in the header list.
- run file
- Runs the tests in file based on file's suffix:
- .c
- file is compiled and executed and the output is copied to the iffe output file.
- .sh
- file is executed as a shell script and the output is copied to the iffe output file.
- no suffix
- .iff
- .iffe
- file contains iffe commands.
- set option value
- Sets option values. The options are
- cc C-compiler-name [ C-compiler-flags ]
- Sets the C compiler name and flags to be used in the feature tests.
- debug level
- Sets the debug level. Level 0 inhibits most error messages, level 1 shows compiler messages, and level 2 traces internal iffe actions.
- in file
- Sets the input file name to file. file must contain iffe commands.
- out file
- Sets the output file name to file.
- prototyped
- Emits at the top of the output file. See proto(1).
- pragma pragma-text
- Emits #pragma pragma-text at the top of the output file.
- shell name
- Sets the internal shell name to name. Used for debugging Bourne shell compatibility (otherwise iffe uses ksh constructs if available).
- static [ flags ]
- Sets the C compiler flags that force static linking. If not set then iffe probes the compiler to determine the flags. iffe must use static linking (no shared libraries) because on some systems missing library symbols are only detected when referenced at runtime.
- sym name
- Defines _ary_name if name is an array, _fun_name if name is a function pointer, _ptr_name if name is a pointer, or _reg_name if name is a scalar. In most cases name is part of a macro expansion.
- sys name
- Defines _sys_name if the header <sys/name.h> exists.
- tst name
- A user defined test on name. A source block must be supplied. Defines _name on success.
- typ name
- Defines _typ_name if name is a type in any of Any characters in name are translated to space before testing and are translated to in the output macro.
- val name
- Code block names may be prefixed by to invert the test sense. The block names are:
- The block is copied to the output file.
- The block is compiled
- The block is compiled, linked, and executed. exit status means success.
- If the test fails then the fail block text is copied to the output file.
- The block is compiled and linked
- The block is preprocessed and text bracketed by is copied to the output file.
- [NOT YET]
- If the test succeeds then the note block is copied to the output as a comment.
- The block is compiled, linked, and executed, and the output is copied to the output file.
- If the test succeeds then the pass block text is copied to the output file.
- The block is preprocessed
- [NOT YET]
- The block is executed as a shell script and the output is copied to the output file.
EXAMPLES
The first examples show iffe command line tests. The command line is preceded by $ and the output follows. Test if volatile or alias are reserved words: $ iffe - key and /* : : generated by iffe version 1998-01-23 : : */ #ifndef _def_volatile_tmp #define _def_volatile_tmp 1 #define _key_volatile 1 /* volatile is a reserved keyword */ #endif Check for <stdlib.h> or <sys/stdlib.h>: $ iffe - hdr,sys stdlib /* : : generated by iffe version 1998-01-23 : : */ #ifndef _def_stdlib_pp #define _def_stdlib_pp 1 #define _hdr_stdlib 1 /* #include <stdlib.h> ok */ #endif The remaining examples may be placed in a file.iff and run by: $ iffe - run file.iff _tst_errno will be defined 1 if errno can be assigned: tst errno errno.h note{ errno can be assigned }end link{ _BEGIN_EXTERNS_ extern int errno; error() { } strerror() { } _END_EXTERNS_ main() { errno = 0; error(); strerror(); return 0; } }end _ptr_dd_buf will be defined 1 if the DIR struct member dd_buf exists and is a pointer. The test will be done as many as 3 times, first with <dirent.h>, next with <ndir.h>, and finally with <sys/dir.h>. tst ptr_dd_buf sys/types.h - dirent.h - ndir.h - sys/dir.h compile{ main() { DIR* dirp; dirp->dd_buf = 0; return 0; } }end Due to limitations in the interpreter, tests scripts containing C escapes must specify \ as \\. This example defines CODE_alert to be the character code value for '\a'. tst output{ _BEGIN_EXTERNS_ extern int printf _ARG_((const char*, ...)); _END_EXTERNS_ main() { printf("#define CODE_alert %d\\n", '\\a'); return 0; } }end
FILES
SEE ALSO
AUTHOR
Glenn Fowler gsf@research.att.com
K. Phong Vo kpv@research.att.com
AT&T Labs Research