-
Notifications
You must be signed in to change notification settings - Fork 59
Code style guide #300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
jperon
wants to merge
2
commits into
master
Choose a base branch
from
jperon_codestyle
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Code style guide #300
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,236 @@ | ||
| # Lunatik C Code Style Guide | ||
|
|
||
| This guide outlines the code style conventions observed in the `lunatik.h` header file, which should be followed for consistency across the Lunatik project. As a general rule, we tend to stick to [Linux kernel rules](https://www.kernel.org/doc/html/latest/process/coding-style.html). | ||
|
|
||
| ## File Headers | ||
|
|
||
| All source files should begin with the SPDX license identifier and copyright information (e.g., [`lunatik.h`](lunatik.h:1-4)). | ||
|
|
||
| ```c | ||
| /* | ||
| * SPDX-FileCopyrightText: (c) 2023-2025 Ring Zero Desenvolvimento de Software LTDA | ||
| * SPDX-License-Identifier: MIT OR GPL-2.0-only | ||
| */ | ||
| ``` | ||
|
|
||
| ## Includes | ||
|
|
||
| Includes should be grouped, with system/kernel headers first, followed by Lua headers, and then project-specific headers. Use an empty line to separate groups (e.g., [`lunatik.h`](lunatik.h:9-16)). | ||
|
|
||
| ```c | ||
| #include <linux/mutex.h> | ||
| #include <linux/spinlock.h> | ||
| #include <linux/slab.h> | ||
| #include <linux/kref.h> | ||
|
|
||
| #include <lua.h> | ||
| #include <lauxlib.h> | ||
|
|
||
| /* #include "project_header.h" (if applicable) */ | ||
| ``` | ||
|
|
||
| ## Indentation | ||
|
|
||
| Use tabs for indentation (e.g., [`lunatik.h`](lunatik.h:20-25)). For consistent alignment, especially within multi-line macros, it is recommended to configure your text editor to display tabs as 8 spaces. | ||
|
|
||
| ## Bracing Style | ||
|
|
||
| ### Functions | ||
|
|
||
| Functions use Allman style, with the opening brace on a new line after the function declaration (e.g., [`lunatik.h`](lunatik.h:37-43)). | ||
|
|
||
| ```c | ||
| static inline bool lunatik_isready(lua_State *L) | ||
| { | ||
| /* ... */ | ||
| } | ||
| ``` | ||
|
|
||
| ### Control Structures (if, for, while, do-while) | ||
|
|
||
| Control structures like `if`, `for`,`while` and `do-while` loops use K&R style | ||
| (e.g., [`lunatik.h`](lunatik.h:20-25), [`lunatik.h`](lunatik.h:47-52)). | ||
|
|
||
| ```c | ||
| if (condition) { | ||
| /* ... */ | ||
| } | ||
|
|
||
| #define lunatik_handle(runtime, handler, ret, ...) \ | ||
| do { \ | ||
| /* ... */ \ | ||
| } while (0) | ||
| ``` | ||
|
|
||
| ## Naming Conventions | ||
|
|
||
| ### Macros | ||
|
|
||
| Macros follow two conventions: | ||
|
|
||
| * **Constants and Definitions**: Use `ALL_CAPS_WITH_UNDERSCORES` for macros defining constants or used for general definitions (e.g., [`lunatik.h`](lunatik.h:17), [`lunatik.h`](lunatik.h:190)). | ||
|
|
||
| ```c | ||
| #define LUNATIK_VERSION "Lunatik 3.6" | ||
| #define LUNATIK_ERR_NULLPTR "null-pointer dereference" | ||
| ``` | ||
|
|
||
| * **Function-like Macros**: Use `lowercase_with_underscores` for macros that behave like functions ; prefix them according to the module name (e.g., [`lunatik.h`](lunatik.h:19), [`lunatik.h`](lunatik.h:27)). | ||
|
|
||
| ```c | ||
| #define lunatik_locker(o, mutex_op, spin_op) | ||
| #define lunatik_newlock(o) | ||
| ``` | ||
|
|
||
| ### Type Definitions (structs, enums) | ||
|
|
||
| Type definitions (structs, enums) use `snake_case` with a `_t` suffix for the `typedef` alias. The struct tag itself can use `_s` suffix (e.g., [`lunatik.h`](lunatik.h:64-68)). | ||
|
|
||
| ```c | ||
| typedef struct lunatik_reg_s { | ||
| const char *name; | ||
| lua_Integer value; | ||
| } lunatik_reg_t; | ||
| ``` | ||
|
|
||
| ### Functions | ||
|
|
||
| Functions use `snake_case` with a prefix (e.g., [`lunatik.h`](lunatik.h:37), [`lunatik.h`](lunatik.h:101)). | ||
|
|
||
| ```c | ||
| static inline bool lunatik_isready(lua_State *L) | ||
| int lunatik_runtime(lunatik_object_t **pruntime, const char *script, bool sleep); | ||
| ``` | ||
|
|
||
| ### Variables | ||
|
|
||
| Variables use `snake_case` (e.g., [`lunatik.h`](lunatik.h:38), [`lunatik.h`](lunatik.h:148)). | ||
|
|
||
| ```c | ||
| lua_State *L; | ||
| lunatik_object_t *runtime; | ||
| ``` | ||
|
|
||
| ## Macros | ||
|
|
||
| Multi-line macros should use `\` for line continuation and be enclosed in a `do { ... } while(0)` block to ensure proper semicolon usage and scope. Align the `\` characters for readability. Parameters should be enclosed in parentheses when used within the macro body to avoid unexpected operator precedence issues (e.g., `(o)->sleep`) | ||
| (e.g., [`lunatik.h`](lunatik.h:19-25), [`lunatik.h`](lunatik.h:46-52), [`lunatik.h`](lunatik.h:54-62)). | ||
|
|
||
| ```c | ||
| #define lunatik_locker(o, mutex_op, spin_op) \ | ||
| do { \ | ||
| if ((o)->sleep) \ | ||
| mutex_op(&(o)->mutex); \ | ||
| else \ | ||
| spin_op(&(o)->spin); \ | ||
| } while(0) | ||
| ``` | ||
|
|
||
| ## Comments | ||
|
|
||
| ### Block Comments | ||
|
|
||
| Use C-style block comments (`/* ... */`) for multi-line comments, especially for file headers (e.g., [`lunatik.h`](lunatik.h:1-4)). | ||
|
|
||
| ```c | ||
| /* | ||
| * This is a block comment. | ||
| */ | ||
| ``` | ||
|
|
||
| ### Inline Comments | ||
|
|
||
| Use C-style block comments (`/* ... */`) for inline comments or short explanations, consistent with kernel practice (e.g., [`lunatik.h`](lunatik.h:40)). | ||
|
|
||
| ```c | ||
| static inline bool lunatik_isready(lua_State *L) | ||
| { | ||
| bool ready; /* This is an inline comment */ | ||
| /* ... */ | ||
| } | ||
| ``` | ||
|
|
||
| ## Whitespace | ||
|
|
||
| ### Binary Operators | ||
|
|
||
| Use spaces around binary operators (`=`, `+`, `-`, `*`, `/`, `==`, `!=`, etc.) (e.g., [`lunatik.h`](lunatik.h:4), [`lunatik.h`](lunatik.h:21)). | ||
|
|
||
| ```c | ||
| total = a + b; | ||
| if (x == y) | ||
| ``` | ||
|
|
||
| ### Commas | ||
|
|
||
| Use a space after commas (e.g., [`lunatik.h`](lunatik.h:27), [`lunatik.h`](lunatik.h:48)). | ||
|
|
||
| ```c | ||
| handler(L, ## __VA_ARGS__); | ||
| const char *name, lua_Integer value; | ||
| ``` | ||
|
|
||
| ### Function Calls | ||
|
|
||
| No space between the function name and the opening parenthesis (e.g., [`lunatik.h`](lunatik.h:37)). | ||
|
|
||
| ```c | ||
| lunatik_isready(L) | ||
| ``` | ||
|
|
||
| ### Unary Operators | ||
|
|
||
| No space between unary operators and their operand (e.g., `*ptr`, `&var`, `!condition`) (e.g., [`lunatik.h`](lunatik.h:98), [`lunatik.h`](lunatik.h:149)). | ||
|
|
||
| ```c | ||
| *pruntime | ||
| &object->kref | ||
| !lunatik_getstate(runtime) | ||
| ``` | ||
|
|
||
| ## Type Casting | ||
|
|
||
| Type casts should be explicit and use parentheses around the type (e.g., [`lunatik.h`](lunatik.h:32), [`lunatik.h`](lunatik.h:307)). | ||
|
|
||
| ```c | ||
| (lunatik_object_t **)lua_getextraspace(L) | ||
| (char *)hook->field | ||
| ``` | ||
|
|
||
| ## Function Parameters | ||
|
|
||
| Parameters in function declarations should be clearly typed. If a parameter is a pointer, the `*` should be next to the variable name (e.g., [`lunatik.h`](lunatik.h:37), [`lunatik.h`](lunatik.h:101)). | ||
|
|
||
| ```c | ||
| lua_State *L | ||
| lunatik_object_t **pruntime | ||
| ``` | ||
|
|
||
| ## Line Breaking | ||
|
|
||
| Staying under 80 characters per line is [preferred](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bdc48fa11e46f867ea4d75fa59ee87a7f48be144), but [don’t stick to this rule against common sense](https://lkml.org/lkml/2020/5/29/1038). | ||
|
|
||
| When a line exceeds the preferred limit, break it at a logical point, such as after a comma in a function argument list, after a binary operator, or before a new expression. Indent the continued line with tabs to align with the start of the expression or argument list. | ||
|
|
||
| ### Function Declarations and Calls | ||
|
|
||
| Break after commas in parameter lists, aligning subsequent parameters (e.g., [`lunatik.h`](lunatik.h:101)). | ||
|
|
||
| ```c | ||
| int lunatik_runtime(lunatik_object_t **pruntime, | ||
| const char *script, bool sleep); | ||
| ``` | ||
|
|
||
| ### Conditional Statements | ||
|
|
||
| Break long conditional expressions after logical operators, aligning the continuation (e.g., [`lunatik.h`](lunatik.h:245-246)). | ||
|
|
||
| ```c | ||
| return class != NULL && | ||
| (pobject = luaL_testudata(L, ix, class->name)) != NULL ? *pobject : NULL; | ||
| ``` | ||
|
|
||
| ## Line breaks, new lines and file Endings | ||
|
|
||
| All source files must end with two empty lines. Otherwise, there mustn’t be multiple consecutive empty lines in the files. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just one, right.. one empty line at the end of the file |
||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We actually don't respect this.. we can agree on a sane number though.. 80 is too little
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the reference above, Linus raised the detected limit in the warning script to 100.
Luacheck by default checks for lines > 120.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we should see what's the longest in the current code base?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
180 characters long.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh that's long.. hehe.. any chance of getting the second longest? I think that might be a good number..
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
176, then 135.
Over 105903 lines whose length > 9, only 58 (lines of code, not comments or LDoc) are above 100, only 11 above 120.
With Linus leaving a warning above 100, I think it could be a good rule, as soon as we agree that common sense keeps all its rights.
IMHO, this style of break (as function definitions are likely the longest ones) would be the best: two tabs before the second line, to avoid confusion with function body. Python follows this convention. Aligning with the opening parenthesis would require mixing tabs and spaces for indentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say 120 and 1 tab.. my vote, at least ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could agree on that, then: