-
Notifications
You must be signed in to change notification settings - Fork 1
Coding style
The project surveillance is based on the Virtual Laboratory Environment (http://www.vle-project.org), therefore, we use the same coding style.
In the declaration of a class, we define in a specific order: typedef, attributes and functions in the following protection: ''public'', ''protected'' and ''private''. This order allows the user to quickly see the functionality of your class. For example:
#ifndef THENAMESPACE_CLASS_HPP
#define THENAMESPACE_CLASS_HPP 1
namespace thenamespace {
class Class : virtual, public, protected, private class1, class2 etc.
{
public:
typedefs ...
variables ... // Public attributes are rare.
functions ...
protected:
typedefs ...
variables ...
functions ...
private:
typedefs ...
variables ...
functions ...
};
} // namespace thenamespace
#endifAll class and function must refer to a ''namespace''. Do not pollute the global space. In VLE we use a simple rule for the name of the ''namespaces'': a repertory = a namespace.
/*
* for a new class into the vle/devs directory.
*/
namespace vle { namespace devs {
class NewEventTable : boost::noncopyable
{
...
};
}} // namespace vle devs
/*
* for a new examples into the examples directory.
*/
namespace vle { examples {
class GeneratorPlugin : public vle::devs::Dynamics
{
...
};
}} // namespace vle examples##Naming rules
** directories : Directory names are in lower case to match namespaces.
mkdir -p examples/generator** namespace: lower case (as directory names).
namespace examples { namespace generator {
...
}}** classe: Les premières lettres de chaque nom en majuscule.
class Position
{
...
};** method: The first letter of method names is lower case.
void position(int& x, int& y);
int x();
void setX(const int x);
const std::string& name() const;
void runLocal();- Class attribute : The first letter of attribute names is lower case, ''m'' (for member) followed by an upper case letter.
int mX, mY;
std::string mName;
double mDX, mDY;-
Functions can not be more than 50 lines and 80 columns
-
Indentation is 4 characters
-
Tabulation is 8 characters
-
Functions can not have more than 6 local variables and no more than 6 local parameters.
-
One instruction per line:
if (condition) {
do_something();
}- No space between the name of the function and the parenthesis:
func (arg); /* bad */
func(arg); /* good */- A space after if, while, switch, etc.:
if(arg) /* bad */
if (arg) /* good */
for(;;) /* bad */
for (;;) /* good */- A space after a comma or dote comma:
func(arg1,arg2); /* bad */
func(arg1, arg2); /* good */
for (i = 0;i < 2;++i) /* bad */
for (i = 0; i < 2; ++i) /* good */- A space before and after ''='', ''+'', ''/'', etc.:
double var=a*5; /* bad */
double var = a * 5; /* good */- No space between the variable type and reference characters and pointer:
int * a; /* bad */
int* a; /* good */- No space between address operators and variables:
int b = * a; /* bad */
int b = *a; /* good */We follow the politic defined by ''Kernighan and Ritchie''. One bracket on the same line of the instruction except in the case of function definitions. Following codes give some examples:
if (x == y) {
...
}int fonction(int x)
{
...
}do {
...
} while (condition);if (x == y) {
...
} else if (x > y) {
...
} else {
...
}switch (test.getX()) {
case 0:
...
break;
case 1:
{
...
}
default:
...
}VLE uses exceptions to detect running errors. The file vle/utils/Exception.hpp define some exception classes. If you want to throw an exception, this one must inherit from the std::exception class (defined in the standard library).
You can use standard exceptions:
- std::logic_error : error in the internal logic of the program.
- std::domain_error : domain error in the mathematical sense.
- std::invalid_argument : invalid function arguments.
- std::length_error : the size of the object exceed maximum size required.
- std::out_of_range : figures out arguments with value exceeding the valid ranges (vector size for instance).
- std::runtime_error : errors that can only be seen at runtime.
- std::range_error : Limit error on type.
Or exceptions defined by the VLE library (file vle/utils/Debug.hpp) :
- vle::utils::FileError : pour reporter une erreur lors de l'accès à un fichier (détection, ouverture, lecture, écriture).
- vle::utils::ParseError : pour reporter une erreur lors de la lecture d'un fichier \texttt{XML}.
- vle::utils::InternalError : pour reporter une erreur interne dans un programme.
A very simple way to detect errors is to use assertion functions defined in the cassert file:
#include <cassert>
int getX(const Point* p)
{
assert(p); // assert that pointer p is not NULL.
return p->x;
}
std::auto_ptr < std::ostream > buildFilename(const std::string& name)
{
std::ofstream* o = new std::ofstream(name);
assert(o.is_open(); // assert the file is open.
return std::auto_ptr < std::ostream >(o);
}Warning! The assert command calls the abort procedure which close the application with an error. If you want to inform the caller method that an error occurred, you should better to throw an exception in this classical way:
#include <vle/utils/Exception.hpp>
int getX(const Point* p)
{
if (not p) {
throw vle::utils::InternalError("Invalid point");
}
return p->x;
}
std::auto_ptr < std::ostream > buildFilename(const std::string& name)
{
std::ofstream* o = new std::ofstream(name);
if (not o.is_open()) {
throw vle::utils::ArgError("Cannot open file");
}
return std::auto_ptr < std::ostream >(o);
}Comments are of primary importance and within files. Every function must have comments to depict the role of the function and how it runs. There must be no comments in the body (the code) of any function.
The doxygen application (A complete description here: http://www.doxygen.org), builds a complete documentation form source code.
/**
* Describe the role of the function, what it does, how it runs ...
* ...
* @param n1 description of parametrer 1 very long description, blabla bla bla
* blablabla bla bla blabla.
* @param n2 description of parameter 2
* @throw indicate exceptions that can be thrown by the function.
* @return description of the return value(s).
*/
int max(int n1, int n2)
{
...
}The project files with extension .cpp and .hpp have the same header defining the license (GNU : GPL) and informations about authors:
/**
* @file FOO/foo/foo.hpp
* @author Superman & Co.
* See the AUTHORS or Authors.txt file
*/
/*
* Project Save Christmas Father
* This file is a part of my project
* http://www.my-project.org
*
* Copyright (C) 2010 MyInstitution
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/