Coding Guidelines

Guidelines for Submitters

General Principles

Follow the Google Style Guide besides exceptions found in this document for all C++ code.

Be aware that existing code may not always reflect current best practices or project preferences. The codebase evolves, and what was once standard may now be outdated. Refer to this document for up-to-date guidelines.

Naming Conventions

  1. File names: use snake_case. Use .h for headers. Keep reasonably short.

  2. Variable names: use lower_case_names.

  3. Class member variables: use m_lower_case.

  4. Class and methods names: use PascalCase. Avoid upper case acronyms, use OcpnFoo and NmeaFoo rather than OCPNFoo and NMEAFoo.

  5. Constants: Pascal case + a 'k' prefix: kSomeConstantValue

C++ Practices

Use C++ standard library components over wxWidgets and old style C equivalents:

Avoid (wxWidgets, C) Use Instead (C++ Standard Library)

wxMutex

std::mutex and std::lock_guard

wxHashTable

std::unordered_map

wxList, wxArray

std::vector or other STL containers

wxThread

std::thread, std::async

wxString

std::string or std::wstring

open()

std::ifstream, std::ofstream, etc

Memory Management

  1. Do not use raw pointers and new/delete. The exception is when raw pointers are required by external libraries like wxWidgets.

  2. Use std::unique_ptr or std::shared_ptr for better memory management.

String Handling

  1. Use double-quoted strings for unicode strings.

  2. Do not use _T() or wxT() macros. See wxWidgets string guidelines.

Exception handling

OpenCPN is compiled with exceptions enabled to handle third party libraries. However, most of OpenCPN is not exception safe. Thus:

  1. Do not throw exceptions.

  2. When using code which throws exceptions these should be caught as soon as possible

Code Documentation

  1. Document code in doxygen format, see doxygen manual

  2. Almost everything is documented in the header files.

  3. Omit @brief and @details tags. The first sentence automatically becomes the brief description.

  4. Avoid redundant phrases like "This class is…​"

  5. Test generated documentation locally. See manual sub-directory.

For an extensive example see rest_server.h, results in the API docs

Error Handling and Logging

  1. Use appropriate logging levels (DEBUG, INFO, WARNING, ERROR) consistently.

  2. Don’t silently fail or ignore errors.

  3. Provide meaningful i18n error messages and context.

Code Refactoring

  1. When working with existing code, gradually refactor to comply with coding guidelines.

  2. Do not submit large PRs that refactor a lot of code changes.

Localization and Internationalization

  1. Use the gettext macro _() for user-visible strings that need translation.

    1. Do not use _() for log file messages and internal strings.

  2. Add new source files containing translatable strings in po/POTFILES.in.

  3. Maintainers run the following commands before each release. Do not run them in your pull requests.

    1. make pot-update - Scans source files and updates the template (.pot) file.

    2. make po-update - Updates all language files (.po) with new strings from template, to merge new strings into existing language files.

Avoid Use Instead

mode = "Auto";

mode = _("Auto");

msg = _("File") + " " + _("not found");

msg = _("File not found");

msg = _("Found") + wxString::Format(" %d ", count) + _("errors");

msg = wxString::Format(_("Found %d errors"), count);

Code Formatting

C/C++

The sources have a uniform coding formatting based on the Google Style.

The style is defined in the .clang-format file which when used by clang-format produces a correctly formatted source file.

Since the 5.10 release all source file modifications must be processed by clang-format to be accepted. The recommended way to do this is using a git pre-commit hook which applies formatting when committing changes

To do this, just install the pre-commit program from https://pre-commit.com/:

$ pip install pre-commit

and then, in the project top directory

$ pre-commit install

which will pick up the configuration from .pre-commit-config.yaml which is part of the project.

CMake

Cmake file uses formatting defined by the .cmake-format.yaml which when used with cmake-format produces correctly formatted files. This has been applied to all cmake/*.cmake files and CMakeLists.txt.

Using clang-format

clang is part of the llvm tools. These are usually installed using package managers like choco (Windows), brew (MacOS) or apt (Debian/Ubuntu).

To format a C, C++ or header file with clang-format with the project’s default configuration use:

clang-format -i  <filename>

Using cmake-format

Install cmake-format as described in https://github.com/cheshirekow/cmake_format. To format a single file use

cmake-format -i  <filename>

Editor and IDE configuration

There is a .editorconfig file in the top directory. This file could be used by most editors to define basic settings.

There are no standard configurations available for IDEs like Visual Studio Code, Eclipse or CLion.

Guidelines for Reviewers

Performance and Compatibility

  1. Ensure changes do not reduce performance.

  2. Verify existing functionality and plugin compatibility are maintained.

Cross-Platform Considerations

  1. Check for consistency across different platforms (Windows, Linux, macOS).

  2. Be aware of platform-specific behaviors, especially for UI elements.

Display Settings

  1. Consider different display settings (e.g., scaled displays, dark modes).

  2. Plugins should be High DPI Display Responsive.

Version Control Best Practices

  1. Write clear, concise commit messages.

  2. Keep commits focused and atomic (one logical change per commit).