1Coding Style 2============ 3 4Mesa is over 20 years old and the coding style has evolved over time. 5Some old parts use a style that's a bit out of date. Different sections 6of mesa can use different coding style as set in the local EditorConfig 7(.editorconfig) and/or Emacs (.dir-locals.el) file. Alternatively the 8following is applicable. If the guidelines below don't cover something, 9try following the format of existing, neighboring code. 10 11``clang-format`` 12---------------- 13 14A growing number of drivers and components are adopting ``clang-format`` 15to standardize the formatting and make it easy for everyone to apply it. 16 17You can re-format the code for the components that have opted-in to the 18formatting enforcement (listed in ``.clang-format-include``) by simply 19running ``ninja -C build/ clang-format``. 20 21Since mass-reformatting commits can be an annoying extra jump to go 22through when looking at ``git blame``, you can configure it to ignore 23them by running:: 24 25 git config blame.ignoreRevsFile .git-blame-ignore-revs 26 27Most code editors also support automatically formatting code as you 28write it; check your editor or its plug-ins to see how to enable this. 29 30Vim 31*** 32 33Add this to your ``.vimrc`` to automatically format any C & C++ file 34(that has a .clang-format config) when you save it: 35 36.. code:: vim 37 38 augroup ClangFormatOnSave 39 au! 40 41 function! ClangFormatOnSave() 42 " Only format files that have a .clang-format in a parent folder 43 if !empty(findfile('.clang-format', '.;')) 44 let l:formatdiff = 1 " Only format lines that have changed 45 py3f /usr/share/clang/clang-format.py 46 endif 47 endfunction 48 49 autocmd BufWritePre *.h,*.c,*.cc,*.cpp call ClangFormatOnSave() 50 augroup END 51 52If ``/usr/share/clang/clang-format.py`` doesn't exist, try 53``/usr/share/clang/clang-format-$CLANG_VERSION/clang-format.py`` 54(replacing ``$CLANG_VERSION`` with your clang version). If your distro 55has put the file somewhere else, look through the files in the package 56providing ``clang-format``. 57 58Emacs 59***** 60 61Add this to your ``.emacs`` to automatically format any C & C++ file 62(that has a .clang-format config) when you save it: 63 64.. code:: emacs 65 66 (load "/usr/share/clang/clang-format.el") 67 68 (defun clang-format-save-hook-for-this-buffer () 69 "Create a buffer local save hook." 70 (add-hook 'before-save-hook 71 (lambda () 72 (when (locate-dominating-file "." ".clang-format") 73 (clang-format-buffer)) 74 ;; Continue to save. 75 nil) 76 nil 77 ;; Buffer local hook. 78 t)) 79 80 ;; Run this for each mode you want to use the hook. 81 (add-hook 'c-mode-hook (lambda () (clang-format-save-hook-for-this-buffer))) 82 (add-hook 'c++-mode-hook (lambda () (clang-format-save-hook-for-this-buffer))) 83 84If ``/usr/share/clang/clang-format.el`` doesn't exist, look through the 85files in the package providing ``clang-format`` in your distro. If you 86can't find anything (e.g. on Debian/Ubuntu), refer to `this StackOverflow 87answer <https://stackoverflow.com/questions/59690583/how-do-you-use-clang-format-on-emacs-ubuntu/59850773#59850773>`__ 88to install clang-format through Emacs instead. 89 90git ``pre-commit`` hook 91*********************** 92 93If your editor doesn't support this, or if you don't want to enable it, you 94can always just run ``ninja clang-format`` to format everything, or add 95a ``pre-commit`` hook that runs this automatically whenever you ``git 96commit`` by adding the following in your ``.git/hooks/pre-commit``: 97 98.. code:: sh 99 100 shopt -s globstar 101 git clang-format $upstream -- $(grep -E '^[^#]' .clang-format-include) 102 # replace $upstream with the name of the remote tracking upstream mesa 103 # if you don't know, it's probably `origin` 104 105 106Basic formatting guidelines 107--------------------------- 108 109- 3-space indentation, no tabs. 110- Limit lines to 78 or fewer characters. The idea is to prevent line 111 wrapping in 80-column editors and terminals. There are exceptions, 112 such as if you're defining a large, static table of information. 113- Opening braces go on the same line as the if/for/while statement. For 114 example: 115 116 .. code-block:: c 117 118 if (condition) { 119 foo; 120 } else { 121 bar; 122 } 123 124- Put a space before/after operators. For example, ``a = b + c;`` and 125 not ``a=b+c;`` 126- This GNU indent command generally does the right thing for 127 formatting: 128 129 .. code-block:: sh 130 131 indent -br -i3 -npcs --no-tabs infile.c -o outfile.c 132 133- Use comments wherever you think it would be helpful for other 134 developers. Several specific cases and style examples follow. Note 135 that we roughly follow `Doxygen <https://www.doxygen.nl>`__ 136 conventions. 137 138 Single-line comments: 139 140 .. code-block:: c 141 142 /* null-out pointer to prevent dangling reference below */ 143 bufferObj = NULL; 144 145 Or, 146 147 .. code-block:: c 148 149 bufferObj = NULL; /* prevent dangling reference below */ 150 151 Multi-line comment: 152 153 .. code-block:: c 154 155 /* If this is a new buffer object id, or one which was generated but 156 * never used before, allocate a buffer object now. 157 */ 158 159 We try to quote the OpenGL specification where prudent: 160 161 .. code-block:: c 162 163 /* Page 38 of the PDF of the OpenGL ES 3.0 spec says: 164 * 165 * "An INVALID_OPERATION error is generated for any of the following 166 * conditions: 167 * 168 * * <length> is zero." 169 * 170 * Additionally, page 94 of the PDF of the OpenGL 4.5 core spec 171 * (30.10.2014) also says this, so it's no longer allowed for desktop GL, 172 * either. 173 */ 174 175 Function comment example: 176 177 .. code-block:: c 178 179 /** 180 * Create and initialize a new buffer object. Called via the 181 * ctx->Driver.CreateObject() driver callback function. 182 * \param name integer name of the object 183 * \param type one of GL_FOO, GL_BAR, etc. 184 * \return pointer to new object or NULL if error 185 */ 186 struct gl_object * 187 _mesa_create_object(GLuint name, GLenum type) 188 { 189 /* function body */ 190 } 191 192- Put the function return type and qualifiers on one line and the 193 function name and parameters on the next, as seen above. This makes 194 it easy to use ``grep ^function_name dir/*`` to find function 195 definitions. Also, the opening brace goes on the next line by itself 196 (see above.) 197- Function names follow various conventions depending on the type of 198 function: 199 200 +---------------------+------------------------------------------+ 201 | Convention | Explanation | 202 +=====================+==========================================+ 203 | ``glFooBar()`` | a public GL entry point (in | 204 | | :file:`glapi_dispatch.c`) | 205 +---------------------+------------------------------------------+ 206 | ``_mesa_FooBar()`` | the internal immediate mode function | 207 +---------------------+------------------------------------------+ 208 | ``save_FooBar()`` | retained mode (display list) function in | 209 | | :file:`dlist.c` | 210 +---------------------+------------------------------------------+ 211 | ``foo_bar()`` | a static (private) function | 212 +---------------------+------------------------------------------+ 213 | ``_mesa_foo_bar()`` | an internal non-static Mesa function | 214 +---------------------+------------------------------------------+ 215 216- Constants, macros and enum names are ``ALL_UPPERCASE``, with \_ 217 between words. 218- Mesa usually uses camel case for local variables (Ex: 219 ``localVarname``) while Gallium typically uses underscores (Ex: 220 ``local_var_name``). 221- Global variables are almost never used because Mesa should be 222 thread-safe. 223- Booleans. Places that are not directly visible to the GL API should 224 prefer the use of ``bool``, ``true``, and ``false`` over 225 ``GLboolean``, ``GL_TRUE``, and ``GL_FALSE``. In C code, this may 226 mean that ``#include <stdbool.h>`` needs to be added. The 227 ``try_emit_*`` method ``src/mesa/state_tracker/st_glsl_to_tgsi.cpp`` 228 can serve as an example. 229