-
Notifications
You must be signed in to change notification settings - Fork 0
Code Format and Commenting
To aid in maintaining consistency across all of the common libraries in formatting, naming, logic structure, and internal documentation style, the following guidelines should be adhered to when contributing or modifying any code.
The Linux kernel coding style has been used as a base for these guidelines.
Tab stops should be set at 4 characters. Tab stops should use the tab character. Do not use spaces.
Column width is to be set to 81 characters.
Each level of indention is to be the same width as a single TAB character. Although indentation does not effect logic structure within the NetLinx language, it is imperative that this is maintained for code readability.
Where possible, excess whitespace should be avoided. The exception to this is where it provides a logical separation between values.
Do not add spaces around (inside) parenthesized expressions. The following is a bad example
foo_bar( x )
Use one space around (on each side of) binary operators, such as any of these:
= + - < > * / % | & ^ <= >= == !=
but no space before the postfix increment & decrement unary operators:
++ --
When calling functions, no space should be inserted between the function name and opening parenthesis of the argument list, however arguments should be separated by a comma followed by a single space.
String concatenation should follow the same spacing form as function argument lists described above.
integer i
for (i = 0; i < 10; i++) {
foo_bar(i * 10, 'abc')
}
is preferable to
integer i
for ( i = 0 ; i < 10 ; i++ ) {
foo_bar ( i * 10, 'abc' )
}
or
integer i
for(i=0;i<10;i++){
foo_bar(i*10,'abc')
}
char[] x = "'foo', $20, 'bar'"
is preferred to
char[] x="'foo',$20,'bar'"
foo_bar(i * 10, 'abc')
is preferable to
foo_bar ( i * 10 , 'abc')
or
foo_bar(i*10,'abc')
Conditional statements should always split the condition and the action into separate lines. For example
if (x == y) {
foo_bar(z)
}
should be used instead of
if (x == y) foo_bar(z)
For complex conditionals which expand beyond the defined [CodeFormatAndCommenting#Column_Width column width] each condition is to be placed on a new line and the line indented by a TAB character further than the parent.
define_function foo_bar()
{
...
if (x > y &&
x <= z &&
w <> x) {
// Do something
}
...
}
If a function requires an extended argument list which causes the invocation to expand beyond the defined [CodeFormatAndCommenting#Column_Width column width], each argument should be placed on it's own line and indented by two tab characters beyond the current level of indentation.
uber_foo_bar(arg0,
arg1,
arg2,
arg3,
arg4,
arg5)
If the arguments can fit within the column width they invocation should be written as a single line
foo_bar(arg0, arg1)
When assigning a list a values to an array, each entry should appear on its own line:
char tmp[] = {
'a',
'b',
'c'
}
rather than
char tmp[] = {'a', 'b', 'c'}
The first line of a function definition should include the required preamble, function name the parameter list. The open brace of the function scope is to be placed on the following line.
define_function char foo_bar (integer a, char b)
{
// Return something
}
Netlinx event handlers are to be formatted in the same way as function blocks. That is, the opening brace is to sit on a line by itself following the event definition.
button_event[device, 0]
{
push:
{
// Do push event guff
}
release:
{
// Do release event
}
}
All other statement block are to have the opening brace appear on the same line as the block's opening statement.
if (x > y) {
// Do something
}
Functions that have analogs to built-in functions in other languages and / or seem like they should be a built-in in regards to standard use of NetLinx in working code should probably be named with similar names (in the former case) and use short names (example: trim). Those that are more specialized should be prefixed with the name of the library in which they are in followed by an underscore.
Function names which utilise multiple component words should separate the words with an underscore.
Do not use cute names like thisVariableIsATemporaryCounter
. Instead it should be called tmp
, which is much easier to write, and remains easy to understand.
However, while mixed-case names are frowned upon, descriptive names for
global variables are a must. If a global variable named something similar to foo
is found anywhere in the repository the commit logs will be traced to find the original author of that line. This person will then be tracked down and slapped with a wet fish. Repeatedly.
Global variables (to be used only if you really need them) need to have descriptive names. If you have a function that counts the number of active users, you should call that count_active_users()
or similar, you should not call it cntusr()
.
Encoding the type of a function into the name (so-called Hungarian notation) is brain damaged - the compiler knows the types anyway and can check those, and it only confuses the programmer.
Local variable names should be short and to the point. If you have
some random integer loop counter, it should be called i
, or similar. Calling it loop_counter
is non-productive, if there is no chance of it being misunderstood. Similarly, tmp
can be just about any type of variable that is used to hold a temporary value.
Sticking with the 'lazy programmer approach' of using short names, functions in which the argument type is implied (ie. sqrt()
) should use a single character variable name - x
. For functions requiring multiple arguments, or where the parameter may not by obvious, descriptive names (which adhere to the above variable naming guidelines) should be utilized.
Although the NetLinx compiler permits the use of a semi-colon (;
) to signify line termination this should not be used, as lines are automatically terminated.
Comments are good, but there is also a danger of over-commenting. NEVER try to explain HOW your code works in a comment: it's much better to write the code so that the working is obvious, and it's a waste of time to explain badly written code.
Generally, you want your comments to tell WHAT your code does, not HOW. Also, try to avoid putting comments inside a function body: if the function is so complex that you need to separately comment parts of it, you should probably go back to chapter 6 for a while. You can make small comments to note or warn about something particularly clever (or ugly), but try to avoid excess. Instead, put the comments at the head of the function, telling people what it does, and possibly WHY it does it.
The preferred style for long (multi-line) comments is:
/*
* This is the preferred style for multi-line
* comments.
* Please use it consistently.
*
* Description: A column of asterisks on the left side,
* with beginning and ending almost-blank lines.
*/
To save space you can put a comment on one line:
/* This comment takes up only one line. */