INTRODUCTION
---------------------------------------------------------------------
Here will you find coding standards to the project. Requirements are
listed in their respective files and can be considered an adendum to
this document.


CODING STYLE
---------------------------------------------------------------------
See linux/Documentation/CodingStyle.

Some highlights:

- Outside of comments and documentation, never
  use spaces. Identation is done using tabs only.

- Do not use tabs to align text documentation. Changing tab
  width should not interfere with the layout/alignment of code,
  only indentation.

- functions are declared like this:
   char *function(const char *test)
   {

   }

- if you use brackets INSIDE a function put them on the same line

    Wrong:
    if (condition)
    {
        do_something;
    }

    Right:
    if (condition) {
        do_something;
    }

- Do not put actions in the same line of conditions:

    Wrong:
    if (condition) do_this;

    Right:
    if (condition)
        do_this;

- Also it is a good practice to use always brackets in conditions:
	 
	 if (condition) {
	 	do_only_this;
	 }
	 
- Variables are always in lower case (like tmp_buf)
- New defined types are capitalized (like OSyncEngine)
- Never use typedefs just to hide pointers

- External APIs, used for integration between components may
  look like this:

	osync_engine_init()

- Always add the osync_ prefix to your functions

- Do not return function calls, like "return do_something();",
  instead, use a auxiliar variable (rationale: easy trace).

- When doing error checking, use goto to help creating a single
  return point. Do not abuse goto usage though... never goto up,
  never create more than one label and do not "gotoo far".

EMACS
---------------------------------------------------------------------
For the above indentation rules, you can add the following 
to your .emacs file:

;; Additional setting to have linux kernel style
;; indentation. Argument lists in next line will only
;; be indented by tabs
(defun c-lineup-arglist-tabs-only (ignored)
  "Line up argument lists by tabs, not spaces"
  (let* ((anchor (c-langelem-pos c-syntactic-element))
     (column (c-langelem-2nd-pos c-syntactic-element))
     (offset (- (1+ column) anchor))
     (steps (floor offset c-basic-offset)))
    (* (max steps 1)
       c-basic-offset)))

(defun my-c-mode-hook ()
  (setq indent-tabs-mode t)
  (c-set-style "linux")
  (c-set-offset 'arglist-cont-nonempty 
                '(c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only))
)

(add-hook 'c-mode-hook 'my-c-mode-hook )

CODE DOCUMENTATION
---------------------------------------------------------------------

* Add FIXME, TODO and XXX comments appropriately.

* Use Doxygen (http://www.stack.nl/~dimitri/doxygen/) to document your code

* Add your doxygen annotations in the header files. This allows other
  developers to read the documentation without having installed the source.

* Add simple READMEs and pictures as needed, but concentrate
  on doxygen.

* Recommended to watch for leading and trailing empty spaces on comments
(vim and emacs can be set to display them).

* Try to describe the *why* of a function and not just the *what* (e.g.
'This function is required by module foo because of protocol X. It does
something'

Some examples:

a) Say that you have a function (e.g. foo) and its declaration in a header
file (foo.h), a good way to document that would be:

 - in foo.h

 /** @brief This functions does something funny.
  *
  * Here you can put further details.
  *
  * @todo something is missing
  *
  * @param bar This is the parameter, please refer \ref bar_func to create
  * this value.
  * @return Returns -1 for failure, 0 for success.
  */
char foo(int bar);


- Implementation must be almost free of comments, because it helps to read the
code. Only really trick parts should be commented (even better, re-written
to be more simple). The wise use of XXX/FIXME/TODO can help a lot to
identify hot spots in the code. So, say in foo.c

void foo(int bar)
{
	/* TODO: write a unit test */

	/* XXX: a dirt trick to workaround a bug in protocol */
	/* here goes the code */


	/* FIXME: this should be moved to another module */
	/* here goes the code */
}


CODE INSTRUMENTATION
-----------------------------------------------------------------

Always:
    * Use const;
    * Use static for internal functions;
    * Use safe glib functions where possible;
    * Use glib functions which are part of at least glib2 version 2.12
    * Check validity of all received parameters;
    * Use osync_assert() while developing;
    * Do not use alloca() or other non-recommended functions;
    * Check for return errors even from malloc() and other
      standard system calls;

Regularly:
    * Use valgrind to profile you application and find memleaks

About header files:
    * Source code has to be split into modules, which are defined as
      a collection of implementation files (.c) with an interface
      exported through a header file (.h).
    * The inclusion (#include) of headers must reflect the dependencies
      between modules in the implementation. The most important
      implications from this statement are:

        . implementation files (.c) *must* include *all* headers it
          directly depends;
        . implementation files (.c) *must not* include headers it
          doesn't directly depend;
        . headers should include headers only when needing a
          definition or declaration;
        . headers should never include other headers just to create a
          "single point of inclusion".

      These rules may sound obvious, but they're actually hard to
      follow.


COMMITS AND CHANGELOGS
---------------------------------------------------------------------
Descriptive and small.

General rules:
   - *Always* do a svn diff and a svn status before a commit and
     document the diff(s) in the changelogs;
   - What matters is not what but why;
   - Several commits are usually better than a big one;
   - Do not commit unrelated modifications at once unless they're
     really trivial;
   - Commit ASAP.

BUILD-SYSTEM
---------------------------------------------------------------------
Standard instructions:

  Code should compile with no warnings, using the following GCC
  options:

    -Wall
    -Werror

    Recomended but not mandatory (for now):
    -W
    -Wmissing-declarations
    -Wmissing-prototypes
    -Wredundant-decls
    -Wshadow
    -Wbad-function-cast
    -Wcast-qual
    -std=iso9899:1990
    -D_FORTIFY_SOURCE=2

    Hint:
    For developers using GCC there is a CMAKE_BUILD_TYPE "hacking" which sets
    the default compiler flags to a recommended compiler flag set.

LOGS and TRACES
---------------------------------------------------------------------
There are two types of logs that must be handled by almost all
applications:

 * HIGH-LEVEL LOGS: these are standard, high-level logs usually
   enabled by default. Useful to advanced users, support-centers and
   alike. Should include basic information, including but not limited
   to:
     - start/end of application
     - errors
     - complex operations

   The requirements document specifies if logs are needed or not.

 * TRACES: traces are a particular kind of log used to debug the
   application. They're used mostly by black-box testers to submit
   failure reports.

   Traces should be enabled in a per-application basis using an
   environment variable or at compile time, to be yet defined.

UNIT TESTS
-----------------------------------------------------------------

* All code should be written together with unit-tests. The tool
  used to implement the tests is "check", available on
  http://check.sourceforge.net/.

  The build-system infra-structure provides a configure option to
  allow check usage. If possible use the CMake macro ADD_CHECK_TEST
  to introduce new tests, for building and integration as testrun
  in the build-environment.

  When using Make, the test can be locally run via:
  $ make test

  Results can also be sent to central testing dashboard CDash at
  http://opensync.org/testing. Command to run tests and send results
  to CDash:
  $ make Experimental

  The tests must be implemented inside a sub-directory called test
  with the following modules:

  check_<component name> --> the test-manager
  check_<unit name>      --> implements tests for interfaces
                             exported by unit
  check_<...>

  Just to remember, an unit, or module, is a collection of
  souce-code files (.c) with an interface exported through
  a header file (.h).

  All interfaces exported by units must be tested (that is,
  all non-static functions). The tests should implement at
  least the following test cases:

    - standard usage
    - upper and bottom limits of buffers and variables as
      needed
    - error conditions
    - critical paths

  Use incremental tests, that is, test functions before using them in
  other test-cases (for example, if you need to call function A to
  prepare the environment to test function B, test function A first).

  Try to write the test-case before the unit or function itself.

  If the test needs an external entity to work (for example, it needs
  a device connected on a specific port), put the test inside a
  condition for an environment variable and document it in a README
  file.
