Hacking mpg123
Here are some minimal guidelines for hacking the mpg123 code, meaning: A description of the coding standards the mpg123 sources follow and that patches to mpg123 should adhere to, to ease integration.
Generally, try to get into discussion with the mpg123 team about your patches and ideas on the mpg123-devel mailing list.
It is C89. Period.
The mpg123 project wants to stay true to its legacy of being the portable MPEG engine UNIX (and Windows, OS/2, ...) folks grew up to love during the end of the last millenium (or the past and current decades, if you prefer;-).
One simple rule for that is: All mpg123 source is written in the C language as specified in the ANSI C89 / ISO C90 standard.
-
Extensions to that standard need to be included in a backwards-compatible way.
One example is our usage of types like off_t only after testing for availabilty (in an autoconf macro) and defining it to a substitute type if necessary.
-
Common system workarounds and inclusion of system-specific headers are collected in the compat.h / compat.c files (that code is directly used by the mpg123 lib and the app). A look into that code might give a hint about what kind of stuff is not to be taken for granted on every system mpg123 is built on.
-
Local variables need to be declared before any other code in a block.
That rule might surprise folks, but it really is one when staying true to C89. Note that it only requires you to declare all variables in each block before the code in that block. One function can contain several blocks (if / else, loops, etc.).
- C++ / C99 - style comments are not allowed. The only comment marker is /* Comment. */, with variations of multi-linedness and doxygen fun.
A good test for conformity is building the code with a recent gcc and the options -std=c89 -pedantic. There is the configure option --enable-nagging to enable such a build.
Style
I won't discuss the reasoning behind coding style here... as it is nonsensical to argue. I will just state it as it is and ask folks to stick to it.
-
Indentation with literal tab characters, one tab is one level of indent. If you want to do alignment of stuff, use spaces for that, in addition to the indent (with the assumption of a fixed-width font).
Btw., I am wondering if one could make funky use of elastic tab stops in future, then one could use tabs for alignment and indent, in a way that makes it just look right and that would prevent silly diffs with additional whitespace in surrounding lines for alignment.
- No strict line length limit. Hard breaking of lines and alignment of code pieces is done per case following personal judgement on readability. Generally I assume people can use editors that support soft wrapping.
- Opening braces start a new line, so that they line up with the closing brace. If the enclosed block is small enough to stay on one line, opening/closing braces can stay on that line as well.
- Generally, the code tends to be a bit flexible with line breaking and spacing. When an if has only a short piece of code with it, then it can be all on one line, one statement not needing the braces around it. One statement is allowed to simply follow the if on the next line, without additional indent. But when a block is missing the prominent braces on lines of their own, it needs to be separaed by a blank line from following code.
- No space between keyword/function and opening parenthesis.
- Flexible handling of line breaking and alignment of long condition chains and function argument lists. Here, lonely parentheses with a block of lines between them are more of an exception for extreme cases. For function calls it is the rule not to break them into multiple lines unless it really is getting unreadable.
Well, here is an actual example of mpg123 code... it's taken as is, possibly not being a perfect example, but showing the main points. What is also shows that we don't have overly many comment lines. That could be improved, but also I think that code can often be written clearly enough not to require additional explanation for each step.
On long broken lines: Yes, that looks ugly when your display program does soft-wrapping without indenting to the level of the beginning of the broken line. But then, if that bothers you, you should use a better tool to work with the code instead of restricting yourself to the archaic specifications of teletypes (or punch cards, even).
Preprocessing
Well, we have C code, so we do use the C preprocessor. Although one should expect from C89-compliant preprocessors that they can take whitespace before the # introducing some preprocessor directive, it is preferred in mpg123 to put the # really right at the beginning of the line.
If indendation of preprocessing directives is necessary (nested #if), then that indent shall be applied directly after the #.
This is not (yet) consistent accross mpg123... Oh, and we probably should use tabs in preprocessor indendation just like in code indendation, unless someone gives me a pointer about preprocessors that choke on tabs there.
Documentation
The API online documentation is generated mainly from mpg123.h (which is generated from mpg123.h.in) using Doxygen. So, any addition to the official API needs to get some properly formatted comment in that header. We do not use Doxygen for the rest of the code, so it is not mandatory to document internal functions that way, though it is also not a bad idea to do so in case doxygen usage is extended.