= Barrelfish coding styles = == Code formatting == * 4 space indents, no hard tabs * code formatted to 80 columns, mostly * Braces on the same line, unless it's a function, in which case the brace goes on a line by itself * We write C99 standard code, so // comments are ok * Macro names all upper case * Function names etc. all lower-case, use underscores to separate words * space between `if/for/while` and the following parenthesis * always use braces for if/for/while, even in the case of a single statement == Coding construct guidelines == Types: * Never typedef a pointer or a struct/union/enum. All typedefs should be base integer types. * don't use the base types like int/long etc, use portable equivalents (eg. uint32_t, uint64_t, uintptr_t) * Enum constants should be prefixed by the enum type name they belong to (and an underscore) and should be in camelcase. Naming/organisation: * always mark functions and global variables `static`, ''unless'' they need to be accessed from code in another file * name non-static functions with a common prefix related to the file name (eg. `serial_putchar`, `microbench_register`, etc.) * never put code in a header file, ''unless'' it's a `static inline` and needs to be there * try to keep constants and preprocessor macros that are unique to a specific source file in that file rather than in a header that is included elsewhere * alternatively, create another header for the private declarations used just by that code * Keep definitions of structures and macros for accessing device hardware in a separate header file from any code/prototypes, and try to write them in a BarrelFish-independent manner. Return values: * Use negative values to indicate errors. In the future, we'll define a standard set of error codes for these. Zero (or anything positive for a function that needs to return a value) should indicate success. For functions that return a pointer, NULL may be used to indicate error. Misc: * use [[http://www.stack.nl/~dimitri/doxygen/docblocks.html|doxygen comments]] * use `assert()` liberally for sanity checks, but if something might fail at runtime, make sure it still behaves correctly (ie. returns an error code) with asserts compiled out == Example code == {{{ /** \brief This function does nothing of any significant purpose */ uintptr_t frongle_blarg(void *blah) { if (blah) { return (uintptr_t)blah - PAGESIZE; // foo } else { assert(!"Badness!"); return -1; } } }}} == Resources == Elisp code to add to `.emacs` file in home directory: {{{ (defun maybe-barrelfish-offset () (if (string-match "barrelfish" buffer-file-name) (setq c-basic-offset 4 cmake-tab-width 4 indent-tabs-mode nil) () ) ) (add-hook 'c-mode-hook 'maybe-barrelfish-offset) (require 'column-marker) (add-hook 'c-mode-hook (lambda () (interactive) (column-marker-1 80))) }}} This enforces 4-space indents and no TABs when the file path contains the name `barrelfish` and is C or cmake source code. It also sets a column marker (you need the file [[attachment:column-marker.el]] in your site-lisp path) at column 80, so you see what you type beyond that spot. Automatic filling of any line more than 80 characters long is possible as well, but not always aesthetic with C source code. This is why manual filling should be used with the help of the column marker. If you haven't done so already, you should enable support for cmake-mode and mercurial-mode in Emacs by adding this to your `.emacs` file: {{{ (setq load-path (cons (expand-file-name "/dir/with/cmake-mode") load-path)) (require 'cmake-mode) (setq auto-mode-alist (append '(("CMakeLists\\.txt\\'" . cmake-mode) ("\\.cmake\\'" . cmake-mode)) auto-mode-alist)) (require 'mercurial) }}}