Trace: » server » reorganisation » coding_guidelines
The Integra svn contains software written in a variety of languages including C, Python, SClang and Max/MSP. Below are a set of guidelines for each language. These guidelines are not strict rules (unless otherwise stated), and are intended to enhance collaboration between contributors.
Common Guidelines
- All code should be documented
- Inline documentation is favoured over 'external' documentation
- Each 'trunk' directory should contain a brief README explaining what is in the trunk
- All code should be clean and readable
- Never commit broken code
- Even if you're not writing Python follow this
Naming Conventions
These conventions apply to Integra module names, not to code itself.
- Integra module class names should be in CamelCase
- Integra module instance names should be in CamelCase with a numeric suffix indicating the instance number: TapDelay1
- Integra module attribute names should be in lowerCamelCase giving us: TapDelay1.delayTime
Text-based code (e.g. C, Python, Java)
- Use four spaces instead of Tabs for indentation (i.e. expand tabs to spaces)
- Use Unix line breaks (i.e. \n not Windows:\r\n)
- A single line should fit in an 80 character terminal and therefore extend no further than 78 characters, if it does - please insert a line break or line continuation character (e.g. '\')
C
- function_and_variable_names_should_be_all_lowercase_with_underscores_and_be_explicit_and_meaningful
- As far as possible, function names should take the form ntg_<category>_<action>. E.g ntg_definition_add(), ntg_attribute_new() and NOT ntg_add_attribute()
- MACROS and CONSTANTS should be in capitals
- We try to conform to the ANSI C99 standard. As a minimum the code should compile with the gcc flags -Wall -Werror -pedantic -ansi -std=c99. If you need to change any of these for testing, please do so by passing the CFLAGS variable to the configure script rather than changing configure.in
- Pointers should be initialised to NULL (not 0)
- Pointer comparisons to 0×000000 should be made against NULL (not 0)
- The 'include' directive should be used in the following order: <config.h>, standard system headers (<..>), non-standard system headers (<…>), libIntegra public headers (”…”), libIntegra private headers (”…”).
- Function definitions should be formatted as follows:
return_type *function_name(params...)
{
...
}
- Otherwise, should always be on the same line as the preceding expression, with no space:
if(foo == 3){
do_something();
}
Debugging/Error handling
- Use the debug and error handling API: integra_debug.h integra_error.h
- error.h/errno may (and should) be used internally inside the library (e.g. for comparisons or printing serious errors to stderror), but integra_error.h should be used for ALL return codes
- Never add your own debug statements using printf or whatever, ALWAYS use the macro in integra_debug.h
Memory allocation
- Use the memory allocation API: integra_memory.h
- If using an external library use their memory allocation functions
- NEVER directly call malloc, free, calloc or realloc
Actionscript 3
file structure
standard gnu license agreement at top of every file
functions within a class should always be ordered as follows: Constructor public functions protected functions private functions
virtual and override functions should be grouped together wherever this is sensible functions relating to similar areas of functionality should be grouped together wherever this is sensible
all variables should be declared private, with public getters/setters as needed all variables should be initialised where they are declared
The ActionScript 3 typed Vector class should be used in preference to the untyped Array class where possible
naming conventions
Classes should be named in upper camel case Functions, variables and constants should be named in lower camel case Member variables should be preceded with an underscore
enumerations
There is no native 'enumeration' type in Actionscript. A common Actionscript convention, also used in the Integra Live GUI, is to define enumerations as classes whose only content is a set of public static const Strings, one for each enumeration value.
indentation style: Allman style ( http://en.wikipedia.org/wiki/Indent_style )
Code flow style: minimise indentation. EG instead of
function doSomething
{
if( condition1 )
{
if( condition2 )
{
if( condition3 )
{
doSomethingElse();
}
}
}
}
it's better to write
function doSomething
{
if( !condition1 )
{
return;
}
if( !condition2 )
{
return;
}
if( !condition3 )
{
return;
}
doSomethingElse();
}
switch statements
Switch statements should always contain a 'default case'. If the default is not expected to be used (eg when there's a case for each value of an enumeration), the default case should fail an assertion, to alert developers to a possible error.
defensive programming - assertions and failsafe mechanisms
There is no native 'Assert' functionality in Actionscript. The Integra Live Gui uses a 3rd party component called 'FlexUnit' (http://opensource.adobe.com/wiki/display/flexunit/FlexUnit), which provides an 'Assert' class. Assertions should be used as liberally as possible. Furthermore, in any situation where an assertion failure is likely to cause a significant software malfunction, and where a simple failsafe mechanism is possible, one should be implemented.
Example of assertion without failsafe mechanism:
Assert.assertNotNull( referenceToSomething ) //subsequent code which relies on referenceToSomething
Example of assertion with failsafe mechanism:
if( referenceToSomething == null )
{
Assert.assertTrue( false );
return;
}
//subsequent code which relies on referenceToSomething
Max/MSP and PD
- Patches should be left aligned
- Crossing patch cords should be avoided
- Segmented patch cords should be avoided unless they really do make the patch easier to read
- Pd and Max module implementations should should be saved as files with lowercase filenames using a - character to seperate words, e.g. tap-delay.pd
Documenting code
All code should be documented. Even simple algorithms should include comments to help contributors learn and understand how the system is built and provide for easy access to the inner workings of the Integra system. A distinction should be made between API documentation and documenting algorithms.
API documentation
The libIntegra code base is documented using Doxygen source code documentation generator tool. Depending on the language, if support is supplied we encourage the use of Doxygen (currently supports C++, C, Java, Objective-C, Python, IDL (Corba and Microsoft flavors), Fortran, VHDL, PHP, C#, and to some extent D), in order to have a coherent and easily accessed API documentation. Following is a shortlist of useful Doxygen markup and guidelines for documenting a function in C.
All functions, public as well as private, should have a documentation block preceeding the function definition in the header file in the ggeneral form:
- brief description of the function
- detailed description of the function
- a list of the parameters the function takes as well as a description of each of the parameters
- a description of the return value (omitted if the functiion returns null)
Deploying code
Making a source code release
It is very straightforward to make a source code release.
From svn: integralive/library/trunk
- Check that version information is correct in configure.in
- sh ./autogen.sh && ./configure –enable-swig && make && make dist
This will give a source tarball like:
libIntegra-0.3.0.tar.gz
Deployment on the Integra server
To deploy on the integra server, upload the latest source tarball (or make one then upload) to your home directory
- tar zxf libIntegra-0.3.0.tar.gz
- cd libIntegra-0.3.0
- ./configure –enable-serialization –enable-swig
- make
- sudo make install
Then change directory to the working svn copy:
- cd /var/svn/integra
- sudo svn update
Test, test, test!
Thats it!