2 |
7u83 |
1 |
<!-- Crown Copyright (c) 1998 -->
|
|
|
2 |
<HTML>
|
|
|
3 |
<HEAD>
|
|
|
4 |
<TITLE>
|
|
|
5 |
tspec - An API Specification Tool
|
|
|
6 |
</TITLE>
|
|
|
7 |
</HEAD>
|
|
|
8 |
|
|
|
9 |
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000FF" VLINK="#400080" ALINK="#FF0000">
|
|
|
10 |
<H1>tspec - An API Specification Tool</H1>
|
|
|
11 |
<H3>January 1998</H3>
|
|
|
12 |
<IMG SRC="../images/no_next.gif" ALT="next section">
|
|
|
13 |
<IMG SRC="../images/no_prev.gif" ALT="previous section">
|
|
|
14 |
<IMG SRC="../images/no_top.gif" ALT="current document">
|
|
|
15 |
<A HREF="../index.html"><IMG SRC="../images/home.gif" ALT="TenDRA home page">
|
|
|
16 |
</A>
|
|
|
17 |
<IMG SRC="../images/no_index.gif" ALT="document index"><P>
|
|
|
18 |
<HR>
|
|
|
19 |
<DL>
|
|
|
20 |
<DT><A HREF="#Intro"><B>1</B> - Introduction</A><DD>
|
|
|
21 |
<DT><A HREF="#Overview"><B>2</B> - Overview of tspec</A><DD>
|
|
|
22 |
<DL>
|
|
|
23 |
<DT><A HREF="#Levels"><B>2.1</B> - Specification Levels</A><DD>
|
|
|
24 |
<DT><A HREF="#Input"><B>2.2</B> - Input Layout</A><DD>
|
|
|
25 |
<DT><A HREF="#Output"><B>2.3</B> - Output Layout</A><DD>
|
|
|
26 |
<DT><A HREF="#Copyright"><B>2.4</B> - Copyright Messages</A><DD>
|
|
|
27 |
<DT><A HREF="#Options"><B>2.5</B> - Command-line Options</A><DD>
|
|
|
28 |
</DL>
|
|
|
29 |
<DT><A HREF="#Structure"><B>3</B> - Specifying API Structure</A><DD>
|
|
|
30 |
<DL>
|
|
|
31 |
<DT><A HREF="#Subset"><B>3.1</B> - +SUBSET</A><DD>
|
|
|
32 |
<DT><A HREF="#Impl"><B>3.2</B> - +IMPLEMENT and +USE</A><DD>
|
|
|
33 |
</DL>
|
|
|
34 |
<DT><A HREF="#Objects"><B>4</B> - Specifying Objects</A><DD>
|
|
|
35 |
<DL>
|
|
|
36 |
<DT><A HREF="#S41"><B>4.1</B> - Object Names</A><DD>
|
|
|
37 |
<DT><A HREF="#Func"><B>4.2</B> - +FUNC</A><DD>
|
|
|
38 |
<DT><A HREF="#Exp"><B>4.3</B> - +EXP and +CONST</A><DD>
|
|
|
39 |
<DT><A HREF="#Macro"><B>4.4</B> - +MACRO</A><DD>
|
|
|
40 |
<DT><A HREF="#Statement"><B>4.5</B> - +STATEMENT</A><DD>
|
|
|
41 |
<DT><A HREF="#Define"><B>4.6</B> - +DEFINE</A><DD>
|
|
|
42 |
<DT><A HREF="#Type"><B>4.7</B> - +TYPE</A><DD>
|
|
|
43 |
<DT><A HREF="#Typedef"><B>4.8</B> - +TYPEDEF</A><DD>
|
|
|
44 |
<DT><A HREF="#Field"><B>4.9</B> - +FIELD</A><DD>
|
|
|
45 |
<DT><A HREF="#Nat"><B>4.10</B> - +NAT</A><DD>
|
|
|
46 |
<DT><A HREF="#Enum"><B>4.11</B> - +ENUM</A><DD>
|
|
|
47 |
<DT><A HREF="#Token"><B>4.12</B> - +TOKEN</A><DD>
|
|
|
48 |
</DL>
|
|
|
49 |
<DT><A HREF="#Others"><B>5</B> - Other tspec Constructs</A><DD>
|
|
|
50 |
<DL>
|
|
|
51 |
<DT><A HREF="#If"><B>5.1</B> - +IF, +ELSE and +ENDIF</A><DD>
|
|
|
52 |
<DT><A HREF="#Text"><B>5.2</B> - Quoted Text</A><DD>
|
|
|
53 |
<DT><A HREF="#Comment"><B>5.3</B> - C Comments</A><DD>
|
|
|
54 |
<DT><A HREF="#Properties"><B>5.4</B> - File Properties</A><DD>
|
|
|
55 |
</DL>
|
|
|
56 |
<DT><A HREF="#S6"><B>6</B> - Miscellaneous Topics</A><DD>
|
|
|
57 |
<DL>
|
|
|
58 |
<DT><A HREF="#FineImpl"><B>6.1</B> - Fine Control of Included Files</A><DD>
|
|
|
59 |
<DT><A HREF="#Protect"><B>6.2</B> - Protection Macros</A><DD>
|
|
|
60 |
<DT><A HREF="#Index"><B>6.3</B> - Index Printing</A><DD>
|
|
|
61 |
<DT><A HREF="#Libraries"><B>6.4</B> - TDF Library Building</A><DD>
|
|
|
62 |
</DL>
|
|
|
63 |
<DT><A HREF="#S7"><B>7</B> - Changes in tspec 2.0</A><DD>
|
|
|
64 |
<DT><A HREF="#S8"><B>8</B> - References</A><DD>
|
|
|
65 |
</DL>
|
|
|
66 |
<HR>
|
|
|
67 |
|
|
|
68 |
<H2><A NAME="Intro">1. Introduction</A></H2>
|
|
|
69 |
<P>
|
|
|
70 |
As explained in reference 1, TDF may be regarded as an abstract target
|
|
|
71 |
machine which can be used to facilitate the separation of target independent
|
|
|
72 |
and target dependent code which characterises portable programs. An
|
|
|
73 |
important aspect of this separation is the Application Programming
|
|
|
74 |
Interface, or API, of the program. Just as, for a conventional machine,
|
|
|
75 |
the API needs to be implemented on that machine before the program
|
|
|
76 |
can be ported to it, so for that program to be ported to the abstract
|
|
|
77 |
TDF machine, an "abstract implementation" of the API needs
|
|
|
78 |
to be provided.
|
|
|
79 |
<P>
|
|
|
80 |
But of course, an "abstract implementation" is precisely
|
|
|
81 |
what is provided by the API specification - it is an abstraction of
|
|
|
82 |
all the possible API implementations. Therefore the TDF representation
|
|
|
83 |
of an API must reflect the API specification. As a consequence, compiling
|
|
|
84 |
a program to the abstract TDF machine is to check it against the API
|
|
|
85 |
specification rather than, as with compiling to a conventional machine,
|
|
|
86 |
against at best a particular implementation of that API.
|
|
|
87 |
<P>
|
|
|
88 |
In this document we address the problem of how to translate a standard
|
|
|
89 |
API specification into its TDF representation, by describing a tool,
|
|
|
90 |
<CODE>tspec</CODE>, which has been developed for this purpose.
|
|
|
91 |
<P>
|
|
|
92 |
The low level form which is used to represent APIs to the C to TDF
|
|
|
93 |
producer is the <CODE>#pragma token</CODE> syntax described in reference
|
|
|
94 |
3. However this is not a suitable form in which to describe API specifications.
|
|
|
95 |
The <CODE>#pragma token</CODE> syntax is necessarily complex, and
|
|
|
96 |
can only be checked through extensive testing using the producer.
|
|
|
97 |
Instead an alternative form, close to C, has been developed for this
|
|
|
98 |
purpose. API specifications in this form are transformed by <CODE>tspec</CODE>
|
|
|
99 |
into the corresponding <CODE>#pragma token</CODE> statements, while
|
|
|
100 |
it applies various internal checks to the API description.
|
|
|
101 |
<P>
|
|
|
102 |
Another reason for introducing <CODE>tspec</CODE> is that the <CODE>#pragma
|
|
|
103 |
token</CODE> syntax is currently limited in some areas. For example,
|
|
|
104 |
at present it has very limited support for expressing constancy of
|
|
|
105 |
expressions. By allowing the <CODE>tspec</CODE> syntax to express
|
|
|
106 |
this information, the API description will contain all the information
|
|
|
107 |
which may be needed in future upgrades to the <CODE>#pragma token</CODE>
|
|
|
108 |
syntax. Thus describing an API using <CODE>tspec</CODE> is hopefully
|
|
|
109 |
a one off process, whereas describing it directly to the <CODE>#pragma
|
|
|
110 |
token</CODE> syntax could require periodic reworkings. Improvements
|
|
|
111 |
in the <CODE>#pragma token</CODE> syntax will be reflected in the
|
|
|
112 |
translations produced by future versions of <CODE>tspec</CODE>.
|
|
|
113 |
<P>
|
|
|
114 |
The <CODE>tspec</CODE> syntax is not designed to be a formal specification
|
|
|
115 |
language. Instead it is a pragmatic attempt to capture the common
|
|
|
116 |
specification idioms of standard API specifications. A glance at these
|
|
|
117 |
specifications shows that they are predominantly C based, but with
|
|
|
118 |
an added layer of abstraction - instead of saying that <CODE>t</CODE>
|
|
|
119 |
is a specific C type, they say, there exists a type <CODE>t</CODE>,
|
|
|
120 |
and so on. The <CODE>tspec</CODE> syntax is designed to reflect this.
|
|
|
121 |
<P>
|
|
|
122 |
<HR>
|
|
|
123 |
|
|
|
124 |
<H2><A NAME="Overview">2. Overview of tspec</A></H2>
|
|
|
125 |
|
|
|
126 |
<H3><A NAME="Levels">2.1. Specification Levels</A></H3>
|
|
|
127 |
<P>
|
|
|
128 |
Let us begin by examining the various levels of specification with
|
|
|
129 |
which <CODE>tspec</CODE> is concerned. At the lowest level it is concerned
|
|
|
130 |
with objects - the types, expressions, constants etc. which comprise
|
|
|
131 |
the API - and indeed most of this document is concerned with how <CODE>tspec
|
|
|
132 |
</CODE> describes these objects. At the highest level, <CODE>tspec</CODE>
|
|
|
133 |
is concerned with APIs. We could just describe an API as being a set
|
|
|
134 |
of objects, however this is to ignore the internal structure of APIs.
|
|
|
135 |
<P>
|
|
|
136 |
At the most obvious level the objects in an API are spread over a
|
|
|
137 |
number of different system headers. For example, in ANSI, the objects
|
|
|
138 |
concerned with file input and output are grouped in <CODE>stdio.h</CODE>,
|
|
|
139 |
whereas those concerned with string manipulation are in <CODE>string.h</CODE>.
|
|
|
140 |
But a further level of refinement is also required. For example, ANSI
|
|
|
141 |
specifies that the type <CODE>size_t</CODE> is defined in both <CODE>stdio.h
|
|
|
142 |
</CODE> and <CODE>string.h</CODE>. Therefore <CODE>tspec</CODE> needs
|
|
|
143 |
to be able to represent subsets of headers in order to express this
|
|
|
144 |
intersection relation.
|
|
|
145 |
<P>
|
|
|
146 |
To conclude, <CODE>tspec</CODE> distinguishes four levels of specification
|
|
|
147 |
- APIs (which are sets of headers), headers (which are sets of objects),
|
|
|
148 |
subsets of headers, and objects. It identifies APIs by an identifying
|
|
|
149 |
name chosen by the person performing the API description. The (purely
|
|
|
150 |
arbitrary) convention is for short, lower case names, for example:
|
|
|
151 |
<UL>
|
|
|
152 |
<LI><CODE>ansi</CODE> refers to ANSI C (X3.159),
|
|
|
153 |
<LI><CODE>posix</CODE> refers to POSIX 1003.1,
|
|
|
154 |
<LI><CODE>xpg3</CODE> refers to X/Open Portability Guide 3.
|
|
|
155 |
</UL>
|
|
|
156 |
<P>
|
|
|
157 |
In this document, headers are identified by the API they belong to
|
|
|
158 |
and the header name. Thus <CODE>ansi:stdio.h</CODE> refers to the
|
|
|
159 |
<CODE>stdio.h</CODE> header of the ANSI API. Finally subsets of headers
|
|
|
160 |
are identified by the header and the subset name. If, for example,
|
|
|
161 |
the <CODE>stdio.h</CODE> header of ANSI has a subset named <CODE>file</CODE>,
|
|
|
162 |
then this is referred to as <CODE>ansi:stdio.h:file</CODE>.
|
|
|
163 |
<H3><A NAME="Input">2.2. Input Layout</A></H3>
|
|
|
164 |
<P>
|
|
|
165 |
The <CODE>tspec</CODE> representation of an API is arranged as a directory
|
|
|
166 |
with the same name as the API, containing a number of files, one for
|
|
|
167 |
each API header. For example, the ANSI API is represented by a directory
|
|
|
168 |
<CODE>ansi</CODE> containing files <CODE>ansi/stdio.h</CODE>, <CODE>ansi/string.h
|
|
|
169 |
</CODE> etc. In addition each API directory contains a master file
|
|
|
170 |
(for ANSI it would be called <CODE>ansi/MASTER</CODE>) which lists
|
|
|
171 |
all the headers comprising that API.
|
|
|
172 |
<P>
|
|
|
173 |
When <CODE>tspec</CODE> needs to find an API directory it does so
|
|
|
174 |
by searching along its input directory path. This is a colon separated
|
|
|
175 |
list of directories to be searched. This may be specified in a number
|
|
|
176 |
of ways. A default search list is built into <CODE>tspec</CODE>, however
|
|
|
177 |
this may be overridden by the system variable <CODE>TSPEC_INPUT</CODE>.
|
|
|
178 |
Directories may be added to the start of the path using the <B>-I</B><I>dir</I>
|
|
|
179 |
command-line option (see <A HREF="#Options">section 2.5</A> for a
|
|
|
180 |
complete list of options). The current working directory is always
|
|
|
181 |
added to the start of the path.
|
|
|
182 |
<H3><A NAME="Output">2.3. Output Layout</A></H3>
|
|
|
183 |
<P>
|
|
|
184 |
<CODE>tspec</CODE> actually outputs two sets of output files, the
|
|
|
185 |
include output files, containing the <CODE>#pragma token</CODE> directives
|
|
|
186 |
corresponding to the input API, and the source output files, which
|
|
|
187 |
provide a rig for TDF library building (see <A HREF="#Libraries">section
|
|
|
188 |
6.4</A>). These output files and directories are built up under two
|
|
|
189 |
standard output directories - the include output directory, <I>incl_dir</I>
|
|
|
190 |
say, and the source output directory, <I>src_dir</I> say. <CODE>tspec</CODE>
|
|
|
191 |
has default values for these directories built in, but these may be
|
|
|
192 |
overridden in a number of ways. Firstly, if the system variable <CODE>TSPEC_OUTPUT
|
|
|
193 |
</CODE> is defined to be <I>dir</I>, say, then <I>incl_dir</I> is
|
|
|
194 |
<I>dir</I><CODE>/include</CODE> and <I>src_dir</I> is <I>dir</I><CODE>/src
|
|
|
195 |
</CODE>. Secondly, <I>incl_dir</I> and <I>src_dir</I> can be set independently
|
|
|
196 |
using the system variables <CODE>TSPEC_INCL_OUTPUT</CODE> and <CODE>TSPEC_SRC_OUTPUT
|
|
|
197 |
</CODE> respectively. Finally, they may also be set using the <B>-O</B><I>dir
|
|
|
198 |
</I> and <B>-S</B><I>dir</I> command-line options respectively.
|
|
|
199 |
<P>
|
|
|
200 |
As an example of the mapping from input files to output files, the
|
|
|
201 |
header <CODE>ansi:stdio.h</CODE> is mapped to the include output file
|
|
|
202 |
<I>incl_dir</I><CODE>/ansi.api/stdio.h</CODE> and the source output
|
|
|
203 |
file <I>src_dir</I><CODE>/ansi.api/stdio.c</CODE>. The header subset
|
|
|
204 |
<CODE>ansi:stdio.h:file</CODE> is mapped to its own pair of output
|
|
|
205 |
files, <I>incl_dir</I><CODE>/shared/ansi.api/file.h</CODE> and <I>src_dir</I>
|
|
|
206 |
<CODE>/ansi.api/file.c</CODE>.
|
|
|
207 |
<P>
|
|
|
208 |
The default output file names can be overridden by means of the <CODE>INCLNAME
|
|
|
209 |
</CODE> and <CODE>SOURCENAME</CODE> file properties described in
|
|
|
210 |
<A HREF="#Properties">section 5.4</A>.
|
|
|
211 |
<P>
|
|
|
212 |
By default, <CODE>tspec</CODE> only creates an output file if the
|
|
|
213 |
date stamps on all the input files it depends on indicate that it
|
|
|
214 |
needs updating. In effect, <CODE>tspec</CODE> creates an internal
|
|
|
215 |
makefile from the dependencies it deduces. This behaviour can be overridden
|
|
|
216 |
by means of the <B>-f</B> command-line option, which forces all output
|
|
|
217 |
files to be created.
|
|
|
218 |
<P>
|
|
|
219 |
In addition, <CODE>tspec</CODE> only creates the source output file
|
|
|
220 |
if it is needed for TDF library building. If the corresponding include
|
|
|
221 |
output file does not contain any token specifications then the source
|
|
|
222 |
output file is suppressed (see <A HREF="#Libraries">section 6.4</A>).
|
|
|
223 |
|
|
|
224 |
<H3><A NAME="Copyright">2.4. Copyright Messages</A></H3>
|
|
|
225 |
<P>
|
|
|
226 |
<CODE>tspec</CODE> will optionally add a copyright message to the
|
|
|
227 |
start of each include output file. This message is copied from a file
|
|
|
228 |
which may be specified either using the <CODE>TSPEC_COPYRIGHT</CODE>
|
|
|
229 |
system variable, or by the <B>-C</B><I>file</I> command-line option.
|
|
|
230 |
|
|
|
231 |
<H3><A NAME="Options">2.5. Command-line Options</A></H3>
|
|
|
232 |
<P>
|
|
|
233 |
There are three main forms for invoking <CODE>tspec</CODE> on the
|
|
|
234 |
command-line, depending on whether it is desired to process an entire
|
|
|
235 |
API, a single header from that API, or only a subset of that header.
|
|
|
236 |
These are given respectively as:
|
|
|
237 |
<PRE>
|
|
|
238 |
tspec [options] api
|
|
|
239 |
tspec [options] api header
|
|
|
240 |
tspec [options] api header subset
|
|
|
241 |
</PRE>
|
|
|
242 |
<P>
|
|
|
243 |
The valid options include:
|
|
|
244 |
<UL>
|
|
|
245 |
<LI>The option <B>-C</B><I>file</I> specifies the copyright message
|
|
|
246 |
file (see <A HREF="#Copyright">section 2.4</A>).
|
|
|
247 |
<LI>The option <B>-I</B><I>dir</I> adds a directory to the input directory
|
|
|
248 |
search path (see <A HREF="#Input">section 2.2</A>).
|
|
|
249 |
<LI>The option <B>-O</B><I>dir</I> specifies the include output directory
|
|
|
250 |
(see <A HREF="#Output">section 2.3</A>).
|
|
|
251 |
<LI>The option <B>-S</B><I>dir</I> specifies the source output directory
|
|
|
252 |
(see <A HREF="#Output">section 2.3</A>).
|
|
|
253 |
<LI>The <B>-c</B> option causes <CODE>tspec</CODE> to only check the
|
|
|
254 |
input files and not to generate any output files.
|
|
|
255 |
<LI>The <B>-e</B> option causes <CODE>tspec</CODE> only to run its
|
|
|
256 |
preprocessor phase, writing the result to the standard output.
|
|
|
257 |
<LI>The <B>-f</B> option forces <CODE>tspec</CODE> to create all output
|
|
|
258 |
files regardless of date stamps.
|
|
|
259 |
<LI>The <B>-i</B> option causes <CODE>tspec</CODE> to print an index
|
|
|
260 |
of all the objects in the input files (see <A HREF="#Index">section
|
|
|
261 |
6.3</A>).
|
|
|
262 |
<LI>The <B>-p</B> option indicates to <CODE>tspec</CODE> that its
|
|
|
263 |
input has already been preprocessed (i.e. it is the output of a previous
|
|
|
264 |
<B>-e</B> option).
|
|
|
265 |
<LI>The <B>-r</B> option causes <CODE>tspec</CODE> to only produce
|
|
|
266 |
output for implemented objects, and not used objects (see <A HREF="#Impl">section
|
|
|
267 |
3.2</A>).
|
|
|
268 |
<LI>The <B>-s</B> option causes <CODE>tspec</CODE> to check all the
|
|
|
269 |
headers in an API separately rather than, as with the <B>-c</B> option,
|
|
|
270 |
all at once.
|
|
|
271 |
<LI>The <B>-u</B> option causes <CODE>tspec</CODE> to generate unique
|
|
|
272 |
token names for the specified objects (see <A HREF="#Names">section
|
|
|
273 |
4.1.1</A>).
|
|
|
274 |
<LI>The <B>-v</B> option causes <CODE>tspec</CODE> to enter verbose
|
|
|
275 |
mode, in which it reports on the output files it creates. If two <B>-v</B>
|
|
|
276 |
options are given then <CODE>tspec</CODE> enters very verbose mode,
|
|
|
277 |
in which it gives more information on its activities.
|
|
|
278 |
<LI>The <B>-V</B> option causes <CODE>tspec</CODE> to print its current
|
|
|
279 |
version number (this document refers to version 2.0).
|
|
|
280 |
</UL>
|
|
|
281 |
<P>
|
|
|
282 |
In addition <CODE>tspec</CODE> has a local input mode for translating
|
|
|
283 |
single headers which are not part of an API into the corresponding
|
|
|
284 |
<CODE>#pragma token</CODE> statements. The form:
|
|
|
285 |
<PRE>
|
|
|
286 |
tspec [options] -l file
|
|
|
287 |
</PRE>
|
|
|
288 |
processes the input file <CODE>file</CODE>, writing the include output
|
|
|
289 |
file to the standard output.
|
|
|
290 |
<P>
|
|
|
291 |
<HR>
|
|
|
292 |
|
|
|
293 |
<H2><A NAME="Structure">3. Specifying API Structure</A></H2>
|
|
|
294 |
<P>
|
|
|
295 |
The basic form of the <CODE>tspec</CODE> description of an API has
|
|
|
296 |
already been explained in <A HREF="#Input">section 2.2</A> - it is
|
|
|
297 |
a directory containing a set of files corresponding to the headers
|
|
|
298 |
in that API. Each file basically consists of a list of the objects
|
|
|
299 |
declared in that header. Each object specification is part of a <CODE>tspec
|
|
|
300 |
</CODE>
|
|
|
301 |
construct. These constructs are identified by keywords. These keywords
|
|
|
302 |
always begin with <CODE>+</CODE> to avoid conflict with C identifiers.
|
|
|
303 |
Comments may be inserted at any point. These are prefixed by <CODE>#</CODE>
|
|
|
304 |
and run to the end of the line.
|
|
|
305 |
<P>
|
|
|
306 |
In addition to the basic object specification constructs, <CODE>tspec</CODE>
|
|
|
307 |
also has constructs for imposing structure on the API description.
|
|
|
308 |
It is these constructs that we consider first.
|
|
|
309 |
<H3><A NAME="Subset">3.1. +SUBSET</A></H3>
|
|
|
310 |
<P>
|
|
|
311 |
A list of <CODE>tspec</CODE> constructs within a header can be grouped
|
|
|
312 |
into a named subset by enclosing them within:
|
|
|
313 |
<PRE>
|
|
|
314 |
+SUBSET "name" := {
|
|
|
315 |
....
|
|
|
316 |
} ;
|
|
|
317 |
</PRE>
|
|
|
318 |
where <CODE>name</CODE> is the subset name. These named subsets can
|
|
|
319 |
be nested, but are still regarded as subsets of the parent header.
|
|
|
320 |
<P>
|
|
|
321 |
Subsets are intended to give a layer of resolution beyond that of
|
|
|
322 |
the entire header (see <A HREF="#Levels">section 2.1</A>). Each subset
|
|
|
323 |
is mapped onto a separate pair of output files, so unwary use of subsets
|
|
|
324 |
is discouraged.
|
|
|
325 |
<H3><A NAME="Impl">3.2. +IMPLEMENT and +USE</A></H3>
|
|
|
326 |
<P>
|
|
|
327 |
<CODE>tspec</CODE> has two import constructs which allow one API,
|
|
|
328 |
or header, or subset of a header to be included in another. The first
|
|
|
329 |
construct is used to indicate that the given set of objects is also
|
|
|
330 |
declared in the including header, and takes one of the forms:
|
|
|
331 |
<PRE>
|
|
|
332 |
+IMPLEMENT "api" ;
|
|
|
333 |
+IMPLEMENT "api", "header" ;
|
|
|
334 |
+IMPLEMENT "api", "header", "subset" ;
|
|
|
335 |
</PRE>
|
|
|
336 |
The second construct is used to indicate that the objects are only
|
|
|
337 |
used in the including header, and take one of the forms:
|
|
|
338 |
<PRE>
|
|
|
339 |
+USE "api" ;
|
|
|
340 |
+USE "api", "header" ;
|
|
|
341 |
+USE "api", "header", "subset" ;
|
|
|
342 |
</PRE>
|
|
|
343 |
For example, <CODE>posix:stdio.h</CODE> is an extension of <CODE>ansi:stdio.h
|
|
|
344 |
</CODE>, so, rather than duplicate all the object specifications from
|
|
|
345 |
the latter in the former, it is easier and clearer to use the construct:
|
|
|
346 |
<PRE>
|
|
|
347 |
+IMPLEMENT "ansi", "stdio.h" ;
|
|
|
348 |
</PRE>
|
|
|
349 |
and just add the extra objects specified by POSIX. Note that this
|
|
|
350 |
makes the relationship between the APIs <CODE>ansi</CODE> and <CODE>posix</CODE>
|
|
|
351 |
absolutely explicit. <CODE>tspec</CODE> is as much concerned with
|
|
|
352 |
the relationships between APIs as their actual contents.
|
|
|
353 |
<P>
|
|
|
354 |
Objects which are specified as being declared in more than one header
|
|
|
355 |
of an API should also be treated using <CODE>+IMPLEMENT</CODE>. For
|
|
|
356 |
example, the type <CODE>size_t</CODE> is declared in a number of <CODE>ansi
|
|
|
357 |
</CODE> headers, namely <CODE>stddef.h</CODE>, <CODE>stdio.h</CODE>,
|
|
|
358 |
<CODE>string.h</CODE> and <CODE>time.h</CODE>. This can be handled
|
|
|
359 |
by declaring <CODE>size_t</CODE> as part of a named subset of, say,
|
|
|
360 |
<CODE>ansi:stddef.h</CODE>:
|
|
|
361 |
<PRE>
|
|
|
362 |
+SUBSET "size_t" := {
|
|
|
363 |
+TYPE (unsigned) size_t ;
|
|
|
364 |
} ;
|
|
|
365 |
</PRE>
|
|
|
366 |
and including this in each of the other headers:
|
|
|
367 |
<PRE>
|
|
|
368 |
+IMPLEMENT "ansi", "stddef.h", "size_t" ;
|
|
|
369 |
</PRE>
|
|
|
370 |
<P>
|
|
|
371 |
Another use of <CODE>+IMPLEMENT</CODE> is in the <CODE>MASTER</CODE>
|
|
|
372 |
file used to list the headers in an API (see <A HREF="#Input">section
|
|
|
373 |
2.2</A>). This basically consists of a list of <CODE>+IMPLEMENT</CODE>
|
|
|
374 |
commands, one per header. For example, with <CODE>ansi</CODE> it consists
|
|
|
375 |
of:
|
|
|
376 |
<PRE>
|
|
|
377 |
+IMPLEMENT "ansi", "assert.h" ;
|
|
|
378 |
+IMPLEMENT "ansi", "ctype.h" ;
|
|
|
379 |
....
|
|
|
380 |
+IMPLEMENT "ansi", "time.h" ;
|
|
|
381 |
</PRE>
|
|
|
382 |
<P>
|
|
|
383 |
To illustrate <CODE>+USE</CODE>, <CODE>posix:sys/stat.h</CODE> uses
|
|
|
384 |
some types from <CODE>posix:sys/types.h</CODE> but does not define
|
|
|
385 |
them. To avoid the user having to include both headers it makes sense
|
|
|
386 |
for the description to include the latter in the former (provided
|
|
|
387 |
there are no namespace restrictions imposed by the API). This would
|
|
|
388 |
be done using the construct:
|
|
|
389 |
<PRE>
|
|
|
390 |
+USE "posix", "sys/types.h" ;
|
|
|
391 |
</PRE>
|
|
|
392 |
<P>
|
|
|
393 |
On the command-line <CODE>tspec</CODE> is given one set of objects,
|
|
|
394 |
be it an API, a header, or a subset of a header. This causes it to
|
|
|
395 |
read that set, which may contain <CODE>+IMPLEMENT</CODE> or <CODE>+USE</CODE>
|
|
|
396 |
commands. It then reads the sets indicated by these commands, which
|
|
|
397 |
again may contain <CODE>+IMPLEMENT</CODE> or <CODE>+USE</CODE> commands,
|
|
|
398 |
and so on. It is possible for this process to lead to infinite cycles,
|
|
|
399 |
but in this case <CODE>tspec</CODE> raises an error and aborts. In
|
|
|
400 |
the legal case, the collection of sets read by <CODE>tspec</CODE>
|
|
|
401 |
is the closure of the set given on the command-line under <CODE>+IMPLEMENT
|
|
|
402 |
</CODE> and <CODE>+USE</CODE>. Some of these sets will be implemented
|
|
|
403 |
- that it to say, connected to the top level by a chain of <CODE>+IMPLEMENT
|
|
|
404 |
</CODE> commands - others will merely be used. By default <CODE>tspec</CODE>
|
|
|
405 |
produces output for all these sets, but specifying the <B>-r</B> command-line
|
|
|
406 |
option restricts it to the implemented sets.
|
|
|
407 |
<P>
|
|
|
408 |
For further information on the <CODE>+IMPLEMENT</CODE> and <CODE>+USE</CODE>
|
|
|
409 |
commands see <A HREF="#FineImpl">section 6.1</A>.
|
|
|
410 |
<P>
|
|
|
411 |
<HR>
|
|
|
412 |
|
|
|
413 |
<H2><A NAME="Objects">4. Specifying Objects</A></H2>
|
|
|
414 |
<P>
|
|
|
415 |
The main body of any <CODE>tspec</CODE> description of an API consists
|
|
|
416 |
of a list of object specifications. Most of this section is concerned
|
|
|
417 |
with the various <CODE>tspec</CODE> constructs for specifying objects
|
|
|
418 |
of various kinds, however we start with a few remarks on object names.
|
|
|
419 |
|
|
|
420 |
<H3><A NAME="S41">4.1. Object Names</A></H3>
|
|
|
421 |
<H4><A NAME="Names">4.1.1. Internal and External Names</A></H4>
|
|
|
422 |
<P>
|
|
|
423 |
All objects specified using <CODE>tspec</CODE> actually have two names.
|
|
|
424 |
The first is the internal name by which it is identified within the
|
|
|
425 |
program, the second is the external name by which the TDF construct
|
|
|
426 |
(actually a token) representing this object is referred to for the
|
|
|
427 |
purposes of TDF linking. The internal names are normal C identifiers
|
|
|
428 |
and obey the normal C namespace rules (indeed one of the roles of
|
|
|
429 |
<CODE>tspec</CODE> is to keep track of these namespaces). The external
|
|
|
430 |
token name is constructed by <CODE>tspec</CODE> from the internal
|
|
|
431 |
name.
|
|
|
432 |
<P>
|
|
|
433 |
<CODE>tspec</CODE> has two strategies for making up these token names.
|
|
|
434 |
The first, which is default, is to use the internal name as the external
|
|
|
435 |
name (there is an exception to this simple rule, namely field selectors
|
|
|
436 |
- see <A HREF="#Field">section 4.9</A>). The second, which is preferred
|
|
|
437 |
for standard APIs, is to construct a "unique name" from
|
|
|
438 |
the API name, the header and the internal name. For example, under
|
|
|
439 |
the first strategy, the external name of the type <CODE>FILE</CODE>
|
|
|
440 |
specified in <CODE>ansi:stdio.h</CODE> would be <CODE>FILE</CODE>,
|
|
|
441 |
whereas under the second it would be <CODE>ansi.stdio.FILE</CODE>.
|
|
|
442 |
The unique name strategy may be specified by passing the <B>-u</B>
|
|
|
443 |
command-line option to <CODE>tspec</CODE> (see <A HREF="#Options">section
|
|
|
444 |
2.5</A>) or by setting the <CODE>UNIQUE</CODE> property to 1 (see
|
|
|
445 |
<A HREF="#Properties">section 5.4</A>).
|
|
|
446 |
<P>
|
|
|
447 |
Both strategies involve flattening the several C namespaces into the
|
|
|
448 |
single TDF token namespace, which can lead to clashes. For example,
|
|
|
449 |
in <CODE>posix:sys/stat.h</CODE> both a structure, <CODE>struct stat</CODE>,
|
|
|
450 |
and a procedure, <CODE>stat</CODE>, are specified. In C the two uses
|
|
|
451 |
of <CODE>stat</CODE> are in different namespaces and so present no
|
|
|
452 |
difficulty, however they are mapped onto the same name in the TDF
|
|
|
453 |
token namespace. To work round such difficulties, <CODE>tspec</CODE>
|
|
|
454 |
allows an alternative external form to be specified. When the object
|
|
|
455 |
is specified the form:
|
|
|
456 |
<PRE>
|
|
|
457 |
iname | ename
|
|
|
458 |
</PRE>
|
|
|
459 |
may be used to specify the internal name <CODE>iname</CODE> and the
|
|
|
460 |
external name <CODE>ename</CODE>.
|
|
|
461 |
<P>
|
|
|
462 |
For example, in the <CODE>stat</CODE> case above we could distinguish
|
|
|
463 |
between the two uses as follows:
|
|
|
464 |
<PRE>
|
|
|
465 |
+TYPE struct stat | struct_stat ;
|
|
|
466 |
+FUNC int stat ( const char *, struct stat * ) ;
|
|
|
467 |
</PRE>
|
|
|
468 |
With simple token names the token corresponding to the structure would
|
|
|
469 |
be called <CODE>struct_stat</CODE>, whereas that corresponding to
|
|
|
470 |
the procedure would still be <CODE>stat</CODE>. With unique token
|
|
|
471 |
names the names would be <CODE>posix.stat.struct_stat</CODE> and <CODE>posix.stat.stat
|
|
|
472 |
</CODE> respectively.
|
|
|
473 |
<P>
|
|
|
474 |
Very occasionally it may be necessary to precisely specify an external
|
|
|
475 |
token name. This can be done using the form:
|
|
|
476 |
<PRE>
|
|
|
477 |
iname | "ename"
|
|
|
478 |
</PRE>
|
|
|
479 |
which makes the object <CODE>iname</CODE> have external name <CODE>ename</CODE>
|
|
|
480 |
regardless of the naming strategy used.
|
|
|
481 |
<H4><A NAME="Identifiers">4.1.2. More on Object Names</A></H4>
|
|
|
482 |
<P>
|
|
|
483 |
Basically the legal identifiers in <CODE>tspec</CODE> (for both internal
|
|
|
484 |
and external names) are the same as those in C - strings of upper
|
|
|
485 |
and lower case letters, decimal digits or underscores, which do not
|
|
|
486 |
begin with a decimal digit. However there is a second class of local
|
|
|
487 |
identifiers - those consisting of a tilde followed by any number of
|
|
|
488 |
letters, digits or underscores - which are intended to indicate objects
|
|
|
489 |
which are local to the API description and should not be visible to
|
|
|
490 |
any application using the API. For example, to express the specification
|
|
|
491 |
that <CODE>t</CODE> is a pointer type, we could say that there is
|
|
|
492 |
a locally named type to which <CODE>t</CODE> is a pointer:
|
|
|
493 |
<PRE>
|
|
|
494 |
+TYPE ~t ;
|
|
|
495 |
+TYPEDEF ~t *t ;
|
|
|
496 |
</PRE>
|
|
|
497 |
<P>
|
|
|
498 |
Finally it is possible to cheat the <CODE>tspec</CODE> namespaces.
|
|
|
499 |
It may actually be legal to have two objects of the same name in an
|
|
|
500 |
API - they may lie in different branches of a conditional compilation,
|
|
|
501 |
or not be allowed to coexist. To allow for this, <CODE>tspec</CODE>
|
|
|
502 |
allows version numbers, consisting of a decimal pointer plus a number
|
|
|
503 |
of digits, to be appended to an identifier name when it is first introduced.
|
|
|
504 |
These version numbers are purely to tell <CODE>tspec</CODE> that this
|
|
|
505 |
version of the object is different from a previous version with a
|
|
|
506 |
different version number (or indeed without any version number). If
|
|
|
507 |
more than one version of an object is specified then which version
|
|
|
508 |
is retrieved by <CODE>tspec</CODE> in any look-up operation is undefined.
|
|
|
509 |
|
|
|
510 |
<H3><A NAME="Func">4.2. +FUNC</A></H3>
|
|
|
511 |
<P>
|
|
|
512 |
The simplest form of object to specify is a procedure. This is done
|
|
|
513 |
by means of:
|
|
|
514 |
<PRE>
|
|
|
515 |
+FUNC prototype ;
|
|
|
516 |
</PRE>
|
|
|
517 |
where <CODE>prototype</CODE> is the full C prototype of the procedure
|
|
|
518 |
being declared. For example, <CODE>ansi:string.h</CODE> contains:
|
|
|
519 |
<PRE>
|
|
|
520 |
+FUNC char *strcpy ( char *, const char * ) ;
|
|
|
521 |
+FUNC int strcmp ( const char *, const char * ) ;
|
|
|
522 |
+FUNC size_t strlen ( const char * ) ;
|
|
|
523 |
</PRE>
|
|
|
524 |
<P>
|
|
|
525 |
Strictly speaking, <CODE>+FUNC</CODE> means that the procedure may
|
|
|
526 |
be implemented by a macro, but that there is an underlying library
|
|
|
527 |
function with the same effect. The exception is for procedures which
|
|
|
528 |
take a variable number of arguments, such as:
|
|
|
529 |
<PRE>
|
|
|
530 |
+FUNC int fprintf ( FILE *, const char *, ... ) ;
|
|
|
531 |
</PRE>
|
|
|
532 |
which cannot be implemented by macros. Occasionally it may be necessary
|
|
|
533 |
to specify that a procedure is only a library function, and cannot
|
|
|
534 |
be implemented by a macro. In this case the form:
|
|
|
535 |
<PRE>
|
|
|
536 |
+FUNC (extern) prototype ;
|
|
|
537 |
</PRE>
|
|
|
538 |
should be used. Thus:
|
|
|
539 |
<PRE>
|
|
|
540 |
+FUNC (extern) char *strcpy ( char *, const char * ) ;
|
|
|
541 |
</PRE>
|
|
|
542 |
would mean that <CODE>strcpy</CODE> was only a library function and
|
|
|
543 |
not a macro.
|
|
|
544 |
<P>
|
|
|
545 |
Increasingly standard APIs are using prototypes to express their procedures.
|
|
|
546 |
However it still may be necessary on occasion to specify procedures
|
|
|
547 |
declared using old style declarations. In most cases these can be
|
|
|
548 |
easily transcribed into prototype declarations, however things are
|
|
|
549 |
not always that simple. For example, <CODE>xpg3:stdlib.h</CODE> declares
|
|
|
550 |
<CODE>malloc</CODE> by the old style declaration:
|
|
|
551 |
<PRE>
|
|
|
552 |
void *malloc ( sz )
|
|
|
553 |
size_t sz ;
|
|
|
554 |
</PRE>
|
|
|
555 |
which is in general different from the prototype:
|
|
|
556 |
<PRE>
|
|
|
557 |
void *malloc ( size_t ) ;
|
|
|
558 |
</PRE>
|
|
|
559 |
In the first case the argument is passed as the integral promotion
|
|
|
560 |
of <CODE>size_t</CODE>, whereas in the second it is passed as a <CODE>size_t
|
|
|
561 |
</CODE>. In general we only know that <CODE>size_t</CODE> is an unsigned
|
|
|
562 |
integral type, so we cannot assert that it is its own integral promotion.
|
|
|
563 |
One possible solution would be to use the C to TDF producer's weak
|
|
|
564 |
prototypes (see reference 3). The form:
|
|
|
565 |
<PRE>
|
|
|
566 |
+FUNC (weak) void *malloc ( size_t ) ;
|
|
|
567 |
</PRE>
|
|
|
568 |
means that <CODE>malloc</CODE> is a library function returning <CODE>void
|
|
|
569 |
*</CODE> which is declared using an old style declaration with a single
|
|
|
570 |
argument of type <CODE>size_t</CODE>. (For an alternative approach
|
|
|
571 |
see <A HREF="#Typedef">section 4.8</A>.)
|
|
|
572 |
<H3><A NAME="Exp">4.3. +EXP and +CONST</A></H3>
|
|
|
573 |
<P>
|
|
|
574 |
Expressions correspond to constants, identities and variables. They
|
|
|
575 |
are specified by:
|
|
|
576 |
<PRE>
|
|
|
577 |
+EXP type exp1, ..., expn ;
|
|
|
578 |
</PRE>
|
|
|
579 |
where <CODE>type</CODE> is the base type of the expressions <CODE>expi</CODE>
|
|
|
580 |
as in a normal C declaration list. For example, in <CODE>ansi:stdio.h</CODE>:
|
|
|
581 |
<PRE>
|
|
|
582 |
+EXP FILE *stdin, *stdout, *stderr ;
|
|
|
583 |
</PRE>
|
|
|
584 |
specifies three expressions of type <CODE>FILE *</CODE>.
|
|
|
585 |
<P>
|
|
|
586 |
By default all expressions are rvalues, that is, values which cannot
|
|
|
587 |
be assigned to. If an lvalue (assignable) expression is required its
|
|
|
588 |
type should be qualified using the keyword <CODE>lvalue</CODE>. This
|
|
|
589 |
is an extension to the C type syntax which is used in a similar fashion
|
|
|
590 |
to <CODE>const</CODE>. For example, <CODE>ansi:errno.h</CODE> says
|
|
|
591 |
that <CODE>errno</CODE> is an assignable lvalue of type <CODE>int</CODE>.
|
|
|
592 |
This is expressed as follows:
|
|
|
593 |
<PRE>
|
|
|
594 |
+EXP lvalue int errno ;
|
|
|
595 |
</PRE>
|
|
|
596 |
On the other hand, <CODE>posix:errno.h</CODE> states that <CODE>errno</CODE>
|
|
|
597 |
is an external value of type <CODE>int</CODE>. As with procedures
|
|
|
598 |
the <CODE>(extern)</CODE> qualifier may be used to express this as:
|
|
|
599 |
<PRE>
|
|
|
600 |
+EXP (extern) int errno ;
|
|
|
601 |
</PRE>
|
|
|
602 |
Note that this automatically means that <CODE>errno</CODE> is an lvalue,
|
|
|
603 |
so the <CODE>lvalue</CODE> qualifier is optional in this case.
|
|
|
604 |
<P>
|
|
|
605 |
If all the expressions are guaranteed to be literal constants then
|
|
|
606 |
one of the equivalent forms:
|
|
|
607 |
<PRE>
|
|
|
608 |
+EXP (const) type exp1, ..., expn ;
|
|
|
609 |
+CONST type exp1, ..., expn ;
|
|
|
610 |
</PRE>
|
|
|
611 |
should be used. For example, in <CODE>ansi:errno.h</CODE> we have:
|
|
|
612 |
<PRE>
|
|
|
613 |
+CONST int EDOM, ERANGE ;
|
|
|
614 |
</PRE>
|
|
|
615 |
<P>
|
|
|
616 |
|
|
|
617 |
<H3><A NAME="Macro">4.4. +MACRO</A></H3>
|
|
|
618 |
<P>
|
|
|
619 |
The <CODE>+MACRO</CODE> construct is similar in form to the <CODE>+FUNC</CODE>
|
|
|
620 |
construct, except that it means that only a macro exists, and no underlying
|
|
|
621 |
library function. For example, in <CODE>xpg3:ctype.h</CODE> we have:
|
|
|
622 |
<PRE>
|
|
|
623 |
+MACRO int _toupper ( int ) ;
|
|
|
624 |
+MACRO int _tolower ( int ) ;
|
|
|
625 |
</PRE>
|
|
|
626 |
since these are explicitly stated to be macros and not functions.
|
|
|
627 |
Of course the <CODE>(extern)</CODE> qualifier cannot be used with
|
|
|
628 |
<CODE>+MACRO</CODE>.
|
|
|
629 |
<P>
|
|
|
630 |
One thing which macros can do which functions cannot is to return
|
|
|
631 |
assignable values or to assign to their arguments. Thus it is legitimate
|
|
|
632 |
for <CODE>+MACRO</CODE> constructs to have their return type or argument
|
|
|
633 |
types qualified by <CODE>lvalue</CODE>, whereas this is not allowed
|
|
|
634 |
for <CODE>+FUNC</CODE> constructs. For example, in <CODE>svid3:curses.h</CODE>,
|
|
|
635 |
a macro <CODE>getyx</CODE> is specified which takes a pointer to a
|
|
|
636 |
window and two integer variables and assigns the cursor position of
|
|
|
637 |
the window to those variables. This may be expressed by:
|
|
|
638 |
<PRE>
|
|
|
639 |
+MACRO void getyx ( WINDOW *win, lvalue int y, lvalue int x ) ;
|
|
|
640 |
</PRE>
|
|
|
641 |
<P>
|
|
|
642 |
|
|
|
643 |
<H3><A NAME="Statement">4.5. +STATEMENT</A></H3>
|
|
|
644 |
<P>
|
|
|
645 |
The <CODE>+STATEMENT</CODE> construct is very similar to the <CODE>+MACRO</CODE>
|
|
|
646 |
construct except that, instead of being a C expression, it is a C
|
|
|
647 |
statement (i.e. something ending in a semicolon). As such it does
|
|
|
648 |
not have a return type and so takes one of the forms:
|
|
|
649 |
<PRE>
|
|
|
650 |
+STATEMENT stmt ;
|
|
|
651 |
+STATEMENT stmt ( arg1, ..., argn ) ;
|
|
|
652 |
</PRE>
|
|
|
653 |
depending on whether or not it takes any arguments. (A <CODE>+MACRO</CODE>
|
|
|
654 |
without any arguments is an <CODE>+EXP</CODE>, so the no argument
|
|
|
655 |
form does not exist for <CODE>+MACRO</CODE>.) As with <CODE>+MACRO</CODE>,
|
|
|
656 |
the argument types <CODE>argi</CODE> can be qualified using <CODE>lvalue</CODE>.
|
|
|
657 |
|
|
|
658 |
<H3><A NAME="Define">4.6. +DEFINE</A></H3>
|
|
|
659 |
<P>
|
|
|
660 |
It is possible to insert macro definitions directly into <CODE>tspec</CODE>
|
|
|
661 |
using the <CODE>+DEFINE</CODE> construct. This has two forms depending
|
|
|
662 |
on whether the macro has arguments:
|
|
|
663 |
<PRE>
|
|
|
664 |
+DEFINE name %% text %% ;
|
|
|
665 |
+DEFINE name ( arg1, ..., argn ) %% text %% ;
|
|
|
666 |
</PRE>
|
|
|
667 |
These translate directly into:
|
|
|
668 |
<PRE>
|
|
|
669 |
#define name text
|
|
|
670 |
#define name( arg1, ..., argn ) text
|
|
|
671 |
</PRE>
|
|
|
672 |
<P>
|
|
|
673 |
The macro definition, <CODE>text</CODE>, consists of any string of
|
|
|
674 |
characters delimited by double percents. If <CODE>text</CODE> is a
|
|
|
675 |
simple number or a single identifier then the double percents may
|
|
|
676 |
be omitted. Thus in <CODE>ansi:stddef.h</CODE> we have:
|
|
|
677 |
<PRE>
|
|
|
678 |
+DEFINE NULL 0 ;
|
|
|
679 |
</PRE>
|
|
|
680 |
<P>
|
|
|
681 |
|
|
|
682 |
<H3><A NAME="Type">4.7. +TYPE</A></H3>
|
|
|
683 |
<P>
|
|
|
684 |
New types may be specified using the <CODE>+TYPE</CODE> construct.
|
|
|
685 |
This has the form:
|
|
|
686 |
<PRE>
|
|
|
687 |
+TYPE type1, ..., typen ;
|
|
|
688 |
</PRE>
|
|
|
689 |
where each <CODE>typei</CODE> has one of the forms:
|
|
|
690 |
<UL>
|
|
|
691 |
<LI><CODE>name</CODE> for a general type (about which we know nothing
|
|
|
692 |
more),
|
|
|
693 |
<LI><CODE>(struct) name</CODE> for a structure type,
|
|
|
694 |
<LI><CODE>(union) name</CODE> for a union type,
|
|
|
695 |
<LI><CODE>struct name</CODE> for a structure tag,
|
|
|
696 |
<LI><CODE>union name</CODE> for a union tag,
|
|
|
697 |
<LI><CODE>(int) name</CODE> for an integral type,
|
|
|
698 |
<LI><CODE>(signed) name</CODE> for a signed integral type,
|
|
|
699 |
<LI><CODE>(unsigned) name</CODE> for an unsigned integral type,
|
|
|
700 |
<LI><CODE>(float) name</CODE> for a floating type,
|
|
|
701 |
<LI><CODE>(arith) name</CODE> for an arithmetic (integral or floating)
|
|
|
702 |
type,
|
|
|
703 |
<LI><CODE>(scalar) name</CODE> for a scalar (arithmetic or pointer)
|
|
|
704 |
type.
|
|
|
705 |
</UL>
|
|
|
706 |
<P>
|
|
|
707 |
To make clear the distinction between structure types and structure
|
|
|
708 |
tags, if we have in C:
|
|
|
709 |
<PRE>
|
|
|
710 |
typedef struct tag { int x, y ; } type ;
|
|
|
711 |
</PRE>
|
|
|
712 |
then <CODE>type</CODE> is a structure type and <CODE>tag</CODE> is
|
|
|
713 |
a structure tag.
|
|
|
714 |
<P>
|
|
|
715 |
For example, in <CODE>ansi</CODE> we have:
|
|
|
716 |
<PRE>
|
|
|
717 |
+TYPE FILE ;
|
|
|
718 |
+TYPE struct lconv ;
|
|
|
719 |
+TYPE (struct) div_t ;
|
|
|
720 |
+TYPE (signed) ptrdiff_t ;
|
|
|
721 |
+TYPE (unsigned) size_t ;
|
|
|
722 |
+TYPE (arith) time_t ;
|
|
|
723 |
+TYPE (int) wchar_t ;
|
|
|
724 |
</PRE>
|
|
|
725 |
|
|
|
726 |
<H3><A NAME="Typedef">4.8. +TYPEDEF</A></H3>
|
|
|
727 |
<P>
|
|
|
728 |
It is also possible to define new types in terms of existing types.
|
|
|
729 |
This is done using the <CODE>+TYPEDEF</CODE> construct, which is identical
|
|
|
730 |
in form to the C <CODE>typedef</CODE> construct. This construct can
|
|
|
731 |
be used to define pointer, procedure and array types, but not compound
|
|
|
732 |
structure and union types. For these see <A HREF="#Field">section
|
|
|
733 |
4.9</A>
|
|
|
734 |
below.
|
|
|
735 |
<P>
|
|
|
736 |
For example, in <CODE>xpg3:search.h</CODE> we have:
|
|
|
737 |
<PRE>
|
|
|
738 |
+TYPE struct entry ;
|
|
|
739 |
+TYPEDEF struct entry ENTRY ;
|
|
|
740 |
</PRE>
|
|
|
741 |
<P>
|
|
|
742 |
There are a couple of special forms. To understand the first, note
|
|
|
743 |
that C uses <CODE>void</CODE> function returns for two purposes. Firstly
|
|
|
744 |
to indicate that the function does not return a value, and secondly
|
|
|
745 |
to indicate that the function does not return at all (<CODE>exit</CODE>
|
|
|
746 |
is an example of this second usage). In TDF terms, in the first case
|
|
|
747 |
the function returns <CODE>TOP</CODE>, in the second it returns <CODE>BOTTOM
|
|
|
748 |
</CODE>. <CODE>tspec</CODE> allows types to be introduced which have
|
|
|
749 |
the second meaning. For example, we could have:
|
|
|
750 |
<PRE>
|
|
|
751 |
+TYPEDEF ~special ( "bottom" ) ~bottom ;
|
|
|
752 |
+FUNC ~bottom exit ( int ) ;
|
|
|
753 |
</PRE>
|
|
|
754 |
meaning that the local type <CODE>~bottom</CODE> is the <CODE>BOTTOM</CODE>
|
|
|
755 |
form of <CODE>void</CODE>. The procedure <CODE>exit</CODE>, which
|
|
|
756 |
never returns, can then be declared to return <CODE>~bottom</CODE>
|
|
|
757 |
rather than <CODE>void</CODE>. Other such special types may be added
|
|
|
758 |
in future.
|
|
|
759 |
<P>
|
|
|
760 |
The second special form:
|
|
|
761 |
<PRE>
|
|
|
762 |
+TYPEDEF ~promote ( x ) y ;
|
|
|
763 |
</PRE>
|
|
|
764 |
means that <CODE>y</CODE> is an integral type which is the integral
|
|
|
765 |
promotion of <CODE>x</CODE>. <CODE>x</CODE> must have previously been
|
|
|
766 |
declared as an integral type. This gives an alternative approach to
|
|
|
767 |
the old style procedure declaration problem described in
|
|
|
768 |
<A HREF="#Func">section 4.2</A>. Recall that:
|
|
|
769 |
<PRE>
|
|
|
770 |
void *malloc ( sz )
|
|
|
771 |
size_t sz ;
|
|
|
772 |
</PRE>
|
|
|
773 |
means that <CODE>malloc</CODE> has one argument which is passed as
|
|
|
774 |
the integral promotion of <CODE>size_t</CODE>. This could be expressed
|
|
|
775 |
as follows:
|
|
|
776 |
<PRE>
|
|
|
777 |
+TYPEDEF ~promote ( size_t ) ~size_t ;
|
|
|
778 |
+FUNC void *malloc ( ~size_t ) ;
|
|
|
779 |
</PRE>
|
|
|
780 |
introducing a local type to stand for the integral promotion of <CODE>size_t
|
|
|
781 |
</CODE>.
|
|
|
782 |
<H3><A NAME="Field">4.9. +FIELD</A></H3>
|
|
|
783 |
<P>
|
|
|
784 |
Having specified a structure or union type, or a structure or union
|
|
|
785 |
tag, we may wish to specify certain fields of this structure or union.
|
|
|
786 |
This is done using the <CODE>+FIELD</CODE> construct. This takes the
|
|
|
787 |
form:
|
|
|
788 |
<PRE>
|
|
|
789 |
+FIELD type {
|
|
|
790 |
ftype field1, ..., fieldn ;
|
|
|
791 |
....
|
|
|
792 |
} ;
|
|
|
793 |
</PRE>
|
|
|
794 |
where <CODE>type</CODE> is the structure or union type and <CODE>field1</CODE>,
|
|
|
795 |
..., <CODE>fieldn</CODE> are field selectors derived from the base
|
|
|
796 |
type <CODE>ftype</CODE> as in a normal C structure definition. <CODE>type</CODE>
|
|
|
797 |
may have one of the forms:
|
|
|
798 |
<UL>
|
|
|
799 |
<LI><CODE>(struct) name</CODE> for a structure type,
|
|
|
800 |
<LI><CODE>(union) name</CODE> for a union type,
|
|
|
801 |
<LI><CODE>struct name</CODE> for a structure tag,
|
|
|
802 |
<LI><CODE>union name</CODE> for a union tag,
|
|
|
803 |
<LI><CODE>name</CODE> for a previously declared structure or union
|
|
|
804 |
type.
|
|
|
805 |
</UL>
|
|
|
806 |
<P>
|
|
|
807 |
Except in the final case (where it is not clear if <CODE>type</CODE>
|
|
|
808 |
is a structure or a union), it is not necessary to have previously
|
|
|
809 |
introduced <CODE>type</CODE> using a <CODE>+TYPE</CODE> construct
|
|
|
810 |
- this declaration is implicit in the <CODE>+FIELD</CODE> construct.
|
|
|
811 |
<P>
|
|
|
812 |
For example, in <CODE>ansi:time.h</CODE> we have:
|
|
|
813 |
<PRE>
|
|
|
814 |
+FIELD struct tm {
|
|
|
815 |
int tm_sec ;
|
|
|
816 |
int tm_min ;
|
|
|
817 |
int tm_hour ;
|
|
|
818 |
int tm_mday ;
|
|
|
819 |
int tm_mon ;
|
|
|
820 |
int tm_year ;
|
|
|
821 |
int tm_wday ;
|
|
|
822 |
int tm_yday ;
|
|
|
823 |
int tm_isdst ;
|
|
|
824 |
} ;
|
|
|
825 |
</PRE>
|
|
|
826 |
meaning that there exists a structure with tag <CODE>tm</CODE> with
|
|
|
827 |
various fields of type <CODE>int</CODE>. Any implementation must have
|
|
|
828 |
these corresponding fields, but they need not be in the given order,
|
|
|
829 |
nor do they have to comprise the whole structure.
|
|
|
830 |
<P>
|
|
|
831 |
As was mentioned above (in <A HREF="#Names">4.1.1</A>), field selectors
|
|
|
832 |
form a special case when <CODE>tspec</CODE> is making up external
|
|
|
833 |
token names. For example, in the case above, the token name for the
|
|
|
834 |
<CODE>tm_sec</CODE> field is either <CODE>tm.tm_sec</CODE> or <CODE>ansi.time.tm.tm_sec
|
|
|
835 |
</CODE>, depending on whether or not unique token names are used.
|
|
|
836 |
<P>
|
|
|
837 |
It is possible to have several <CODE>+FIELD</CODE> constructs referring
|
|
|
838 |
to the same structure or union. For example, <CODE>posix:dirent.h</CODE>
|
|
|
839 |
declares a structure with tag <CODE>dirent</CODE> and one field, <CODE>d_name
|
|
|
840 |
</CODE>, of this structure. <CODE>xpg3:dirent.h</CODE> extends this
|
|
|
841 |
by adding another field, <CODE>d_ino</CODE>.
|
|
|
842 |
<P>
|
|
|
843 |
There is a second form of the <CODE>+FIELD</CODE> construct which
|
|
|
844 |
has more in common with the <CODE>+TYPEDEF</CODE> construct. The form:
|
|
|
845 |
<PRE>
|
|
|
846 |
+FIELD type := {
|
|
|
847 |
ftype field1, ..., fieldn ;
|
|
|
848 |
....
|
|
|
849 |
} ;
|
|
|
850 |
</PRE>
|
|
|
851 |
means that the type <CODE>type</CODE> is defined to be exactly the
|
|
|
852 |
given structure or union type, with precisely the given fields in
|
|
|
853 |
the given order.
|
|
|
854 |
<H3><A NAME="Nat">4.10. +NAT</A></H3>
|
|
|
855 |
<P>
|
|
|
856 |
In the example given in <A HREF="#Field">section 4.9</A>, <CODE>posix:dirent.h
|
|
|
857 |
</CODE>
|
|
|
858 |
specifies that the <CODE>d_name</CODE> field of <CODE>struct dirent</CODE>
|
|
|
859 |
is a fixed sized array of characters, but that the size of this array
|
|
|
860 |
is implementation dependent. We therefore have to introduce a value
|
|
|
861 |
to stand for the size of this array using the <CODE>+NAT</CODE> construct.
|
|
|
862 |
This has the form:
|
|
|
863 |
<PRE>
|
|
|
864 |
+NAT nat1, ..., natn ;
|
|
|
865 |
</PRE>
|
|
|
866 |
where <CODE>nat1</CODE>, ..., <CODE>natn</CODE> are the array sizes
|
|
|
867 |
to be declared. The example thus becomes:
|
|
|
868 |
<PRE>
|
|
|
869 |
+NAT ~dirent_d_name_size ;
|
|
|
870 |
+FIELD struct dirent {
|
|
|
871 |
char d_name [ ~dirent_d_name_size ] ;
|
|
|
872 |
} ;
|
|
|
873 |
</PRE>
|
|
|
874 |
Note the use of a local variable to stand for a value, namely the
|
|
|
875 |
array size, which is invisible to the user (see
|
|
|
876 |
<A HREF="#Identifiers">section 4.1.2</A>).
|
|
|
877 |
<P>
|
|
|
878 |
As another example, in <CODE>ansi:setjmp.h</CODE> we know that <CODE>jmp_buf
|
|
|
879 |
</CODE> is an array type. We therefore introduce objects to stand
|
|
|
880 |
for the type which it is an array of and for the size of the array,
|
|
|
881 |
and define <CODE>jmp_buf</CODE> by a <CODE>+TYPEDEF</CODE> command:
|
|
|
882 |
<PRE>
|
|
|
883 |
+NAT ~jmp_buf_size ;
|
|
|
884 |
+TYPE ~jmp_buf_elt ;
|
|
|
885 |
+TYPEDEF ~jmp_buf_elt jmp_buf [ ~jmp_buf_size ] ;
|
|
|
886 |
</PRE>
|
|
|
887 |
Again, local variables have been used for the introduced objects.
|
|
|
888 |
|
|
|
889 |
<H3><A NAME="Enum">4.11. +ENUM</A></H3>
|
|
|
890 |
<P>
|
|
|
891 |
Currently <CODE>tspec</CODE> only has limited support for enumeration
|
|
|
892 |
types. A <CODE>+ENUM</CODE> construct is translated directly into
|
|
|
893 |
a C definition of an enumeration type. The <CODE>+ENUM</CODE> construct
|
|
|
894 |
has the form:
|
|
|
895 |
<PRE>
|
|
|
896 |
+ENUM etype := {
|
|
|
897 |
entry,
|
|
|
898 |
....
|
|
|
899 |
} ;
|
|
|
900 |
</PRE>
|
|
|
901 |
where <CODE>etype</CODE> is the enumeration type being defined - either
|
|
|
902 |
a type name or <CODE>enum etag</CODE> for some enumeration tag <CODE>etag</CODE>
|
|
|
903 |
- and each <CODE>entry</CODE> has one of the forms:
|
|
|
904 |
<PRE>
|
|
|
905 |
name
|
|
|
906 |
name = number
|
|
|
907 |
</PRE>
|
|
|
908 |
as in a C enumeration type. For example, in <CODE>xpg3:search.h</CODE>
|
|
|
909 |
we have:
|
|
|
910 |
<PRE>
|
|
|
911 |
+ENUM ACTION := { FIND, ENTER } ;
|
|
|
912 |
</PRE>
|
|
|
913 |
|
|
|
914 |
<H3><A NAME="Token">4.12. +TOKEN</A></H3>
|
|
|
915 |
<P>
|
|
|
916 |
As was mentioned in <A HREF="#Intro">section 1</A>, the <CODE>#pragma
|
|
|
917 |
token</CODE> syntax is highly complex, and the token descriptions
|
|
|
918 |
output by <CODE>tspec</CODE> form only a small subset of those possible.
|
|
|
919 |
It is possible to directly access the full <CODE>#pragma token</CODE>
|
|
|
920 |
syntax from <CODE>tspec</CODE> using the construct:
|
|
|
921 |
<PRE>
|
|
|
922 |
+TOKEN name %% text %% ;
|
|
|
923 |
</PRE>
|
|
|
924 |
where the token <CODE>name</CODE> is defined by the sequence of characters
|
|
|
925 |
<CODE>text</CODE>, which is delimited by double percents. This is
|
|
|
926 |
turned into the token description:
|
|
|
927 |
<PRE>
|
|
|
928 |
#pragma token text name #
|
|
|
929 |
</PRE>
|
|
|
930 |
<P>
|
|
|
931 |
No checks are applied to <CODE>text</CODE>. A more sophisticated mechanism
|
|
|
932 |
for defining complex tokens may be introduced in a later version of
|
|
|
933 |
<CODE>tspec</CODE>.
|
|
|
934 |
<P>
|
|
|
935 |
For example, in <CODE>ansi:stdarg.h</CODE> a token <CODE>va_arg</CODE>
|
|
|
936 |
is defined which takes a variable of type <CODE>va_list</CODE> and
|
|
|
937 |
a type <CODE>t</CODE> and returns a value of type <CODE>t</CODE>.
|
|
|
938 |
This is given by:
|
|
|
939 |
<PRE>
|
|
|
940 |
+TOKEN va_arg %% PROC ( EXP lvalue : va_list : e, TYPE t ) EXP rvalue : t : %% ;
|
|
|
941 |
</PRE>
|
|
|
942 |
See reference 3 for more details on the token syntax.
|
|
|
943 |
<P>
|
|
|
944 |
<HR>
|
|
|
945 |
|
|
|
946 |
<H2><A NAME="Others">5. Other tspec Constructs</A></H2>
|
|
|
947 |
<P>
|
|
|
948 |
Although most <CODE>tspec</CODE> constructs are concerned either with
|
|
|
949 |
specifying new objects or imposing structure upon various sets of
|
|
|
950 |
objects, there are a few which do not fall into these categories.
|
|
|
951 |
|
|
|
952 |
<H3><A NAME="If">5.1. +IF, +ELSE and +ENDIF</A></H3>
|
|
|
953 |
<P>
|
|
|
954 |
It is possible to introduce conditional compilation into the API description
|
|
|
955 |
by means of the constructs:
|
|
|
956 |
<PRE>
|
|
|
957 |
+IF %% text %%
|
|
|
958 |
+IFDEF %% text %%
|
|
|
959 |
+IFNDEF %% text %%
|
|
|
960 |
+ELSE
|
|
|
961 |
+ENDIF
|
|
|
962 |
</PRE>
|
|
|
963 |
which are translated into:
|
|
|
964 |
<PRE>
|
|
|
965 |
#if text
|
|
|
966 |
#ifdef text
|
|
|
967 |
#ifndef text
|
|
|
968 |
#else /* text */
|
|
|
969 |
#endif /* text */
|
|
|
970 |
</PRE>
|
|
|
971 |
respectively. If <CODE>text</CODE> is just a simple number or a single
|
|
|
972 |
identifier the double percent delimiters may be excluded.
|
|
|
973 |
<P>
|
|
|
974 |
A couple of special <CODE>+IFDEF</CODE> (and also <CODE>+IFNDEF</CODE>)
|
|
|
975 |
forms are available which are useful on occasion. These are:
|
|
|
976 |
<PRE>
|
|
|
977 |
+IFDEF ~building_libs
|
|
|
978 |
+IFDEF ~protect ( "api", "header" )
|
|
|
979 |
</PRE>
|
|
|
980 |
The macros in these constructs expand respectively to <CODE>__BUILDING_LIBS
|
|
|
981 |
</CODE> which, by convention is defined if and only if TDF library
|
|
|
982 |
building is taking place (see <A HREF="#Libraries">section 6.4</A>),
|
|
|
983 |
and the protection macro <CODE>tspec</CODE> makes up to protect the
|
|
|
984 |
file
|
|
|
985 |
<CODE>api:header</CODE> against multiple inclusion (see
|
|
|
986 |
<A HREF="#Protect">section 6.2</A>).
|
|
|
987 |
<H3><A NAME="Text">5.2. Quoted Text</A></H3>
|
|
|
988 |
<P>
|
|
|
989 |
It is sometimes desirable to include text in the specification file
|
|
|
990 |
which will be copied directly into one of the output files - for example,
|
|
|
991 |
sections of C. This can be done by enclosing the text for copying
|
|
|
992 |
into the include output file in double percents:
|
|
|
993 |
<PRE>
|
|
|
994 |
%% text %%
|
|
|
995 |
</PRE>
|
|
|
996 |
and text for copying into the source output file in triple percents:
|
|
|
997 |
<PRE>
|
|
|
998 |
%%% text %%%
|
|
|
999 |
</PRE>
|
|
|
1000 |
<P>
|
|
|
1001 |
In fact more percents may be used. An even number always indicates
|
|
|
1002 |
text for the include output file, and an odd number the source output
|
|
|
1003 |
file. Note that any <CODE>#</CODE> characters in <CODE>text</CODE>
|
|
|
1004 |
are copied as normal, and not treated as comments. This also applies
|
|
|
1005 |
to the other cases where percent delimiters are used.
|
|
|
1006 |
<H3><A NAME="Comment">5.3. C Comments</A></H3>
|
|
|
1007 |
<P>
|
|
|
1008 |
A special case of quoted text are C style comments:
|
|
|
1009 |
<PRE>
|
|
|
1010 |
/* text */
|
|
|
1011 |
</PRE>
|
|
|
1012 |
which are copied directly into the include output file.
|
|
|
1013 |
<H3><A NAME="Properties">5.4. File Properties</A></H3>
|
|
|
1014 |
<P>
|
|
|
1015 |
Various properties of individual sets of objects or global properties
|
|
|
1016 |
can be set using file properties. These take the form:
|
|
|
1017 |
<PRE>
|
|
|
1018 |
$property = number ;
|
|
|
1019 |
</PRE>
|
|
|
1020 |
for numeric (or boolean) properties, and:
|
|
|
1021 |
<PRE>
|
|
|
1022 |
$property = "string" ;
|
|
|
1023 |
</PRE>
|
|
|
1024 |
for string properties.
|
|
|
1025 |
<P>
|
|
|
1026 |
The valid property names are as follows:
|
|
|
1027 |
<UL>
|
|
|
1028 |
<LI><CODE>APINAME</CODE> is a string property which may be used to
|
|
|
1029 |
override the API name of the current set of objects.
|
|
|
1030 |
<LI><CODE>FILE</CODE> is a string property which is used by the <CODE>tspec
|
|
|
1031 |
</CODE> preprocessor to indicate the current input file name.
|
|
|
1032 |
<LI><CODE>FILENAME</CODE> is a string property which may be used to
|
|
|
1033 |
override the header name of the current set of objects.
|
|
|
1034 |
<LI><CODE>INCLNAME</CODE> is a string property which may be used to
|
|
|
1035 |
set the name of the include output file in place of the default name
|
|
|
1036 |
given in <A HREF="#Output">section 2.3</A>. Setting the property to
|
|
|
1037 |
the empty string suppresses the output of this file.
|
|
|
1038 |
<LI><CODE>INTERFACE</CODE> is a numeric property which may be set
|
|
|
1039 |
to force the creation of the source output file and cleared to suppress
|
|
|
1040 |
it.
|
|
|
1041 |
<LI><CODE>LINE</CODE> is a numeric property which is used by the <CODE>tspec
|
|
|
1042 |
</CODE> preprocessor to indicate the current input file line number.
|
|
|
1043 |
<LI><CODE>METHOD</CODE> is a string property which may be used to
|
|
|
1044 |
specify alternative construction methods for TDF library building
|
|
|
1045 |
(see <A HREF="#Libraries">section 6.4</A>).
|
|
|
1046 |
<LI><CODE>PREFIX</CODE> is a string property which may be used as
|
|
|
1047 |
a prefix to unique token names in place of the API and header names
|
|
|
1048 |
(see <A HREF="#Names">section 4.1.1</A>).
|
|
|
1049 |
<LI><CODE>PROTECT</CODE> is a string property which may be used to
|
|
|
1050 |
set the macro used by <CODE>tspec</CODE> to protect the include output
|
|
|
1051 |
file against multiple inclusions (see <A HREF="#Protect">section 6.2</A>).
|
|
|
1052 |
Setting the property to the empty string suppresses this macro.
|
|
|
1053 |
<LI><CODE>SOURCENAME</CODE> is a string property which may be used
|
|
|
1054 |
to set the name of the source output file in place of the default
|
|
|
1055 |
name given in <A HREF="#Output">section 2.3</A>. Setting the property
|
|
|
1056 |
to the empty string suppresses the output of this file.
|
|
|
1057 |
<LI><CODE>SUBSETNAME</CODE> is a string property which may be used
|
|
|
1058 |
to override the subset name of the current set of objects.
|
|
|
1059 |
<LI><CODE>UNIQUE</CODE> is a numeric property which may be used to
|
|
|
1060 |
switch the unique token name flag on and off (see <A HREF="#Names">section
|
|
|
1061 |
4.1.1</A>). For standard APIs it is recommended that this property
|
|
|
1062 |
is set to 1 in the API <CODE>MASTER</CODE> file.
|
|
|
1063 |
<LI><CODE>VERBOSE</CODE> is a numeric property which may be used to
|
|
|
1064 |
set the level of the verbose option (see <A HREF="#Options">section
|
|
|
1065 |
2.5</A>).
|
|
|
1066 |
<LI><CODE>VERSION</CODE> is a string property which may be used to
|
|
|
1067 |
assign a version number or other identification to a <CODE>tspec</CODE>
|
|
|
1068 |
description. This information is reproduced in the corresponding include
|
|
|
1069 |
output file.
|
|
|
1070 |
</UL>
|
|
|
1071 |
<P>
|
|
|
1072 |
<HR>
|
|
|
1073 |
|
|
|
1074 |
<H2><A NAME="S6">6. Miscellaneous Topics</A></H2>
|
|
|
1075 |
<P>
|
|
|
1076 |
In this section we round up a few miscellaneous topics.
|
|
|
1077 |
<H3><A NAME="FineImpl">6.1. Fine Control of Included Files</A></H3>
|
|
|
1078 |
<P>
|
|
|
1079 |
The <CODE>+IMPLEMENT</CODE> and <CODE>+USE</CODE> commands described
|
|
|
1080 |
in <A HREF="#Impl">section 3.2</A> are capable of further refinement.
|
|
|
1081 |
Normally each such command is translated into a corresponding inclusion
|
|
|
1082 |
command in both the include and source output files. Occasionally
|
|
|
1083 |
this is not desirable - in particular the inclusion in the source
|
|
|
1084 |
output file can cause problems during TDF library building. For this
|
|
|
1085 |
reason the
|
|
|
1086 |
<CODE>tspec</CODE> syntax has been extended to allow for fine control
|
|
|
1087 |
of the output corresponding to <CODE>+IMPLEMENT</CODE> and <CODE>+USE</CODE>
|
|
|
1088 |
commands. This takes the forms:
|
|
|
1089 |
<PRE>
|
|
|
1090 |
+IMPLEMENT "api" (key) ;
|
|
|
1091 |
+IMPLEMENT "api", "header" (key) ;
|
|
|
1092 |
+IMPLEMENT "api", "header", "subset" (key) ;
|
|
|
1093 |
</PRE>
|
|
|
1094 |
with corresponding forms for <CODE>+USE</CODE>. <CODE>key</CODE> specifies
|
|
|
1095 |
which output files the inclusion commands should appear in. It can
|
|
|
1096 |
be:
|
|
|
1097 |
<UL>
|
|
|
1098 |
<LI><CODE>??</CODE>, indicating neither output file,
|
|
|
1099 |
<LI><CODE>!?</CODE>, indicating the include output file only,
|
|
|
1100 |
<LI><CODE>?!</CODE>, indicating the source output file only,
|
|
|
1101 |
<LI><CODE>!!</CODE>, indicating both output files (this is the same
|
|
|
1102 |
as the normal form).
|
|
|
1103 |
</UL>
|
|
|
1104 |
<P>
|
|
|
1105 |
The second refinement comes from the fact that APIs fall into two
|
|
|
1106 |
categories - the base APIs, such as <CODE>ansi</CODE>, <CODE>posix</CODE>
|
|
|
1107 |
and <CODE>xpg3</CODE>, and the extension APIs, such as <CODE>x11</CODE>,
|
|
|
1108 |
the X Windows API. The latter can be used to extend the former, so
|
|
|
1109 |
that we can form <CODE>ansi</CODE> plus <CODE>x11</CODE>, <CODE>posix</CODE>
|
|
|
1110 |
plus <CODE>x11</CODE>, and so on. Base APIs may be distinguished in
|
|
|
1111 |
<CODE>tspec</CODE> by including the command:
|
|
|
1112 |
<PRE>
|
|
|
1113 |
+BASE_API ;
|
|
|
1114 |
</PRE>
|
|
|
1115 |
in their <CODE>MASTER</CODE> file. Occasionally, in an extension API,
|
|
|
1116 |
we may wish to include a version of a header from the base API, but,
|
|
|
1117 |
because this base API is not fixed, not be able to use a simple <CODE>+USE
|
|
|
1118 |
</CODE> command. Instead the special form:
|
|
|
1119 |
<PRE>
|
|
|
1120 |
+USE ( "api" ), "header" ;
|
|
|
1121 |
</PRE>
|
|
|
1122 |
is provided for this purpose (this is the only permitted form). It
|
|
|
1123 |
indicates that <CODE>tspec</CODE> should use the <CODE>api</CODE>
|
|
|
1124 |
version of <CODE>header</CODE> for checking purposes, but allow the
|
|
|
1125 |
inclusion of the version from the base API in normal use.
|
|
|
1126 |
<H3><A NAME="Protect">6.2. Protection Macros</A></H3>
|
|
|
1127 |
<P>
|
|
|
1128 |
Each include output file is surrounded by a construct of the form:
|
|
|
1129 |
<PRE>
|
|
|
1130 |
#ifndef MACRO
|
|
|
1131 |
#define MACRO
|
|
|
1132 |
....
|
|
|
1133 |
#endif /* MACRO */
|
|
|
1134 |
</PRE>
|
|
|
1135 |
to protect it against multiple inclusions. Normally <CODE>tspec</CODE>
|
|
|
1136 |
will generate the macro name, <CODE>MACRO</CODE>, but it can be set
|
|
|
1137 |
using the <CODE>PROTECT</CODE> file property (see
|
|
|
1138 |
<A HREF="#Properties">section 5.4</A>). Setting <CODE>PROTECT</CODE>
|
|
|
1139 |
to the empty string suppresses the protection construct altogether.
|
|
|
1140 |
(Also see
|
|
|
1141 |
<A HREF="#If">section 5.1</A>.)
|
|
|
1142 |
<H3><A NAME="Index">6.3. Index Printing</A></H3>
|
|
|
1143 |
<P>
|
|
|
1144 |
If it is invoked with the <B>-i</B> command-line option, instead of
|
|
|
1145 |
creating its output file, <CODE>tspec</CODE> prints an index of all
|
|
|
1146 |
the objects it has read to the standard output. This information includes
|
|
|
1147 |
the external token name associated with the object, whether the object
|
|
|
1148 |
is implemented or used, and where in the API description it is defined.
|
|
|
1149 |
It also includes a brief description of the object. It is intended
|
|
|
1150 |
that these indexes should be usable as quick reference guides to the
|
|
|
1151 |
underlying APIs.
|
|
|
1152 |
<H3><A NAME="Libraries">6.4. TDF Library Building</A></H3>
|
|
|
1153 |
<P>
|
|
|
1154 |
As was explained in reference 1, the <CODE>#pragma token</CODE> headers
|
|
|
1155 |
output by <CODE>tspec</CODE> are used for two purposes - checking
|
|
|
1156 |
applications against the API during normal compilation and checking
|
|
|
1157 |
implementations against the API during TDF library building. This
|
|
|
1158 |
dual use does necessitate some extra work for <CODE>tspec</CODE>.
|
|
|
1159 |
It is not always possible to use exactly the same code in the two
|
|
|
1160 |
cases (usually because the C rules on, for example, structure definitions
|
|
|
1161 |
get in the way during library building). <CODE>tspec</CODE> uses a
|
|
|
1162 |
standard macro, <CODE>__BUILDING_LIBS</CODE>, to distinguish between
|
|
|
1163 |
the two cases. It is assumed to be defined if and only if library
|
|
|
1164 |
building is taking place. <CODE>tspec</CODE> descriptions can access
|
|
|
1165 |
this macro directly using <CODE>~building_libs</CODE> (see
|
|
|
1166 |
<A HREF="#If">section 5.1</A>).
|
|
|
1167 |
<P>
|
|
|
1168 |
The actual library building process consists of compiling the <CODE>#pragma
|
|
|
1169 |
token</CODE> descriptions of the objects comprising the API along
|
|
|
1170 |
with the implementation of that API from the system headers (or wherever).
|
|
|
1171 |
This creates the local token definitions for this API, which may be
|
|
|
1172 |
stored in a token library. To facilitate this process <CODE>tspec</CODE>
|
|
|
1173 |
creates the source output files for each implemented header <CODE>api:header
|
|
|
1174 |
</CODE> containing something like:
|
|
|
1175 |
<PRE>
|
|
|
1176 |
#pragma implement interface <../api/header>
|
|
|
1177 |
#include <header>
|
|
|
1178 |
</PRE>
|
|
|
1179 |
together with a makefile to compile all these programs to token definitions
|
|
|
1180 |
and to combine these token definitions into a token library. In fact
|
|
|
1181 |
two makefiles are created in the source output directory (see
|
|
|
1182 |
<A HREF="#Output">section 2.3</A>). The first is called <CODE>M_api</CODE>
|
|
|
1183 |
and is designed for stand-alone library construction. The second is
|
|
|
1184 |
called
|
|
|
1185 |
<CODE>Makefile</CODE> and is designed for use with the library building
|
|
|
1186 |
script <CODE>MAKE_LIBS</CODE> provided with <CODE>tspec</CODE>.
|
|
|
1187 |
<P>
|
|
|
1188 |
There are other methods whereby the source output file may be changed
|
|
|
1189 |
into a set of token definitions. For example, in <CODE>c:sys.h</CODE>
|
|
|
1190 |
the <CODE>METHOD</CODE> file property (see <A HREF="#Properties">section
|
|
|
1191 |
5.4</A>) is set to <CODE>TDP</CODE>, causing the <CODE>tdp</CODE>
|
|
|
1192 |
program to be invoked to produce the definitions for the basic C tokens
|
|
|
1193 |
for the system. As another example consider:
|
|
|
1194 |
<PRE>
|
|
|
1195 |
$METHOD = "TNC" ;
|
|
|
1196 |
+MACRO double fl_abs ( double ) ;
|
|
|
1197 |
%%%
|
|
|
1198 |
( make_tokdef fl_abs ( exp x ) exp
|
|
|
1199 |
( floating_abs impossible x ) )
|
|
|
1200 |
%%%
|
|
|
1201 |
</PRE>
|
|
|
1202 |
<P>
|
|
|
1203 |
The include output file will specify a token <CODE>fl_abs</CODE> which
|
|
|
1204 |
takes a <CODE>double</CODE> and returns a <CODE>double</CODE>. The
|
|
|
1205 |
<CODE>TNC</CODE> method tells <CODE>MAKE_LIBS</CODE> that the source
|
|
|
1206 |
output file, which will just contain the quoted text:
|
|
|
1207 |
<PRE>
|
|
|
1208 |
( make_tokdef fl_abs ( exp x ) exp
|
|
|
1209 |
( floating_abs impossible x ) )
|
|
|
1210 |
</PRE>
|
|
|
1211 |
is an input file for the TDF notation compiler, <CODE>tnc</CODE> (see
|
|
|
1212 |
reference 2). Thus we have defined a token which directly accesses
|
|
|
1213 |
the TDF <CODE>floating_abs</CODE> construct.
|
|
|
1214 |
<P>
|
|
|
1215 |
<HR>
|
|
|
1216 |
|
|
|
1217 |
<H2><A NAME="S7">7. Changes in tspec 2.0</A></H2>
|
|
|
1218 |
<P>
|
|
|
1219 |
This document describes <CODE>tspec</CODE> version 2.0. <CODE>tspec</CODE>
|
|
|
1220 |
2.0 contains significant changes from previous releases. For convenience
|
|
|
1221 |
the main changes which are visible to the <CODE>tspec</CODE> user
|
|
|
1222 |
are listed here:
|
|
|
1223 |
<UL>
|
|
|
1224 |
<LI>The added specification level of named subsets of headers has
|
|
|
1225 |
been introduced (see <A HREF="#Levels">section 2.1</A>). This has
|
|
|
1226 |
been done by introducing the <CODE>+SUBSET</CODE> construct and extending
|
|
|
1227 |
the
|
|
|
1228 |
<CODE>+IMPLEMENT</CODE> and <CODE>+USE</CODE> constructs, as well
|
|
|
1229 |
as the command-line options. The previous method of dealing with such
|
|
|
1230 |
subsets - namely shared headers - is now obsolete and its use is discouraged.
|
|
|
1231 |
<LI>A number of new command-line options have been added, and some
|
|
|
1232 |
of the existing options have been modified slightly (see
|
|
|
1233 |
<A HREF="#Options">section 2.5</A>).
|
|
|
1234 |
<LI>The suffix <CODE>.api</CODE> has been added to the output directories
|
|
|
1235 |
(see <A HREF="#Output">section 2.3</A>) to avoid possible confusion
|
|
|
1236 |
with other include file directories.
|
|
|
1237 |
<LI>The use of identifiers beginning with <CODE>~</CODE> as local
|
|
|
1238 |
variables is new (see <A HREF="#Identifiers">section 4.1.2</A>).
|
|
|
1239 |
<LI>The <CODE>+STATEMENT</CODE> and <CODE>+DEFINE</CODE> constructs
|
|
|
1240 |
(see <A HREF="#Statement">section 4.5</A> and <A HREF="#Define">section
|
|
|
1241 |
4.6</A>) are new.
|
|
|
1242 |
<LI>The <CODE>(extern)</CODE>, <CODE>(weak)</CODE> and <CODE>(const)</CODE>
|
|
|
1243 |
qualifiers for <CODE>+FUNC</CODE> and <CODE>+EXP</CODE> (see
|
|
|
1244 |
<A HREF="#Func">section 4.2</A> and <A HREF="#Exp">section 4.3</A>)
|
|
|
1245 |
are new.
|
|
|
1246 |
<LI>The <CODE>(signed)</CODE> and <CODE>(unsigned)</CODE> qualifiers
|
|
|
1247 |
for <CODE>+TYPE</CODE> (see <A HREF="#Type">section 4.7</A>) are new.
|
|
|
1248 |
<LI>The <CODE>~special</CODE> type constructor (see
|
|
|
1249 |
<A HREF="#Typedef">section 4.8</A>) is new.
|
|
|
1250 |
<LI>The <CODE>~abstract</CODE> type constructor has been abandoned.
|
|
|
1251 |
<LI>The <CODE>+BASE_API</CODE> command described in
|
|
|
1252 |
<A HREF="#FineImpl">section 6.1</A> is new.
|
|
|
1253 |
<LI>The indexing routines (see <A HREF="#Index">section 6.3</A>) have
|
|
|
1254 |
been greatly improved.
|
|
|
1255 |
</UL>
|
|
|
1256 |
<P>
|
|
|
1257 |
<HR>
|
|
|
1258 |
|
|
|
1259 |
<H2><A NAME="S8">8. References</A></H2>
|
|
|
1260 |
<P>
|
|
|
1261 |
<I>"TDF and Portability"</I>, DRA, 1993.
|
|
|
1262 |
<P>
|
|
|
1263 |
<I>"The TDF Notation Compiler"</I>, DRA, 1993.
|
|
|
1264 |
<P>
|
|
|
1265 |
<I>"The C to TDF Producer"</I>, DRA, 1993.
|
|
|
1266 |
<P>
|
|
|
1267 |
<HR>
|
|
|
1268 |
<P><I>Part of the <A HREF="../index.html">TenDRA Web</A>.<BR>Crown
|
|
|
1269 |
Copyright © 1998.</I></P>
|
|
|
1270 |
</BODY>
|
|
|
1271 |
</HTML>
|