 ------------- Olympus Development Guidelines v1 -------------


To keep the project code base and build system coherent, readable
and maintanable, the Olympus development team has developed this
document. All the specifications contained in this document should
be strictly followed. If code is found that is non-compliant it 
should be brought into line with the standards.


Table of Contents
-----------------

    1.  Indentation
    2.  Braces and Blocks
    3.  Spacing
    4.  Control Flow Statments
    5.  Variables
          5.1 Declaring
          5.2 Initializing
          5.3 Naming
    6.  Comments
    7.  Files
          7.1 Naming
          7.2 Headings
          7.3 #includes
    8.  Repository
          8.1 Directory Structure
          8.2 Additions and Changes
    9.  Makefiles and the Build System
    10. Bug Reports


1.  Indentation
---------------
All indents are 4 spaces wide and are actual spaces, not tab characters.


2.  Braces and Blocks
---------------------

if, while and other such control flow statements should be formatted as
follows:

    if (<EXPR>)
    {
        <CODE>
    }
    else
    {
        <CODE>
    }

Basically, it follows the ANSI style with opening and closing curly braces
on lines by themselves aligned with the keyword (if, else, etc) with the
code contained in each of the blocks indented in once. The evaluated
expression following the keyword should be on the same line as the keyword.


switch statements are to be formatted as follows:

    switch (<VAR>)
    {
        case <VALUE>:
            <CODE>
            break;
            
        case <VALUE>:
            <CODE>
            break;
            
        default:
            <CODE>
    }

Note that the case statement is indented with its code indented once more, 
including the break statement. For long switch statements (~10 or more cases),
switch statements with large case blocks or when local variables are needed in
individual case statements, the preferred method becomes:

    switch (<VAR>)
    {
        case <VALUE>
        {
            <CODE>
            break;
        }
        
        ...
        
        default
        {
            <CODE>
        }
    }

Class declarations should be formatted as close to the following as possible:

    <CLASSNAME> [: <INHERITANCE>]
    {
        public:
            <CONSTUCTORS>
            <DECONSTRUCTOR>
            
            <FUNCTIONS>
            
            <VARS>

        protected:
            <CONSTUCTORS>
                        
            <FUNCTIONS>
                        
            <VARS>
    
        private:
            <CONSTUCTORS>
                
            <FUNCTIONS>
                        
            <VARS>
    };

Very long parenthetical lists that end up spanning multiple lines should 
be formatted :
    
    (<EXPR1> <OPERATOR>
     <EXPR2> <OPERATOR>
     ...
     <EXPRN>)

For example:

    if (intOne != someObject.someMethod(anArgument, anotherArgument) &&
        someObj.otherMethod() == otherObject.otherMethod() &&
        something == 1)

In complex boolean expressions, parens should be used appropriately 
to allow easy reading.


3.  Spacing
-----------

This section deals with spaces between elements, punctuation, etc. The
general rules are:

    o There are no spaces between a parens and the value it contains
    o There is always a space after a comma, but not before it
    o There is always a space on either side of a (non-unary) operator 
        (e.g. =, ==, !=, >, ...)


Method/function calls should have no spaces between the method name and the
list of arguments: 

    <FUNCTIONNAME>(<PARAM1>, <PARAM2, .., <PARAMN>);

Flow control statements on the other hand should: 

    <CONDITIONAL> (<PARAM1>, .., <PARAMN>)



4.  Control Flow Statements
---------------------------

The following control flow statements are not used:
    o ternary operators (e.g. the ugly ?:)
    
The following flow controls should be avoided at all costs:
    
    o do/while loops (just use while() instead) 

Additionaly, the following are preferred:
    o while loops are preferred over for loops as they are more efficient.
      however, forcing for loops to become while loops where it is ugly
      isn't any better.
    o if/if else blocks are preferred over large switch statements



5.  Variables
-------------

- 5.1 Declaring -

Variables should be declared as close to the top of the block of code they
are used in as possible and in the following order:

    o static
    o extern
    o local


- 5.2 Initializing -

Initializing a variable is always done like:
    
    int i = 4;
Not:
    
    int i(4);


- 5.3 Return Values -

Returns are always done like:
    
    return <EXPR>;

Not:
    
    return(<EXPR>);

- 5.3 Naming -

Variable names should be:
    
    o Short, but self explanatory
    o Consistent across methods/source files. For example commID and sessionID 
      should always be commID and sessionID regardless of where it is in the
      source, and these names should NOT be used for ANYTHING else.
    o first letter lowercase, additional words capped. eg: thisVarName
    o only #def'd constants should be in ALL CAPS


6.  Comments
------------

Comments should be added to any non-obvious code or important
checkpoints. Additionaly, a brief comment should appear at the top
of each file (see section 7.2 on Headings) and before any
method that is not obvious in function or critical for proper
functionality.

All comments should be written for someone who did not write the code
in the first place. If they are only truly useful to the original author
there is no point to having them. Additionally, if it is bleeding obvious
what the code does, why comment it?

Single line comments should use // and multi-line comments should use /* */

    // One liners

    /*
     * multi
     * liners
     */



7.  Files
---------

- 7.1 Naming -

Source code files end in .cc and header files end in .h

A .h file name should be the name of the class it defines. 

A source file is named after its contents, which can be one of the following 
three mixes of methods:

    o An entire class (only if it is a small class), in which case the name should
      the class name (thisClass.cc)
    o A single method (if the method is large or deserving of its own file), in which 
      case the name would be the method (methodName.cc)
    o A group of related methods. The name should then reflect the purpose of these 
      methods (slots.cc, networkOps.cc, etc)
    
Source files should not be split/joined up along any other lines.


- 7.2 Headings -

All files should start with a comment block that looks like the following:

/****************************************************************************
** filename
**
** This is where a short description would go if applicable.
**
** Author: Original Author <author@email.address>
**
** Copyright (c) 2000 Mount Linux Inc.
**
** This file is part of Mount Linux Olympus.
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License version 2 as published
** by the Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but
** WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
** or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
** for more details.
**
** You should have received a copy of version 2 of the GNU General Public
** License along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*****************************************************************************/


- 7.3 #includes -

Any identifier that can be defined as a forward reference in a header file 
should be. The actual #include directives should appear in the individual 
source files that require them. 
    
    
#includes should appear in the following order:

        #include <systemlib.h>
        
        #include "globalheaders.h"
        
        #include "localheaders.h"

When including config.h and defs.h, config.h MUST be included first.




8.  Repository
--------------

- 8.1 Directory Structure -    

Within the source tree (src/) there are the main branches: client/, server/,
help/ and common/. Anything that is not specific to either client/ or server/ 
should appear in common/. The help/ directory is where the help system can
be found.

In client, due to its size, each class has its own subdirectory. In server
the structure is slightly different, but immediately apparent upon perusal.

Outside of the source tree, there are several other directories. All but two 
of these are specific to individual maintainers and besides these people should 
not be touched by anyone else. The two exceptions are conf/ and docs/. Within
conf/ are found the default olympusd.conf (used to store run-time config 
options for the server) and olympus.data (which is the file used to populate 
the system database if it is empty when the server runs. The docs/ directory 
is where all the documentation is found.
    
    
- 8.2 Additions and Changes

Before making substantial changes to the repository email the devel lists for 
comment. Once a directory is put into CVS, it is a pain to remove it cleanly.
Also, when making substantial changes it causes rebuilds. This should be 
avoided unless it is either necessary or produces measurable benefits.

Religiously add new files and commit changes to existing ones, but ONLY after 
testing (minimally, compile the source). If you find the repository 
broken, immediately email developers@mountlinux.com and/or inform the individual 
responsible for the breakage.
    

9.  Makefiles and the Build System
----------------------------------
    
When a header file is added or removed from a source or header file,
immediately update dependency information in the appropriate Makefile.in
Failing to do so can cause strange behaviour as changes occur and incremental
builds are done. This pisses people off.

When creating a new file, add it to the Makefile.in in both the objects and
dependecies areas before committing. Failing to do so also pisses people off.

Plugins do not get a Makefile.in, just a Makefile which is committed to the
CVS repository. Plugins must be added to the src/client/plugins/Makefile.in
file to be built properly.
    
If extensive additions/changes are needed to the build system, report them to 
the build maintainer (Cade <cairnsc@mountlinux.com) and allow time for it to 
be done. Automated builds are a low priority up until public release times.

When making changes to the build system do "make distclean", run autogen.sh,
build from scratch and run the executables before committing the changes.


10. Bug Reports
---------------
    
A bug report should consist of the following items, in email, to the current 
maintainer of the problem code, or if unsure who is the maintainer or
where the bug is exactly to developers@mountlinux.com:

    o A description of the actual bug in as much detail as possible
    o A description of what led up to the bug in as much details as possible
    o A backtrace if at ALL possible
    o Possible fixes, but ONLY if you have traced the bug to specific lines
