From 9aeabc14fe862f5b7dd10ea4ca831c123eeb737c Mon Sep 17 00:00:00 2001 From: Anna Petrasova Date: Thu, 12 Sep 2024 16:04:01 -0400 Subject: [PATCH] contributing: update style guide for C (#4312) --- doc/development/style_guide.md | 137 ++++++++++++++++++++++++++++++++- 1 file changed, 136 insertions(+), 1 deletion(-) diff --git a/doc/development/style_guide.md b/doc/development/style_guide.md index 8268114ad5d..8f1d5ab5245 100644 --- a/doc/development/style_guide.md +++ b/doc/development/style_guide.md @@ -75,7 +75,7 @@ flake8 --ignore=E203,E266,E501 --max-line-length=88 python_file.py C and C++ code is formatted with [ClangFormat](https://clang.llvm.org/docs/ClangFormat.html). Contributions are -expected to be formatted with `clang-format` (currently with version 15+). The +expected to be formatted with `clang-format` (currently with version 18+). The most convenient method to install clang-format and format files is [using pre-commit](#using-pre-commit). @@ -92,6 +92,38 @@ If using pre-commit is not an option, for whatever reason, there is a helper script [grass_clang_format.sh](./utils/grass_clang_format.sh), which simplifies bulk reformatting. +#### Order of include headers + +In general, headers should be included in the order: + +1. Core system headers (stdio.h, ctype.h, ...) +2. Headers for non-core system components (X11, libraries). +3. GRASS headers (grass/gis.h, grass/glocale.h, ...) +4. Headers for the specific library/program (geodesic.h, ...) + +Each class of headers has an obligation to be compatible with those above it in +the list, but not those below it. The header groups should be alphabetically +sorted and separated by a newline. + +```c +#include +#include +#include + +#include +#include +#include + +#include "local_proto.h" +#include "mask.h" +``` + +#### Naming conventions + +Use function names which fulfill the official [GNU naming +convention](https://www.gnu.org/prep/standards/html_node/Names.html). Instead of +naming a function like: MyNewFunction() use snake case: my_new_function()`. + ### Using pre-commit It is highly recommended to install and use [pre-commit](https://pre-commit.com) @@ -652,6 +684,30 @@ standard tool output if it has one. ### Developing GRASS Addons +To streamline the development of a GRASS addon in python, you can use [this +template](https://github.com/OSGeo/grass-addon-cookiecutter) powered by +Cookiecutter. + +#### Copyright header + +Use the following header in your source code. + +```python +############################################################################## +# MODULE: r.foo +# +# AUTHOR(S): John Doe +# +# PURPOSE: Provide short description of module here... +# +# COPYRIGHT: (C) 2024 by John Doe and the GRASS Development Team +# +# This program is free software under the GNU General Public +# License (>=v2). Read the file COPYING that comes with GRASS +# for details. +############################################################################## +``` + #### Use Standard Options in Interface GRASS tools must use the GRASS parser to handle its command line parameters. To @@ -887,3 +943,82 @@ self.bwizard = wx.Button(..., # GTC %s will be replaced with name of current shell gs.message(_("Running through {}").format(shellname)) ``` + +### Developing C tools + +Refer to the [online GRASS Programmer's +Manual](​https://grass.osgeo.org/programming8/) or generate it with `make +htmldocs` or `make pdfdocs`. + +#### Use GRASS library functions + +Use the GRASS library functions, when available, instead of the standard C +functions. The reason for this is that the following functions ensure good +programming practice (e.g. always checking if memory was allocated) and/or +improves portability. + +- Memory management: `G_malloc()`, `G_calloc()`, `G_realloc()`, `G_free()` +- Environmental variables: `G_getenv()`, `G_setenv()`, `G_unsetenv()` +- File seek: `G_fseek()`, `G_ftell()` +- Printing: `G_asprintf()`, `G_vsaprintf()`, `G_vfaprintf()`, ... + +Please refer to [the programmers manual](https://grass.osgeo.org/programming8/) +for the proper use (e.g., determining if any casts are needed for arguments or +return values) of these library functions. They may perform a task slightly +different from their corresponding C library function, and thus, their use may +not be the same. + +#### Returning value of main function + +Tool exit status is defined as `EXIT_SUCCESS` or `EXIT_FAILURE` (declared in +`stdlib.h`), e.g. + +```c + { + ... + if (G_parser (argc, argv)) + exit (EXIT_FAILURE); + + ... + exit (EXIT_SUCCESS); + } +``` + +#### Messages and data output + +See rules for [messages in Python scripts](#messages) for proper usage of +`G_fatal_error()`, `G_warning()`, etc. Message output is not expected to be sent +to pipe or file. + +For data output redirected to pipe or file, please use `fprintf()` and specify +the stdout stream as follows: + +```c + fprintf(stdout, ...); + fflush(stdout); + + fflush(stdout) /* always required when using fprintf(stdout, ...). */ +``` + +#### Header section + +Add a header section to file main.c of your tool and make sure you include the +copyright. If you are modifying an existing file you may under no circumstances +remove prior copyright or licensing text that is not your own, even for a major +rewrite. If any original code or code that is in part derived from another's +original work remains, it must be properly cited. + +```c +/**************************************************************************** + * + * MODULE: g.foo + * AUTHOR(S): John Doe + * PURPOSE: Provide short description of module here... + * COPYRIGHT: (C) 2010 by John Doe, and the GRASS Development Team + * + * This program is free software under the GNU General Public + * License (>=v2). Read the COPYING file that comes with GRASS + * for details. + * + *****************************************************************************/ +```