---
name: "iffe"
section: "1"
platform: "linux"
package: "zmailer"
version: "2.99.55-3"
release: "Debian 3.0 (Woody)"
platforms: ["linux"]
url: "https://new.carta.tech/iffe"
---

# iffe(1)

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 ...]
```

*op*s *and* *arg*s *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* op      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. *block*s 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* run      command, if any, or the first *op* of the first command, and directory is basname component of either the  run      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* .sh      (see the run      feature test op 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 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 #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.

- 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 #include      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 #pragma prototyped      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 no      to invert the test sense. The block names are:

- cat

  The block is copied to the output file.

- compile

  The block is compiled

- execute

  The block is compiled, linked, and executed. 0      exit status means success.

- fail

  If the test fails then the fail block text is copied to the output file.

- link

  The block is compiled and linked

- macro

  The block is preprocessed and text bracketed by is copied to the output file.

- menu

  \[*NOT YET*\]

- note

  If the test succeeds then the note 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 pass block text is copied to the output file.

- preprocess

  The block is preprocessed

- prompt

  \[*NOT YET*\]

- run

  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

- **features/***op***.c**

  *C program to compile and run for* *op*. *Execution output copied to the FEATURE output file.*

- **features/***op***.sh**

  [*sh*(1)](/sh/1.md) *script to run for* *op*. *Execution output copied to the FEATURE output file.*

- **features/***op*

  *iffe* *override tests for* *op*.

## SEE ALSO

*[cc(1)](/cc/1.md), [cpp(1)](/cpp/1.md), nmake(1), [probe(1)](/probe/1.md)*

## AUTHOR

*Glenn Fowler	gsf@research.att.com*\
 *K. Phong Vo	kpv@research.att.com*\
 *AT&T Labs Research*
