<Product Name> Programming Guidelines.

This document contains coding standards and guidelines for <Product Name> contributors. These standards and guidelines are expected to be followed when contributing to the <Product Name> project.

Note: Some of the code in the <Product Name> project does not currently conform to this standard. This is because the coding style of some of the code from which <Product Name> was derived has evolved over the past several years. As time permits, we will make the code conform when we visit source files where changes are made. It is expected that all new code will follow this standard.

This document is rudimentary. More examples and better formatting are needed.

{TODO: where appropriate, explain why we chose each standard or guideline. Give contributors insight as to what we are trying to achieve with each of the the guidelines.}


Standards



General Coding Style



Here's an example that puts this all together:

if ((foo == 0) && (bar == 0)) {
    GetFooBar(&foo, &bar);
}



Comments

Use Ansi-C style (/* ... */) comments. C++ style comments are not recommended. Some C compilers do not support C++ style comments.

Comments about a block of code should be placed after the opening brace. For example:

if (foo) {
    /* comments about the block in general go directly after opening brace */

    other executable lines of code
}

Shorter comments should go directly above the executable line of code, as in this example:

/* round down to a multiple of 4 */
length &= ~3;



Indentation with Spaces

Use spaces to indent, not tabs. The <Product Name> project uses 4 (four) spaces for indentation.

{TODO: Get examples of how to setup emacs, vi, etc. Dave will fill in this.}



Brace Style

The <Product Name> project uses K&R brace style, where the opening brace is placed on the same line as the source code line preceding it.

This is correct:

if (response) {
    /* do something */
}

These are not correct:

if (response)
{
    /* do something */
}

if (response)
    {
        /* do something */
    }



Always use braces--even for single statement blocks

This is correct:

if (list == NULL) {
    Warning ("The list is empty.");
}

This is incorrect:

if (list == NULL)
    Warning ("The list is empty.");

This applies to all control structures: if, while, for, do.



Function/Subroutine Names and Declarations

Functions names should have the first letter of each component of the name capitalized. Here's an example declaring several function prototypes:

static int GetResponseFromUser(void);
BOOL ClearMimeCache(ConnectionStruct *client);



Storage class (if specified) and data type are placed on a line by themselves directly preceding the name of the function.

storage-class data-type

FunctionName(parameters...)

{


}



The opening brace is placed on a line by itself directly after the function name, and the opening brace is not indented.

Example:

static int
GetResponseFromUser(void)
{
     /* Function implementation */
}



Variable Names and Declarations

General

One declaration per line. Assignments are OK. Put one space between the data type and the variable name. For pointer declarations, do not use spaces between the asterisk and the variable.

Examples:

register const char *ptr;
int ccode = 0;



Global variables

The first letter of each component of the name is capitalized. Global variables should be namespaced.

Example:

unsigned char *XplHeadPtr = NULL;



Static Variables

Static variables are scoped to the source file and are persistent whether they are declared inside or outside of a function. Therefore we declare these identically to global variables, i.e., the first letter of each component of the name is capitalized.

Example:

static unsigned char *HeadPtr = NULL;



Local variables

First letter of each component of the name is capitalized, except for the first letter of the first component, which is lower case.

Example:

ValueStruct *servers = NULL;
unsigned char *driverName;



Typedefs

The first letter of each component of the name of the type definition is capitalized.

Example:

typedef struct _CalendarInfo {
    unsigned long state;
    unsigned long utcStart;
    unsigned char type;
    unsigned long uid;
} CalenderInfo;

Defines

Macros—All capital letters with underscores between components of the name.

Example:

#define CHAR_SET_TYPE_NONE 0



Macros which are to be treated as function calls should be named as functions.

Example:

#define XplStrCaseCmp () strcasecmp()

Name Spacing

All global functions should be prefixed with the library they are used with. For example all IMAP globals should be prefixed with IMAP.

Static functions (functions that are scoped to a source file) are not prefixed with a name space.

Comment Blocks at Beginning of Functions

Well written code should be mostly self documenting, and therefore comment blocks at beginning functions are usually not required. However, if you desire to put a block comment at the beginning of functions, use this style:

/*  Sum
 *
 *  Adds a to b and places result in the address pointed to by c.
 *
 *  In:
 *      int a: first integer to be added
 *      int b: second integer to be added
 *
 *  Out:
 *      int *c:  result of sum of a and b.
 *
 *  In/Out:
 *     None
 *  
 *  Return:  
 *      non-zero for success, zero for failure. 
 */
static int
Sum(int a, int b, int *c)
{
    if (c == NULL) {
        return(0);
    }    

    *c = a + b;
    return(1);
}




Guidelines

Make each header "stand alone"

Each C header file must be written so it can be included without including another file first. To test if a header files meets this property, always include the corresponding header file first in each C source file. The only exception is the include of <config.h>, which goes first.

Here's an example:

{TODO: add example from OCS}

/*
 *
 * nautilus-icon-factory.c: Class for obtaining icons for files and other objects.
 *
 * Copyright (C) 1999, 2000 Red Hat Inc.
 * Copyright (C) 1999, 2000 Eazel, Inc.
 *
 * License agreement goes here.
 *
 * Author: John Sullivan <sullivan@eazel.com>
 */

#include <config.h>
#include "nautilus-icon-factory.h"

#include <string.h>
#include <stdio.h>
Include statements for other header files go here.

Other declarations and code go here.



Use type casts as little as possible

There are some instances where you must cast to make the program work, but try to do whatever you can to avoid this. Also, we prefer to cast data pointers, rather than casting function pointers, since there's so much more to get wrong with function pointer casts.



Avoid in-band signaling

This means, for example, that we avoid using special values to indicate errors. This can lead to subtle bugs when a valid result is misinterpreted as an error, and can make it hard to tell if the code handles errors correctly.



Use for-loops if it makes the code easier to read

The alternative is usually to use a while loop.



Declare local variables at the beginning of a block

C99 allows you to declare variables anywhere in a function, but a lot of compilers still do not support C99.



Avoid comparing a variable or return value against TRUE

What is typically intended is to determine if the operation was successful. The macro TRUE takes on a single value, whereas a function could return any non-zero value to indicate success.

Do not use the following method to test for success:

if (bar == TRUE) {
    /* do something */
}

Rather, use the following

if (bar) {
    /* do something */
}

if (!bar) {
    /* do something else */
}