-
Pascal case - Each word of a function's name starts with a capital letter. There is no separation between words.
Examples:SystemStartup
,DebugPrint
-
Snake case - Each word of a function's name starts with a small letter. Words are separated by an underscore.
Examples:system_startup
,debug_print
-
Capital snake case - Same as regular snake case except that all letters are capital.
Examples:SYSTEM_STARTUP
,DEBUG_PRINT
-
Camel case - Same as Pascal case except that the first letter is small.
Examples:systemStartup
,debugPrint
-
To indent code, use tabs, not spaces. An exception can be seen in the Alignment section below.
-
Lines shouldn't stretch for more than 125 characters. This is a soft limit that's usually respected.
-
File names are all lowercase, and abide by the 8.3 restriction. (8 characters for the file name and 3 characters for the extension)
- When aligning, make sure to use spaces instead of tabs.
Correct:
DbgPrint("Some values: %d %d %d",
Value1,
Value2,
Value3);
Incorrect (and it'll be obvious why if you aren't using a tab width of 4):
DbgPrint("Some values: %d %d %d",
Value1,
Value2,
Value3);
These two statements will look the same only if you prefer a tab width of 4.
If needed, you may mix up spaces (for alignment) and tabs (for indenting), for example:
void PrintValues(int Value1, int Value2, int Value3)
{
DbgPrint("Some values: %d %d %d",
Value1,
Value2,
Value3);
}
Incorrect, for the same reason as the previous incorrect alignment:
void PrintValues(int Value1, int Value2, int Value3)
{
DbgPrint("Some values: %d %d %d",
Value1,
Value2,
Value3);
}
-
Function names are written in Pascal case.
-
All function names, except for static functions, must be preceded by a namespace. See Namespaces
Example:KiSystemStartup
,HalInitAcpi
-
Acronyms are written the same way as regular words. However, writing the acronym in capitals is also accepted.
Right:Acpi
, OK:ACPI
Function definitions usually look the following way:
return_type MyFunction(arg1, arg2, ...);
However, sometimes there is not enough space on one line. In that case, split the function declaration as follows:
return_type MyFunction(
arg1,
arg2,
arg3);
where the opening parenthesis is on the line containing the function name, but the closing one is on the line containing the last argument.
Don't do this - this isn't how we roll:
return_type
MyFunction(
arg1,
arg2,
arg3
);
However, you can do something like that in calls:
MyFunction(
arg1,
arg2,
arg3
);
And especially don't split the declaration if it isn't warranted. So something like this is totally OK:
void KeWaitForMultipleObjects(
int Count,
void* Objects[],
int WaitType,
int WaitReason,
int WaitMode,
bool Alertable,
PKWAIT_BLOCK WaitBlockArray)
But something like this isn't...:
void DbgPrint(
const char* Message,
...);
... because we can write it on a single line without going over the maximum line length.
Local variable names are written in Pascal case.
These follow the same pattern as Local Variable Names do.
-
All structures must be typedef'd (except for Limine bootloader request structures).
Here is an example of a correct way to define a structure:typedef struct MY_STRUCT_tag { //... } MY_STRUCT, *PMY_STRUCT;
-
Type names are written in capital snake case.
-
If part of the Ke namespace,
K
will be appended to the start of the type name, as in,KPRCB
-
If part of the Mm namespace,
MM
will be appended to the start of the type name, as in,MMPTE
-
An additional pointer typedef must be defined, with
P
appended to the start of the type name.
-
All enumeration values are written in capital snake case.
Example:enum { VALUE_ONE, VALUE_TWO, VALUE_SEVERAL, };
-
If a type definition for an enum is needed, follow the Type names rule.
-
All macro names are written in capital snake case.
-
Parameter names follow the Function arguments rule.
The Boron kernel is currently structured in the following namespaces:
Ke
- Kernel core and architecture specifics (ex:KeGetCurrentPRCB
)Mm
- Memory manager (ex:MmAllocatePhysicalPage
)Hal
- Hardware abstraction layer (currently baked into the kernel) (ex:HalMPInit
)Ex
- Executive services (ex:ExAllocatePool
)Ob
- Object management system (ex:ObReferenceObjectByName
)Io
- I/O manager (ex:IoAllocateIrp
)Brn
- System calls/native interfaces (ex:BrnCreateFile
)
Sometimes one doesn't need to expose a function to the rest of the system. In that case, the prefix should be mutated to mark this.
p
is added after the prefix if the function is private/static (ex.MmpPlugLeaks
)i
replaces the last letter or is added after the prefix if the function is internal but may be needed by other parts of the kernel (ex.MiAllocateSlab
)
All* source code files will have the following comment header attached:
/***
The Boron Operating System
Copyright (C) <Year(s) of Maintenance> <Author or The Boron Operating System Contributors>
Module name:
<Your File Name>
Abstract:
<Your Module's Abstract>
Author:
<Author Name Here> - <Creation Date - ex. 27 September 2023>
***/
Functions may have a standardized description that looks something like this:
/***
Function description:
Your Function's Description
Arguments:
ExampleArgument - Supplies an example argument
Return Value:
Your Return Value.
[Optional] IPL:
[Example] IPL <= IPL_DPC.
[Optional] Resources held:
[Example] KepExampleLock held for entire duration.
***/
The above rule is deprecated however, and will not be taken into account in the future. A different way of documenting IPL, resources and functionality of a procedure may be created.