Difference between revisions of "Code Formatting Conventions"

Jump to navigation Jump to search
→‎Switch/Case constructs: enhanced to avoid ambiguity
(→‎Whitespaces: add section about references)
(→‎Switch/Case constructs: enhanced to avoid ambiguity)
 
(35 intermediate revisions by 11 users not shown)
Line 11: Line 11:
Braces in your code should look like the following example:
Braces in your code should look like the following example:


<syntax type="C++">
<syntaxhighlight lang="cpp">
for (int i = 0; i < t; i++) {
for (int i = 0; i < t; i++) {
     [...]
     [...]
Line 17: Line 17:


if (j < k) {
if (j < k) {
    [...]
} else if (j > k) {
     [...]
     [...]
} else {
} else {
Line 22: Line 24:
}
}


class Dummy() {
class Dummy {
     [...]
     [...]
};
};
</syntax>
</syntaxhighlight>


Did you see the {}'s on that?
Did you see the {}'s on that?
Line 37: Line 39:
'''Conventional operators surrounded by a space character'''
'''Conventional operators surrounded by a space character'''


<syntax type="C++">
<syntaxhighlight lang="cpp">
a = (b + c) * d;
a = (b + c) * d;
</syntax>
</syntaxhighlight>


'''C++ reserved words separated from opening parentheses by a white space'''
'''C++ reserved words separated from opening parentheses by a white space'''


<syntax type="C++">
<syntaxhighlight lang="cpp">
while (true) {
while (true) {
</syntax>
</syntaxhighlight>


'''Commas followed by a white space'''
'''Commas followed by a white space'''


<syntax type="C++">
<syntaxhighlight lang="cpp">
someFunction(a, b, c);
someFunction(a, b, c);
</syntax>
</syntaxhighlight>
<syntax type="C++">
<syntaxhighlight lang="cpp">
int d, e;
int d, e;
</syntax>
</syntaxhighlight>


'''Semicolons followed by a space character, if there is more on a line'''
'''Semicolons followed by a space character, if there is more on a line'''


<syntax type="C++">
<syntaxhighlight lang="cpp">
for (int a = 0; b++; c < d)
for (int a = 0; b < c; d++)
</syntax>
</syntaxhighlight>
<syntax type="C++">
<syntaxhighlight lang="cpp">
doSomething(e); doSomething(f); // This is probably bad style anyway
doSomething(e); doSomething(f); // This is probably bad style anyway
</syntax>
</syntaxhighlight>
 
'''Mandatory ''{}'' for empty ''for''/''while'' loops'''
 
<syntaxhighlight lang="cpp">
while (i < length - 1 && array[++i] != item);  // bad
while (i < length - 1 && array[++i] != item) {} // good
</syntaxhighlight>


'''When declaring class inheritance and in a ? construct, colons should be surrounded by white space'''
'''When declaring class inheritance and in a ? construct, colons should be surrounded by white space'''


<syntax type="C++">
<syntaxhighlight lang="cpp">
class BusWheel : public RubberInflatable {
class BusWheel : public RubberInflatable {
</syntax>
</syntaxhighlight>
<syntax type="C++">
<syntaxhighlight lang="cpp">
(isNight) ? colorMeDark() : colorMeBright();
(isNight) ? colorMeDark() : colorMeBright();
</syntax>
</syntaxhighlight>


'''Indentation level is not increased after namespace clause'''
'''Indentation level is not increased after namespace clause'''


<syntax type="C++">
<syntaxhighlight lang="cpp">
namespace Scumm {
namespace Scumm {


Line 86: Line 95:


} // End of namespace Scumm
} // End of namespace Scumm
</syntax>
</syntaxhighlight>


'''Array delete operator has no whitespace before []'''
'''Array delete operator has no whitespace before []'''
<syntax type="C++">
<syntaxhighlight lang="cpp">
delete[] foo;
delete[] foo;
</syntax>
</syntaxhighlight>


'''Template definitions'''
'''Template definitions'''


No whitespace between template keyword and <
No whitespace between template keyword and <
<syntax type="C++">
<syntaxhighlight lang="cpp">
template<typename foo>
template<typename foo>
void myFunc(foo arg) {
void myFunc(foo arg) {
     // ...
     // ...
}
}
</syntax>
</syntaxhighlight>


'''Operator overloading'''
'''Operator overloading'''


Operator keyword is NOT separated from the name, except for type conversion operators where it is required.
Operator keyword is NOT separated from the name, except for type conversion operators where it is required.
<syntax type="C++">
<syntaxhighlight lang="cpp">
struct Foo {
struct Foo {
     void operator()() {
     void operator()() {
Line 116: Line 125:
     }
     }
};
};
</syntax>
</syntaxhighlight>


'''Pointers and casts'''
'''Pointers and casts'''


No whitespace after a cast; and in a pointer, we write a whitespace before the start but not after it.
No whitespace after a cast; and in a pointer, we write a whitespace before the star but not after it.
<syntax type="C++">
<syntaxhighlight lang="cpp">
const char *ptr = (const char *)foobar;
const char *ptr = (const char *)foobar;
</syntax>
</syntaxhighlight>


'''References'''
'''References'''


We use the same rule for references as we do for pointers: use a whitespace before the "&" but not after it.
We use the same rule for references as we do for pointers: use a whitespace before the "&" but not after it.
<syntax type="C++">
<syntaxhighlight lang="cpp">
int i = 0;
int i = 0;
int &ref = i;
int &ref = i;
</syntax>
</syntaxhighlight>
 
'''Arrow operator'''
 
We put no spaces around the arrow operator.
<syntaxhighlight lang="cpp">
int a = foo->bar;
</syntaxhighlight>
 
'''Vertical alignment'''


== Switch / Case constructs ==
When it adds to readability, a vertical alignment by means of extra tabs or spaces is allowed. However, it is not advised to have the opening and closing brackets/braces to occupy a single line.
<syntaxhighlight lang="cpp">
int foo    = 2;
int morefoo = 3;


<syntax type="C++">
Common::Rect *r = new Common::Rect(x,
                                  y,
                                  x + w,
                                  y + h);
</syntaxhighlight>
 
== Switch/Case constructs ==
 
<syntaxhighlight lang="cpp">
switch (cmd) {
switch (cmd) {
case kSomeCmd:
    a = 1;
    func1();
    b = a + 1;
    // fall through
case kSomeVerySimilarCmd:
    someMoreCmd();
    a = 3;
    break;
case kSaveCmd:
case kSaveCmd:
     save();
     save();
Line 147: Line 185:
     Dialog::handleCommand(sender, cmd, data);
     Dialog::handleCommand(sender, cmd, data);
}
}
</syntax>
</syntaxhighlight>
* Note the comment on whether fall through is intentional. Use exactly this and not some variation both for consistency and so that the compiler will see it and suppress potential warnings.
 
== Vertical space ==
 
'''Avoid composite one liners'''
 
<syntaxhighlight lang="cpp">
if (condition) do_foo();  // <-- bad example
 
// Proper way of writing it
if (condition)
    do_foo();
</syntaxhighlight>
 
 
'''Split out variable declarations'''
<syntaxhighlight lang="cpp">
int a = 1;
int b = 2;
int c;
 
c = a + b;
</syntaxhighlight>
 
'''Split out logical program blocks'''
<syntaxhighlight lang="cpp">
void MacWindowManager::setScreen(ManagedSurface *screen) {
    _screen = screen;
    delete _screenCopy;
    _screenCopy = nullptr;
 
    if (_desktop)
        _desktop->free();
    else
        _desktop = new ManagedSurface();
 
    _desktop->create(_screen->w, _screen->h, _pixelformat);
    drawDesktop();
}
</syntaxhighlight>
 
== Preprocessor pragmas ==
All preprocessor pragrmas must start from the first column:
 
<syntaxhighlight lang="cpp">
#include "common/system.h"
 
#pragma mark --- Start of example ---
void example() {
    int i = 0;
 
#ifdef USE_FEATURE
    Feature f = new Feature();
#endif
 
    for (int x = 0; x < 10; x++) {
 
#define FOO f
        warning("%d", (FOO).code());
#undef FOO
    }
}
</syntaxhighlight>


== Naming ==
== Naming ==
Line 160: Line 261:
(As a side remark, we recommend avoiding #define for creating constants, because these can lead to weird and difficult to track down conflicts. Instead use enums or the <code>const</code> keyword.)
(As a side remark, we recommend avoiding #define for creating constants, because these can lead to weird and difficult to track down conflicts. Instead use enums or the <code>const</code> keyword.)


'''Classes'''
'''Type names'''


Camel case starting with upper case.
Camel case starting with upper case. This includes template types.


<syntax type="C++">
<syntaxhighlight lang="cpp">
class MeClass() {
class MyClass { /* ... */ };
</syntax>
struct MyStruct { /* ... */ };
typedef int MyInt;
 
template typename<FancyPants>
void bestClothes(FancyPants pants) {/* ... */ }
</syntaxhighlight>


'''Class member variables'''
'''Class member variables'''
Line 172: Line 278:
Prefixed with '_' and in camel case (Yo! no underscore separators), starting with lowercase.
Prefixed with '_' and in camel case (Yo! no underscore separators), starting with lowercase.


<syntax type="C++">
<syntaxhighlight lang="cpp">
char *_someVariableName;
char *_someVariableName;
</syntax>
</syntaxhighlight>


'''Class methods'''
'''Class methods'''
Line 180: Line 286:
Camel case, starting with lowercase.
Camel case, starting with lowercase.


<syntax type="C++">
<syntaxhighlight lang="cpp">
void thisIsMyFancyMethod();
void thisIsMyFancyMethod();
</syntax>
</syntaxhighlight>
 
'''Non-member functions'''
 
Camel case, starting with lowercase.
 
<syntaxhighlight lang="cpp">
void thisIsMyFancyGlobalFunction();
</syntaxhighlight>
 
'''Local variables'''
 
Use camel case (Yo! no underscore separators), starting with lowercase.
 
<syntaxhighlight lang="cpp">
char *someVariableName;
</syntaxhighlight>
 
Note that for POD structures it is fine to use this rule too.


'''Global variables'''
'''Global variables'''
Line 188: Line 312:
In general you should avoid global variables, but if it can't be avoided, use 'g_' as prefix, camel case, and start with lowercase
In general you should avoid global variables, but if it can't be avoided, use 'g_' as prefix, camel case, and start with lowercase


<syntax type="C++">
<syntaxhighlight lang="cpp">
int g_someGlobaleVariable;
int g_someGlobalVariable;
</syntax>
</syntaxhighlight>


== Special comments ==
== Special comments ==
Line 200: Line 324:
* '''TODO''' marks incomplete code, or things that could be done better but are left for the future.
* '''TODO''' marks incomplete code, or things that could be done better but are left for the future.
* '''WORKAROUND''' marks code that works around bugs in the original game, like script bugs. Sometimes these bugs worked in the original due to bugs in the original engine, sometimes the bug was visible in the original, too. It's important that you explain here what exactly you work around, and if applicable, refer to relevant tracker items!
* '''WORKAROUND''' marks code that works around bugs in the original game, like script bugs. Sometimes these bugs worked in the original due to bugs in the original engine, sometimes the bug was visible in the original, too. It's important that you explain here what exactly you work around, and if applicable, refer to relevant tracker items!
* '''I18N:''' Adds comment to translators for internationalization. See [[Supporting GUI Translation]].


=== Doxygen documentation comments ===
=== Doxygen documentation comments ===
Line 209: Line 334:
There are many ways to mark such comments, but developers are encouraged to use the JavaDoc style:
There are many ways to mark such comments, but developers are encouraged to use the JavaDoc style:


<syntax type="C++">
<syntaxhighlight lang="cpp">
/**
/**
  * Move ("warp") the mouse cursor to the specified position in virtual
  * Move ("warp") the mouse cursor to the specified position in virtual
Line 217: Line 342:
  */
  */
virtual void warpMouse(int x, int y) = 0;
virtual void warpMouse(int x, int y) = 0;
</syntax>
</syntaxhighlight>
(See [http://doxygen.scummvm.org/d9/df4/classOSystem.html#ecab84670def917107d6c1b5ca3b82c3 here] for the docs generated from this.)
(See [http://doxygen.scummvm.org/d9/df4/classOSystem.html#ecab84670def917107d6c1b5ca3b82c3 here] for the docs generated from this.)


Line 223: Line 348:


If you want to add a brief explanation of a variable or function ''after'' its declaration, this is the correct syntax:
If you want to add a brief explanation of a variable or function ''after'' its declaration, this is the correct syntax:
<syntax type="C++">
<syntaxhighlight lang="cpp">
int16 x; //!< The horizontal part of the point
int16 x; ///< The horizontal part of the point
int16 y; //!< The vertical part of the point
int16 y; ///< The vertical part of the point
</syntax>
</syntaxhighlight>
(See [http://doxygen.scummvm.org/d7/d66/structCommon_1_1Point.html#2d868735aeaaf391ce9b3df9232c031f here] for the docs generated from this.)
(See [http://doxygen.scummvm.org/d7/d66/structCommon_1_1Point.html#2d868735aeaaf391ce9b3df9232c031f here] for the docs generated from this.)


Line 234: Line 359:


== Automatically converting code to our conventions ==
== Automatically converting code to our conventions ==
The following settings for [http://astyle.sourceforge.net/ Artistic Style] (als known as astyle) approximate our code formatting convetions and can be used to quickly convert a big bunch of source files to our conventions. Note that you still may have to manually clean up some stuff afterwards.
The following settings for [http://astyle.sourceforge.net/ Artistic Style] (also known as astyle) approximate our code formatting conventions and can be used to quickly convert a big bunch of source files to our conventions. Note that you may still have to manually clean up some stuff afterwards.
<pre>
<pre>
indent=tab=4
indent=tab=4
brackets=attach
style=attach
pad=oper
pad-oper
unpad=paren
pad-header
align-pointer=name
unpad-paren
indent-preprocessor
convert-tabs
</pre>
 
=== Emacs style ===
Put the following in your .emacsrc file
 
<pre>
(setq-default default-tab-width 4)
(setq-default c-basic-offset 4)
(setq-default indent-tabs-mode t)
</pre>
</pre>

Navigation menu