Hacking Guidelines
==================

This document is an introduction to hacking on GnuCash.

Related Documents
-----------------

In addition to this file, you should read the README file, which
explains the details of getting the CVS source, building GnuCash,
and creating patches for submission.

The src/doc/design directory contains a preliminary design document
which you should read as well. You should also feel free to hack on
the design document.


Coding Style Conventions
------------------------

General:

 * When modifying a file, the style convention in that file should be
   followed.

 * When creating a new file, the style of existing files should be
   followed.

 * When creating lots of new files in a new directory, you may use
   your own coding standards, but please try to stick as closely as
   possible to the GNU coding standards.

 * Do not submit patches that consist of (gratuitous) stylistic changes.


C:

 * Use ISO C.

 * Use glib memory routines where possible. This means you should be
   using g_malloc(), g_new(), g_free(), etc., instead of malloc(),
   free(), etc. Do not mix glib memory calls with libc calls!

 * Where possible, use glib data abstractions instead of rolling your
   own. Glib linked lists and pointer arrays are very convenient and
   have been extensively used and tested.

 * All gnucash functions and global variables are prefixed with gnc_

 * Use static functions whenever possible

 * Use const whenever possible


Scheme:

 * All gnucash functions and global variables are prefixed with gnc:

 * All global variables are enclosed in ** (i.e. gnc:*load-path*)

 * All private functions are enclosed in __ (i.e. gnc:_do-not-call_)

 * All C functions wrapped with g-wrap have dashes in place of underscores.
   (xaccSplitGetBalance --> gnc:split-get-balance).


Dave Peticolas <dave@krondo.com>
August 22, 2000

=====================================================================
TIPS AND HINTS
=====================================================================

Starting Gnucash from the build tree:
-------------------------------------

Getting Trace Messages From GnuCash:
------------------------------------
Note that piping stdout from gnucash to a file causes gnucash to crash.
Don't know why, this is a bug that needs to be fixed.  Here's another
way to get trace messages into a file:

-- edit src/engine/gnc-engine.c and find the call to qof_log_set_level
   for the module you are intersted in.  Adjust the log level
   appropriately.
-- edit the call to qof_log_file_init() in this same file to change
   where you want messages to go to.


Starting GnuCash in GDB
-----------------------
To run gdb on an installed version of gnucash (installed in /opt/gnc/unstable:)

    % /opt/gnc/unstable/bin/gnucash &
    [ pid number output here ]
    % gdb /opt/gnc/unstable/bin/gnucash-bin
    [gdb output]
    gdb> attach <pid>
    
You'll also probably want to know about these:

    gdb> catch fork
    gdb> set follow-fork-mode child

-----
It may be the case that running GDB from within emacs doesn't work for you,
with the following error:

[C-u M-x gdb /opt/gnucash-cvs/bin/gnucash-bin
 ...in buffer *gud-gdb*:]

    (gdb) attach <pid>

jsled needed to re-define a gud.el function as such:

  (defun gud-gdb-massage-args (file args)
    (let ((l (copy-list args)))
      (nconc l (list "-cd" (expand-file-name default-directory) "-fullname"))))


Using Electric Fence with GnuCash
---------------------------------
    % configure --enable-efence
(except this doesn't actually enable efence :-( need to hack
configure.in and add $LIBS = -lefence and re-run ./autogen.sh)

Don't know why, efence does not currently work with gnucash:
I get a bunch of errors:
   warning: Cannot initialize thread debugging library: unknown thread_db error '22'

If you know how to fix this, please update tehse instructions.


Using Valgrind with GnuCash
---------------------------
-- run ./src/bin/overrides/gnucash-valgrind

However, I did not find valgrind to be useful.  It reported a bunch of
guile bugs, some g_hash_table bugs, and then the program exited prematurely 
for no appearenet reason. :-( 

For the moment, use the supressions in src/valgrind-gnucash.supp

This file needs to be cleaned up in two ways:

1/ There are a bunch of duplicate supressions in the file.
   * The supressions in place were auto-generated by valgrind itself
     [--gen-suppressions=yes], and it makes no effort to output the
     suppression only once.

2/ There are a bunch of suppressions which need to not be supressions, but
   instead just not be generated by valgrind.


Look up exported and imported symbols
-------------------------------------
These commands may be useful to find out the library that actually
exported a particular symbol, and to check which import symbol one
particular library depends upon and where they are imported
from. Run these from the top-level of the build tree.

# Create a table of all exported symbols and where they come from
nm -A `find . -name '*.so'` | grep ' T ' | \
  sed 's/^\([^:]*\).* \([^ ]*\)$/\1: \2/' > exportedsymbols

# For a particular library, check symbol import requirements, 
# listing all symbols (needs the file from above)
A=src/gnc-module/.libs/libgw-gnc-module.so && echo "$A requirements:" \
  && nm $A | grep ' U ' | sed 's/^.* \([^ ]*\)$/\1/' | \
  grep -wFf- exportedsymbols

# For a particular library, check import requirements, 
# summarized by library
A=src/gnc-module/.libs/libgw-gnc-module.so && echo "$A requirements:" \
  && nm $A | grep ' U ' | sed 's/^.* \([^ ]*\)$/\1/' | \
  grep -wFf- exportedsymbols | cut -d: -f1 | sort | uniq

# For a particular library, check import requirements, 
# summarized by library, formatted for Makefile.am
A=src/gnc-module/.libs/libgw-gnc-module.so && echo "$A requirements:" \
  && nm $A | grep ' U ' | sed 's/^.* \([^ ]*\)$/\1/' | \
  grep -wFf- exportedsymbols | cut -d: -f1 | sort | uniq | \
  sed 's!.libs/!!' | sed 's/.so$/.la \\/' | sed 's!^.!  \${top_builddir}!'

# List all import requirements summarized by library for a full
# recursive directory tree
for A in `find src/business/business-core -name '*.so'`; do \
  echo -e "\n##$A requirements:" && nm $A | grep ' U ' | \
  sed 's/^.* \([^ ]*\)$/\1/' | grep -wFf- exportedsymbols | \
  cut -d: -f1 | sort | uniq; done

