Main:
PARI/GP?
Download
Packages
Search
Support:
FAQ
Documentation
Mailing Lists
Links
Development:
Version Control
Coding Guidelines
Latest Changes
Bugs
Buildlogs
Statistics:
Benchmarks
WWW Stats
|
Coding guidelines
In order to keep the PARI/GP code consistent, please use the following
conventions when writing code that you intend to check into our repository or
submit to the development mailing list.
Best practices
- Language: all comments should be written in english. Try to keep function
and variables names (preferably in english) consistent and reasonably
short. Only use 7bit characters.
- Patches: Always send context diffs to pari-dev, the BTS or the
maintainers (preferably, use diff -u). State precisely what the
object of a patch is and check that the patch contains no useless chunk,
unrelated to the patch object. Try to break big patches in small independent
units.
- Robustness: before sending a patch, always try make doc
and make bench: nothing should be changed in the latter unless you
have a very good reason for it (state it), and then the patch must include the
updated output for the test. The code should compile with all C89, C99
and C++ compilers (in particular, do not use gcc or MSVC extensions, or
C++-style comments // blah).
- Globals: avoid adding global variables, even static to a code module.
When it is unavoidable (?), make sure whether you need the THREAD
modifier: do all threads need a copy of this or is it safe to share
it?
- Tests: write tests for new code in src/test; if you fix a bug,
you may add a regression test to the relevant test. Try not to change the
make bench subset: it is a common reference point.
- Write short generic functions, with obvious (and reusable) functionality
rather than huge monolithic ones. Avoid assumptions about the inputs, then
document explicitly what is left, e.g. p must be prime.
- Avoid using malloc() / free(), the PARI stack is at
your disposal.
- Comment non-obvious code, document shortcomings (use FIXME
markers in the code), document each non-trivial function: above the
definition, and possibly in doc/usersch5.tex,
doc/develop.tex or src/functions/.
Finalization / Cleanup
- Scopes and declarations: check that all variables have a sensible
scope, ideally the smallest possible scope. Define temporary variable at the
start of the block that need them. (Only declare variables at the
beginning of a block.) A function must be either static, or
declared in paridecl.h or paripriv.h. A function ending up
in paridecl.h must be documented in one of the doc/
manuals.
- If you add or modify a function in the src/functions/ database,
make sure the GP2C descriptions are up to date.
- Try to integrate diagnostics within the DEBUGLEVEL,
DEBUGMEM scheme. Never use printf() directly, use wrappers
like fprintferr(). Use the pari_err() and
pari_warn() functions for fatal errors and warnings respectively,
never exit() or abort().
- Public functions should be gerepileupto-safe and, if possible,
memory clean (not leave garbage on the stack). It is allowed to leave
a few small objects on the stack to avoid a huge garbage collection,
but this should be documented, and one should use stackdummy
in this case.
Formatting, spacing and indentation
The most important is to be consistent with neighbouring code, never reformat
the latter so that it adapts to your style.
- Line length: no line should be longer than 80 characters unless absolutely
necessary. Do not leave trailing whitespace.
- Indentation: use 2 spaces for each indentation levels. Do not use
TABs but actual whitespace characters.
- Where to put spaces: do not put spaces before an opening
parenthesis or bracket when calling functions or indexing. Use them around
equal signs and after commas or semi-colons.
- Where to put braces: either of these is acceptable
if (a) { if (a)
code(); {
code(); code();
} code();
}
the first one being usually preferred. Avoid uneccessary open/close braces
and line breaks: use
if (a) code();
rather than
if (a) {
code();
}
- Nesting: to limit indentation levels, it is
often advisable to use
for (...) {
if (!a) continue;
...
}
rather than
for (...) {
if (a)
{
...
}
}
Try not to use repeated tests against a boolean flag to get out of
deeply nested constructions. Often, moving part of the loop code to a
subroutine and using a simple return is the best solution.
|