NetworkManager/CONTRIBUTING

107 lines
5 KiB
Plaintext
Raw Normal View History

Guidelines for Contributing:
1) Platform-specific functionality (for example, location of binaries that
NetworkManager calls, or functionality used only on some platforms or
distribution, like resolvconf) should be configurable at build time, with the
normal autoconf mechanisms for putting a #define in config.h (AC_DEFINE), then
with #ifdef MY_DEFINE / #endif in the code.
2) Coding standards are generally GNOME coding standards, with these exceptions:
a) 4 space tabs (_not_ 8-space tabs)
b) REAL tabs (_not_ a mix of tabs and spaces in the initial indent)
c) spaces used to align continuation lines past the indent point of the
first statement line, like so:
if (some_really_really_long_variable_name &&
another_really_really_long_variable_name) {
...
}
2009-10-07 19:28:10 +00:00
* Keep a space between the function name and the opening '('.
GOOD: g_strdup (x)
BAD: g_strdup(x)
* C-style comments
2009-10-07 19:28:10 +00:00
GOOD: f(x); /* comment */
BAD: f(x); // comment
* Keep assignments in the variable declaration area pretty short.
GOOD: MyObject *object;
BAD: MyObject *object = complex_and_long_init_function(arg1, arg2, arg3);
* 80-cols is a guideline, don't make the code uncomfortable in order to fit in
less than 80 cols.
* Constants are CAPS_WITH_UNDERSCORES and use the preprocessor.
GOOD: #define MY_CONSTANT 42
BAD: static const unsigned myConstant = 42;
3) Legal:
NetworkManager is partly licensed under terms of GNU Lesser General Public License
version 2 or later (LGPL-2.0+). That is for example the case for libnm.
For historical reasons, the daemon itself is licensed under terms of GNU General
Public License, version 2 or later (GPL-2.0+). See the license comment in the source
files.
Note that all novel contributions to NetworkManager MUST be made under terms of
LGPL-2.0+, that is also the case for parts that are currently licensed GPL-2.0+.
The reason for that is that we might eventually relicense everything as LGPL and
new contributions already must agree with that future change.
Assertions in NetworkManager code
=================================
There are different kind of assertions. Use the one that is appropriate.
1) g_return_*() from glib. This is usually enabled in release builds and
can be disabled with G_DISABLE_CHECKS define. This uses g_log() with
a cG_LOG_LEVEL_CRITICAL level (which allows the program to continue,
until G_DEBUG=fatal-criticals or G_DEBUG=fatal-warnings is set). As such,
this is the preferred way for assertions that are commonly enabled.
Make a mild attempt to work around such assertion failure, but don't try
to hard. A failure of g_return_*() assertion might allow the process
to continue, but there is no guarantee.
2) nm_assert() from NetworkManager. This is disabled by default in release
builds, but enabled if you build --with-more-assertions. See "WITH_MORE_ASSERTS"
define. This is preferred for assertions that are expensive to check or
nor necessary to check frequently (stuff that is really not expected to
fail). Use this deliberately and assume it's not present in production builds.
3) g_assert() from glib. This is used in unit tests and commonly enabled
in release builds. It can be disabled with G_DISABLE_ASSERT assert
define. Since this results in a hard crash on assertion failure, you
should almost always prefer g_return_*() over this (except unit tests).
4) assert() from <assert.h>. It is usually enabled in release builds and
can be disabled with NDEBUG define. Don't use it in NetworkManager,
it's basically like g_assert().
5) g_log() from glib. These are always compiled in, depending on the levels
these are assertions too. G_LOG_LEVEL_ERROR aborts the program, G_LOG_LEVEL_CRITICAL
logs a critical warning (like g_return_*(), see G_DEBUG=fatal-criticals)
and G_LOG_LEVEL_WARNING logs a warning (see G_DEBUG=fatal-warnings).
G_LOG_LEVEL_DEBUG level is usually not printed, unless G_MESSAGES_DEBUG environment
is set.
In general, avoid using g_log() in NetworkManager. We have nm-logging instead.
From a library like libnm it might make sense to log warnings (if someting
is really wrong) or debug messages. But better don't. If it's important,
find a way to report the notification via the API to the caller. If it's
not important, keep silent.
6) g_warn_if_*() from glib. These are always compiled in and log a G_LOG_LEVEL_WARNING
warning. Don't use this.
7) G_TYPE_CHECK_INSTANCE_CAST() from glib. Unless building with "WITH_MORE_ASSERTS",
we disable G_DISABLE_CAST_CHECKS. This means, cast macros like NM_DEVICE(ptr)
translate to plain C pointer casts. Use the cast macros deliberately, in production
code they are cheap, with debugging enabled they assert that the pointer is valid.
Of course, every assertion failure is a bug, and they must not have side effects.
Theoretically, you are welcome to disable G_DISABLE_CHECKS and G_DISABLE_ASSERT
in production builds. In practice, nobody tests such a configuration, so beware.
For testing, you also want to run NetworkManager with G_DEBUG=fatal-warnings
to crash un critical and warn g_log() messages.