Jade internals
PrevJade internalsNext

Coding conventions


The following list gives some hints on the coding conventions used throughout the source.


Every header file should be surrounded by an ifndef. Here is a skeleton for a header file named filename.h:

/* copyright notice goes here */

#ifndef filename_INCLUDED
#define filename_INCLUDED 1

/* contents go here */

#endif /* not filename_INCLUDED */


Every file should be surrounded by a namespace. Namespaces are never used directly in order to support compilers which don't understand namespaces. The general skeleton for a .cxx file in the namespace NAMESPACE is:

/* includes go here */

namespace NAMESPACE {

/* content goes here */


Files in the lib/, nsgmls/, sgmlnorm/, spam/, spent/, spgrove/ and sx/ directories use the namespace SP_NAMESPACE. Files in grove/ use the namespace GROVE_NAMESPACE. Files in style/ and jade/ use DSSSL_NAMESPACE.

DSSSL_NAMESPACE imports everything from SP_NAMESPACE and GROVE_NAMESPACE (see style/dsssl_ns.h).

VC 5 and 6 have bugs in the namespace management, which mean that all these 3 need to be defined to be the same.

The conditional stuff is to deal with compilers that don't support namespaces.


To cope with different compilers capabilities with respect to templates, all template instantiations are collected in files with names ending in _inst.cxx. These are generated from _inst.m4 files.

To add a new template instantiation, add a macro call of the form
__instantiate(/* your template instatiation */)
to the appropriate .m4 file.

API definitions

When building DLLs on Windows, every class or function which should be exported by the DLL has to be prefixed with
when building the DLL and with
when using it outside the DLL.

This is hidden behind the _API macros which get defined appropriately. Every declaration of a class of function which is part of the public interface of its library should be prefixed with the proper _API macro. Files in lib/ and include/ use SP_API, files in grove/ use GROVE_API, files in spgrove/ use SPGROVE_API, files in style/ use STYLE_API.


Messages for the main classes are collected in separate classes. Eg there is a class InterpreterMessages for all messages of the class Interpreter.

The sources (.h and .cxx files and, on Windows, .rc files) for the <class>Messages classes are generated from .msg files by the msggen.pl Perl script.

Adding a new message amounts to adding one line to the correct .msg file. The lines in these files have the following format:

<message type><args>+<identifier>+<relevant clause>+<message text>

<message type> must be one of the I, W, Q, X or E. These stand for info, warning, quantity error, idref error and error, respectively.

<args> is the number of placeholders of the form %n in the <message text>.

<identifier> is the C++-identifier used to refer to the message.

<relevant clause> is used in SP to give an exact reference to the SGML standard for each error message. Outside of SP, this field is usually left empty.

<message text> is the text of the message. It can contain placeholders of the form %n where n is a number between 0 and <args> - 1. These placeholders will be replaced by suitable arguments if the message is issued.

Message arguments come from classes derived from MessageArg. StringMessageArg is a string, NumberMessageArg is an unsigned long.

There is a special form of message which also gives a location for the error which can be defined by adding one more field of the form +<aux text> at the end of message definition. <aux text> will usually be an explanation of the location like "first definition was here" (for a duplicate definition error). This form of message is only implemented for <args>≤1.

Issuing a message is done by a call of the form message(<class>Messages::<identifier>, ...) where <class> is the class to which the message belongs and <identifier> is the identifier used in the message definition. The remaining arguments to the message() call must match the %n placeholders in the message. For messages which give location information, the last argument must be an object of type Location.

Jade internals General overview