Last updated for Ambulant version 1.1.
Everything is kept under CVS, on sourceforge. On Unix we use the standard automake, autoconf, configure and gcc (version 3.2 or later) toolset to build things. On Windows we use Visual Studio 7. For cross-compilation for Windows CE we use Embedded Visual C++ 3.0. For cross-compilation for the Zaurus Linux handheld we use the Sharp toolset, based on gcc 2.95.
At the toplevel we have a number of subdirectories:
Here's a somewhat random list of source code conventions that we have decided to use:
Indent 4 spaces, with the following exceptions:
Whether opening braces are at end-of-line or beginning of the next line depends on the circumstances and personal taste. Closing braces, when on a line by themselves, must however align with the construct that opened them.
no camelCase, CamelCase or Capitalization in class or variable names
Underscores to delimit words
attribute names start with "m_"
static attributes start with "s_"
Code that is tightly-coupled to an external framework (such as GUI code) may relax the previous rules and adhere to the conventions of the external framework.
we have a toplevel namespace ambulant, with a second level of namespaces under that
semi-private classes go into into a namespace named "detail".
Template type parameters start with an upper case letter (as in: template <class A> {})
Header files need to include any header files on which they depend, and they guard against multiple inclusion with a preprocessor construct.
Header files are all in an "ambulant" directory, and are included by full path, as in:
#include "ambulant/net/url.h"
Everything goes into namespace "ambulant", with sub-namespaces "lib", "net", etc. Machine-dependent code goes into it's own "unix", "win32", etc subnamespace of those.
Source files have using namespace ambulant; at the top. In addition, there's a using namespace for your own namespace, i.e. using namespace common; for source files in common. Normally, there are no other global using namespace declarations, i.e. everything outside of your own namespace is used qualified.
Header files that declare abstract interfaces try to include as few other header files as possible. In other words, if you need a lib::node * in an abstract header file it is better not to include ambulant/lib/node.h, but instead to add a construct:
namespace ambulant { namespace lib { class node; } }
If you need to switch on platform in an ifdef please use the ambulant-specific constants: AMBULANT_PLATFORM_MACOS, AMBULANT_PLATFORM_LINUX, AMBULANT_PLATFORM_UNIX (any Unix variant), AMBULANT_PLATFORM_WIN32 (any Windows variant, including CE), AMBULANT_PLATFORM_WIN32_WCE (WinCE)
APIs that could be considered external must be documented inline, in a form compatible with Doxygen. The easiest way to do this is with a triple-slashed comment block. The first line should end in a period and is the short description. Anything after that is the long description:
/// Hold user preference information. /// This class holds all settings the user can change. It is normally subclassed /// in machine-dependent code to override the load() and save() methods. class preferences { /// Load preferences from disk. void load(); /// Save preferences to disk. void save(); }