The style and layout to be used for programming on cmgui, cmulgeom, gx, mulgraph, emap and related projects.
For the examples in this document, < and > are used to enclose things that depend on the instance.
For questions, clarification or justification see David Bullivant.
if (<condition>)
{
<body>
}
In general, a module is built around a data structure or group of data structures and contains the type definitions (.h) and the function prototypes (.h) and function definitions (.c) for manipulating the types. For a widget module, there may also be a .uil file.
Notes:
/*******************************************************************************
FILE : <module_name>.h
LAST MODIFIED : <day> <month as name> <year including century>
DESCRIPTION :
<A description of what the module is for and what it can do.>
==============================================================================*/
#if !defined (<module name in capitals>_H)
#define <module name in capitals>_H
#include <<system includes>>
#include "<project includes specified relative to project base directory eg.
graphics/finite_element.h>"
/*
Global types
------------
*/
<type definitions>
/*
Global variables
----------------
*/
<variable declarations. Should all be storage class extern>
/*
Global functions
----------------
*/
<prototypes for the functions that can be used by other modules>
#endif
Notes:
/*******************************************************************************
FILE : <module_name>.c
LAST MODIFIED : <day> <month as name> <year including century>
DESCRIPTION :
<A description of what the module is for and what it can do.>
==============================================================================*/
#include <<system includes>>
#include "<project includes specified relative to project base directory eg.
graphics/finite_element.h>
/*
Global variables
----------------
*/
<variable declarations. Same as in .h except without extern and with
initializers>
/*
Module types
------------
*/
<declarations for types which are only used within the module. Should be
storage class static>
/*
Module variables
----------------
*/
<declarations for variables which are global to this module only. Should be
storage class static>
/*
Module functions
----------------
*/
<definitions for functions which are used in this module only. Should be
storage class static>
/*
Global functions
----------------
*/
<definitions for the functions prototyped in .h>
Notes:
!*******************************************************************************
!FILE : <module_name>.uil
!
!LAST MODIFIED : <day> <month as name> <year including century>
!
!DESCRIPTION :
!<A description of what the widgets are for.>
!===============================================================================
module <module_name>_module
names=case_sensitive
procedure
<names of the procedures used in the uil code and assigned in the C code. On
separate lines>
identifier
<names of the identifiers used in the uil code and assigned in the C code. On
separate lines>
object
<the widget definitions>
end module;
Notes:
struct <Struct_name>
/*******************************************************************************
LAST MODIFIED : <day> <month as name> <year including century>
DESCRIPTION :
<A description of what the type is for.>
==============================================================================*/
{
<struct body>
}; /* struct <Struct_name> */
Notes:
struct
{
<struct body>
} <field_name>;
Notes:
As for struct, but with struct replaced by union.
enum <Enum_type>
/*******************************************************************************
LAST MODIFIED : <day> <month as name> <year including century>
DESCRIPTION :
<A description of what the type is for.>
==============================================================================*/
{
<ENUM_CONSTANTs on separate lines>
}; /* enum <Enum_type> */
Notes:
<return type> <function_name>(<parameter list>);
/*******************************************************************************
LAST MODIFIED : <day> <month as name> <year including century>
DESCRIPTION :
<A description of what the function does and what the parameters are.>
==============================================================================*/
Notes:
<return type> <function_name>(<parameter list>)
/*******************************************************************************
LAST MODIFIED : <day> <month as name> <year including century>
DESCRIPTION :
<A description of what the function does and what the parameters are.>
==============================================================================*/
{
<variable declarations>
ENTER(function_name);
<function body>
LEAVE;
return (<return_variable>);
} /* <function_name> */
Notes:
int anatomical_list_length,coordinate_list_length,field_list_length,i;
struct FE_node_field *node_field_1,*node_field_2;
struct FE_node_field_component *component_1,*component_2;
struct FE_node_field_info *field_info;
struct FE_node_field_info_list_item *item;
struct FE_node_field_list_item *node_field_item;
if (<condition>)
{
<then clause>
}
else
{
<else clause>
}
Notes:
do
{
<do body>
} while (<condition>);
Notes:
while (<condition>)
{
<while body>
}
Notes:
for (<initialize>;<terminate>;<update>)
{
<for body>
}
Notes:
switch (<expression>)
{
case <case_label1>: case <case_label2>:
{
<case clause>
} break;
default:
{
<default clause>
} break;
}
Notes:
Debug statements should be preceded by the comment
/*???debug */and the indentation should be restarted in column 1.
Apart from the special comments shown above, all comments should be on separate lines and be indented at the current level of indentation. Temporary comments querying existing code or suggesting enhancements should be of the form
/*???<programmer identification> . <text> */
The return statement should only ever be the last statement in a function. There should be at most one return statement per function.
The exit statement should not be used.
The break statement should only be used to end clauses in a switch statement (see above).
The continue statement should not be used.
goto should not be used.
elseif should not be used.
typedef should not be used for struct's, union's or enum's.
The macros ALLOCATE and DEALLOCATE (in general/debug.h) should be used for all memory allocation and deallocation (no malloc or free).
ENTER should be the first statement and LEAVE should be the second to last or last (if no return) statement in every function.
Comments should be factual, and should only attempt humour if they are bloody funny.
Code should not be obscure. One tactic to help achieve this is to only do one thing per statement, e.g.,
a[i]=b;instead of
i++;
a[i++]=b;
Macros have been written (graphics/list.h) for creating and using lists. These macros should be used for all lists.
NULL should always be caste to the appropriate type.
Reference counting should be carried out using the macros ACCESS, DEACCESS, and REACCESS on objects that need it. When this is done, the following rules apply: