-
Notifications
You must be signed in to change notification settings - Fork 3
Style Guide
In order for Doxygen to be able to generate documentation of the code, comments need to be in a particular format. There a are variety of supported styles of comments, so for consistency Loom follows a subset of these styles. The preferred way to comment typical elements of Loom code are detailed below
At the top of each file, provide a description of its contents and some general information, in the following format:
///////////////////////////////////////////////////////////////////////////////
///
/// @file Filename
/// @brief Some short file description.
/// @details Even more file description can go here.
/// @author Author 1
/// @author Author 2
/// @date 2020
/// @copyright GNU General Public License v3.0
///
///////////////////////////////////////////////////////////////////////////////
A comment describing a variable should look like:
/// Description of variable
int var;
or
/// Description of variable.
/// Further details
int var;
Alternatively, if there are several similar variables in sequence, they may be commented as such:
int var1; ///< Description of var1
int var2; ///< Description of var2
int var3; ///< Description of var3
If a more detailed description is warranted, you may also use the following
int var; ///< A more detailed description
///< after the variable
A comment describing a class should look like the following unless it represents a module, in which case see the details below
/// Description of class
class ExampleClass
{
...
}
Prefer for a sequence of similarly formatted, short lines of code (e.g. switch statements, items of enum definitions)
code ///< Brief inline comment
code ///< Detailed inline
///< comment
/// Brief description.
/// Detailed description
/// goes here.
/// @param[in] param1 Brief description of param1
/// @param[out] param2 Brief description of param2
/// @param[in,out] param3 Brief description of param3
/// @return Brief description of return value
bool func(float param1, int& param2, char* param3);
Leave a blank line after function declaration.
Note: Function templates are declared and defined in header file, but the above comment block will apply
Note: If documenting a constructor see the alternate form detailed below
Only has a divider between other function definitions, description goes in header file
/////////////////////////////////////////////////////////////////////
int func(float param1, int& param2, char* param3)
{
...
code implementation
...
}
Leave a blank line after function definition.
General comment blocks may look like the following:
/// Brief description which ends at this dot.
/// Details follow here.
/// ... text ...
/// ... text ...
/// ... text ...
A comment describing a preprocessor definition should look like:
/// Description of define
#define DEFINITION 1
Alternatively, if there are several similar definitions in sequence, they may be commented as such:
#define DEF1 123 ///< Description of DEF1
#define DEF2 4.56 ///< Description of DEF2
#define DEF3 "acb" ///< Description of DEF3
If sections of code within a file warrant dividers for readability and ease of navigation, headers / dividers should looks as follows. If code is different enough, it can likely go in its own files, rather than dividing it like this.
// ================================================================
// === Major Section Title ===
// ================================================================
// === === Minor Section Title === ===
The comments in the code that are not used to generate documentation should generally follow a style as follows:
// Comment goes here
... code being ...
... commented on ...
A series of short lines of code may also be commented as:
statement1; // comment 1
statement2; // comment 2
statement3; // comment 3
Prefer the conditional operator for short, binary control flow:
(condition) ? [true outcome] : [false outcome] ;
Prefer indentation style if/else statement if outcome body is a single line
if(condition)
[True Outcome]
else
[False Outcome]
Never return from within an if statement. Instead, initialize a variable of return type as base case, assign within logic body, and return the placeholder.
type exampleFunction(type arg1, type arg2) {
type placeholder = baseCase;
if(arg1) {
if(arg2)
placeholder = value1;
else
placeholder = value2;
} else
placeholder = value3;
return placeholder;
}
Loom has a configuration web app that will output device configuration's based on user input to a graphical user interface. In order for any new classes to appear as options (automatically) in the configurator, the class must follow specific documentation described below.
Before each class declaration, put text that matches the following format:
///////////////////////////////////////////////////////////////////////////////
///
/// Some short class description.
///
/// A more detailed class description can go here.
///
/// @par Resources
/// - [SomeLink](https://github.com/OPEnSLab-OSU/Loom)
///
/// @pre Any preconditions noted here.
/// @bug Any bugs noted here.
/// @warning Provide any warnings
///
///////////////////////////////////////////////////////////////////////////////
If there are not preconditions, bugs, or warnings, omit the tag.
///////////////////////////////////////////////////////////////////////////////
///
/// InternetPlat built off of SSLClient running over an Ethernet Featherwing.
///
/// @attention Requires 7KB of free SRAM at runtime to use.
///
/// @par Resources
/// - [Module Documentation](https://openslab-osu.github.io/Loom/html/class_loom___ethernet.html)
/// - [Product Page: Adafruit Ethernet Featherwing](https://www.adafruit.com/product/3201)
/// - [Dependency: EthernetLarge](https://github.com/OPEnSLab-OSU/EthernetLarge) OPEbS Lab fork of Arduino Ethernet library
/// - [Dependency: SSLClient](https://github.com/OPEnSLab-OSU/SSLClient)
///
///////////////////////////////////////////////////////////////////////////////
class Loom_Ethernet : public LoomInternetPlat
{
... /*rest of class code... */
}
Immediately before the constructor for your class put text that matches the following format:
/// <moduleName> module constructor.
///
/// @param[<in,out>] <paramName> <paramDataType> | <paramValue> | <paramRange> | <Description of param>
/// ...
/// ...
-
moduleName: the name of the module, which is also the name of the class
-
in,out: The parameter will either be in and/or out
-
paramDataType: The C++ data type of the parameter
-
paramValue: The actual value of the parameter, following C++ syntax for all data types values
-
paramRange: If the range of acceptable values for the parameter are discreet, then this will be a comma separated list inside curly braces. If the acceptable range is continuous then this will be a two hyphen separated values inside brackets. If a range value does not make sense for the data type then this value will be null.
-
Description of param: Write a brief description of this parameter
/// OLED module constructor.
///
/// @param[in] module_name String | <"OLED"> | null | OLED module name
/// @param[in] enable_rate_filter Bool | <true> | {true, false} | Whether or not to impose maximum update rate
/// @param[in] min_filter_delay Int | <300> | [50-5000] | Minimum update delay, if enable_rate_filter enabled
/// ...
/// ...
Loom_OLED(
const char* module_name = "OLED",
bool enable_rate_filter = true,
uint min_filter_delay = 300,
...
...
);
Make use of tabs for alignment of elements of the documentation for readability.