| 1 | NOTE: Please improve this list! |
| 2 | |
| 3 | Dear (new) GRASS developer, |
| 4 | |
| 5 | when submitting C code to GRASS SVN repository, please take care of |
| 6 | following rules: |
| 7 | |
| 8 | * [wiki:Submitting/Python Python code hints] |
| 9 | * [wiki:Submitting/WxGUI for wxPython GUI code hints] |
| 10 | * [wiki:Submitting/Docs for documentation] |
| 11 | |
| 12 | 1. Get and read the GRASS Programmer's Manual here:[[BR]] |
| 13 | http://grass.osgeo.org/programming7/ |
| 14 | |
| 15 | or generate it from this source code (the programmer's manual is |
| 16 | integrated in the source code in doxygen style): |
| 17 | {{{ |
| 18 | make htmldocs |
| 19 | make pdfdocs |
| 20 | }}} |
| 21 | |
| 22 | 2. Use the directory structure to place your module appropriately into |
| 23 | the source tree |
| 24 | {{{ |
| 25 | - libes go into lib/ |
| 26 | - raster modules go into raster/ |
| 27 | - vector modules go into vector/ |
| 28 | - ... |
| 29 | }}} |
| 30 | Consider to take a look at "GNU Coding Standards"[[BR]] |
| 31 | http://www.gnu.org/prep/standards.html |
| 32 | |
| 33 | |
| 34 | 3. Add a header section to each file you submit and make sure you |
| 35 | include the copyright. The purpose section is meant to contain a |
| 36 | general overview of the code in the file to assist other |
| 37 | programmers that will need to make changes to your code. If you |
| 38 | are modifying an existing file you may under no circumstances |
| 39 | remove prior copyright or licensing text that is not your own, |
| 40 | even for a major rewrite. If any original code or code that is in |
| 41 | part derived from another's original work remains, it must be |
| 42 | properly cited. |
| 43 | |
| 44 | Example (ficticious header for a file called color.c) : |
| 45 | {{{ |
| 46 | /**************************************************************************** |
| 47 | * |
| 48 | * MODULE: g.foo |
| 49 | * AUTHOR(S): John Doe <jdoe at somewhere org> |
| 50 | * PURPOSE: Provide short description of module here... |
| 51 | * COPYRIGHT: (C) 2010 by John Doe, and the GRASS Development Team |
| 52 | * |
| 53 | * This program is free software under the GNU General Public |
| 54 | * License (>=v2). Read the COPYING file that comes with GRASS |
| 55 | * for details. |
| 56 | * |
| 57 | *****************************************************************************/ |
| 58 | }}} |
| 59 | The copyright protects your rights according to GNU General Public |
| 60 | License (www.gnu.org). |
| 61 | |
| 62 | |
| 63 | 4. We don't want the $ID$ in source code any more as it causes problems |
| 64 | for the SVN branches. |
| 65 | |
| 66 | |
| 67 | 5. To ensure that the software system continues to work, please include |
| 68 | {{{ |
| 69 | #include <grass/config.h> |
| 70 | }}} |
| 71 | in your files and make use of the various system dependencies |
| 72 | contained therein. As one example of this, see `lib/gmath/fft.c`. |
| 73 | Please refrain from declaring system functions within the |
| 74 | software; include the proper header files (conditionally dependent |
| 75 | on config.h macros if necessary) instead. |
| 76 | |
| 77 | |
| 78 | 6. Order of include headers |
| 79 | |
| 80 | In general, headers should be included in the order: |
| 81 | |
| 82 | 1. Core system headers (stdio.h, ctype.h, ...) |
| 83 | 2. Headers for non-core system components (X11, libraries). |
| 84 | 3. Headers for core systems of the package being compiled (`grass/gis.h`, `grass/glocale.h`, ...) |
| 85 | 4. Headers for the specific library/program being compiled (`geodesic.h`, ...) |
| 86 | |
| 87 | Each class of header has an obligation to be compatible with those |
| 88 | above it in the list, but not those below it. |
| 89 | |
| 90 | |
| 91 | 7. Always specify the return type for ALL functions including those that |
| 92 | return type "void", and insert return statements for any function |
| 93 | which returns a value. |
| 94 | |
| 95 | Also, use ANSI C prototypes to declare your functions. |
| 96 | For module return values, see "Exit status" below. |
| 97 | |
| 98 | Examples: |
| 99 | {{{ |
| 100 | void G_something(void); |
| 101 | int G_something_else(int, int); |
| 102 | |
| 103 | void G_something(void) |
| 104 | { |
| 105 | /* Snipped out code */ |
| 106 | |
| 107 | return; |
| 108 | } |
| 109 | |
| 110 | int G_something_else(int x, int y) |
| 111 | { |
| 112 | /* Snipped out code */ |
| 113 | |
| 114 | return 0; |
| 115 | } |
| 116 | }}} |
| 117 | |
| 118 | 8. Module exit status is defined as `EXIT_SUCCESS` or `EXIT_FAILURE` |
| 119 | (declared in `stdlib.h`), e.g. |
| 120 | |
| 121 | {{{ |
| 122 | { |
| 123 | ... |
| 124 | if (G_parser (argc, argv)) |
| 125 | exit (EXIT_FAILURE); |
| 126 | |
| 127 | ... |
| 128 | exit (EXIT_SUCCESS); |
| 129 | } |
| 130 | }}} |
| 131 | |
| 132 | 9. Use `fprintf()` instead of `printf()` |
| 133 | |
| 134 | For errors and warnings please use the `G_fatal_error()` and |
| 135 | `G_warning()` functions. General messages for the user should use |
| 136 | `G_message()` while debug messages should use `G_debug()` whenever |
| 137 | possible. There are two variants to `G_message()`: `G_verbose_message()` |
| 138 | which will only display the message if in `--verbose` mode, and |
| 139 | `G_important_message()` which will always show the message unless |
| 140 | the module is running in `--quiet` mode. `G_fatal_error()` and |
| 141 | `G_warning()` will always be displayed regardless of verbosity setting. |
| 142 | Messages sent to any of these functions will be printed to stderr. |
| 143 | |
| 144 | `G_message()` output is not expected to be sent to pipe or file. |
| 145 | |
| 146 | Always use the gettext macros with `_("")` for user messages, |
| 147 | example: |
| 148 | {{{ |
| 149 | G_fatal_error(_("Vector map <%s> not found"), name); |
| 150 | }}} |
| 151 | It is suggested to add a comment line before translatable user message |
| 152 | to give a hint to translators about meaning or use of |
| 153 | cumbersome or obscure message. First word in the comment must be GTC |
| 154 | - GRASS translation comment, |
| 155 | example: |
| 156 | {{{ |
| 157 | /* GTC A name of a projection */ |
| 158 | G_message(_("State Plane")); |
| 159 | }}} |
| 160 | Any message with a noun in plural form has to pass _n() macro, |
| 161 | even if for the English language it is not required! |
| 162 | G_message(_n("One map", "%d maps", number), number); |
| 163 | |
| 164 | See [src:grass/trunk/locale/README] for details. |
| 165 | |
| 166 | |
| 167 | Pipe/file data output: |
| 168 | For data output redirected to pipe or file, please use `fprintf()` and |
| 169 | specify the stdout stream as follows: |
| 170 | {{{ |
| 171 | fprintf(stdout, ...); |
| 172 | fflush(stdout); |
| 173 | |
| 174 | fflush(stdout) /* always required when using fprintf(stdout, ...). */ |
| 175 | }}} |
| 176 | |
| 177 | 10. Use the GRASS library function `G_asprintf()` instead of the |
| 178 | standard C functions `asprintf()`, `vsnprintf()` and `snprintf()`. These |
| 179 | functions are not portable or have other issues. Example: |
| 180 | {{{ |
| 181 | char *msg; |
| 182 | |
| 183 | G_asprintf(&msg, "%s", parameters); |
| 184 | do_something_with_msg(); |
| 185 | G_free(msg); |
| 186 | }}} |
| 187 | Note that you should free memory when `G_asprintf()` is used. |
| 188 | |
| 189 | |
| 190 | 11. Use the following GRASS library functions instead of the standard C |
| 191 | functions. The reason for this is that the following functions ensure |
| 192 | good programming practice (e.g. always checking if memory was allocated) |
| 193 | and/or improves portability. PLEASE refer to the programmers manual |
| 194 | for the proper use (e.g. determining if any casts are needed for arguments |
| 195 | or return values) of these library functions. They may perform a task |
| 196 | slightly different from their corresponding C library function, and thus, |
| 197 | their use may not be the same. |
| 198 | {{{ |
| 199 | G_malloc() instead of malloc() |
| 200 | G_calloc() instead of calloc() |
| 201 | G_realloc() instead of realloc() |
| 202 | G_free() instead of free() |
| 203 | G_getenv() instead of getenv() |
| 204 | G_setenv() instead of setenv() |
| 205 | G_unsetenv() instead of unsetenv() |
| 206 | G_sleep() instead of sleep() |
| 207 | }}} |
| 208 | Could somebody please add others (please verify that they are |
| 209 | useful and safe first) |
| 210 | |
| 211 | |
| 212 | 12. Use function names which fulfill the official GNU naming convention.[[BR]] |
| 213 | http://www.gnu.org/prep/standards/html_node/Names.html#Names |
| 214 | |
| 215 | Instead of naming a function like: `MyNewFunction()` use underscores |
| 216 | for seperation and lower case letters: `my_new_function()``. |
| 217 | |
| 218 | |
| 219 | 13. Don't use the C++ comment style! This confuses several compilers. |
| 220 | Use instead: |
| 221 | {{{ |
| 222 | /* C-comments */ |
| 223 | }}} |
| 224 | If you want to comment code portions, use |
| 225 | {{{ |
| 226 | #ifdef notdef |
| 227 | portion_to_be_commented; |
| 228 | #endif |
| 229 | }}} |
| 230 | This is safe comparing to nested `/* comments */` |
| 231 | |
| 232 | Functions in the library must be documented in doxygen style to |
| 233 | get them into the programmer's manual (generate with |
| 234 | {{{ |
| 235 | make pdfdocs |
| 236 | or |
| 237 | make htmldocs). |
| 238 | }}} |
| 239 | See [src:grass/trunk/lib/gis/] for examples. |
| 240 | |
| 241 | |
| 242 | 14. PLEASE take the time to add comments throughout your code explaining what |
| 243 | the code is doing. It will save a HUGE amount of time and frustration for |
| 244 | other programmers that may have to change your code in the future. |
| 245 | |
| 246 | |
| 247 | 15. To promote a consistent coding style, please use the "indent" program |
| 248 | on all new C modules using the following switches: |
| 249 | {{{ |
| 250 | $ indent -bad -bap -bbb -br -bli0 -bls -cli0 -ncs -fc1 -hnl -i4 \ |
| 251 | -nbbo -nbc -nbfda -nbfde -ncdb -ncdw -nce -nfca -npcs -nprs \ |
| 252 | -npsl -nsc -nsob -saf -sai -saw -sbi0 -ss -ts8 -ut main.c |
| 253 | }}} |
| 254 | Existing code should not be re-indented except in extreme cases, as this |
| 255 | will make "diff" comparisons with older versions impossible. If indent is |
| 256 | needed, do not check in any changes other than the indentation in the same |
| 257 | commit! Do add the indent switches and any indent warning messages to the |
| 258 | SVN log. Any change or fix mixed in with an indent is very hard to track |
| 259 | making it hard for others to follow the change or fix any new bugs. |
| 260 | For your convenience use the tools/grass_indent.sh script. |
| 261 | |
| 262 | |
| 263 | 16. Platform dependent code: |
| 264 | Do not remove `#ifdef __CYGWIN__` and/or `#ifndef __CYGWIN__` lines and |
| 265 | their encapsulated lines from source code (one example was that someone |
| 266 | removed `drand48` definition.) |
| 267 | |
| 268 | |
| 269 | 17. Suggested compiler flags: |
| 270 | We suggest to use very strict compiler flags to capture errors |
| 271 | at the very beginning. Here our list of flags, please use them |
| 272 | to configure you development version of GRASS: |
| 273 | |
| 274 | GNU/Linux: |
| 275 | {{{ |
| 276 | MYCFLAGS="-g -Wall -Werror-implicit-function-declaration -fno-common" |
| 277 | MYCXXFLAGS="-g -Wall" |
| 278 | |
| 279 | CFLAGS="$MYCFLAGS" CXXFLAGS="$MYCXXFLAGS" ./configure ... |
| 280 | }}} |
| 281 | MacOSX: [to be suggested] |
| 282 | |
| 283 | MS-Windows: [to be suggested] |
| 284 | |
| 285 | |
| 286 | 18. Make sure a new line is at the end of each file and UNIX style newlines |
| 287 | are used (`\n`). |
| 288 | |
| 289 | |
| 290 | 19. When writing Makefiles, use the current standard. |
| 291 | |
| 292 | If you have to use commands, please check for: |
| 293 | {{{ |
| 294 | avoid | use instead |
| 295 | ------------------+--------------- |
| 296 | make target | $(MAKE) target |
| 297 | mkdir target | $(MKDIR) target |
| 298 | cp (executable) | $(INSTALL) -m 755 file target |
| 299 | cp (normal file) | $(INSTALL) -m 644 file target |
| 300 | ar | $(AR) |
| 301 | |
| 302 | rm: be VERY careful with recursive remove. Also beware of |
| 303 | removing $(FOO)* if $(FOO) has any chance of being empty. |
| 304 | |
| 305 | Examples: see below examples or others |
| 306 | raster/r.info/Makefile |
| 307 | vector/v.edit/Makefile |
| 308 | }}} |
| 309 | If you are unsure, please ask on the GRASS Developers list. |
| 310 | |
| 311 | |
| 312 | 20. Have a look at [src:grass/trunk/INSTALL] |
| 313 | |
| 314 | |
| 315 | 21. Have a function included in your module which writes to the history |
| 316 | file of the map (e.g. command line, parameters etc.). See e.g. |
| 317 | [src:grass/raster/r.patch/main.c] |
| 318 | |
| 319 | (the same applies to vector and raster3d modules!) |
| 320 | |
| 321 | |
| 322 | 22. Standard parser options: use `G_define_standard_option()` whenever possible |
| 323 | to define standard module command line options. This will save you time, |
| 324 | create fewer bugs, and make things easier on the translators. |
| 325 | See [src:grass/trunklib/gis/parser.c] for details of the function definition. |
| 326 | |
| 327 | |
| 328 | 23. Add/update, if required the related GUI menus: |
| 329 | {{{ |
| 330 | gui/wxpython/xml/menudata.xml |
| 331 | }}} |
| 332 | |
| 333 | 24. For consistency, use `README` rather than `README.txt` for any `README` files. |
| 334 | |
| 335 | |
| 336 | 25. GRASS/Environment variables:[[BR]] |
| 337 | If you add a new variable, please follow the naming convention.[[BR]] |
| 338 | All variables are described in[[BR]] |
| 339 | src:grass/trunk/lib/init/variables.html |
| 340 | |
| 341 | |
| 342 | 26. Be sure to develop on top of the LATEST GRASS code (which is in our SVN |
| 343 | repository). You can re-check before submission with `svn diff`: |
| 344 | |
| 345 | Be sure to create unified (`diff -u`) format. "Plain" diffs (the default |
| 346 | format) are risky, because they will apply without warning to code which |
| 347 | has been substantially changed; they are also harder to read than unified. |
| 348 | |
| 349 | Such diffs should be made from the top-level directory, e.g. |
| 350 | `svn diff display/d.vect/main.c`; that way, the diff will |
| 351 | include the pathname rather than just an ambiguous `main.c`. |
| 352 | |
| 353 | |
| 354 | 27. Try to use module names which describe shortly the intended purpose of the module. |
| 355 | |
| 356 | The first letters for module name should be: |
| 357 | {{{ |
| 358 | d. - display commands |
| 359 | db. - database commands |
| 360 | g. - general GIS management commands |
| 361 | i. - imagery commands |
| 362 | m. - miscellaneous tool commands |
| 363 | ps. - postscript commands |
| 364 | r. - raster commands |
| 365 | r3. - raster3D commands |
| 366 | v. - vector commands |
| 367 | }}} |
| 368 | Some additional naming conventions |
| 369 | * export modules: (type).out.(format) eg: r.out.arc, v.out.ascii |
| 370 | * import module: (type).in.(format) eg: r.in.arc, v.in.ascii |
| 371 | * conversion modules: (type).to.(type) eg: r.to.vect, v.to.rast, r3.to.rast |
| 372 | |
| 373 | Avoid module names with more than two dots in the name. |
| 374 | Example: |
| 375 | instead of r.to.rast3.elev use r.to.rast3elev |
| 376 | |
| 377 | |
| 378 | 28. Use the grass test suite to test your modules. |
| 379 | |
| 380 | http://www-pool.math.tu-berlin.de/~soeren/grass/GRASS_TestSuite |
| 381 | |
| 382 | You can easily write specific tests for your modules. |
| 383 | |
| 384 | If your module is part of GRASS and you created some standard test |
| 385 | cases, please contact the developers to add your tests to the |
| 386 | default test suite. This will automatize complex test scenarios |
| 387 | and assure to find bugs much faster, if changes were made to your |
| 388 | modules or to the grass library. |
| 389 | |
| 390 | Consider to subscribe to the GRASS Quality Assessment System to |
| 391 | get immediate notification about the code quality: |
| 392 | |
| 393 | http://lists.osgeo.org/mailman/listinfo/grass-qa |
| 394 | |
| 395 | |
| 396 | 29. When submitting new files to the repository set SVN properties, |
| 397 | usually for directory |
| 398 | {{{ |
| 399 | svn:ignore : *.tmp.html |
| 400 | *OBJ* |
| 401 | }}} |
| 402 | or e.g. for C-file |
| 403 | {{{ |
| 404 | svn:mime-type : text/x-csrc |
| 405 | svn:keywords : Author Date Id |
| 406 | svn:eol-style : native |
| 407 | }}} |
| 408 | See |
| 409 | http://svnbook.red-bean.com/en/1.4/svn.advanced.props.html |
| 410 | |
| 411 | To set a property: |
| 412 | {{{ |
| 413 | svn propset svn:keywords 'Author Date Id' <file> |
| 414 | svn propset svn:mime-type text/x-sh grass_shellscript.sh |
| 415 | }}} |
| 416 | To edit the `svn:ignore` property using your default text editor: |
| 417 | {{{ |
| 418 | svn propedit svn:ignore <directory> |
| 419 | }}} |
| 420 | To set the svn:ignore property non-interactively, first create a |
| 421 | file containing the value: |
| 422 | {{{ |
| 423 | echo "*.tmp.html" > ignore.txt |
| 424 | echo "*OBJ*" >> ignore.txt |
| 425 | }}} |
| 426 | then use: |
| 427 | {{{ |
| 428 | svn propset -F ignore.txt svn:ignore <directory> |
| 429 | }}} |
| 430 | List of mime-type: |
| 431 | {{{ |
| 432 | C++ files (.cpp): text/x-c++src |
| 433 | C files (.c): text/x-csrc |
| 434 | DTD files (.dtd): text/xml-dtd |
| 435 | GIF files (.gif): image/gif |
| 436 | Header files (.h): text/x-chdr |
| 437 | HTML files (.html): text/html |
| 438 | JPEG files (.jpg): image/jpeg |
| 439 | Makefiles: text/x-makefile |
| 440 | PNG files (.png): image/png |
| 441 | Python files (.py): text/x-python |
| 442 | Shell scripts (.sh): text/x-sh |
| 443 | Text files (.txt): text/plain |
| 444 | XML files (.xml): text/xml |
| 445 | }}} |
| 446 | (please update the list...) |
| 447 | |
| 448 | For your convenience use the src:grass/trunk/tools/module_svn_propset.sh script. |
| 449 | |
| 450 | 30. Use doxygen style for source code documentation. It is required |
| 451 | for GRASS libraries, but also recommended for GRASS modules. |
| 452 | |
| 453 | Do not use structural command inside documentation block since it |
| 454 | leads to some duplication of information (e.g. do not use `\fn` |
| 455 | command in comment blocks). The exception is `\file` command for |
| 456 | documenting a file, in this case structural command is required. |
| 457 | |
| 458 | For files |
| 459 | {{{ |
| 460 | /*! |
| 461 | \file snap.c |
| 462 | |
| 463 | \brief Vector library - Clean vector map (snap lines) |
| 464 | |
| 465 | (C) 2001-2008 by the GRASS Development Team |
| 466 | |
| 467 | This program is free software under the GNU General Public |
| 468 | License (>=v2). Read the file COPYING that comes with GRASS |
| 469 | for details. |
| 470 | |
| 471 | \author Radim Blazek |
| 472 | */ |
| 473 | }}} |
| 474 | For functions |
| 475 | {{{ |
| 476 | /*! |
| 477 | \brief Snap lines in vector map to existing vertex in threshold |
| 478 | |
| 479 | For details see Vect_snap_lines_list() |
| 480 | |
| 481 | \param Map pointer to input vector map |
| 482 | \param type filter features of given type to be snap |
| 483 | \param thresh threshold value for snapping |
| 484 | \param[out] Err pointer to vector map where lines representing snap are written or NULL |
| 485 | \param[out] msgout file pointer where messages will be written or NULL |
| 486 | |
| 487 | \return 1 |
| 488 | */ |
| 489 | }}} |
| 490 | |
| 491 | 31. If you need to add support for a different library in the 'configure' script, |
| 492 | you should first seek consent in the grass-dev mailing list (see below), then |
| 493 | you need to expand 'configure.in' and run subsequently `autoconf-2.13` (later |
| 494 | versions will not work) to re-generate 'configure'. |
| 495 | |
| 496 | 32. Tell the other developers about the new code using the following e-mail:[[BR]] |
| 497 | grass-dev@lists.osgeo.org |
| 498 | |
| 499 | To subscribe to this mailing list, see[[BR]] |
| 500 | http://lists.osgeo.org/mailman/listinfo/grass-dev |
| 501 | |
| 502 | |
| 503 | 33. In case of questions feel free to contact the developers at the above |
| 504 | mailing list.[[BR]] |
| 505 | http://grass.osgeo.org/development/ |
| 506 | |
| 507 | ... |
| 508 | [please add further hints if required] |
| 509 | |
| 510 | |
| 511 | "Your attention to detail is appreciated." |