IFFE ( 1 ) USER COMMANDSIFFE ( 1 )


NAME

iffe - C compilation environment feature probe

SYNOPSIS

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

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 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 autoconf(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 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 op 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 op 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 and does not remove core dumps on exit.
-D, --define

Successful test macro definitions are emitted. This is the default.
-E, --explicit

Disable implicit test output.
-F, --features=hdr

Sets the feature test header to hdr. This header typically defines *_SOURCE feature test macros. The default value is NONE.
-i, --input=file

Sets the input file name to file, which must contain iffe statements.
-I, --include=dir

Adds -Idir to the C compiler flags.
-L, --library=dir

Adds -Ldir to the C compiler flags.
-n, --name-value

Output name=value assignments only.
-N, --optimize

--nooptimize disables compiler optimization options. On by default; -N means --nooptimize .
-o, --output=file

Sets the output file name to file.
-O, --stdio=hdr

Sets the standard io header to hdr. The default value is stdio.h.
-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.
-r, --regress

Massage output for regression testing.
-s, --shell=name

Sets the internal shell name to name. Used for debugging Bourne shell compatibility (otherwise iffe uses ksh constructs if available). The supported names are ksh, bsh, bash , and osh. osh forces the read -r compatibility read command to be compiled and used instead of read -r. The default is determined by probing the shell at startup.
-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.
-x, --cross=crosstype

Some tests compile an executable (a.out) and then run it. If the C compiler is a cross compiler and the executable format is incompatible with the execution environment then the generated executables must be run in a different environment, possibly on another host. crosstype is the HOSTTYPE for generated executables (the package(1) command generates a consistent HOSTTYPE namespace). Generated executables are run via crossexec(1) with crosstype as the first argument. crossexec supports remote execution for cross-compiled executables. See crossexec(1) for details.
-X, --exclude=dir

Removes -Idir and -I*/dir C compiler flags.

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 statement syntax is: [name =] [!] test[,test...] [-] [arg[, arg...]] [prereq ...] [begin{ ... |end ...] [= [default]]. tests and args may be combined, separated by commas, to perform a set of tests on a set of arguments. name = before test overrides the default test variable and macro name, and - after test performs the test but does not define the test variable and macro values. ! before test inverts the test sense for if, elif, and yes{ and no{ blocks.

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)
#include <stdio.h>

= default may be specified for the key, lib, mac, mth and typ tests. 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 tests. #ifndef _def_name_directory ... #endif guards the generated header from multiple #includes, where name is determined by either the run statement input file name if any, or the first test in the first statement, and directory is the basename component of either the run statement 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 test 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-ignorant file systems happy.

The feature tests are:

# comment

Comment line - ignored.
api name YYYYMMDD symbol ...

Emit api compatibility tests for name and #define symbol symbol_YYYYMMDD when NAME_API is >= YYYYMMDD (NAME is name converted to upper case). If NAME_API is not defined then symbol maps to the newest YYYYMMDD for name.
define name [ (arg,...) ] [ value ]

Emit a macro #define for name if it is not already defined. The definition is passed to subsequent tests.
extern name type [ (arg,...) | [dimension] ]

Emit an extern prototype for name if one is not already defined. The prototype is passed to subsequent tests.
header header

Emit #include <header> if header exists. The #include is passed to subsequent tests.
print text

Copy text to the output file. text is passed to subsequent tests.
reference header

If header exists then add #include header to subsequent tests.
ver name YYYYMMDD

#define NAME_VERSION YYYYMMDD (NAME is name converted to upper case).
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.
dfn name

If name is a macro in the candidate headers then a #define name value statment is output for the value defined in the headers. The definition is #ifndef guarded.
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 tests; undefined names evaluate to 0. If name was defined in a previous successful test then the current and subsequent exp test on name are skipped. If name is - then the expression is simply evaluated.
hdr name

Defines _hdr_name if the header <name.h> exists. The --config macro name is HAVE_NAME_H.
if statement ... | elif statement ... | else | endif

Nested if-else test control.
iff name

The generated header #ifndef-#endif macro guard is _name _H.
inc file [ re ]

Read #define macro names from file and arrange for those names to evaluate to 1 in exp expressions. If re is specified then macros not matching re are ignored.
key name

Defines _key_name if name is a reserved word (keyword).
lcl name

Generates a #include statement for the native version of the header < name.h> if it exists. Defines _lcl_name on success. The --config macro name is HAVE_ NAME_H. The default re is ^HAVE_ for --config and ^_ otherwise.
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 test then name may be used to name the output file and/or the output header guard macro. Otherwise this test is ignored.
npt name

Defines _npt_name if the name symbol requires a prototype. The --config macro name is HAVE_NAME_DECL with the opposite sense.
num name

Defines _num_name if name is a numeric constant enum or macro.
nxt name

Defines a string macro _nxt_name suitable for a #include statement to include the next (on the include path) or native version of the header <name.h> if it exists. Also defines the "..." form _nxt_name_str. The --config macro name is HAVE_NAME_NEXT .
one header ...

Generates a #include statement for the first header found in the header list.
opt name

Defines _opt_name if name is a space-separated token in the global environment variable PACKAGE_OPTIONS.
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. If no operands are specified then the default PATH directories are used. 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. Macros and headers supplied to begin{ ... }end are also supplied to 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. tst - ... is treated as tst - - ....
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.
var name

A user defined test on name. A source block must be supplied. Sets the exp variable _name on success but does not define a macro.
(expression)

Equivalent to exp - expression.

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).
cross

The block is executed as a shell script using crossexec(1) if --cross is on, or on the local host otherwise, and the output is copied to the output file. Test macros are not exported to the script.
execute

The block is compiled, linked, and executed. 0 exit status means success.
fail
If the test fails then the block text is evaluated by sh(1).
link
The block is compiled and linked (cc -o).
macro

The block is preprocessed (cc -E) and lines containing text bracketed by <<" ... ">> (less-than less-than double-quote ... double-quote greater-than greater-than) are copied to the output file with the brackets omitted.
no
If the test fails then the block text is copied to the output file. Deprecated: use { if elif else endif } with unnamed { ... } blocks.
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 is evaluated by sh(1).
preprocess

The block is preprocessed (cc -E).
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.
status

The block is compiled, linked, and executed, and the exit status is the test outcome, 0 for failure, the value otherwise.
yes
If the test succeeds then the block text is copied to the output file. yes{ ... }end is equivalent to the unnamed block { ... }. Deprecated: use { if elif else endif } with unnamed { ... } blocks.

SEE ALSO

autoconf(1), config(1), getconf(1), crossexec(1), nmake(1), package(1), proto(1), sh(1)

IMPLEMENTATION

version

iffe (AT&T Research) 2012-06-08
author

Glenn Fowler <glenn.s.fowler@gmail.com>
author

Phong Vo <kpv@research.att.com>
copyright

Copyright © 1994-2012 AT&T Intellectual Property
license

http://www.eclipse.org/org/documents/epl-v10.html