Blame | Last modification | View Log | RSS feed
<!-- Crown Copyright (c) 1998 -->
<HTML>
<HEAD>
<TITLE>
C++ Producer Guide: Style guide
</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000FF" VLINK="#400080" ALINK="#FF0000">
<H1>C++ Producer Guide</H1>
<H3>March 1998</H3>
<A HREF="alg.html"><IMG SRC="../images/next.gif" ALT="next section"></A>
<A HREF="std.html"><IMG SRC="../images/prev.gif" ALT="previous section"></A>
<A HREF="index.html"><IMG SRC="../images/top.gif" ALT="current document"></A>
<A HREF="../index.html"><IMG SRC="../images/home.gif" ALT="TenDRA home page">
</A>
<IMG SRC="../images/no_index.gif" ALT="document index"><P>
<HR>
<DL>
<DT><A HREF="#language"><B>3.1.1</B> - C coding standard</A><DD>
<DT><A HREF="#api"><B>3.1.2</B> - API usage and target dependencies</A><DD>
<DT><A HREF="#src"><B>3.1.3</B> - Source code modules</A><DD>
</DL>
<HR>
<H2>3.1. Source code organisation</H2>
<P>
This section describes the basic organisation of the source code for
the C++ producer. This includes the coding conventions applied, the
application programming interface (API) observed and the division
of the code into separate modules.
</P>
<HR>
<H3><A NAME="language">3.1.1. C coding standard</A></H3>
<P>
The C++ producer is written in a subset of C which is compatible with
C++ (it compiles with most C compilers, but also bootstraps itself).
It has been written to conform to the local (OSSG)
<A HREF="index.html#cstyle">C coding standard</A>; most of the conformance
checking being automated by use of a
<A HREF="pragma.html#usr">user-defined compilation profile</A>,
<CODE>ossg_std.h</CODE>. The standard macros described in the coding
standard are defined in the standard header <CODE>ossg.h</CODE>. This
is included from the header <CODE>config.h</CODE> which is included
by all source files. The default definitions for these macros, set
according to the value of <CODE>__STDC__</CODE> and other compiler-defined
macros, should be correct, but they can be overridden by defining
the <CODE>FS_*</CODE> macros, described in the header, as command-line
options.
</P>
<P>
The most important of these macros are those used to handle function
prototypes, enabling both ISO and pre-ISO C compilers to be accommodated.
Simple function definitions take the form:
<PRE>
ret function
PROTO_N ( ( p1, p2, ...., pn ) )
PROTO_T ( par1 p1 X par2 p2 X .... X parn pn )
{
....
}
</PRE>
with the <CODE>PROTO_N</CODE> macro being used to list the parameter
names (note the double bracket) and the <CODE>PROTO_T</CODE> macro
being used to list the parameter types using <CODE>X</CODE> (cartesian
product) as a separator. The corresponding function declaration will
have the form:
<PRE>
ret function PROTO_S ( ( par1, par2, ...., parn ) ) ;
</PRE>
The case where there are no parameter types is defined using:
<PRE>
ret function
PROTO_Z ()
{
....
}
</PRE>
and declared as:
<PRE>
ret function PROTO_S ( ( void ) ) ;
</PRE>
Functions with ellipses are defined using:
<PRE>
#if FS_STDARG
#include <stdarg.h>
#else
#include <varargs.h>
#endif
ret function
PROTO_V ( ( par1 p1, par2 p2, ...., parn pn, ... ) )
{
va_list args ;
....
#if FS_STDARG
va_start ( args, pn ) ;
#else
par1 p1 ;
par2 p2 ;
....
parn pn ;
va_start ( args ) ;
p1 = va_arg ( args, par1 ) ;
p2 = va_arg ( args, par2 ) ;
....
pn = va_arg ( args, parn ) ;
#endif
....
va_end ( args ) ;
....
}
</PRE>
and declared as:
<PRE>
ret function PROTO_W ( ( par1, par2, ...., parn, ... ) ) ;
</PRE>
Note that <CODE><varargs.h></CODE> does not allow for parameters
preceding the <CODE>va_alist</CODE>, so the fixed parameters need
to be explicitly assigned from <CODE>args</CODE>.
</P>
<P>
The following <A HREF="pragma.html#keyword">TenDRA keywords</A> are
defined (with suitable default values for non-TenDRA compilers):
<PRE>
#pragma TenDRA keyword SET for set
#pragma TenDRA keyword UNUSED for discard variable
#pragma TenDRA keyword IGNORE for discard value
#pragma TenDRA keyword EXHAUSTIVE for exhaustive
#pragma TenDRA keyword REACHED for set reachable
#pragma TenDRA keyword UNREACHED for set unreachable
#pragma TenDRA keyword FALL_THROUGH for fall into case
</PRE>
</P>
<P>
Various flags giving properties of the compiler being used are defined
in <CODE>ossg.h</CODE>. Among the most useful are <CODE>FS_STDARG</CODE>,
which is true if the compiler supports ellipsis functions (see above),
and <CODE>FS_STDC_HASH</CODE>, which is true if the preprocessor supports
the ISO stringising and concatenation operators. The macros
<CODE>CONST</CODE> and <CODE>VOLATILE</CODE>, to be used in place
of
<CODE>const</CODE> and <CODE>volatile</CODE>, are also defined.
</P>
<P>
A policy of rigorous static program checking is enforced. The TenDRA
C producer is applied with the user-defined compilation mode
<CODE>ossg_std.h</CODE> and intermodule checks enabled. Checking
is applied with both the C and <CODE>#pragma token</CODE>
<A HREF="../utilities/calc.html"><CODE>calculus</CODE> output files</A>.
The C++ producer itself is applied with the same checks. <CODE>gcc
-Wall</CODE> and various versions of <CODE>lint</CODE> are also periodically
applied.
</P>
<HR>
<H3><A NAME="api">3.1.2. API usage and target dependencies</A></H3>
<P>
Most of the API features used in the C++ producer are to be found
in the ISO C API, with just a couple of extensions from POSIX required.
These POSIX features can be disabled with minimal loss of functionality
by defining the macro <CODE>FS_POSIX</CODE> to be false.
</P>
<P>
The following features are used from the ISO <CODE><stdio.h></CODE>
header:
<PRE>
BUFSIZ EOF FILE SEEK_SET
fclose fflush fgetc fgets
fopen fprintf fputc fputs
fread fseek fwrite rewind
sprintf stderr stdin stdout
vfprintf
</PRE>
from the ISO <CODE><stdlib.h></CODE> header:
<PRE>
EXIT_SUCCESS EXIT_FAILURE NULL abort
exit free malloc realloc
size_t
</PRE>
and from the ISO <CODE><string.h></CODE> header:
<PRE>
memcmp memcpy strchr strcmp
strcpy strlen strncmp strrchr
</PRE>
The three headers just mentioned are included in all source files
via the
<CODE>ossg_api.h</CODE> header file (included by <CODE>config.h</CODE>).
The remaining headers are only included as and when they are needed.
The following features are used from the ISO <CODE><ctype.h></CODE>
header:
<PRE>
isalpha isprint
</PRE>
from the ISO <CODE><limits.h></CODE> header:
<PRE>
UCHAR_MAX UINT_MAX ULONG_MAX
</PRE>
from the ISO <CODE><stdarg.h></CODE> header:
<PRE>
va_arg va_end va_list va_start
</PRE>
(note that if <CODE>FS_STDARG</CODE> is false the XPG3
<CODE><varargs.h></CODE> header is used instead); and from the
ISO
<CODE><time.h></CODE> header:
<PRE>
localtime time time_t struct tm
tm::tm_hour tm::tm_mday tm::tm_min tm::tm_mon
tm::tm_sec tm::tm_year
</PRE>
The following features are used from the POSIX
<CODE><sys/stat.h></CODE> header:
<PRE>
stat struct stat stat::st_dev stat::st_ino
stat::st_mtime
</PRE>
The <CODE><sys/types.h></CODE> header is also included to provide
the necessary types for <CODE><sys/stat.h></CODE>.
</P>
<P>
There are a couple of target dependencies in the producer which can
overridden using command-line options:
<OL>
<LI>It assumes that if a count of the number of characters read from
an input file is maintained, then that count value can be used as
an argument to <CODE>fseek</CODE>. This may not be true on machines
where the end of line marker consists of both a newline and a carriage
return. In this case the <CODE>-m-f</CODE> command-line option can
be used to switch to a slower, but more portable, algorithm for setting
file positions.
<P>
<LI>It assumes that a file is uniquely determined by the
<CODE>st_dev</CODE> and <CODE>st_ino</CODE> fields of its corresponding
<CODE>stat</CODE> value. This is used when processing
<CODE>#include</CODE> directives to prevent a file being read more
than once if this is not necessary. This assumption may not be true
on machines with a small <CODE>ino_t</CODE> type which have file systems
mounted from machines with a larger <CODE>ino_t</CODE> type. In this
case the <CODE>-m-i</CODE> command-line option can be used to disable
this check.
</OL>
</P>
<HR>
<H3><A NAME="src">3.1.3. Source code modules</A></H3>
<P>
For convenience, the source code is divided between a number of directories:
<OL>
<LI>The base directory contains only the module containing the
<CODE>main</CODE> function, the basic type descriptions and the
<CODE>Makefile</CODE>.
<LI>The directories <CODE>obj_c</CODE> and <CODE>obj_tok</CODE> contain
respectively the C and <CODE>#pragma token</CODE> headers generated
from the type algebra by <A HREF="../utilities/calc.html"><CODE>calculus</CODE>
</A>. The directory <CODE>obj_templ</CODE> contains certain <CODE>calculus
</CODE>
template files.
<LI>The directory <CODE>utility</CODE> contains routines for such
utility operations as memory allocation and error reporting, including
the <A HREF="error.html">error catalogue</A>.
<LI>The directory <CODE>parse</CODE> contains routines concerned with
parsing and preprocessing the input, including the
<A HREF="../utilities/sid.html"><CODE>sid</CODE> grammar</A>.
<LI>The directory <CODE>construct</CODE> contains routines for building
up and analysing the internal representation of the parsed code.
<LI>The directory <CODE>output</CODE> contains routines for outputting
the internal representation in various formats including as a
<A HREF="tdf.html">TDF capsule</A>, a <A HREF="link.html">C++ spec
file</A>, or a <A HREF="dump.html">symbol table dump file</A>.
</OL>
</P>
<P>
Each module consists of a C source file, <CODE><I>file</I>.c</CODE>
say, containing function definitions, and a corresponding header file
<CODE><I>file</I>.h</CODE> containing the declarations of these functions.
The header is included within its corresponding source file to check
these declarations; it is protected against multiple inclusions by
a macro of the form <CODE><I>FILE</I>_INCLUDED</CODE>. The header
contains a brief comment describing the purpose of the module; each
function in the source file contains a comment describing its purpose,
its inputs and its output.
</P>
<P>
The following table lists all the source modules in the C++ producer
with a brief description of the purpose of each:
</P>
<P>
<CENTER>
<TABLE BORDER>
<TR><TH>Module</TH> <TH>Directory</TH>
<TH>Purpose</TH>
<TR><TD>access</TD> <TD>construct</TD>
<TD>member access control</TD>
<TR><TD>allocate</TD> <TD>construct</TD>
<TD><CODE>new</CODE> and <CODE>delete</CODE> expressions<TD>
<TR><TD>assign</TD> <TD>construct</TD>
<TD>assignment expressions<TD>
<TR><TD>basetype</TD> <TD>construct</TD>
<TD>basic type operations</TD>
<TR><TD>buffer</TD> <TD>utility</TD>
<TD>buffer reading and writing routines</TD>
<TR><TD>c_class</TD> <TD>obj_c</TD>
<TD><CODE>calculus</CODE> support routines</TD>
<TR><TD>capsule</TD> <TD>output</TD>
<TD>top-level TDF encoding routines</TD>
<TR><TD>cast</TD> <TD>construct</TD>
<TD>cast expressions</TD>
<TR><TD>catalog</TD> <TD>utility</TD>
<TD>error catalogue definition</TD>
<TR><TD>char</TD> <TD>parse</TD>
<TD>character sets</TD>
<TR><TD>check</TD> <TD>construct</TD>
<TD>expression checking</TD>
<TR><TD>chktype</TD> <TD>construct</TD>
<TD>type checking</TD>
<TR><TD>class</TD> <TD>construct</TD>
<TD>class and enumeration definitions</TD>
<TR><TD>compile</TD> <TD>output</TD>
<TD>TDF tag definition encoding routines</TD>
<TR><TD>constant</TD> <TD>parse</TD>
<TD>integer constant evaluation</TD>
<TR><TD>construct</TD> <TD>construct</TD>
<TD>constructors and destructors</TD>
<TR><TD>convert</TD> <TD>construct</TD>
<TD>standard type conversions</TD>
<TR><TD>copy</TD> <TD>construct</TD>
<TD>expression copying</TD>
<TR><TD>debug</TD> <TD>utility</TD>
<TD>development aids</TD>
<TR><TD>declare</TD> <TD>construct</TD>
<TD>variable and function declarations<TD>
<TR><TD>decode</TD> <TD>output</TD>
<TD>bitstream reading routines</TD>
<TR><TD>derive</TD> <TD>construct</TD>
<TD>base class graphs; inherited members</TD>
<TR><TD>destroy</TD> <TD>construct</TD>
<TD>garbage collection routines</TD>
<TR><TD>diag</TD> <TD>output</TD>
<TD>TDF diagnostic output routines</TD>
<TR><TD>dump</TD> <TD>output</TD>
<TD>symbol table dump routines</TD>
<TR><TD>encode</TD> <TD>output</TD>
<TD>bitstream writing routines</TD>
<TR><TD>error</TD> <TD>utility</TD>
<TD>error output routines</TD>
<TR><TD>exception</TD> <TD>construct</TD>
<TD>exception handling</TD>
<TR><TD>exp</TD> <TD>output</TD>
<TD>TDF expression encoding routines</TD>
<TR><TD>expression</TD> <TD>construct</TD>
<TD>expression processing</TD>
<TR><TD>file</TD> <TD>parse</TD>
<TD>low-level I/O routines</TD>
<TR><TD>function</TD> <TD>construct</TD>
<TD>function definitions and calls</TD>
<TR><TD>hash</TD> <TD>parse</TD>
<TD>hash table and identifier name routines</TD>
<TR><TD>identifier</TD> <TD>construct</TD>
<TD>identifier expressions</TD>
<TR><TD>init</TD> <TD>output</TD>
<TD>TDF initialiser expression encoding routines</TD>
<TR><TD>initialise</TD> <TD>construct</TD>
<TD>variable initialisers</TD>
<TR><TD>instance</TD> <TD>construct</TD>
<TD>template instances and specialisations</TD>
<TR><TD>inttype</TD> <TD>construct</TD>
<TD>integer and floating point type routines</TD>
<TR><TD>label</TD> <TD>construct</TD>
<TD>labels and jumps</TD>
<TR><TD>lex</TD> <TD>parse</TD>
<TD>lexical analysis</TD>
<TR><TD>literal</TD> <TD>parse</TD>
<TD>integer and string literals</TD>
<TR><TD>load</TD> <TD>output</TD>
<TD>C++ spec reading routines</TD>
<TR><TD>macro</TD> <TD>parse</TD>
<TD>macro expansion</TD>
<TR><TD>main</TD> <TD>-</TD>
<TD>main routine; command-line arguments</TD>
<TR><TD>mangle</TD> <TD>output</TD>
<TD>identifier name mangling</TD>
<TR><TD>member</TD> <TD>construct</TD>
<TD>member selector expressions</TD>
<TR><TD>merge</TD> <TD>construct</TD>
<TD>intermodule merge routines</TD>
<TR><TD>namespace</TD> <TD>construct</TD>
<TD>namespaces; name look-up</TD>
<TR><TD>operator</TD> <TD>construct</TD>
<TD>overloaded operators</TD>
<TR><TD>option</TD> <TD>utility</TD>
<TD>compiler options</TD>
<TR><TD>overload</TD> <TD>construct</TD>
<TD>overload resolution</TD>
<TR><TD>parse</TD> <TD>parse</TD>
<TD>low-level parser routines</TD>
<TR><TD>pragma</TD> <TD>parse</TD>
<TD><CODE>#pragma</CODE> directives</TD>
<TR><TD>predict</TD> <TD>parse</TD>
<TD>parser look-ahead routines</TD>
<TR><TD>preproc</TD> <TD>parse</TD>
<TD>preprocessing directives</TD>
<TR><TD>print</TD> <TD>utility</TD>
<TD>error argument printing routines</TD>
<TR><TD>quality</TD> <TD>construct</TD>
<TD>extra expression checks</TD>
<TR><TD>redeclare</TD> <TD>construct</TD>
<TD>variable and function redeclarations</TD>
<TR><TD>rewrite</TD> <TD>construct</TD>
<TD>inline member function definitions</TD>
<TR><TD>save</TD> <TD>output</TD>
<TD>C++ spec writing routines</TD>
<TR><TD>shape</TD> <TD>output</TD>
<TD>TDF shape encoding routines</TD>
<TR><TD>statement</TD> <TD>construct</TD>
<TD>statement processing</TD>
<TR><TD>stmt</TD> <TD>output</TD>
<TD>TDF statement encoding routines</TD>
<TR><TD>struct</TD> <TD>output</TD>
<TD>TDF structure encoding routines</TD>
<TR><TD>syntax[0-9]*</TD> <TD>parse</TD>
<TD><CODE>sid</CODE> parser output</TD>
<TR><TD>system</TD> <TD>utility</TD>
<TD>system dependent routines</TD>
<TR><TD>table</TD> <TD>parse</TD>
<TD>portability table reading</TD>
<TR><TD>template</TD> <TD>construct</TD>
<TD>template declarations and checks</TD>
<TR><TD>throw</TD> <TD>output</TD>
<TD>TDF exception handling encoding routines</TD>
<TR><TD>tok</TD> <TD>output</TD>
<TD>TDF standard tokens encoding</TD>
<TR><TD>tokdef</TD> <TD>construct</TD>
<TD>token definitions</TD>
<TR><TD>token</TD> <TD>construct</TD>
<TD>token declarations and expansion</TD>
<TR><TD>typeid</TD> <TD>construct</TD>
<TD>run-time type information</TD>
<TR><TD>unmangle</TD> <TD>output</TD>
<TD>identifier name unmangling</TD>
<TR><TD>variable</TD> <TD>construct</TD>
<TD>variable analysis</TD>
<TR><TD>virtual</TD> <TD>construct</TD>
<TD>virtual functions</TD>
<TR><TD>xalloc</TD> <TD>utility</TD>
<TD>memory allocation routines</TD>
</TABLE>
</CENTER>
</P>
<HR>
<P><I>Part of the <A HREF="../index.html">TenDRA Web</A>.<BR>Crown
Copyright © 1998.</I></P>
</BODY>
</HTML>