GnomeBaker Coding Standards
-----------------------------------------


1. All functions use the GB_LOG_FUNC macro and GB_TRACE
-------------------------------------------------------------------------------

The first line in any function should be GB_LOG_FUNC. It is a really simple
macro which when enabled logs the function entry to a console. It's pretty
noddy but helps when debugging people's problems remotely. 

Also, when wishing to output debugging info, please use the GB_TRACE macro. Please 
apply the following rules when using GB_TRACE as shown below:

	* Put the function name first in the trace.
	* Place square brackets around parameters so you can see the exact contents
	  of the arguments. 
	  
	GB_TRACE("burn_create_data_cd - [%s]\n", convertedfile);


Both macros are enabled by starting the app with the flag --trace-on.

eg. gnomebaker --trace-on &> gboutput.txt



2. Brackets go on next line from control statements. 
-------------------------------------------------------------------------------

All of the existing code is formatted this way so this is the way the remainder 
will be formatted.


void
my_function()
{
	GB_LOG_FUNC
	if(some_other_function())
	{
		/* do something */
	}
	else
	{
		/* do something else */
	}
}



3. Scope variables as tightly as possible
-------------------------------------------------------------------------------

Variables should assigned on the line they are declared as shown below:

void 
my_function()
{
	GB_LOG_FUNC
	if(some_other_function())
	{
		gint count = get_count();
		++count;
	}
}

rather than:

void 
my_function()
{
	GB_LOG_FUNC
	gint count;
	if(some_other_function())
	{
		count = get_count();
		++count;
	}
}



4. Check function parameters using glib macros
-------------------------------------------------------------------------------

GLib provides several convenient macros for checking parameter values. They should
be used.

void 
my_function(const gchar *value)
{
	GB_LOG_FUNC
	g_return_if_fail(value != NULL);
	...
}


gboolean 
my_function(const gchar *value)
{
	GB_LOG_FUNC
	g_return_val_if_fail(value != NULL, FALSE);
	...
}



5. Avoid multiple return points where possible
-------------------------------------------------------------------------------

Multiple return points aren't all bad but consider the following code (it's
not a great example as it doesn't make much sense and is somewhat extreme):


gboolean 
my_function()
{
	GB_LOG_FUNC
	
	GString *value1 = g_string_new("");
	GString *value2 = g_string_new("");
	
	if(!some_function(value1, value2))
	{
		g_string_free(value1, TRUE);
		g_string_free(value1, TRUE);
		return FALSE;
	}

	if(!some_other_function(value1, value2))
	{
		g_string_free(value1, TRUE);
		g_string_free(value1, TRUE);
		return FALSE;
	}
	
	another_function(TRUE);
	
	g_message("value1 is %s", value1->str);
	g_message("value2 is %s", value2->str);
	
	g_string_free(value1, TRUE);
	g_string_free(value1, TRUE);

	return TRUE;
}


is much better written:


gboolean 
my_function()
{
	GB_LOG_FUNC
	gboolean ret = FALSE;
	GString *value1 = g_string_new("");
	GString *value2 = g_string_new("");
	
	if(!some_function(value1, value2))
	{
		g_critical("Error calling some_function");
	}
	else if(!some_other_function(value1, value2))
	{
		g_critical("Error calling some_other_function");
	}
	else
	{
		another_function(TRUE);
		g_message("value1 is %s", value1->str);
		g_message("value2 is %s", value2->str);
		ret = TRUE;
	}
	
	g_string_free(value1, TRUE);
	g_string_free(value1, TRUE);

	return ret;
}


Now there is one allocation and one free. There's less lines of code and memory
is guaranteed to be freed. Where there are multiple exit points it's easy to
miss a call to free. The preferred way also forces you to log a g_critical or
something appropriate as you have to do something in the if.



6. Function names begin with the filename and words are separated with _
-------------------------------------------------------------------------------

Where practical, function names should begin with the file they are implemented
in.

ie

	 /*
	 * File: datacd.h
	 * Created by: Luke Biddell <Email>
	 * Created on: Sun May  9 15:16:08 2004
	 */
	
	#ifndef _DATACD_H_
	#define _DATACD_H_
	
	#ifdef HAVE_CONFIG_H
	#  include <config.h>
	#endif
	
	#include <glade/glade.h>
	#include <gnome.h>
	
	void datacd_new();
	void datacd_clear();
	void datacd_remove();
	void datacd_add_selection(GtkSelectionData *selection);
	void datacd_import_session();

Note that the names are all lower case and the word separation is with _.



7. Don't forward declare functions
-------------------------------------------------------------------------------

Private functions should be ordered such that forward declaration in the .c
file should be unnecessary. Public functions will obviously be declared in the .h



8. Externalise all strings
--------------------------------------------------------------------------------

When you need a string which will be displayed to a user, write this:

_("Something") will make the string translatable. _( is for gettext to do 
its work. Now, the po/gnomebaker.pot should be updated by the configure script to 
reflect all the strings in the source files. A translator needs to copy that 
file to a locale file, eg. pt_BR.po. In this file he can translate the strings.



9. Compiler warnings
--------------------------------------------------------------------------------

As far as I am concerned, compiler warnings are errors. Please do not commit
anything until it compiles without warnings unless there's a good reason.



10. Adding translation files
--------------------------------------------------------------------------------

* po file goes into po directory in cvs HEAD (eg fr.po)
* update configure.in and add the language code (ie fr) the the ALL_LINGUAS variable.
* make sure the translator has added their name to the translator_credits string in the po file.
* run 'make update-po' in the po directory to make sure that the po file does not contain errors.



11. Comments
--------------------------------------------------------------------------------

All code comments are to use proper c style comments /* */ rather than //.



12. Variable naming
--------------------------------------------------------------------------------

Although the majority of existing GnomeBaker code does not follow this at the moment,
please name all variables in lower case and separate words using _.

eg.

const gint count_of_items;
static char a_random_char;



13. Operator use
--------------------------------------------------------------------------------

When using a conditional operator please use spaces.

eg.

Use:

if(count_of_items > 0)

rather than:

if(count_of_items>0)



14. Indenting
--------------------------------------------------------------------------------

Indents are 4 spaces in size except where a statement overflows a line and then
we double indent. As a rule we overflow at 100 chars.

eg.

if(planets_aligned)
	do_something();

gbcommon_populate_disk_size_option_menu(PROJECT_WIDGET(project)->menu, data_disk_sizes, 
		DISK_SIZE_COUNT, preferences_get_int(GB_DATA_DISK_SIZE));



15. Library versions
--------------------------------------------------------------------------------

GnomeBaker currently only requires GTK 2.4. When writing code please 
avoid using functions from newer GTK versions as we want to stay as distro
friendly as possible. If that function is necessary and avoids writing a whole
bunch of code then we will up the required version of GTK.

