-
Notifications
You must be signed in to change notification settings - Fork 1
Coding Style
This document outlines the C coding style guidelines for the KallistiOS (KOS) codebase. These guidelines are not strict rules but should be followed for consistency and readability.
- Write readable and maintainable code.
- Avoid overly complex functions or structures.
- Prioritize code clarity over optimization unless critical.
- Consistency: Follow the same patterns throughout the project.
- Use 4-character tabs (or equivalent 4 spaces) for indentation.
- Limit code to 3 levels of indentation to maintain readability.
- Example:
if(condition) { // level 1 if(other_condition) { // level 2 while(loop_condition) { // level 3 } } }
- Place the opening brace
{
on the same line as the control statement or function header. - Place the closing brace
}
on its own line. - Example:
if(x == y) { do_something(); } else { do_something_else(); }
-
Global Variables/Functions: Use descriptive names, typically prefixed with the subsystem (e.g.,
pvr_
,net_
).- Example:
pvr_init()
,net_send_packet()
.
- Example:
-
Local Variables: Use short, clear names (e.g.,
i
,tmp
,ptr
), especially in small scopes. -
Constants: Use all uppercase letters and underscores (e.g.,
MAX_BUFFER_SIZE
). - Example:
static const int MAX_USERS = 100; int user_count = 0;
- Keep functions short and focused—ideally fitting within 1-2 screenfuls (80x24 characters).
- Avoid more than 5-10 local variables in a function. Use helper functions if needed.
- Use descriptive names for functions, reflecting their purpose.
- Example:
void reset_device(int device_id) { // Clear settings and restart the device }
- Functions that take no arguments should be explicitly marked with
void
in the argument list.- Example:
void my_function(void) { // Function logic }
- Prefer block comments over inline comments for better clarity.
- Example of block comments:
/* * Align the given address to the specified alignment. * Return the aligned address. */ size_t align_to(size_t address, size_t alignment) { ... }
- Add header-style comments before functions or complex sections:
- Describe the function’s purpose, parameters, and return value.
- Avoid redundant comments like:
// Open the file f = fopen(filename, "r");
Each header file should follow this structure for consistency and clarity:
-
Start with a file header comment, which includes basic information about the file:
/* KallistiOS ##version## directory/foobar.h Copyright (C) 2024 Your Name */
-
Follow this with a Doxygen comment block that describes the purpose of the file, its group, and any relevant authors:
/** \file directory/foobar.h \brief Foo support. \ingroup foobar This file contains the interface to the foo system of KOS. Foobars are used to ... \author Your Name */
-
Next, include a header guard to prevent multiple inclusions:
#ifndef __FOOBAR_H #define __FOOBAR_H
-
Inside the header guard, add a C++ guard for compatibility and include any necessary headers:
#include <sys/cdefs.h> __BEGIN_DECLS // Insert other headers here
-
If applicable, define your Doxygen group and provide a brief overview of the API:
/** \defgroup foobar Foobar Management \brief Foobar System API \ingroup Utility This module provides functionality for managing foobar objects, including operations to toggle between active and inactive states. @{ */
-
Next, add type definitions and function declarations. Each of those should be accompanied by a Doxygen comment that explains its purpose, parameters, etc:
/** \brief Initializes the foobar system. Comment here if you want to get into more detail. \return 0 on success, -1 on failure. */ int foobar_init(void);
-
Finally, close the Doxygen group and both the C++ and header guards:
/** @} */ __END_DECLS #endif /* __FOOBAR_H */
- Each source file should start with a file header comment:
/* KallistiOS ##version## directory/foobar.c Copyright (C) 2024 Your Name */
- Followed by headers. Include only necessary headers and avoid redundant includes.
- Include order:
- Standard C headers (
<stdio.h>
,<string.h>
, etc.) - KOS headers (
<kos/thread.h>
, etc.) - Architecture-specific headers (
<dc/g2bus.h>
, etc.)
- Standard C headers (
- Include order:
- After that, feel free to put a block comment explaining what's in the file
and describing any notes about the module, followed by the functions/variables themselves:
- Example:
/* This module supports foobars in KOS. A foobar is used to ... */ // Insert function definitions here
- Use sized integer types from
<stdint.h>
rather than built-in types likeuint8
,uint16
, etc.- Example:
#include <stdint.h> int32_t my_var;
- Type names should have a
_t
suffix if typedef'd. - Prefix types related to a specific subsystem with an identifier.
- Example:
typedef uint32 pvr_token_t;
- Example:
- Always check return values of functions that can fail (e.g., memory allocation, file operations).
- Use error codes or
errno
for error reporting. - Example:
if((ptr = malloc(size)) == NULL) { dbglog(DBG_ERROR, "malloc failed"); return -1; }
Follow these guidelines to ensure that your code remains clean, readable, and maintainable. While certain guidelines may be flexible, consistency and clarity are paramount.