Coding standard
Contents
Overview
Odamex relies on a coding standard to ensure continuity, this reduces bugs and provides easy readability of the code.
Requirements
- Make logical changes in separate patches
- Minimise the number of changes in each patch
- Provide an off switch for every new feature
- Do not submit things you cannot test (e.g. code for alternative platforms)
Code guidelines
General
- Add a test for every change (or an explanation of why this is impossible)
Things you should definitely AVOID in your code:
- Changing code that already works
- Precompiler macros
- Global variables (they can create problems elsewhere in code)
- Variants (tagged unions) - they can present a performance problem
- Magic numbers (use #define or const in your code for fixed numbers, at the top of files)
- Hungarian notation (just plan evil)
- C style strings. (replace them with C++ types where it is safe to do so)
- goto
File Operations
When using file i/o based functions, such as fopen() etc or filename string functions, there are some that are not provided, ie retrieving the length of a file, checking if a file exists or not.
Thankfully, Odamex provides some internal functions for doing such. Be sure to check out m_fileio.h before writing your own, it may have already been implemented! If it isn't, write us a patch and send it in.
Some of the useful functions included are:
- SDWORD M_FileLength(FILE *) - Returns the length of an open file handle
Filename operations:
- BOOL M_FileExists(std::string Filename) - Checks if a file exists or not
- BOOL M_AppendExtension(std::string &Filename, std::string Extension, bool If_Needed = true) - Add an extension on to the end of a filename, If_Needed detects if Extension is in the path, if it isn't, it is added
- void M_ExtractFilePath(std::string Path, std::string &Destination) - Returns the path of a filename in Destination
- BOOL M_ExtractFileExtension(std::string Filename, std::string &Destination) - Returns the extension of Filename in Destination
- void M_ExtractFileBase(std::string Path, std::string &Destination) - Returns the base name of Path in Destination
- void M_ExtractFileName(std::string Path, std::string &Destination) - Returns the complete filename of Path in Destination
Others include:
- BOOL M_WriteFile(std::string Filename, void *Buffer, QWORD Length) - Creates/overwrites a file and writes a block of data to it.
- QWORD M_ReadFile(std::string Filename, BYTE **Buffer) - Allocates a buffer using Z_Malloc and reads the data into it from a file, lifetime is PU_STATIC.
Memory Management
If you need to use malloc(), calloc(), realloc(), free() functions. Use the macros located in m_alloc.h, these are provided because they are much better when it comes to debugging code and such:
- M_Malloc(size_t Size)
- M_Calloc(size_t Items, size_t Size)
- M_Realloc(void *Pointer, size_t Size)
- M_Free(uintptr_t &Reference)
A list of features these functions offer:
- The Size value can NEVER be 0, this prevents platform-specific behaviour.
- M_Free uses a reference instead of a pointer, it still does the same as normal free(), but will NULL the address on return.
- They will abort the program if their operation fails.
Z_Zone Memory Management
- Be aware that the all Z_Zone allocated memory is freed when the WAD changes
Formatting
- If creating a new file, include a GPL header at the top of it, as seen in other files.
- Descriptive comments
- Comments of reasonable size. (not too big and not too small)
- Comment formatting. (in c/c++, either // for 1 liners or /* */ for multiple lines)
- Indentations to be of 1 tab character, using 4 space width tabs
- Be sure your editor/IDE's EOL mode is LF, not CRLF or CR
- 80 line character limit, for devs with text-based editors
- if you can, limit functions to a maximum size (like the amount that would fit on a monitor with a reasonable screen resolution)
What you should strive for:
- Clarity of code
- Defensive and secure coding practices
- Maintain traditional naming conventions, for consistency