Tip of the day: Almost every channel mode can be disabled. Don't like halfops? Use blacklist-module chanmodes/halfop;
|
Dev:Coding guidelines
This article describes how code for UnrealIRCd should be written and committed. See Contributing for the process around it, such as: reporting bugs, discussing changes, submitting patches.
Code style
Code formatting
Code formatting is fully automated.
The rules live in the .clang-format file in the source and you apply them by running make format (this requires clang-format major version 21).
The easiest way is to let your editor format on save, see Dev:Visual Studio Code. Pull requests containing unformatted code will be rejected by the CI.
A few things are deliberately not auto-formatted: hand-formatted tables and similar are surrounded by /* clang-format off */ and /* clang-format on */ markers.
Only use these markers when manual layout genuinely is more readable, such as in large data tables.
Git pre-commit hook
Developers with commit access are assumed to have a git pre-commit hook that refuses unformatted code.
Save the following as .git/hooks/pre-commit and make it executable (chmod +x):
#!/bin/sh # Check-only hook: refuse to commit code that is not clang-formatted. # Never modifies anything. Bypass once with: git commit --no-verify output=$(git clang-format --staged --diff 2>/dev/null) case "$output" in ""|"no modified files to format"*|"clang-format did not modify any files"*) exit 0 ;; *) echo "ERROR: Commit rejected: staged changes are not clang-formatted." echo "Run 'make format', review the result, and commit again." echo "(Bypass once with: git commit --no-verify)" exit 1 ;; esac
This requires git-clang-format, which comes with clang-format on most distributions.
Again, you should use clang version 21 here. If you have multiple clang versions installed, then tell it which one to use with: git config clangFormat.binary clang-format-21
Major restructuring or cleanups
If you want to restructure or clean up existing code beyond a bug or isolated feature you are working on, then you MUST discuss it first. The stable tree is often not really suitable for such things, especially if we are talking multiple files etc.
Also be careful with cleanups in general: if something looks redundant or useless at first sight, look again. It may indeed be useless, but it may also be a subtle thing that creates great bugs when 'cleaned up'.
Comments
Comment your code. It will help the next person reading it, and it will help you when you look at your own code two years later. If there is some obscure pitfall in the code, then DO mention it. Don't just hope the next author will see it like you did.
For documenting functions and struct members we use doxygen style comments: /** Like this */.
Regular comments use /* this style */.
Using // is acceptable for a short single-line remark, but multi-line comments always use /* */.
Don't mass-convert comments from one style to the other.
Writing good code
String handling
Be careful about overflows, do not do any unchecked string copies.
Instead of strcpy, strcat and sprintf, use the length-checking functions: strlcpy, strlcat and snprintf/ircsnprintf.
If you are copying or writing character-by-character in a loop, for example using *p++ = x;, then be very sure about your size counting.
Often it is better to avoid such code altogether and simply use strlcat and similar functions for everything.
Memory
Use safe_alloc, safe_free, safe_strdup and safe_strldup. These functions properly initialize memory (such as structs) with zeroes.
Do NOT use malloc, calloc, free or strdup directly.
Logging
All (new) code uses unreal_log() for logging and server notices (snomasks, etc). Don't use legacy calls. Exceptions are config_warn/config_error in config code.
Readability comes first
When writing or optimizing code, readability and stability come FIRST, speed comes after that.
We prefer readable code over a highly optimized routine that nobody understands, is difficult to extend, and might have several bugs.
Portability
The minimum is a C99 compiler, which ./configure enforces. In practice the code is built as C17 with GNU extensions on *NIX.
Code must also compile on Windows with Visual Studio 2019, so don't use exotic compiler-specific extensions.
Enums
- Use enums rather than #define constants whenever possible. It is cleaner and it aids debugging. For bit flags, we still use defines.
Before you commit
Test your code
Very important: TEST your code before committing or doing a Pull Request. Not just that it compiles, but also that it does what you want. Yes, also that one line change that you are 100% sure about breaks nothing :-)
There is also a test suite which the CI runs on every push and pull request.
Copyright
- New files must contain a proper copyright header. UnrealIRCd is GNU GPLv2 or later, so it must be compatible.
- If code from other people or projects is used, it MUST be properly credited (and again, the license must permit it).
Security issues
If you found a security issue, then do NOT report or discuss it on the public bug tracker. See Policy: Handling of security issues for how to report it privately.
Developers with commit access
The following applies to developers who commit directly to the repository, including when merging someone else's pull request.
Changes that need prior discussion
The rules about discussing changes from Contributing apply to developers with commit access as well. Especially since commits go in directly, without any reviews or way to stop it prior.
Before starting on anything big, make sure there is a bugtracker entry for it and that it has been discussed or acknowledged. Same for protocol changes or major code restructuring, breaking module API, etc.
Commit messages
The following applies to commits from yourself and if you merge someones PR:
- The first line of the commit message is a short summary of max 70 characters. This is what GitHub and
git log --onelineshow in commit overviews, so it must make sense on its own. - The rest of the commit message should explain what you changed and why.
- If there is a related item on bugs.unrealircd.org you end the commit message with:
Reported by XYZ in https://bugs.unrealircd.org/view.php?id=####
It is important to credit people: they have taken the time to report an issue/feature so they deserve credit.
After committing
If the commit relates to a bug# on bugs.unrealircd.org:
- Mark the issue as 'Resolved' and set the 'Fixed in version' to the future release
- In the comment on the bug tracker copy-paste the commit reference: at least the github URL to the commit, but preferably the copy-paste of 'git log' that is relevant
Version files
Do not touch version.c.SH or version.h.
Those are for the head coders, as part of doing releases.