iffe ( 1 ) USER COMMANDSiffe ( 1 )


NAME

iffe - host C compilation environment feature probe

SYNOPSIS

iffe [ options ] [ - ] [ file.iffe | statement [ : statement ... ] ]

DESCRIPTION

iffe is a command interpreter that probes the host 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 and generated programs.

iffe statements are line oriented. Statements may appear in the operand list with the : operand or newline as the line delimiter. The standard input is read if there are no command line statements or if file.iffe is omitted.

Though similar in concept to autoconfig(1) and config(1), there are fundamental differences. The latter tend to generate global headers accessed by all components in a package, whereas iffe is aimed at localized, self contained feature testing.

Output is generated in FEATURE/test by default, where test is the base name of file.iffe or the iffe run command file operand. Output is first generated in a temporary file; the output file is updated if it does not exist or if the temporary file is different. If the first operand is - then the output is written to the standard output and no update checks are done.

Files with suffixes .iffe and .iff are assumed to contain iffe statements.

OPTIONS

-a, --all
Define failed test macros 0. By default only successful test macros are defined 1.
-c, --cc=C-compiler-name [C-compiler-flags ...]
Sets the C compiler name and flags to be used in the feature tests.
-C, --config
Generate config(1) style HAVE_* macro names. This implies --undef. Since config(1) has inconsistent naming conventions, the exp command may be needed to translate from the (consistent) iffe names. Unless otherwise noted a config macro name is the iffe macro name prefixed with HAVE and converted to upper case. --config is set by default if the command arguments contain a run command on an input file with the base name config .
-d, --debug=level
Sets the debug level. Level 0 inhibits most error messages, level 1 shows compiler messages, and level 2 traces internal iffe sh(1) actions.
-i, --input=file
Sets the input file name to file , which must contain iffe statements.
-o, --output=file
Sets the output file name to file .
-e, --package=name
Sets the proto(1) package name to name.
-p, --prototyped
Emits #pragma prototyped at the top of the output file. See proto(1).
-P, --pragma=text
Emits #pragma text at the top of the output file.
-s, --shell=shell-path
Sets the internal shell name to shell-path. Used for debugging Bourne shell compatibility (otherwise iffe uses ksh constructs if available).
-S, --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 dlls) because on some systems missing library symbols are only detected when referenced at runtime from dynamically linked executables.
-u, --undef
#undef failed test macros. By default only successful test macros are defined 1.
-v, --verbose
Produce a message line on the standard error for each test as it is performed.

SYNTAX

iffe input consists of a sequence of statement lines. Statements that span more than one line contain begin{ as the last operand (where begin is command specific) and zero or more data lines terminated by a line containing }end as the first operand. The statements syntax is: op[,op...] [arg[,arg...]] [prereq ...] [begin{ ... |end ...] [= [default]]. ops and args may be combined, separated by commas, to perform a set of operations on a set of arguments.

prereqs are used when applying the features tests and may be combinations of:
compiler options
-D*, -L *, etc.
library references
-l*, *.a, etc. _LIB_name is defined to be 1 if -lname is a library.
header references
*.h. _dir_name is defined to be 1 if dir/name.h is a header, or if dir is omitted, _hdr_name is defined to be 1 if name.h is a header.
-
Prereq grouping mark; prereqs before the first - are passed to all feature tests. Subsequent groups are attempted in left-to-right order until the first successful group is found.

begin{ ... }end delimit multiline 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 for maximal portability. In addition to all macro definitions generated by previous tests, 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)

= default may be specified for the key, lib, mth and typ commands. If the test fails for arg then #define arg default is emitted. key accepts multiple = default values; the first valid one is used.

Each test statement generates a portion of 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 generated header from multiple #includes, where name is determined by either the run command input file name if any, or the first op of the first command, and directory is the basname component of either the run command file, if any, or the current working directory. The output file name is determined in this order:
-
If the first command line operand is - then the output is written to the standard output.
--output=file
Output is file .
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 FEATURE/file from features/ file[suffix], where suffix may be omitted, .c, or .sh (see the run command below). Because #include prerequisites are automatically detected, nmake(1) ensures that all prerequisite iffe headers are generated before compilation. Note that the directories are deliberately named FEATURE and features to keep case-insensitive file systems happy.

The feature test commands are:
# comment
Comment line - ignored.
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 default libraries.
def name
Equivalent to cmd,dat,hdr,key,lib,mth,sys,typ name.
exp name expression
If expression is a "..." string then name is defined to be the string, else if the expr(1) evaluation of expression is not 0 then name is defined to be 1, otherwise name is defined to be 0. Identifiers in expression may be previously defined names from other iffe commands; undefined names evaluate to 0.
hdr name
Defines _hdr_name if the header <name.h> exists. The --config macro name is HAVE_NAME_H.
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 #include 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. The --config macro name is HAVE_NAME_H.
lib name
Defines _lib_name if name is an external symbol in the default libraries.
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
If this is the first command then name may be used to name the output file and/or the output header guard macro. Otherwise this command is ignored.
npt name
Defines _npt_name if the name symbol requires a prototype. The --config macro name is NAME_DECLARED with the opposite sense.
num name
Defines _num_name if name is a numeric constant enum or macro.
one header ...
Generates a #include statement for the first header found in the header list.
pth file [ dir ... | { g1 - ... - gn } | < pkg [ver ...] > ]
Defines _pth_file, with embedded / chars translated to _, to the path of the first instance of file in the dir directories. { ... } forms a directory list from the cross-product of - separated directory groups g1 ... gn. < ... > forms a directory list for the package pkg with optional versions. The --config macro name is NAME_PATH.
run file
Runs the tests in file based on the file 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.
.iffe or no suffix
file contains iffe statements.
set option value
Sets option values. The options are described above.
siz name
Defines _siz_name to be sizeof(name) if name is a type in any of <sys/types.h>, <times.h>, <stddef.h>, <stdlib.h>. Any . characters in name are translated to space before testing and are translated to _ in the output macro name.
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. The --config macro name is HAVE_SYS_NAME_H.
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 <sys/types.h>, <times.h>, <stddef.h>, <stdlib.h>. Any . characters in name are translated to space before testing and are translated to _ in the output macro name.
val name
The output of echo name is written to the output file.

Code block names may be prefixed by no to invert the test sense. The block names are:
cat
The block is copied to the output file.
compile
The block is compiled (cc -c).
execute
The block is compiled, linked, and executed. 0 exit status means success.
fail
If the test fails then the block text evaluated by sh(1).
link
The block is compiled and linked (cc -o).
macro
The block is preprocessed (cc -E) and text bracketed by << ... >> is copied to the output file.
menu
Not implemented.
no
If the test fails then the block text is copied to the output file.
note
If the test succeeds then the block is copied to the output as a /* ... */ comment.
output
The block is compiled, linked, and executed, and the output is copied to the output file.
pass
If the test succeeds then the block text evaluated by sh(1).
preprocess
The block is preprocessed (cc -E).
prompt
Not implemented.
run
The block is executed as a shell script and the output is copied to the output file. Succesful test macros are also defined as shell variables with value 1 and are available within the block. Likewise, failed test macros are defined as shell variables with value 0.
yes
If the test succeeds then the block text is copied to the output file.

SEE ALSO

autoconfig(1), config(1), nmake(1), proto(1), sh(1)

IMPLEMENTATION

version
iffe (AT&T Labs Research) 2000-03-17
author
Glenn Fowler <gsf@research.att.com>
author
Phong Vo <kpv@research.att.com>
copyright
Copyright © 1994-2000 AT&T Corp.
license
http://www.research.att.com/sw/license/ast-open.html