2017-08-05 14:01:05 +00:00
|
|
|
This document superceeds any other prior documentation or commentary regarding
|
|
|
|
the formatting of the Hamlib C and C++ source code. This document does not
|
|
|
|
apply to the Autotools build system, i.e. configure.ac, Makefile.am or the
|
|
|
|
Autoconf macros in the 'macros/' directory.
|
|
|
|
|
|
|
|
|
|
|
|
0. Background
|
|
|
|
|
|
|
|
Throughout its life, a number of coding styles have found their way into the
|
|
|
|
Hamlib source tree. Besides lacking a readable consistency, recent compilers
|
|
|
|
have reported logic errors likely due to inconsistent formatting. Such errors
|
|
|
|
can escape notice during casual scanning of a source file.
|
|
|
|
|
|
|
|
|
|
|
|
1. Objective
|
|
|
|
|
|
|
|
Adopt certain mandatory and recommended coding guidelines to aid in
|
|
|
|
readability of the Hamlib C source code and avoid logic errors due to
|
|
|
|
inconsistent code formatting to the extent possible.
|
|
|
|
|
|
|
|
|
|
|
|
2. Mandatory rules
|
|
|
|
|
|
|
|
* The use of tab characters, ASCII hexadecimal 0x09, shall no longer be
|
|
|
|
permitted for the indentation and alignment of C or C++ source or header
|
|
|
|
files, only spaces, ASCII hexadecimal 0x20, shall be used for indentation
|
|
|
|
and alignment. The use of the '\t' escape sequence in rig_debug() output,
|
|
|
|
static strings, and the like is permitted.
|
|
|
|
|
|
|
|
* Indentation shall be 4 spaces. Alignment shall consist of the number of
|
|
|
|
spaces necessary after indentation.
|
|
|
|
|
|
|
|
Discussion: Plenty has been written regarding the use of the tab character in
|
|
|
|
source files and the proper setup of the various editors. There is no point
|
|
|
|
in rehashing that here, except to say that spaces are universal. Modern
|
|
|
|
editors are configurable to setting indents to four spaces and tab stops to
|
|
|
|
four spaces.
|
|
|
|
|
2017-10-05 02:10:27 +00:00
|
|
|
* Bare conditionals shall be avoided. All conditionals--'if', 'else', 'for',
|
|
|
|
'while', and 'do while' shall have their statements enclosed in braces.
|
|
|
|
|
|
|
|
NOTE: Exceptions will be allowed in certain rare circumstances. See
|
|
|
|
Recommended coding style bullet points below.
|
2017-08-05 14:01:05 +00:00
|
|
|
|
|
|
|
Discussion: Consider this conditional:
|
|
|
|
|
|
|
|
if (something);
|
|
|
|
do_that();
|
|
|
|
|
|
|
|
No harm, eh? Look again. The programmer gave the 'if' conditional a null
|
2017-10-05 02:10:27 +00:00
|
|
|
statement with the trailing ';' at the end of the line and also indented the
|
|
|
|
'do_that();' statement. As a result, 'do_that()' will be called whether
|
|
|
|
'something' is true or not. Is that what the programmer intended?
|
2017-08-05 14:01:05 +00:00
|
|
|
|
2017-10-05 02:10:27 +00:00
|
|
|
If, instead, the code is formatted to:
|
2017-08-05 14:01:05 +00:00
|
|
|
|
2017-10-05 02:10:27 +00:00
|
|
|
if (something)
|
|
|
|
{
|
2017-08-05 14:01:05 +00:00
|
|
|
;
|
|
|
|
do_that();
|
|
|
|
}
|
|
|
|
|
2017-10-05 02:10:27 +00:00
|
|
|
the null statement becomes harmless and 'do_that()' is called depending on the
|
|
|
|
truth of 'something'.
|
2017-08-05 14:01:05 +00:00
|
|
|
|
|
|
|
Here proper indentation and alignment is only half the battle in finding such
|
|
|
|
bugs, enclosing all statement blocks in braces is the other half.
|
|
|
|
|
|
|
|
Patch submissions will be checked for adherence to these two rules. While
|
|
|
|
patches won't be rejected outright, the corrections will be applied and the
|
|
|
|
patch set rebased before being pushed to the repositories.
|
|
|
|
|
|
|
|
|
|
|
|
3. Recommended coding style
|
|
|
|
|
|
|
|
The following bullet points follow the formatting the Artistic Style code
|
|
|
|
formatter will apply when using the included 'scripts/astylerc' configuration
|
|
|
|
file. Any version from 2.03 or later should work. It can be invoked from a
|
|
|
|
backend directory as follows:
|
|
|
|
|
2017-10-05 02:10:27 +00:00
|
|
|
$ astyle --options=../scripts/astylerc moonmelter.c
|
2017-08-05 14:01:05 +00:00
|
|
|
|
|
|
|
The old file will be copied to 'moonmelter.c.orig' as a back up.
|
|
|
|
|
2017-10-05 02:10:27 +00:00
|
|
|
* Brace style is Allman where the opening brace of a function definition is on
|
|
|
|
a new line in the far left column following the function signature.
|
|
|
|
|
|
|
|
For conditionals, the opening brace is also on a new line after the
|
|
|
|
conditional test and aligned in the same column as the first letter of the
|
|
|
|
keyword.
|
|
|
|
|
|
|
|
In all cases the closing brace is on a line of its own and lines up
|
|
|
|
vertically with the opening brace.
|
|
|
|
|
|
|
|
The 'else', 'else if', or 'while' from a 'do while' loop keywords are not
|
|
|
|
cuddled after the closing brace but placed on a new line after the closing
|
|
|
|
brace of the previous block.
|
2017-08-05 14:01:05 +00:00
|
|
|
|
|
|
|
* Indents are four spaces as detailed above. Each level of code should be one
|
2017-10-05 02:10:27 +00:00
|
|
|
indent further to the right.
|
2017-08-05 14:01:05 +00:00
|
|
|
|
|
|
|
* Isolate conditional blocks with a blank line before and after. Like
|
|
|
|
paragraphs in prose that focus on a topic, it's important that conditionals
|
|
|
|
be obvious to the reader. An exception is where another conditional follows
|
2017-10-05 02:10:27 +00:00
|
|
|
immediately on the next line. Indentation is sufficient.
|
2017-08-05 14:01:05 +00:00
|
|
|
|
2017-10-05 02:10:27 +00:00
|
|
|
* No space between parentheses and the enclosed characters.
|
2017-08-05 14:01:05 +00:00
|
|
|
|
|
|
|
* One space on either side of operators and between function arguments.
|
|
|
|
|
|
|
|
* One space between a conditional key word and its opening parentheses.
|
|
|
|
|
|
|
|
* No space between a function name and its opening paretheses.
|
|
|
|
|
|
|
|
* No space between a pointer operator ('*') and the pointer name. Likewise
|
|
|
|
for the address operator ('&'). Exception: In a function prototype and
|
|
|
|
definition, a space should be put between the '*' operator and the
|
|
|
|
function/macro name to indicate a pointer is returned, not that the
|
|
|
|
function/macro name is an assigned pointer value.
|
|
|
|
|
|
|
|
* Keep code lines under 80 characters. This will require some judgement on
|
|
|
|
where the break works best. A couple of keys are, a) break conditionals
|
2017-10-05 02:10:27 +00:00
|
|
|
before a comparison operator so it appears at the beginning of the next
|
|
|
|
line, and, b) when breaking a function call, put all arguments on their own
|
|
|
|
line. It is sometimes necessary for strings to go beyond the 80 character
|
|
|
|
point. This is fine. If needed, a C compiler will concatenate strings that
|
|
|
|
are split across multiple lines.
|
2017-08-05 14:01:05 +00:00
|
|
|
|
|
|
|
* Avoid trailing comments when possible. Comments should precede the
|
|
|
|
statement(s) they describe.
|
|
|
|
|
2017-10-05 02:10:27 +00:00
|
|
|
* One line conditionals should enclose the statement in braces, as in:
|
|
|
|
|
|
|
|
if (whatsit == 5) { return whatsit; }
|
|
|
|
|
|
|
|
or:
|
|
|
|
|
|
|
|
do { x++; } while (x < 10)
|
|
|
|
|
|
|
|
When choosing not to use braces on a simple one line conditional, please
|
|
|
|
comment your intention:
|
|
|
|
|
|
|
|
/* NOP unless x is true. */
|
|
|
|
while (!x);
|
2017-08-05 14:01:05 +00:00
|
|
|
|
2020-05-31 22:29:29 +00:00
|
|
|
3.1 Shell scripts
|
|
|
|
|
|
|
|
Shell scripts should be written for POSIX portability as much as possible.
|
|
|
|
Avoid using '/bin/bash' in the shebang line. Use '/bin/sh' instead to allow
|
|
|
|
for use of the system shell (some systems may not have Bash installed at all!)
|
|
|
|
when the script is run. The caveat is that some favorite Bash extensions are
|
|
|
|
not POSIX portable so care is needed. To help avoid the pitfalls, various
|
|
|
|
tools exist such as 'checkbashisms' which will report syntax that is not
|
|
|
|
portable.
|
|
|
|
|
|
|
|
* Use four space indents as with the C style above.
|
|
|
|
|
|
|
|
* Vertical space around conditional blocks can aid readability (newlines are
|
|
|
|
cheap!).
|
|
|
|
|
|
|
|
* Try to keep line length between 80 and 100 characters if possible.
|
|
|
|
Backslashes (\) can sometimes be used to break up long lines. Be careful as
|
|
|
|
the shell is often less forgiving than the C compiler with extra spaces.
|
|
|
|
Experiment.
|
|
|
|
|
2020-05-30 23:30:29 +00:00
|
|
|
* Avoid the use of backticks (`) to invoke a subshell, also known as the grave
|
2020-05-31 22:29:29 +00:00
|
|
|
accent and backquote, in shell scripts, configure.ac, any Makefile.am, or
|
|
|
|
.m4 files we maintain. While their use will likely be long supported, they
|
|
|
|
do require some care in use and can be difficult to read on the screen.
|
2020-05-30 23:30:29 +00:00
|
|
|
|
|
|
|
The preferred construct is to use parentheses to invoke a subshell and the
|
|
|
|
'$()' construct when the output of the command is intended to be captured in
|
|
|
|
a shell variable. This answer covers the reasoning well:
|
|
|
|
|
|
|
|
https://unix.stackexchange.com/a/126928
|
|
|
|
|
|
|
|
In Makefile.am files use the '$$()' construct to capture subshell command
|
|
|
|
output into a make variable.
|
|
|
|
|
|
|
|
Exceptions:
|
|
|
|
|
|
|
|
Files intended to be formatted in Markdown syntax use backticks as a
|
|
|
|
formatting cue. In these files such use is permitted.
|
|
|
|
|
|
|
|
There are a number of files sourced from the GNU Project where the
|
|
|
|
backtick is used extensively as an opening single quote character. As we
|
|
|
|
don't usually maintain these files except to update them as needed, these
|
|
|
|
rules are waived for those files.
|
|
|
|
|
2020-05-31 22:29:29 +00:00
|
|
|
3.2 Python
|
|
|
|
|
|
|
|
Python authors are already well aware of the classic PEP8 and need no further
|
|
|
|
instruction on the matter.
|
|
|
|
|
|
|
|
3.3 Perl
|
|
|
|
|
|
|
|
Perl authors already know their code can resemble modem line noise and it will
|
|
|
|
work flawlessly. Somehow.
|
|
|
|
|
|
|
|
3.4 Makefile
|
|
|
|
|
|
|
|
When indenting a line in a Makefile.am (and the resulting Makefile) that a
|
|
|
|
real Tab character (0x09) is required. Spaces will cause 'make' errors.
|
|
|
|
|
2017-08-05 14:01:05 +00:00
|
|
|
|
|
|
|
4. Use of code formatting tools
|
|
|
|
|
|
|
|
There are a number of tools that can be used to format the source code. Some
|
|
|
|
are standalone and others are part of an editor or IDE.
|
|
|
|
|
|
|
|
4.1 astyle
|
|
|
|
|
|
|
|
Use of the Artistic Style (astyle) formatter (http://astyle.sourceforge.net/)
|
|
|
|
with the included options file ('scripts/astylerc') will provide most of the
|
|
|
|
objectives outlined above. Some manual formatting may be required. For
|
|
|
|
example, if a line is already less than 80 characters and ends with an
|
2017-10-05 02:10:27 +00:00
|
|
|
operator, astyle will not move the operator to the beginning of the next line
|
2017-08-05 14:01:05 +00:00
|
|
|
where it is preferred.
|
|
|
|
|
|
|
|
4.2 GNU Indent
|
|
|
|
|
|
|
|
GNU Indent lacked a few of the features of astyle for padding conditional
|
|
|
|
blocks and enforcing spaces around operators and between comma separated
|
|
|
|
arguments (if I'm mistaken, please provide a working example--N0NB).
|
|
|
|
Otherwise, acceptable results should be possible.
|
|
|
|
|
|
|
|
4.3 GNU Emacs
|
|
|
|
|
|
|
|
GNU Emacs with the included C Mode can be configured to provide acceptable
|
|
|
|
formatting while editing source files. Eventually a custom Hamlib style elisp
|
|
|
|
file will be included in the 'scripts/' directory.
|
|
|
|
|
|
|
|
Useful minor modes include:
|
|
|
|
|
|
|
|
modeline-char: Displays the character and its Unicode value on the
|
|
|
|
modeline.
|
|
|
|
fill-column-indicator: Draws a vertical line at fill column.
|
|
|
|
|
|
|
|
highlight-numbers: Applies a color face to numeric constants.
|
|
|
|
|
|
|
|
highlight-parentheses: Highlights parentheses and the nesting braces
|
|
|
|
around point (cursor).
|
|
|
|
cwarn: Parses the C code for harmful constructs.
|
|
|
|
|
|
|
|
whitespace: Shows whitespace--tabs, spaces, and newlines in the
|
|
|
|
buffer.
|
|
|
|
|
|
|
|
4.4 Other editors & IDEs
|
|
|
|
|
|
|
|
Other editors and IDEs likely have various ways to apply ones preferred
|
|
|
|
style. The main things to configure are having the <Tab> key produce four
|
|
|
|
spaces and that tab stops be every four positions across the screen (if
|
|
|
|
configurable).
|
|
|
|
|
|
|
|
|
|
|
|
5 Summary
|
|
|
|
|
|
|
|
Hamlib source code is no place for an entry into the obfuscated C contest!
|
|
|
|
Many of us are hobbyists and write this for fun. Easy to read and understand
|
|
|
|
logic is preferred over a clever solution. If your solution must be written
|
|
|
|
in a clever fashion, please document it well in your comments.
|
|
|
|
|
|
|
|
73, Nate, N0NB
|