Difference between revisions of "CodingStandard"

From GnuCash
Jump to: navigation, search
(astyle version is important as well)
(Add C++ section.)
Line 37: Line 37:
 
The rationale for the arguments is contained in [http://lists.gnucash.org/pipermail/gnucash-devel/2009-August/026121.html this email].
 
The rationale for the arguments is contained in [http://lists.gnucash.org/pipermail/gnucash-devel/2009-August/026121.html this email].
  
= Framework =
+
= C++ Format =
Gnucash is a [http://www.gtk.org Gtk+] project. It's design is object-oriented using Gnome's [http://developer.gnome.org/gobject/stable/ GObject] C-language framework.
+
C++ follows the C format guidelines above, with the following modifications:
 +
* Namespaces shall be all lower case, and the outermost one shall be named '''gnucash'''.
 +
* All '''identifiers''' shall be '''camel-cased'''.
 +
** '''Typenames''' (i.e. class, struct, enum, and POD type-aliases) shall begin with an upper-case letter.
 +
** '''Function''' and '''object''' (including enumerator) names shall begin with a lower-case letter.
 +
 
 +
In addition, certain types of variables shall have prefixes denoting their roles:
 +
* '''Member variables''': '''m_'''.
 +
* '''Static member variables''' (a.k.a class variables): '''c_'''.
 +
* '''Static constants''': '''k_'''.
 +
* '''Free static variables''': '''s_'''. Free static variables means statics which are not local and not members of a class or struct, regardless of scope.
 +
 
 +
Headers and implementation files should be named for the class they declare or implement. In general any file should declare or implement only one class.
 +
 
 +
== Coding Guidance ==
  
Remember that even though it's in C, it's supposed to be object-oriented code, so decompose your problem with objects, not procedurally. Try to keep functions short and well named.  
+
* Write modern, idiomatic C++ using the new features of C++11 and later.
 +
* Maximize use of the C++ standard library, especially the algorithms, and Boost.
 +
* Keep thread-safety and reentrancy in mind: Modern processors are mostly multi-core, and modern operating systems and dispatchers will multi-thread programs on their own if possible.
 +
* Avoid adding dependencies if possible. If you must, ensure that their licenses are compatible with GnuCash's and that we comply with any license requirements like crediting the copyright holder in documentation. We may not distribute dependencies on Linux and BSD, but we do on Windows and MacOSX.
  
Gnucash is also based upon [http://developer.gnome.org/glib/stable/ GLib], a very rich foundation library. Familiarize yourself with GLib's many utilities and data types, ''and use them''. In particular ''do not write a utility for something which GLib already does.''
+
= Framework =
 +
Gnucash is a [http://www.gtk.org Gtk+] project. It's design is object-oriented. The current object orientation is implemented mostly with Gnome's [http://developer.gnome.org/gobject/stable/ GObject] C-language framework and makes heavy use of [http://developer.gnome.org/glib/stable/ GLib]. While this is a rich eco-system, it brings with it a huge number of dependencies which makes GnuCash difficult to port to other operating systems. Consequently the developers have decided to migrate all of GnuCash except the GUI to C++. No new GObject or GLib-dependent code should be written; instead use C++, the C++ standard library, and Boost libraries.
  
(Yes, in spite of those fine words, there's a lot of code in Gnucash that doesn't use GLib types, duplicates GLib or GObject functionality, or is procedural instead of object oriented. We'll eventually get that refactored out, but in the meantime, don't make it any worse.)
 
  
 
= Guile and Scheme =
 
= Guile and Scheme =
 
Gnucash is partly implemented in a [http://groups.csail.mit.edu/mac/projects/scheme/ Scheme] dialect called [http://www.gnu.org/s/guile/ Guile]. (It was originally written mostly in Guile, but that implementation was largely replaced with C several years ago.) In particular, the reports system and part of the business system are written in Guile. To support that, most of the core "engine" API is wrapped and accessible from Guile.
 
Gnucash is partly implemented in a [http://groups.csail.mit.edu/mac/projects/scheme/ Scheme] dialect called [http://www.gnu.org/s/guile/ Guile]. (It was originally written mostly in Guile, but that implementation was largely replaced with C several years ago.) In particular, the reports system and part of the business system are written in Guile. To support that, most of the core "engine" API is wrapped and accessible from Guile.

Revision as of 23:29, 8 September 2014

C Format

Gnucash is fairly relaxed about code format, but we will periodically run a reformatter called Artistic Style (astyle) over the code to clean it up. To reduce the need for this (it messes up VCS history, particularly "blame"), please format your code as follows.

In general, follow the GNU format except use four spaces instead of two for the indents, and don't indent the braces. To summarize, a properly formatted function will look like this:

 guint
 gnc_account_foo (Account *account, gpointer bar)
 {
      Split *baz;
      guint salt;
      if (gnc_split_waldo (baz) > 0)
      {
           salt = gnc_split_pepper (baz);
      }
      return salt;
 }

Please keep lines under 80 characters. If you need to wrap, line up the function arguments like this:

 gnc_account_function_with_a_lot_of_paramters (LongTypeName foo, LongerTypeName *bar,
                                               TypeName baz)
 {
 }

We don't do the wide separation of names and aligned parameters, so don't do this:

 void gnc_account_foo               (Account     *bar,
                                     Split       *baz,
                                     gpointer     waldo);
 Split *gnc_account_pepper          (Account     *salt,
                                     Transaction *sausage);

Instead, do it this way:

 void gnc_account_foo (Account *bar, Split *baz, gpointer waldo);
 Split *gnc_account_pepper (Account *salt, Transaction *sausage);

For the record, the astyle commandline we use (with astyle version 1.24; other versions might result in slightly different formatting) is

 astyle --indent=spaces=4 --brackets=break --pad-oper  *.[hc]

The rationale for the arguments is contained in this email.

C++ Format

C++ follows the C format guidelines above, with the following modifications:

  • Namespaces shall be all lower case, and the outermost one shall be named gnucash.
  • All identifiers shall be camel-cased.
    • Typenames (i.e. class, struct, enum, and POD type-aliases) shall begin with an upper-case letter.
    • Function and object (including enumerator) names shall begin with a lower-case letter.

In addition, certain types of variables shall have prefixes denoting their roles:

  • Member variables: m_.
  • Static member variables (a.k.a class variables): c_.
  • Static constants: k_.
  • Free static variables: s_. Free static variables means statics which are not local and not members of a class or struct, regardless of scope.

Headers and implementation files should be named for the class they declare or implement. In general any file should declare or implement only one class.

Coding Guidance

  • Write modern, idiomatic C++ using the new features of C++11 and later.
  • Maximize use of the C++ standard library, especially the algorithms, and Boost.
  • Keep thread-safety and reentrancy in mind: Modern processors are mostly multi-core, and modern operating systems and dispatchers will multi-thread programs on their own if possible.
  • Avoid adding dependencies if possible. If you must, ensure that their licenses are compatible with GnuCash's and that we comply with any license requirements like crediting the copyright holder in documentation. We may not distribute dependencies on Linux and BSD, but we do on Windows and MacOSX.

Framework

Gnucash is a Gtk+ project. It's design is object-oriented. The current object orientation is implemented mostly with Gnome's GObject C-language framework and makes heavy use of GLib. While this is a rich eco-system, it brings with it a huge number of dependencies which makes GnuCash difficult to port to other operating systems. Consequently the developers have decided to migrate all of GnuCash except the GUI to C++. No new GObject or GLib-dependent code should be written; instead use C++, the C++ standard library, and Boost libraries.


Guile and Scheme

Gnucash is partly implemented in a Scheme dialect called Guile. (It was originally written mostly in Guile, but that implementation was largely replaced with C several years ago.) In particular, the reports system and part of the business system are written in Guile. To support that, most of the core "engine" API is wrapped and accessible from Guile.