Coding Standard

(Difference between revisions)
Jump to: navigation, search
(C/C++ code)
Line 1: Line 1:
 
The increasing number of contributors require that we clearly define coding rules and guidelines. Although for historical reasons the current code of Stellarium does not always comply to these rules, they should now be respected for any addition or modification of the code.
 
The increasing number of contributors require that we clearly define coding rules and guidelines. Although for historical reasons the current code of Stellarium does not always comply to these rules, they should now be respected for any addition or modification of the code.
  
=== Stylistic Conventions ===
+
== Stylistic Conventions ==
* Source code should use ASCII character set. Characters such as 'é' or 'ö' are not portable when hardcoded. Gettext translated strings should be used for such characters.  
+
*Source code should use ASCII character set. Characters such as 'é' or 'ö' are not portable when hard-coded. Gettext translated strings should be used for such characters.  
* Variable names and comments should be in english.
+
*Variable names and comments should be in English.
 
+
*Class names are nouns, in mixed-case, with an initial upper-case letter and the first letter of each subsequent word capitalized (e.g. CoreFactory).
* Class names are nouns, in mixed-case, with an initial upper-case letter and the first letter of each subsequent word capitalized (e.g. CoreFactory).
+
*Method names are verbs or nouns in mixed-case, starting with a lower-case letter (e.g. update() or addElement()).
* Method names are verbs or nouns in mixed-case, starting with a lower-case letter (e.g. update() or addElement()).
+
*Methods that return a value should take the form getSize().
* Methods that return a value should take the form getSize().
+
*The names of local variables should be in mixed case, starting with a lower-case letter (e.g. packetSize). This also applies to the formal parameters of methods. Do not use names starting with underscore.
* The names of local variables should be in mixed case, starting with a lower-case letter (e.g. packetSize). This also applies to the formal parameters of methods. Do not use names starting with underscore.
+
*The names of macro or static final constants should be all upper-case words, separated by underscore:
* The names of macro or static final constants should be all upper-case words, separated by underscore:
+
 
  #define MIN_WIDTH 3
 
  #define MIN_WIDTH 3
 
  static const string VERSION = "0.8.2";
 
  static const string VERSION = "0.8.2";
 
+
*Indentation should be done with tabs, not spaces. This allows each developers to use his favorite indent size without changing the code.
* Indentation should be done with tabs, not spaces. This allows each developers to use his favorite indent size without changing the code.
+
*Use the following layout for braces:
 
+
* Use the following layout for braces:
+
 
  void MyClass::myMethod(int x)
 
  void MyClass::myMethod(int x)
 
  {
 
  {
Line 23: Line 20:
 
     }
 
     }
 
  }
 
  }
 +
*Use blank lines as follows:
 +
**1 between methods, before (block or single line) comment
 +
**1 between logical sections of a method
 +
**2 between sections of a source file
  
* Use blank lines as follows:
+
== File Names ==
** 1 between methods, before (block or single line) comment
+
** 1 between logical sections of a method
+
** 2 between sections of a source file
+
 
+
=== File Names ===
+
 
+
 
The extensions are .hpp/.cpp for C++ headers/code, .h/.c for C headers/code.
 
The extensions are .hpp/.cpp for C++ headers/code, .h/.c for C headers/code.
 
C++ files should have the same name and case than the class they contain. For example class StelFontMgr should be declared in file StelFontMgr.hpp and implemented in StelFontMgr.cpp.
 
C++ files should have the same name and case than the class they contain. For example class StelFontMgr should be declared in file StelFontMgr.hpp and implemented in StelFontMgr.cpp.
  
=== Doxygen Comments ===
+
== Doxygen Comments ==
 
+
 
Stellarium source code should be documented with [http://www.stack.nl/~dimitri/doxygen/index.html Doxygen]. From Doxygen webpage:
 
Stellarium source code should be documented with [http://www.stack.nl/~dimitri/doxygen/index.html Doxygen]. From Doxygen webpage:
  
Line 50: Line 44:
 
  vector<wstring> listMatchingObjectsI18n(const wstring& objPrefix, unsigned int maxNbItem=5) const;
 
  vector<wstring> listMatchingObjectsI18n(const wstring& objPrefix, unsigned int maxNbItem=5) const;
  
for methods definitions in .cpp files, a simpler comment for each method is sufficient:
+
For methods definitions in .cpp files, a simpler comment for each method is sufficient:
 
  /*************************************************************************
 
  /*************************************************************************
 
   Find and return the list of at most maxNbItem objects auto-completing the  
 
   Find and return the list of at most maxNbItem objects auto-completing the  
Line 59: Line 53:
 
     etc..
 
     etc..
  
=== C/C++ code ===
+
== C/C++ code ==
 
Use C++ replacement for C functions wherever possible. This includes the following:
 
Use C++ replacement for C functions wherever possible. This includes the following:
* use [http://www.sgi.com/tech/stl/basic_string.html std::string] instead of char*
+
*Use [http://www.sgi.com/tech/stl/basic_string.html std::string] instead of char*
* use [http://www.cplusplus.com/ref/iostream/ iostream C++ classes] instead of C file managment with fopen().
+
*Use [http://www.cplusplus.com/ref/iostream/ iostream C++ classes] instead of C file managment with fopen().
* pass objects as references when needed instead of using pointers.
+
*Pass objects as references when needed instead of using pointers.
* include standard headers the C++ way, it is more portable:
+
*Include standard headers the C++ way, it is more portable:
 
+
 
  #include <'''stdio.h'''> // Bad
 
  #include <'''stdio.h'''> // Bad
 
 
  #include <'''cstdio'''>  // Good
 
  #include <'''cstdio'''>  // Good
 
+
*Avoid using pointers when not needed, this prevents creating memory leaks. For example:
* Avoid using pointers when not needed, this prevents creating memory leaks. For example:
+
 
  string mapFileName = getDataDir() + "fontmap.dat";
 
  string mapFileName = getDataDir() + "fontmap.dat";
+
  ifstream '''*'''mapFile = '''new''' ifstream(mapFileName.c_str());  // Bad  
  ifstream '''*'''mapFile = '''new''' ifstream(mapFileName.c_str());  // Bad
+
  ifstream mapFile(mapFileName.c_str());                             // Good
+
*Use STL containers such as std::vector or std::map, they are extremely efficient. Documentation is [http://www.sgi.com/tech/stl/ here].
  ifstream mapFile(mapFileName.c_str());                         // Good
+
*Avoid using global function and variable. Encapsulate them in classes or namespaces as static members/variable.
 
+
*Avoid using C macro, use static const variables instead. It is safer because it is type safe.
* Use STL containers such as std::vector or std::map, they are extremely efficient. Documentation is [http://www.sgi.com/tech/stl/ here].
+
  #define RADIUS 12 // Bad  
 
+
* Avoid using global function and variable. Encapsulate them in classes or namespaces as static members/variable.
+
 
+
* Avoid using C macro, use static const variables instead. It is safer because it is type safe.
+
 
+
  #define RADIUS 12 // Bad
+
+
 
  static const int RADIUS = 12;
 
  static const int RADIUS = 12;
  
* Use stdc++ math functions instead of C ones. There are more protable and are also overrided for float, thus may be faster.
+
*Use stdc++ math functions instead of C ones. There are more protable and are also overrided for float, thus may be faster.
 
+
  double cosLat = cos(lat);    // Bad  
  double cosLat = cos(lat);    // Bad
+
+
 
  double cosLat = std::cos(lat); // Good
 
  double cosLat = std::cos(lat); // Good
  
=== Translatable strings and text console output ===
+
== Translatable strings and text console output ==
In Stellarium, translatable text is translated using the Translator class, which is a C++ wrapper to gettext. The translation process is done using the _() macro which takes in input a std::string in english and return in output a std::wstring (a string of wide characters) translated in another langage using the current global langage.
+
In Stellarium, translatable text is translated using the Translator class, which is a C++ wrapper to gettext. The translation process is done using the _() macro which takes in input a std::string in english and return in output a std::wstring (a string of wide characters) translated in another language using the current global language.
 
+
*Translatable text in sources or in data files should be written in English, encoded in ASCII or UTF-8 if needed.
* Translatable text in sources or in data files should be written in english, encoded in ASCII or UTF-8 if needed.
+
*Translatable text should obey English typo conventions, for example there should be no space before ':'
* Translatable text should obey english typo conventions, for example there should be no space before ':'
+
 
+
 
  wstring myTranslatedText = _("Distance of the planet ''':'''") // Bad
 
  wstring myTranslatedText = _("Distance of the planet ''':'''") // Bad
 
 
  wstring myTranslatedText = _("Distance of the planet''':'''")  // Good
 
  wstring myTranslatedText = _("Distance of the planet''':'''")  // Good
  
* When modifying the code, avoid to modify translatable string unless really needed. Any modification on one of them means that all the translators for all the langages will have to re-translate the new string.
+
*When modifying the code, avoid to modify translatable string unless really needed. Any modification on one of them means that all the translators for all the langages will have to re-translate the new string.
 
+
*In general no translated text (i.e. no wstring) should be output on the console because there are problems when string and wstring are output on the same console. This means that you should never use wcout, wcerr or wprintf(). Console output should be used for informations, errors and warnings which are not required by the user in nominal use.
* In general no translated text (i.e. no wstring) should be output on the console because there are problems when string and wstring are output on the same console. This means that you should never use wcout, wcerr or wprintf(). Console output should be used for informations, errors and warnings which are not required by the user in nominal use.
+
*Errors and warnings should be output in the stderr file, not stdout.
 
+
  '''cout''' << "Error while opening file " << myFileName << "." << endl; // Bad  
* Errors and warnings should be output in the stderr file, not stdout.
+
 
+
  '''cout''' << "Error while opening file " << myFileName << "." << endl; // Bad
+
+
 
  '''cerr''' << "Error while opening file " << myFileName << "." << endl; // Good
 
  '''cerr''' << "Error while opening file " << myFileName << "." << endl; // Good

Revision as of 19:37, 28 January 2007

The increasing number of contributors require that we clearly define coding rules and guidelines. Although for historical reasons the current code of Stellarium does not always comply to these rules, they should now be respected for any addition or modification of the code.

Contents

Stylistic Conventions

  • Source code should use ASCII character set. Characters such as 'é' or 'ö' are not portable when hard-coded. Gettext translated strings should be used for such characters.
  • Variable names and comments should be in English.
  • Class names are nouns, in mixed-case, with an initial upper-case letter and the first letter of each subsequent word capitalized (e.g. CoreFactory).
  • Method names are verbs or nouns in mixed-case, starting with a lower-case letter (e.g. update() or addElement()).
  • Methods that return a value should take the form getSize().
  • The names of local variables should be in mixed case, starting with a lower-case letter (e.g. packetSize). This also applies to the formal parameters of methods. Do not use names starting with underscore.
  • The names of macro or static final constants should be all upper-case words, separated by underscore:
#define MIN_WIDTH 3
static const string VERSION = "0.8.2";
  • Indentation should be done with tabs, not spaces. This allows each developers to use his favorite indent size without changing the code.
  • Use the following layout for braces:
void MyClass::myMethod(int x)
{
   if (x>10)
   {
      cout << "You won." << endl;
   }
}
  • Use blank lines as follows:
    • 1 between methods, before (block or single line) comment
    • 1 between logical sections of a method
    • 2 between sections of a source file

File Names

The extensions are .hpp/.cpp for C++ headers/code, .h/.c for C headers/code. C++ files should have the same name and case than the class they contain. For example class StelFontMgr should be declared in file StelFontMgr.hpp and implemented in StelFontMgr.cpp.

Doxygen Comments

Stellarium source code should be documented with Doxygen. From Doxygen webpage:

"Doxygen is a documentation system for C++, C, Java, [...] It can generate an on-line documentation browser (in HTML) and/or an off-line reference manual (in LaTeX) from a set of documented source files. [...] The documentation is extracted directly from the sources, which makes it much easier to keep the documentation consistent with the source code. [...] You can also visualize the relations between the various elements by means of include dependency graphs, inheritance diagrams, and collaboration diagrams, which are all generated automatically.

All public and protected classes and methods from Stellarium should be fully documented in the headers (.hpp).

There are different ways to comment C++ code with Doxygen, in Stellarium use the following for headers files:

//! Find and return the list of at most maxNbItem objects auto-completing the passed object I18n name.
//! @param objPrefix the case insensitive first letters of the searched object.
//! @param maxNbItem the maximum number of returned object names.
//! @return a vector of matching object name by order of relevance, or an empty vector if nothing match.
vector<wstring> listMatchingObjectsI18n(const wstring& objPrefix, unsigned int maxNbItem=5) const;

For methods definitions in .cpp files, a simpler comment for each method is sufficient:

/*************************************************************************
 Find and return the list of at most maxNbItem objects auto-completing the 
 passed object I18n name.
*************************************************************************/
vector<wstring> listMatchingObjectsI18n(const wstring& objPrefix, unsigned int maxNbItem=5) const
{
    etc..

C/C++ code

Use C++ replacement for C functions wherever possible. This includes the following:

  • Use std::string instead of char*
  • Use iostream C++ classes instead of C file managment with fopen().
  • Pass objects as references when needed instead of using pointers.
  • Include standard headers the C++ way, it is more portable:
#include <stdio.h> // Bad
#include <cstdio>  // Good
  • Avoid using pointers when not needed, this prevents creating memory leaks. For example:
string mapFileName = getDataDir() + "fontmap.dat";
ifstream *mapFile = new ifstream(mapFileName.c_str());  // Bad 
ifstream mapFile(mapFileName.c_str());                              // Good
  • Use STL containers such as std::vector or std::map, they are extremely efficient. Documentation is here.
  • Avoid using global function and variable. Encapsulate them in classes or namespaces as static members/variable.
  • Avoid using C macro, use static const variables instead. It is safer because it is type safe.
#define RADIUS 12 // Bad 
static const int RADIUS = 12;
  • Use stdc++ math functions instead of C ones. There are more protable and are also overrided for float, thus may be faster.
double cosLat = cos(lat);     // Bad 
double cosLat = std::cos(lat); // Good

Translatable strings and text console output

In Stellarium, translatable text is translated using the Translator class, which is a C++ wrapper to gettext. The translation process is done using the _() macro which takes in input a std::string in english and return in output a std::wstring (a string of wide characters) translated in another language using the current global language.

  • Translatable text in sources or in data files should be written in English, encoded in ASCII or UTF-8 if needed.
  • Translatable text should obey English typo conventions, for example there should be no space before ':'
wstring myTranslatedText = _("Distance of the planet :") // Bad
wstring myTranslatedText = _("Distance of the planet:")  // Good
  • When modifying the code, avoid to modify translatable string unless really needed. Any modification on one of them means that all the translators for all the langages will have to re-translate the new string.
  • In general no translated text (i.e. no wstring) should be output on the console because there are problems when string and wstring are output on the same console. This means that you should never use wcout, wcerr or wprintf(). Console output should be used for informations, errors and warnings which are not required by the user in nominal use.
  • Errors and warnings should be output in the stderr file, not stdout.
cout << "Error while opening file " << myFileName << "." << endl; // Bad 
cerr << "Error while opening file " << myFileName << "." << endl; // Good
Personal tools
Namespaces
Variants
Actions
in this wiki
other languages
Toolbox