Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
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 &quot;abstract implementation&quot; of the API needs
78
to be provided.   
79
<P>
80
But of course, an &quot;abstract implementation&quot; 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 &quot;name&quot; := {
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 &quot;api&quot; ;
333
	+IMPLEMENT &quot;api&quot;, &quot;header&quot; ;
334
	+IMPLEMENT &quot;api&quot;, &quot;header&quot;, &quot;subset&quot; ;
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 &quot;api&quot; ;
340
	+USE &quot;api&quot;, &quot;header&quot; ;
341
	+USE &quot;api&quot;, &quot;header&quot;, &quot;subset&quot; ;
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 &quot;ansi&quot;, &quot;stdio.h&quot; ;
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 &quot;size_t&quot; := {
363
	    +TYPE (unsigned) size_t ;
364
	} ;
365
</PRE>
366
and including this in each of the other headers:   
367
<PRE>
368
	+IMPLEMENT &quot;ansi&quot;, &quot;stddef.h&quot;, &quot;size_t&quot; ;
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 &quot;ansi&quot;, &quot;assert.h&quot; ;
378
	+IMPLEMENT &quot;ansi&quot;, &quot;ctype.h&quot; ;
379
	....
380
	+IMPLEMENT &quot;ansi&quot;, &quot;time.h&quot; ;
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 &quot;posix&quot;, &quot;sys/types.h&quot; ;
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 &quot;unique name&quot; 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 | &quot;ename&quot;
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 ( &quot;bottom&quot; ) ~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 ( &quot;api&quot;, &quot;header&quot; )
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 = &quot;string&quot; ;
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 &quot;api&quot; (key) ;
1091
	+IMPLEMENT &quot;api&quot;, &quot;header&quot; (key) ;
1092
	+IMPLEMENT &quot;api&quot;, &quot;header&quot;, &quot;subset&quot; (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 ( &quot;api&quot; ), &quot;header&quot; ;
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 &lt;../api/header&gt;
1177
	#include &lt;header&gt;
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 = &quot;TNC&quot; ;
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>&quot;TDF and Portability&quot;</I>, DRA, 1993.   
1262
<P>
1263
<I>&quot;The TDF Notation Compiler&quot;</I>, DRA, 1993.   
1264
<P>
1265
<I>&quot;The C to TDF Producer&quot;</I>, DRA, 1993.   
1266
<P>
1267
<HR>
1268
<P><I>Part of the <A HREF="../index.html">TenDRA Web</A>.<BR>Crown
1269
Copyright &copy; 1998.</I></P>
1270
</BODY>
1271
</HTML>