1# Fluoride Style Guide 2This document outlines the coding conventions and code style used in Fluoride. 3Its primary purpose is to provide explicit guidance on style so that developers 4are consistent with one another and spend less time debating style. 5 6As a rule, we follow the Google C++ 7[Style Guide](https://google.github.io/styleguide/cppguide.html). 8Exceptions will be noted below. 9 10## Directory structure 11Directories at the top-level should consist of major subsystems in Fluoride. 12Each subsystem's purpose should be documented in the `doc/directory_layout.md` 13file, even if it seems obvious from the name. 14 15For a subsystem that contains code, its directory structure should look like: 16``` 17 Android.mk 18 include/ 19 src/ 20 test/ 21``` 22Further, the directory structure inside `src/` and `include/` should be 23mirrored. In other words, if `src/` contains a subdirectory called `foo/`, 24`include/` must also have a subdirectory named `foo/`. 25 26## Target architecture 27Fluoride targets a variety of hardware and cannot make many assumptions about 28memory layout, sizes, byte order, etc. As a result, some operations are 29considered unsafe and this section outlines the most important ones to watch out 30for. 31 32### Pointer / integer casts 33In general, do not cast pointers to integers or vice versa. 34 35The one exception is if an integer needs to be temporarily converted to a 36pointer and then back to the original integer. This style of code is typically 37needed when providing an integral value as the context to a callback, as in the 38following example. 39``` 40void my_callback(void *context) { 41 uintptr_t arg = context; 42} 43 44set_up_callback(my_callback, (uintptr_t)5); 45``` 46Note, however, that the integral value was written into the pointer and read 47from the pointer as a `uintptr_t` to avoid a loss of precision (or to make the 48loss explicit). 49 50### Byte order 51It is not safe to assume any particular byte order. When serializing or 52deserializing data, it is unsafe to memcpy unless both source and destination 53pointers have the same type. 54 55## Language 56Fluoride is written in C99 and should take advantage of the features offered by 57it. However, not all language features lend themselves well to the type of 58development required by Fluoride. This section provides guidance on some of the 59features to embrace or avoid. 60 61### C Preprocessor 62The use of the C preprocessor should be minimized. In particular: 63* use functions or, if absolutely necessary, inline functions instead of macros 64* use `static const` variables instead of `#define` 65* use `enum` for enumerations, not a collection of `#define`s 66* minimize the use of feature / conditional macros 67 68The last point is perhaps the most contentious. It's well-understood that 69feature macros are useful in reducing code size but it leads to an exponential 70explosion in build configurations. Setting up, testing, and verifying each of 71the `2^n` build configurations is untenable for `n` greater than, say, 4. 72 73### C++ 74Although C++ offers constructs that may make Fluoride development faster, 75safer, more pleasant, etc. the decision _for the time being_ is to stick with 76pure C99. The exceptions are when linking against libraries that are written 77in C++. At the time of writing these libraries are `gtest` and `tinyxml2`, 78where the latter is a dependency that should be eliminated in favor of simpler, 79non-XML formats. 80 81### Variadic functions 82Variadic functions are dangerous and should be avoided for most code. The 83exception is when implementing logging since the benefits of readability 84outweigh the cost of safety. 85 86### Functions with zero arguments 87Functions that do not take any arguments (0 arity) should be declared like so: 88``` 89void function(void); 90``` 91Note that the function explicitly includes `void` in its parameter list to 92indicate to the compiler that it takes no arguments. 93 94### Variable declarations 95Variables should be declared one per line as close to initialization as possible. 96In nearly all cases, variables should be declared and initialized on the same line. 97Variable declarations should not include extra whitespace to line up fields. For 98example, the following style is preferred: 99``` 100 int my_long_variable_name = 0; 101 int x = 5; 102``` 103whereas this code is not acceptable: 104``` 105 int my_long_variable_name = 0; 106 int x = 5; 107``` 108 109As a result of the above rule to declare and initialize variables together, 110`for` loops should declare and initialize their iterator variable in the 111initializer statement: 112``` 113 for (int i = 0; i < 10; ++i) { 114 // use i 115 } 116``` 117 118### Contiguous memory structs 119Use C99 flexible arrays as the last member of a struct if the array needs 120to be allocated in contiguous memory with its containing struct. 121A flexible array member is writen as `array_name[]` without a specified size. 122For example: 123``` 124typedef struct { 125 size_t length; 126 uint8_t data[]; 127} buffer_t; 128 129// Allocate a buffer with 128 bytes available for my_buffer->data. 130buffer_t *my_buffer = malloc(sizeof(buffer_t) + 128); 131uint8_t *data = my_buffer->data; 132``` 133 134### Pointer arithmetic 135Avoid pointer arithmetic when possible as it results in difficult to read code. 136Prefer array-indexing syntax over pointer arithmetic. 137 138In particular, do not write code like this: 139``` 140typedef struct { 141 size_t length; 142} buffer_t; 143 144buffer_t *my_buffer = malloc(sizeof(buffer_t) + 128); 145uint8_t *data = (uint8_t *)(my_buffer + 1); 146``` 147Instead, use zero-length arrays as described above to avoid pointer arithmetic 148and array indexing entirely. 149 150### Boolean type 151Use the C99 `bool` type with values `true` and `false` defined in `stdbool.h`. 152Not only is this a standardized type, it is also safer and provides more 153compile-time checks. 154 155### Booleans instead of bitfields 156Use booleans to represent boolean state, instead of a set of masks into an 157integer. It's more transparent and readable, and less error prone. 158 159### Function names as strings 160C99 defines `__func__` as an identifier that represents the function's name 161in which it is used. The magic identifier `__FUNCTION__` should not be used 162as it is a non-standard language extension and an equivalent standardized 163mechanism exists. In other words, use `__func__` over `__FUNCTION__`. 164 165## Fluoride conventions 166This section describes coding conventions that are specific to Fluoride. 167Whereas the _Language_ section describes the use of language features, this 168section describes idioms, best practices, and conventions that are independent 169of language features. 170 171### Memory management 172Use `osi_malloc` or `osi_calloc` to allocate bytes instead of plain `malloc`. 173Likewise, use `osi_free` over `free`. These wrapped functions provide additional 174lightweight memory bounds checks that can help track down memory errors. 175 176By convention, functions that contain `*_new` in their name are allocation 177routines and objects returned from those functions must be freed with the 178corresponding `*_free` function. For example, list objects returned from 179`list_new` should be freed with `list_free` and no other freeing routine. 180 181### Asserts 182Use `CHECK` liberally throughout the code to enforce invariants. Assertions 183should not have any side-effects and should be used to detect programming logic 184errors. Please do not use `assert`. 185 186At minimum, every function should assert expectations on its arguments. The 187following example demonstrates the kinds of assertions one should make on 188function arguments. 189``` 190 size_t open_and_read_file(const char *filename, void *target_buffer, size_t max_bytes) { 191 CHECK(filename != NULL); 192 CHECK(filename[0] != '\0'); 193 CHECK(target_buffer != NULL); 194 CHECK(max_bytes > 0); 195 196 // function implementation begins here 197 } 198``` 199 200## Header files 201In general, every source file (`.c` or `.cpp`) in a `src/` directory should 202have a corresponding header (`.h`) in the `include/` directory. 203 204### Template header file 205``` 206[copyright header] 207 208#pragma once 209 210#include <system/a.h> 211#include <system/b.h> 212 213#include "subsystem/include/a.h" 214#include "subsystem/include/b.h" 215 216typedef struct alarm_t alarm_t; 217typedef struct list_t list_t; 218 219// This comment describes the following function. It is not a structured 220// comment, it's English prose. Function arguments can be referred to as 221// |param|. This function returns true if a new object was created, false 222// otherwise. 223bool template_new(const list_t *param); 224 225// Each public function must have a comment describing its semantics. In 226// particular, edge cases, and whether a pointer argument may or may not be 227// NULL. 228void template_use_alarm(alarm_t *alarm); 229``` 230 231### License header 232Each header file must begin with the following Apache 2.0 License with `<year>` 233and `<owner>` replaced with the year in which the file was authored and the 234owner of the copyright, respectively. 235``` 236/****************************************************************************** 237 * 238 * Copyright <year> <owner> 239 * 240 * Licensed under the Apache License, Version 2.0 (the "License"); 241 * you may not use this file except in compliance with the License. 242 * You may obtain a copy of the License at: 243 * 244 * http://www.apache.org/licenses/LICENSE-2.0 245 * 246 * Unless required by applicable law or agreed to in writing, software 247 * distributed under the License is distributed on an "AS IS" BASIS, 248 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 249 * See the License for the specific language governing permissions and 250 * limitations under the License. 251 * 252 ******************************************************************************/ 253``` 254 255### Include guard 256After the license header, each header file must contain the include guard: 257``` 258#pragma once 259``` 260This form is used over traditional `#define`-based include guards as it is less 261error-prone, doesn't pollute the global namespace, is more compact, and can 262result in faster compilation. 263 264## Formatting 265Code formatting is done automatically using clang-format. 266 267The style file is located at the root of the source tree in .clang-format. The 268-style=file option instructs clang-format to look for this file. You may find 269clang-format --help useful for more advanced usage. The [Online clang-format 270Documentation](http://clang.llvm.org/docs/ClangFormat.html) can also be helpful. 271 272`clang-format -style=file -i path_to_files/filename_or_*` 273 274### My Patch Doesn't Apply Anymore! 275Choose one of the options below. The fewer patches that have been applied to 276the tree since the formatting change was applied, the better. In this short 277guide, commands you type will be marked as `code`, with output in *italics*. 278 279#### Option 1: The Best Case 280Use this option if your patch touches only a few files with few intermediate 281patches. 282 283##### Find the formatting patch 284 285`git log --oneline path_to_files/filename_or_* | grep clang-format | head -n 5` 286 287 **15ce1bd** subtree: Apply **clang-format** for the first time* 288 289##### Revert the formatting patch 290 291`git revert HASH -n` 292 293(Replace HASH with 15ce1bd in this example.) 294 295##### Check for conflicts with your patch 296 297`git status | grep both.modified` 298 299If this list contains files modified by your patch, you should give up 300 301`git revert --abort` 302 303and try a different method. 304 305If this list contains files not modified by your patch, you should unstage them 306 307`git reset HEAD both_modified_file` 308 309and remove their changes 310 311`git checkout both_modified_file` 312 313##### Apply your patch 314 315`git cherry-pick your_patch_that_used_to_apply_cleanly` 316 317##### Reformat the code 318 319`clang-format -style=file -i path_to_files/filename_or_*` 320 321##### Commit the code that your patch touched 322 323`git add path_to_files/filename_or_*` 324 325`git commit --amend` 326 327##### Clean up any other files 328 329`git checkout .` 330 331##### Review your new patch 332 333`git diff` 334 335#### Option 2: Reformat your patch 336 337##### Start with a tree with your patch applied to the tip of tree 338 339`git log --oneline | head -n 1` 340 341 **dc5f0e2** Unformatted but vital patch* 342 343(**Remember the HASH from this step**) 344 345##### Create a new branch starting from the first unrelated patch 346 347`git checkout HEAD^ -b reformat_my_patch_branch` 348 349`git log --oneline | head -n 1` 350 351 **15ce1bd** First Unrelated patch* 352 353##### Reformat the code 354 355`clang-format -style=file -i path_to_files/filename_or_*` 356 357##### Commit your temporary formatting patch 358 359`git add path_to_files/filename_or_*` 360 361`git commit -m tmp_format_patch` 362 363##### Revert your temporary formatting patch (**Bear with me!**) 364 365`git revert HEAD --no-edit` 366 367##### Apply your patch 368 369`git cherry-pick HASH` 370 371(The HASH of your patch, dc5f0e2 in this case) 372 373##### Reformat the code 374 375`clang-format -style=file -i path_to_files/filename_or_*` 376 377##### Commit your second temporary formatting patch 378 379`git add path_to_files/filename_or_*` 380 381`git commit -m tmp_format_patch_2` 382 383##### Check to see that everything looks right 384 385`git log --oneline | head -n 5` 386 387*04c97cf tmp_format_patch_2* 388 389*cf8560c Unformatted but vital patch* 390 391*04c97cf Revert "tmp_format_patch"* 392 393*d66bb6f tmp_format_patch* 394 395*15ce1bd First Unrelated patch* 396 397##### Squash the last three patches with git rebase 398 399`git rebase -i HEAD^^^` 400 401*pick 04c97cf tmp_format_patch_2* 402 403*squash cf8560c Unformatted but vital patch* 404 405*squash 04c97cf Revert "tmp_format_patch"* 406 407##### Remember to edit the commit message! 408 409`clang-format -style=file -i path_to_files/filename_or_*` 410 411##### Check to see that everything looks right 412 413`git log --oneline | head -n 2` 414 415*523078f Reformatted vital patch* 416 417*d66bb6f tmp_format_patch* 418 419##### Review your new patch 420 421`git show` 422 423##### Checkout the current tree and cherry pick your reformatted patch! 424 425`git checkout aosp/master` 426 427`git cherry-pick HASH` 428 429(HASH is 523078f in this example) 430