Hard-wrap style guide for clearer diffs

This commit is contained in:
2014-11-29 13:11:14 -05:00
parent 13d00cd27a
commit 6f9b5c8f69

View File

@@ -2,11 +2,22 @@
Blades of Exile Coding Conventions
==================================
This file lists some guidelines for submitting code to the Open Blades of Exile project. Most of these can be taken as guidelines rather than hard rules.
This file lists some guidelines for submitting code to the Open Blades
of Exile project. Most of these can be taken as guidelines rather than
hard rules.
The most important rule is, no formatting-only changes mixed in a commit with actual code changes. Feel free to reformat a line that has been otherwise touched, or re-indent a section that you've edited, but don't change formatting just for the sake of changing formatting. If you make a change that requires re-indenting a large block of code (about 10 lines or more), such as wrapping it in a loop, if, or try, we prefer it to be split into two commits - one for the re-indenting, then one for the actual logic.
The most important rule is, no formatting-only changes mixed in a commit
with actual code changes. Feel free to reformat a line that has been
otherwise touched, or re-indent a section that you've edited, but don't
change formatting just for the sake of changing formatting. If you make
a change that requires re-indenting a large block of code (about 10
lines or more), such as wrapping it in a loop, if, or try, we prefer it
to be split into two commits - one for the re-indenting, then one for
the actual logic.
With that out of the way, here's the actual guidelines. The coding guidelines are loosely based on Google's style guide; the formatting guidelines, however, are my own.
With that out of the way, here's the actual guidelines. The coding
guidelines are loosely based on Google's style guide; the formatting
guidelines, however, are my own.
Header Files
============
@@ -14,26 +25,33 @@ Header Files
Include Guards
--------------
All headers should have an include guard. The preferred format of the include guard #define is BOE_COMPONENT_FILENAME.
All headers should have an include guard. The preferred format of the
include guard #define is BOE_COMPONENT_FILENAME.
Possible components are:
* game - files specific to the game
* data - files defining the game's data (currently kept in the classes folder)
* data - files defining the game's data (currently kept in the classes
folder)
* pced - files specific to the player character editor
* scened - files specific to the scenario editor
* dlog - files that are part of the DialogXML framework
The COMPONENT can be omitted if none of the above apply.
Any hyphens or periods in the FILENAME should be replaced with underscores in the include guard.
Any hyphens or periods in the FILENAME should be replaced with
underscores in the include guard.
Declarations
------------
Whenever feasible, try to forward declare required classes instead of including the file that defines them. With templates, however, it's generally preferred to include. Don't use pointers solely for the purpose of avoiding an include.
Whenever feasible, try to forward declare required classes instead of
including the file that defines them. With templates, however, it's
generally preferred to include. Don't use pointers solely for the
purpose of avoiding an include.
Unless dependencies make it impossible, the order of declarations in a header should be:
Unless dependencies make it impossible, the order of declarations in a
header should be:
* preprocessor defines
* typedef or using declarations
@@ -42,55 +60,86 @@ Unless dependencies make it impossible, the order of declarations in a header sh
* classes
* global functions
However, it's preferred to not include classes, enums, and global functions in the same file. Try to keep enum declarations in a separate header file, and don't include functions in the same file as a class unless they're directly related to the class.
However, it's preferred to not include classes, enums, and global
functions in the same file. Try to keep enum declarations in a separate
header file, and don't include functions in the same file as a class
unless they're directly related to the class.
One class per header is preferred. More is tolerated, if they're related classes.
One class per header is preferred. More is tolerated, if they're related
classes.
Never use a using namespace declaration in a header file.
Order of Includes
-----------------
Include files at the top of any file (header or source) should appear in the following order, with a blank line between groups:
Include files at the top of any file (header or source) should appear in
the following order, with a blank line between groups:
* the source file's counterpart header (only applicable for source files)
* the source file's counterpart header (only applicable for source
files)
* System headers (eg WinAPI, Cocoa, CoreFoundation, POSIX, X)
* C or C++ standard library headers (use the cxx form instead of xx.h for C headers)
* C or C++ standard library headers (use the cxx form instead of xx.h
for C headers)
* Boost library headers
* Other library headers (eg SFML, OpenGL, Zlib, TinyXML++, etc)
* DialogXML headers
* General Blades of Exile headers
* Component-specific Blades of Exile headers
All except the last three and the first one should use the angle brackets include style.
All except the last three and the first one should use the angle
brackets include style.
Try to make all includes explicit in the header files, rather than relying on indirect includes by including one file that includes others.
Try to make all includes explicit in the header files, rather than
relying on indirect includes by including one file that includes others.
Inline template definition headers should be included at the bottom of the header.
Inline template definition headers should be included at the bottom of
the header.
Include by filename only for Blades of Exile headers; assume all project folders containing headers are in the include path.
Include by filename only for Blades of Exile headers; assume all project
folders containing headers are in the include path.
Scoping
=======
Never use a using namespace declaration in a header file. It's acceptable in a source file, but discouraged. Using declarations are fine in source files, but not in header files unless they're in an inline function or class declaration. Namespace aliases are encouraged for long namespaces.
Never use a using namespace declaration in a header file. It's
acceptable in a source file, but discouraged. Using declarations are
fine in source files, but not in header files unless they're in an
inline function or class declaration. Namespace aliases are encouraged
for long namespaces.
Don't use nested classes.
Only put absolutely necessary functions in header files; if a function only needs to be used in one file, it shouldn't be in a header. In this case, it should be declared static. (Don't use an anonymous namespace for this purpose.)
Only put absolutely necessary functions in header files; if a function
only needs to be used in one file, it shouldn't be in a header. In this
case, it should be declared static. (Don't use an anonymous namespace
for this purpose.)
Local variables should be declared as close to the point of use as possible. Much of the legacy code placed all variable declarations at the top of the function, since this was required in C at that time; don't do this in new code.
Local variables should be declared as close to the point of use as
possible. Much of the legacy code placed all variable declarations at
the top of the function, since this was required in C at that time;
don't do this in new code.
Whenever possible, eliminate global variables. It's accepted that some global variables can;t be helped, such as the global cUniverse and the global cScenario, but if a global is just being used to pass information between disparate functions, find another way. There are such variables in the code currently which we would like to eliminate.
Whenever possible, eliminate global variables. It's accepted that some
global variables can;t be helped, such as the global cUniverse and the
global cScenario, but if a global is just being used to pass information
between disparate functions, find another way. There are such variables
in the code currently which we would like to eliminate.
Classes
=======
Use the explicit keyword for constructors that have only one non-defaultable argument, unless you actually intend to define an implicit conversion. An operator bool should usually be declared explicit as well.
Use the explicit keyword for constructors that have only one
non-defaultable argument, unless you actually intend to define an
implicit conversion. An operator bool should usually be declared
explicit as well.
Generally, you should use the class keyword (rather than the struct keyword) to declare anything with member functions or non-public members.
Generally, you should use the class keyword (rather than the struct
keyword) to declare anything with member functions or non-public
members.
Operator overloading is encouraged, provided it doesn't change the basic meaning of the operator being overloaded.
Operator overloading is encouraged, provided it doesn't change the basic
meaning of the operator being overloaded.
Declarations within a class should be in the following order:
@@ -108,7 +157,10 @@ Be sparing with friend declarations.
Functions
=========
If a function takes a parameter by reference or pointer and doesn't modify it, the parameter should be const. Don't declare parameters const if they are passed by value. Don't use const pointers for parameters (eg int*const).
If a function takes a parameter by reference or pointer and doesn't
modify it, the parameter should be const. Don't declare parameters const
if they are passed by value. Don't use const pointers for parameters (eg
int*const).
Overloading functions is encouraged.
@@ -119,84 +171,124 @@ Don't use throw() specifications
General Coding Style
====================
Use of exceptions is encouraged, though you should ensure that they get caught somewhere before main().
Use of exceptions is encouraged, though you should ensure that they get
caught somewhere before main().
Prefer C++-style casts to C-style casts.
Do not use cout, clog, or cin. Do not include <iostream>. To write log messages, use printf. All other C++ streams are permitted and in fact encouraged. Do not use sprintf for anything.
Do not use cout, clog, or cin. Do not include <iostream>. To write log
messages, use printf. All other C++ streams are permitted and in fact
encouraged. Do not use sprintf for anything.
Use const whenever it makes sense. In particular, declare string constants as const char*const.
Use const whenever it makes sense. In particular, declare string
constants as const char*const.
Never use simple macros for constants. Create an enum instead. Macros that take arguments may be acceptable, depending.
Never use simple macros for constants. Create an enum instead. Macros
that take arguments may be acceptable, depending.
Don't use 0 where a pointer is expected; use NULL or nullptr instead.
Feel free to use auto if it simplifies the code, but generally only for local variables.
Feel free to use auto if it simplifies the code, but generally only for
local variables.
Don't use lambda expressions. Use of std::function and std::bind is encouraged.
Don't use lambda expressions. Use of std::function and std::bind is
encouraged.
Use of Boost libraries is encouraged.
Naming Rules
============
Header files should have a .hpp extension. C++ source files should have a .cpp extension, and Objective-C++ files should have a .mm extension.
Header files should have a .hpp extension. C++ source files should have
a .cpp extension, and Objective-C++ files should have a .mm extension.
Files specific to one component should be named with one of the prefixes "boe.", "pc.", "scen.".
Files specific to one component should be named with one of the prefixes
"boe.", "pc.", "scen.".
Sometimes, a header will define an interface that has to be implemented differently depending on the platform. In this case, the naming should be as follows:
Sometimes, a header will define an interface that has to be implemented
differently depending on the platform. In this case, the naming should
be as follows:
* file.hpp
* file.win.cpp
* file.mac.mm (or file.mac.cpp)
* file.linux.cpp
If the Mac and Linux implementation happen to be the same due to only using POSIX headers, use "file.posix.cpp".
If the Mac and Linux implementation happen to be the same due to only
using POSIX headers, use "file.posix.cpp".
For files containing inline template definitions, an extension of .tpl.hpp is preferred.
For files containing inline template definitions, an extension of
.tpl.hpp is preferred.
In general, functions and variables should always start with a lowercase letter. Both underscore_separated and camelCase names are acceptable.
In general, functions and variables should always start with a lowercase
letter. Both underscore_separated and camelCase names are acceptable.
Enums should be named with a lowercase e followed by an uppercase letter.
Enums should be named with a lowercase e followed by an uppercase
letter.
Classes should either start with an uppercase letter or a lowercase c followed by an uppercase letter.
Classes should either start with an uppercase letter or a lowercase c
followed by an uppercase letter.
Typedef or using declarations should usually end with _t.
Do not use a trailing underscore or m_ prefix for member variables.
Names of constants (both enum constants and other constants) should either be all uppercase and separated by underscores, or camelCase starting with a lowercase k followed by an uppercase letter.
Names of constants (both enum constants and other constants) should
either be all uppercase and separated by underscores, or camelCase
starting with a lowercase k followed by an uppercase letter.
Macros, when present, should be all uppercase and separated by underscores.
Macros, when present, should be all uppercase and separated by
underscores.
Comments
========
Generally, C++-style comments are preferred, but feel free to use C-style comments for longer comments.
Generally, C++-style comments are preferred, but feel free to use
C-style comments for longer comments.
If we ever introduce Doxygen comments, they will be in the Javadoc style - block comments start with /**, line comments start with ///, and directives start with @.
If we ever introduce Doxygen comments, they will be in the Javadoc style
- block comments start with /**, line comments start with ///, and
directives start with @.
Comment whenever something's purpose may be unclear. If you're uncertain of something's purpose, feel free to add a TODO: comment. Use TODO for anything that is temporary or not perfect, or in places where there needs to be code that hasn't been written yet.
Comment whenever something's purpose may be unclear. If you're uncertain
of something's purpose, feel free to add a TODO: comment. Use TODO for
anything that is temporary or not perfect, or in places where there
needs to be code that hasn't been written yet.
For organizing the function popup menu, use MARK: comments rather than #pragma mark.
For organizing the function popup menu, use MARK: comments rather than
#pragma mark.
Formatting
==========
There's no line limit, and breaking a long line up by simply adding line breaks is discouraged. However, if a line is longer than about 100 character, you should probably consider writing it in a way to shorten it, such as using more intermediate local variables or writing a function to compute the value.
There's no line limit, and breaking a long line up by simply adding line
breaks is discouraged. However, if a line is longer than about 100
character, you should probably consider writing it in a way to shorten
it, such as using more intermediate local variables or writing a
function to compute the value.
If you need non-ASCII characters in strings, make sure the file is saved as UTF-8.
If you need non-ASCII characters in strings, make sure the file is saved
as UTF-8.
All indentation should be tabs. Assume four spaces per tab.
Braces go on the same line as the control statement or function declaration. The else keyword shares its line with the closing brace of the preceding if statement.
Braces go on the same line as the control statement or function
declaration. The else keyword shares its line with the closing brace of
the preceding if statement.
Do not put space after an open parenthesis or before a closing parenthesis. Do not put space between a keyword or function and the following open parenthesis.
Do not put space after an open parenthesis or before a closing
parenthesis. Do not put space between a keyword or function and the
following open parenthesis.
In declarations of pointers and references, the pointer or reference operator should bind to the type, not the variable. Never declare another type in the same declaration as a pointer or reference.
In declarations of pointers and references, the pointer or reference
operator should bind to the type, not the variable. Never declare
another type in the same declaration as a pointer or reference.
Do not put parentheses around return values.
If a constructor initializer must be wrapped, put the colon on the first line and one variable per line thereafter.
If a constructor initializer must be wrapped, put the colon on the first
line and one variable per line thereafter.
Never put whitespace at the end of a line (unless there's nothing else on the line and the whitespace matches nearby indentation). Never have more than two consecutive blank lines.
Never put whitespace at the end of a line (unless there's nothing else
on the line and the whitespace matches nearby indentation). Never have
more than two consecutive blank lines.