mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-01 02:48:14 +00:00
370 lines
10 KiB
Plaintext
370 lines
10 KiB
Plaintext
|
|
OpenCellular Coding Style
|
|
=========================
|
|
|
|
We follow Linux Kernel coding style with following exceptions.
|
|
|
|
Exceptions:
|
|
----------
|
|
|
|
o 4-space indentation
|
|
o Typedef enums and structs
|
|
o indent case labels
|
|
switch (suffix) {
|
|
case 'G':
|
|
case 'g':
|
|
mem <<= 30;
|
|
break;
|
|
case 'M':
|
|
case 'm':
|
|
mem <<= 20;
|
|
break;
|
|
case 'K':
|
|
case 'k':
|
|
mem <<= 10;
|
|
/* fall through */
|
|
default:
|
|
break;
|
|
}
|
|
|
|
Additions:
|
|
---------
|
|
|
|
o Non-public functions (functions not exported in header for use by other
|
|
modules) should be static
|
|
o Unless absolutely necessary, global variables within a module should be static
|
|
o Avoid using forward declarations, just #include headers when possible
|
|
o Static variables of the form s_variableName
|
|
o Non-static functions of the form ModuleName_functionName()
|
|
o File names
|
|
o C and header files in same directory
|
|
o ModuleName.c/h
|
|
o All directory names should be lowercase, with underscores added as
|
|
needed to improve readability (e.g. my_complex_directory/Foo.h)
|
|
o Hex values are upper-case: 0xFB
|
|
o Unless size doesn't matter, use fixed-width types defined in <stdint.h>
|
|
(uint32_t, int8_t, etc.)
|
|
o Enums
|
|
o ALL_CAPS, start with enum name (within reason) for namespacing/readability
|
|
typedef enum SbdFlowControl {
|
|
SBD_FLOW_CONTROL_DISABLED = 0,
|
|
SBD_FLOW_CONTROL_HW = 3,
|
|
SBD_FLOW_CONTROL_SW = 4,
|
|
SBD_FLOW_CONTROL_ALL = 6
|
|
} SbdFlowControl;
|
|
typedef enum AtLineType {
|
|
AT_LINE_TYPE_RESPONSE = 0,
|
|
AT_LINE_TYPE_CMD_ECHO,
|
|
|
|
COUNT_AT_LINE_TYPE
|
|
} AtLineType;
|
|
|
|
o #includes should be in alphabetical order & logically separated:
|
|
/* Module header[s] */
|
|
…
|
|
/* stdlib headers */
|
|
…
|
|
/* TI includes */
|
|
…
|
|
/* OC includes */
|
|
o Wrap functions like this:
|
|
ReturnType ReallyLongFunctionName(Type par_name1, Type par_name2,
|
|
Type par_name3)
|
|
{
|
|
DoSomething();
|
|
...
|
|
}
|
|
|
|
ReturnType ReallyReallyReallyLongFunctionNameThatJustWillNotFit(
|
|
Type par_name1, /* double indent */
|
|
Type par_name2,
|
|
Type par_name3)
|
|
{
|
|
DoSomething(); /* regular indent */
|
|
...
|
|
}
|
|
|
|
o No spaces after end of line
|
|
o No blank lines at the end of file
|
|
o Each file should have description of what it does, which function it contains
|
|
etc.
|
|
o Each function should describe what operation it execute on the parameters and
|
|
what it returns. If there are any parameter overloaded, specify it clearly.
|
|
o No dead code.
|
|
o Function shouldn't be more than one page.
|
|
o Central exiting of function
|
|
o Use /* */ for comments. Multiple lines:
|
|
/*
|
|
*
|
|
*/
|
|
o MACROS are NOT to define functions. MACROS shouldn't effect control or effect
|
|
registers or changes the system states.
|
|
|
|
|
|
Sample Code:
|
|
-----------
|
|
|
|
ExampleModule.h
|
|
/*
|
|
* Copyright 2004-present Facebook. All Rights Reserved.
|
|
*
|
|
* See Canonical Style Documents at:
|
|
*
|
|
* TODO: reference style document
|
|
*
|
|
* Example header that demonstrates our current C style. The goal of this
|
|
* code, while nonsensical, is to show a visual example of as many of our
|
|
* style rules/guidelines as possible.
|
|
*
|
|
* Note the #include order: stdlib includes, TI includes, then OpenCellular
|
|
* includes in quotes (""). Each group should be in alphabetical order.
|
|
* Additionally, we only want to include the headers necessary for the
|
|
* interfaces/structs/enums in the header, everything else should be in the
|
|
* source file
|
|
*/
|
|
|
|
/* TODO: what do we want to do for #include guards? #pragma once doesn't have
|
|
* namespacing issues and is generally faster, but not guaranteed to be portable
|
|
*/
|
|
#ifndef EXAMPLEMODULE_H_
|
|
#define EXAMPLEMODULE_H_
|
|
|
|
/* stdlib includes */
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
/* OC includes */
|
|
#include "some_project_folder/SomeDependency.h"
|
|
|
|
/*
|
|
* Initializes the module and stuff
|
|
*/
|
|
void ExampleModule_init(void);
|
|
|
|
/*
|
|
* Takes lots of arguments, but doesn't do much that's useful with them.
|
|
*
|
|
* @param count an integer input (by value)
|
|
* @param value an enum input (by value)
|
|
* @param name a string input (by const-ref)
|
|
* @param outVal output integer arg (by pointer)
|
|
*
|
|
* @return true if function succeeds, false otherwise
|
|
*/
|
|
bool ExampleModule_funcWithManyArgs(int64_t count,
|
|
EnumType value,
|
|
const char *name,
|
|
uint32_t *outVal);
|
|
|
|
|
|
/*
|
|
* Another useless function
|
|
*
|
|
* @param param1 first example integer (by value)
|
|
* @param param2 second example integer (by value)
|
|
* @param param3 third example integer (by const-ref)
|
|
*/
|
|
void ExampleModule_methodThatHasAReallyLongNameOhCrapImRunningOutOfSpace(
|
|
int param1,
|
|
bool param2,
|
|
const uint32_t *param3);
|
|
|
|
#endif /* EXAMPLEMODULE_H_ */
|
|
ExampleModule.c
|
|
/*
|
|
* Copyright 2004-present Facebook. All Rights Reserved.
|
|
*
|
|
* See additional comments in: ExampleModule.h
|
|
*
|
|
* Note the #include order: First our related .h file, then the same
|
|
* order as we'd do elsewhere (see ExampleModule.h).
|
|
*
|
|
* This file is formatted with clang-format -i
|
|
*/
|
|
|
|
#include "ExampleModule.h"
|
|
|
|
/* stdlib includes */
|
|
#include <math.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
/* TI includes */
|
|
#include <driverlib/I2C.h>
|
|
#include <driverlib/UART.h>
|
|
|
|
/* OC includes */
|
|
#include "drivers/Power.h"
|
|
#include "drivers/Rf.h"
|
|
#include "helpers/Memory.h"
|
|
#include "helpers/Array.h"
|
|
|
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
|
|
|
typedef enum SampleState {
|
|
SAMPLE_STATE_INIT,
|
|
SAMPLE_STATE_RUN,
|
|
SAMPLE_STATE_IDK,
|
|
|
|
COUNT_SAMPLE_STATE
|
|
} SampleState;
|
|
|
|
typedef struct UselessConfig {
|
|
uint32_t someInt; /*!< Sample comment on member */
|
|
int8_t otherValue; /*!< This looks important */
|
|
SampleState state; /*!< All your base are belong to us */
|
|
struct UselessConfig *next; /*!< Pointer to next item in list */
|
|
} UselessConfig;
|
|
|
|
static SampleState s_myUselessConfig = {
|
|
.someInt = 5,
|
|
.state = SAMPLE_STATE_INIT
|
|
};
|
|
|
|
static SampleState s_simpleInitSample = { .otherValue = 2 };
|
|
|
|
static uint32_t s_someStaticVariable;
|
|
|
|
/* Array Initializer List Example */
|
|
static const uint32_t sampleTable[COUNT_SAMPLE_STATE] = {
|
|
[SAMPLE_STATE_INIT] = 6,
|
|
[SAMPLE_STATE_RUN] = 42,
|
|
[SAMPLE_STATE_IDK ] = 0xFACEB00C
|
|
};
|
|
|
|
static const uint8_t anotherArray[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06
|
|
0x07, 0x08, 0x09, 0x0A, 0x0B };
|
|
|
|
/* TODO: How do we want to comment on functions? Having a full header block
|
|
* might be a bit overkill since we're planning on doing doxygen comments in
|
|
* the header. Some sort of comment to make it easier to see the beginning of
|
|
* new functions might be nice though. Not sure how we want to document static
|
|
* functions either - probably don't need to be as strict as for public
|
|
* functions
|
|
*/
|
|
void ExampleModule_init(void)
|
|
{
|
|
s_myUselessConfig.state = SAMPLE_STATE_RUN;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* This additional comment is not in the javadoc style, as it's supposed to
|
|
* describe more concrete implementation details. Any comments that may be
|
|
* useful to the class API "customer" (as opposed to someone who might modify
|
|
* this class) should instead be in JavaDoc style in ExampleCode.h.
|
|
******************************************************************************/
|
|
/* TODO: should this be MapLookup instead? */
|
|
static uint32_t mapLookup(SampleState state, bool uselessParam)
|
|
{
|
|
if (state < COUNT_SAMPLE_STATE) {
|
|
return sampleTable[state];
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
const uin32_t ExampleModule_methodThatHasALongNameOhCrapImRunningOutOfSpace(
|
|
int param1,
|
|
bool param2,
|
|
const uint32_t *param3)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* TODO: not sure for sure how we want to do wrapping parameters. I'm on the
|
|
* fence between this style (FB & Google) vs. what I wrote above in the document
|
|
*/
|
|
bool ExampleModule_funcWithManyArgs(int64_t count,
|
|
EnumType value,
|
|
const char *name,
|
|
uint32_t *outVal)
|
|
{
|
|
/*
|
|
* The body of this function is used to demonstrate common code constructs
|
|
* so that the indentation, braces, and spacing styles for them are
|
|
* immediately apparent.
|
|
*/
|
|
|
|
/*
|
|
* This section demonstrates different kinds of if() blocks, including
|
|
* long/short if() blocks, complicated if() expressions, and validity
|
|
* checks on pointer/handle variables.
|
|
*/
|
|
if (count < 0) {
|
|
++count;
|
|
} else if (count == 0) {
|
|
--count;
|
|
} else {
|
|
count *= 2;
|
|
}
|
|
|
|
if (strlen(name) < 20 &&
|
|
!strcmp(name, "some string that I made up") &&
|
|
(count < 0 || count > 5)) {
|
|
*outVal += count;
|
|
}
|
|
|
|
if (name) {
|
|
count += strlen(name);
|
|
}
|
|
|
|
int64_t *realPtr = NULL;
|
|
if (!realPtr) {
|
|
realPtr = malloc(sizeof(*realPtr));
|
|
}
|
|
|
|
/* This section demonstrates looping constructs. */
|
|
for (int64_t i = 0; i < count; ++i) {
|
|
*outVal *= 2;
|
|
}
|
|
|
|
int i = 10;
|
|
while (i > 0) {
|
|
--i;
|
|
}
|
|
|
|
do {
|
|
++i;
|
|
} while (i <= 10);
|
|
|
|
/*
|
|
* This section demonstrates formatting for switch statments
|
|
*/
|
|
switch (s_myUselessConfig.state) {
|
|
case SAMPLE_STATE_INIT:
|
|
s_myUselessConfig.state = SAMPLE_STATE_RUN;
|
|
break;
|
|
case SAMPLE_STATE_RUN: {
|
|
uint32_t i = s_someStaticVariable - 1;
|
|
printf("Doing stuff %d", i);
|
|
break;
|
|
}
|
|
case SAMPLE_STATE_IDK:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* This section demonstrates formatting for basic expressions, operators,
|
|
* and initializations.
|
|
*/
|
|
char s[] = "startValue";
|
|
size_t someSize = sizeof(*realPtr);
|
|
int val = count / 2;
|
|
count = (count + val) & ((val << 3) + count * val);
|
|
uint32_t *samplePtr = &s_someStaticVariable;
|
|
SampleState zeroInitializedStruct = {};
|
|
|
|
/* Multiple variables of same type */
|
|
/* TODO: allow multiple vars on one line? eg. int var1, var2, var3 */
|
|
int var1;
|
|
int *var2;
|
|
int *var3;
|
|
|
|
var1 = 2;
|
|
var2 = &var1;
|
|
var3 = var2;
|
|
|
|
return true;
|
|
}
|
|
|