The include directive is used to extract constants and
type definitions from C header files and put them into the equivalent
Cyclone header file. For example, here is part of the spec that we
use to interface to C's errno.h:
errno.h:
include { E2BIG EACCES EADDRINUSE ... }
The spec says that the Cyclone version of errno.h should use
the C definitions of error constants like E2BIG. These are
typically macro-defined as integers, but the integers can differ from
system to system. We ensure that Cyclone uses the right constants by
running buildlib on each system.
For another example, our spec for sys/types.h reads, in part:
sys/types.h:
include { id_t mode_t off_t pid_t ... }
Here the symbols are typedef names, and the result will be that the
Cyclone header file contains the typedefs that define id_t,
etc. Again, these can differ from system to system.
You can use include to obtain not just constants (macros) and
typedefs, but struct and union definitions as well. Furthermore, if a
definition you include requires any other definitions that you do
not explicitly include, those other definitions will be placed into
the Cyclone header too. Moreover, for all such definitions, you can include
an optional, expected Cyclonedefinition that is ``equivalent'' to the C
definition on your system. By ``equivalent,'' we mean that your definition
defines all of the same elements as the system definition (but possibly
fewer), and each of these elements is ``representation-compatible'' in the
sense that they use the same amount of storage when compiled. As example,
here is our spec for grp.h:
include {
gid_t
group {
struct group {
char @gr_name;
char @gr_passwd;
gid_t gr_gid;
char ** @zeroterm gr_mem;
};
}
}
This provides richer information than the compatible definition on most
systems. Here is the Linux definition:
struct group {
char *gr_name;
char *gr_passwd;
gid_t gr_gid;
char **gr_mem;
};
The user definition refines the system definition by indicating that for
group strings gr_name and gr_passwd must be
non-NULL, and indicates that the array of strings gr_mem, is
null-terminated. But note that the two definitions are
representation-compatible in that they have the same run-time storage
requirements. The Cyclone version simplifies provides more precise type
information. You can provide user definitions for enumerated types and
typedef's as well.
Some refinements (such as polymorphism), are not yet supported for user
definitions. Also, include does not work for variable or function
declarations. You have to use the hstub directive to add variable
and function declarations to your Cyclone header.