C.2. Code Layout

C.2.1. Application Code Layout

Use the following order for laying out the code in the application C source code:

  1. Application standard header

  2. Inclusion of system header files

  3. Inclusion of local header files

  4. Definition of constants

  5. Definition of data types

  6. Global variables (try to avoid these altogether)

  7. Function prototypes

  8. main() function

  9. Functions

A template application C source code file is provided in the myemboss applications directory, e.g.:

.../embassy/myemboss/src/template.c

The file is shown below:

** @source __ApplicationName__
**
** __ShortDescription__
**
** @author Copyright (C) __Year__  __AuthorName__
** @version __VersionNumber__   __description of version__</replaceable>
** @modified __EditDate__  __EditorName__  __description of edit__</replaceable>
** @@
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation; either version 2
** of the License, or (at your option) any later version.
** 
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
** 
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
********************************************************************/


/* ==================================================================== */
/* ========================== include files =========================== */
/* ==================================================================== */

#include "emboss.h"

/* Inclusion of system and local header files goes here */



/* ==================================================================== */
/* ============================ constants ============================= */
/* ==================================================================== */

/* #define and enum statements go here */



/* ==================================================================== */
/* ======================== global variables ========================== */
/* ==================================================================== */

/* Global variables definitions go here */



/* ==================================================================== */
/* ============================== data ================================ */
/* ==================================================================== */

/* Definition of datatypes go here */



/* ==================================================================== */
/* ==================== function prototypes =========================== */
/* ==================================================================== */

/* Function prototypes for public (external) functions go here */


/* @prog __ApplicationName ****************************************************
**
** __ShortDescription__
**
******************************************************************************/

int main(int argc, char **argv)
{
}


/* ==================================================================== */
/* ============================ functions ============================= */
/* ==================================================================== */

C.2.1.1. Standard File Sections

Standard sections in the file .../embassy/myemboss/src/template.c are summarised below.

C.2.1.1.1. Application Standard Header

All application source code files must begin with the standard documentation header (see Appendix D, Code Documentation Standards).

C.2.1.1.2. Inclusion of Header Files

The EMBOSS header file emboss.h is included first followed by includes for any required system files. For example:

#include "emboss.h"
#include <limits.h>
#include <float.h>

emboss.h includes the EMBOSS header file ajax.h which has the following includes:

#include <stdio.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

There is therefore no need to include these files explicitly in the application source code.

C.2.1.1.3. Definition of Constants

These should be given in a block and documented where necessary. For example:

#define TIMEOUT 30      /* Arbitrary pipe timeout (secs)                  */
#define TIMEBUFFER 256  /* Arbitrary length buffer for time printing      */
#define PUTTIMEOUT  120 /* Max no. of secs to write a file                */
#define R_BUFFER 2048   /* Arbitrary length buffer for reentrant syscalls */

Or:

enum blastdbtype {BLAST1P, BLAST1N, BLAST2P, BLAST2N};
C.2.1.1.4. Definition of Global Variables

You should not use global variables unless absolutely necessary. Where they are used they should be documented.

C.2.1.1.5. Definition of Data Types

Any unions and C data structure definitions that are specific to the application should be given next. All datatypes should be defined in the EMBOSS style. It is recommended, but not strictly required, that application data structures are documented in a standard way (see Appendix D, Code Documentation Standards).

The programming of new datatypes is covered in detail elsewhere (Section 5.3, “Objects (C Data Structures)”).

C.2.1.1.6. Function Prototypes

All functions must be prototyped using the full ANSI C style.

C.2.1.1.7. main() Function

The main function is preceded with a standard documentation header (see Appendix D, Code Documentation Standards). The main() function should be given before other functions. This saves people from having to wade through many functions before they find it, and also helps avoid accidental implicit function declarations.

C.2.1.1.8. Functions

Functions should be listed in the order they are prototyped and separated by whitespace (4 newlines). All application-specific functions should be declared static and have a name that begins with the application name. It is recommended that all application functions are documented in a standard way (see Appendix D, Code Documentation Standards).

The programming of new functions is covered in more detail elsewhere (Section 5.3, “Objects (C Data Structures)”).

C.2.2. Library Code Layout

C.2.2.1. Library Header File

In header files, use the following order for the code:

  1. Standard pre-processor directives

  2. Inclusion of system header files

  3. Inclusion of local header files

  4. Definition of constants

  5. Definition of public (external) data types

  6. Function prototypes for public (external) functions

All exported prototype definitions must be bounded by the following comment definitions:

/*
** Prototype definitions
*/

... exported function prototypes here ...

/*
** End of prototype definitions
*/

This is to allow the information to be extracted for Windows compilation. The function names of exported prototypes must be on the same line as their return datatype.

A template header file is provided in the AJAX and NUCLEUS directories, e.g.:

.../emboss/ajax/core/template.h

The file (which is the same for AJAX and NUCLEUS) is shown below:

#ifdef __cplusplus
extern "C"
{
#endif

#ifndef LibraryFileName_h
#define LibraryFileName_h


/* ==================================================================== */
/* ========================== include files =========================== */
/* ==================================================================== */

/* Inclusion of system and local header files goes here */



/* ==================================================================== */
/* ============================ constants ============================= */
/* ==================================================================== */

/* #define and enum statements go here */



/* ==================================================================== */
/* ========================== public data ============================= */
/* ==================================================================== */

/* Definition of public (external) data types go here */





/* ==================================================================== */
/* ======================= public functions =========================== */
/* ==================================================================== */

/* Function prototypes for public (external) functions go here */


#endif
#ifdef __cplusplus
}
#endif

C.2.2.2. Library Source File

Use the following order for the source file:

  1. Standard library documentation header

  2. Inclusion of system header files

  3. Inclusion of local header files

  4. Definition of constants

  5. Definition of global variables (avoid them!)

  6. Definition of private data types

  7. Function prototypes for private (static) functions

  8. Definition of functions

A template source file is provided in the AJAX and NUCLEUS directories, e.g.:

.../emboss/ajax/core/template.c

The file is shown below:

** @source __AJAX or NUCLEUS__  __LibraryArea__ functions
**
** __ShortDescription__
**
** @author Copyright (C) __Year__  __AuthorName__
** @version __VersionNumber__   __description of version__</replaceable>
** @modified __EditDate__  __EditorName__  __description of edit__</replaceable>
** @@
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation; either version 2
** of the License, or (at your option) any later version.
** 
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
** 
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
********************************************************************/

/* ==================================================================== */
/* ========================== include files =========================== */
/* ==================================================================== */

/* Inclusion of system and local header files goes here */



/* ==================================================================== */
/* ============================ constants ============================= */
/* ==================================================================== */

/* #define and enum statements go here */



/* ==================================================================== */
/* ======================== global variables ========================== */
/* ==================================================================== */

/* Global variables definitions go here */



/* ==================================================================== */
/* ========================== private data ============================ */
/* ==================================================================== */

/* Definition of private datatypes go here */




/* ==================================================================== */
/* ====================== private functions =========================== */
/* ==================================================================== */

/* Function prototypes for private (static) functions go here */



/* ==================================================================== */
/* ===================== All functions by section ===================== */
/* ==================================================================== */

/* Functions definitions go here, organised into sections */

C.2.2.3. Standard File Sections

Standard sections in the library header and C source files are summarised below.

C.2.2.3.1. Standard Pre-processor Directives

The contents of every header (*.h) file must be enclosed in a standard pre-processor directive (below). LibraryFileName is the name of the library file, e.g. str for ajstr.h/c:

#ifdef __cplusplus
extern "C"
{
#endif

#ifndef ajLibraryFileName_h
#define ajLibraryFileName_h

/* Everything else goes here */

#endif
#ifdef __cplusplus
}
#endif
C.2.2.3.2. Standard Library Documentation Header

A standard documentation header (see Appendix D, Code Documentation Standards) should go at the top of every library source (*.c) file.

C.2.2.3.3. Inclusion of Header Files

Any files that are required for compilation are included before any code proper. Inclusions of system files are given before local files. You should never use nested includes.

C.2.2.3.4. Definition of Constants

These include #define and enum statements and should be given in a block and documented where necessary.

C.2.2.3.5. Definition of Global Variables

Global variables follow constants in the library source (*.c) file. Global variables should normally be commented if their function is not obvious from their name. They should be avoided wherever possible.

C.2.2.3.6. Definition of Datatypes

Any unions and C data structures (objects) that are private (and should be declared as static) are given in the library source (*.c) file. Any public (external) unions and structures are given in the library header (*.h) file. All datatypes should be defined in the EMBOSS style (Section C.8, “Structures and Unions”). All public datatypes must be documented in a standard way (see Appendix D, Code Documentation Standards). Such documentation is not required for private structures and unions, although it is recommended.

Programming of objects is covered in detail elsewhere (Section 5.3, “Objects (C Data Structures)”).

C.2.2.3.7. Function Prototypes

Avoid exporting names outside individual C source files; i.e., declare as static (in the library source file *.c) every function that you possibly can (i.e. any which are not known to be externally required). All functions must be prototyped using the full ANSI C style.

C.2.2.3.8. Definition of Functions

The functions are given last of all in the library source (*.c) file. All public functions must be documented in a standard way (see Appendix D, Code Documentation Standards below). Such documentation is not required for private functions, although it is recommended.

The programming of new functions is covered in more detail elsewhere (Section 5.3, “Objects (C Data Structures)”).

C.2.3. Ease of Reading

Your code should be easy to read. This is perhaps more important than the code actually working. If it's easy to read then at least someone else stands a chance of fixing it, whereas if it's difficult to read, no one is ever easily going to be able to modify or improve it.

C.2.3.1. Line Length

Lines should typically be no longer than 79/80 characters to avoid line-wrap on screen (or premature line termination on printouts), which can be confusing. Exceptions are allowed where it renders the code easier to read.

C.2.3.2. Variable Names

Variable names should not be too short or too long. Overly long variable names can make the code unreadable, names that are too short can make the code incomprehensible. That said, single characters (i, j, k etc) are fine for standard loop counters. Use common sense to strike a balance. If for example you're coding a mathematical formula or algorithm from a paper, then use variables with the same name as the symbols. If a variable is a temporary one then make that clear in its name. Consider:

for (elementindex = 0; elementindex < DIMENSION; ++elementindex)
    printf("%d\n", element[elementindex]);

for (i = 0; i < DIMENSION; ++i)
    printf("%d\n", element[i]);

In the first example, you have to read more text before you can recognize the for loop idiom, and then you have more hard work to parse the loop body. Since clarity is the goal, a name should contain only necessary and sufficient information to identify the variable. Informative names are unnecessary, however, if the declaration and use of the variable is limited to a small, local section of code. Longer, more informative names are often suitable for variables with larger scope.

C.2.3.3. Braces

Matching braces should appear in the same column and indentation should be consistent. This is good:

int fred(void)
{
    ...

    for(i=0;  i<LIMIT; ++i)
    {
        ...
    }

    return 0;
}

whereas this is messy:

int fred(void) {
    ...
    for(i=0; i<LIMIT; ++i) {
        ...
    }

    return 0;
}

and so is this:

int fred(void)
{
    ...
    for(i=0;  i<LIMIT; ++i)
        {
            ...
        }

    return 0;
}

Don't use braces unnecessarily. The following is good:

for(i=0; i<LIMIT; ++i)
    sum += i;

but this code is cluttered:

for(i=0; i<LIMIT; ++i)
{
    sum += i;
}

The body of a for statement should appear in its own block distinct from the for statement itself. The following could be confusing if nested in a larger body of code:

for(i=0; i<LIMIT; ++i) sum += i;

C.2.3.4. Indentation

Indentation of 4 characters is recommended but more importantly, be consistent. If you find that indentation within nested loops results in many of the lines wrapping then you should check whether the code structure can be improved.

There are some lines you can add to your .emacs file which will (usually) automatically place braces in the correct places and indent properly. They are available in the file http://emboss.open-bio.org/downloads/EmacsConfig and are shown below:

(defun set-if-void (symbol value)
  (or (boundp symbol)
      (set symbol value)))

(require 'cc-mode)
(setq auto-mode-alist
  (append
    '(("\\.C$"    . c++-mode)
      ("\\.H$"    . c++-mode)
      ("\\.cc$"   . c++-mode)
      ("\\.hh$"   . c++-mode)
      ("\\.c$"    . c-mode)
      ("\\.h$"    . c-mode)
      ("\\.m$"    . objc-mode)
      ("\\.java$" . java-mode)
     ) auto-mode-alist))



(defconst emboss-c-style
  '((c-tab-always-indent           . t)
    (c-comment-only-line-offset    . 0)
    (c-hanging-braces-alist        . ((brace-list-open)))
    (c-hanging-colons-alist        . ((member-init-intro before)
                                      (inher-intro)
                                      (case-label after)
                                      (label after)
                                      (access-label after)))
    (c-cleanup-list                . (scope-operator
                                      empty-defun-braces
                                      defun-close-semi))
;; Uncomment the following line if you don't want newlines after semicolons
;;    (c-hanging-semi&;comma-criteria)
    (c-offsets-alist               . ((arglist-close     . c-lineup-arglist)
                                      (substatement-open . 0)
                                      (case-label        . 4)
                                      (block-open        . 0)
                                      (knr-argdecl-intro . -)))
    )
  "EMBOSS C Programming Style")

;; Customisations for all of c-mode, c++-mode, and objc-mode
(defun emboss-c-mode-common-hook ()
  ;; add EMBOSS style and set it for the current buffer
  (c-add-style "EMBOSS" emboss-c-style t)
  ;; offset customisations not in emboss-c-style
  (c-set-offset 'member-init-intro '++)
  ;; other customisations
  (setq tab-width 8
        ;; this will make sure spaces are used instead of tabs
        indent-tabs-mode nil)
  ;; auto-newline [for hungry-delete use (c-toggle-auto-hungry-state 1)]
  (c-toggle-auto-state 1)

  ;; keybindings for C, C++, and Objective-C.  Can put these in
  ;; c-mode-map because c++-mode-map and objc-mode-map inherit it
  (define-key c-mode-map "\C-m" 'newline-and-indent)
  )

(add-hook 'c-mode-common-hook 'emboss-c-mode-common-hook)

This will also let you reformat existing code (with some manual intervention) using the emacs command M-x indent-region.