Author: Ernst Bablick

## Coding Standards for the Grid Engine Project

In a continuous attempt to unify the structure and the format of the Grid Engine source code, we have collected a few guidelines here to which we ask you to adhere as you add new source code or modify the existing code. Please make every effort to follow our guidelines before you submit your contributions to the project. We also ask for your help in improving existing incompliant code as you make modifications to it.
We plan to use the "indent" tool in the future to format C source code automatically. Unfortunately, this is not possible yet due to technical reasons.

### General

To prevent code sections to be formated, place a disabling control comment

    /* *INDENT-OFF* */

on a line by itself just before that section. The enabling control comment is

    /* *INDENT-ON* */

The script, which will be used in the future to automatically change the lookout, can be found here:

    gridengine/source/scripts/format.sh

### Tabs, Line Length and Indentation.

Please do not use tabs inside of the code and wrap lines after the 80th character in a line. We do not like tabs because different editors and editor settings always lead to different displays. In order to be able to still use the tab key in your editing you can either configure your editor to replace tabs by spaces automatically or you use the "gridengine/source/scripts/format.sh" script to take out the tabs when you have finished editing.
Lines have to be indented by three spaces for each code block level. The format script will also perform this automatically. See more details below.

### Comments

Source code documentation is essential in an increasing group of developers producing software collabortatively and efficiently. Comments within the source code are one way to create a comprehensive documentation. This insures that the related information is in the right place and makes it easier for the software engineer to maintain it.

Inside Grid Engine we use line comments to describe certain attributes, block comments to explain bigger code sections and Autodoc comments (ADOC) to declare modules, functions and other important parts of the software.

Line comments look like this

    lList ptf_job;  /* JL_Type */

They are at the end of a line after the code or in the line before it just like block comments as shown below:

    /*
     * Stuff implementing fast access to the next job
     * that is to be dispatched accordingly to the
     * job sorting policy
     */
    if (!so_pgr) {
       so_pgr = lParseSor ...

ADOC comments can be extracted from the source code by the adoc tool. The adoc tool identifies the different sections inside an ADOC comment and creates a texinfo file which can be converted to man/html pages, pdf, GNU Info ...

    /****** src/sge_ls_get_pid() *********************************
    *
    *  NAME
    *     sge_ls_get_pid -- get pid of a loadsensor
    *
    *  SYNOPSIS
    *     static pid_t sge_ls_get_pid(lListElem *this_ls)
    *
    *  FUNCTION
    *     Returns the pid which is stored in a CULL element of
    *     the type LS_Type. If the corresponding loadsensor was
    *     not started until now then -1 will be returned.
    *
    *  INPUTS
    *     this_ls - pointer to a CULL element of type LS_Type
    *
    *  RESULT
    *     returns pid or -1
    *
    *************************************************************/

This is a typical ADOC-comment describing a function. Source code inside ADOC comments should look like the real source code. Information about using ADOC can be found here

#### Special Comments

Format: /* <Initials>: <Keyword> [(<issue #)]: <text> */
<Initials> = 2 character initials, same as in Changelog
<Keyword> =

> TODO
> DEBUG

Optionally an IssueZilla id can be specified referencing the correspondent issue.

### Statements

Functions should have the following format:

    static int qmod_queue_weakclean(lListElem *qep, u_long32 force,
                                    lList **answer, char *user,
                                    char *host, int isoperator, int isowner)
    {
       ...
    }

They should start with the qualifier and return type. There is no space between the function name and the open parentheses. If the arguments do not fit into one line split the line and continue the arguments under the first one of the previous line. The brace in function definitions, has to be in column zero again. Statements inside the function body should be indented with 3 spaces like Statements inside a compound statement. In contrast to functions, the opening left brace of a compound statement should be at the end of the line beginning the compound statement and the closing right brace should be alone on a line. Some examples:

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

    while (1) {
       ...
    }

    do {
       ...
    } while (!found);

    if (i == 1) {
       ...
    } else if (i == -5) {
       ...
    } else {
       only_one_call();
    }

    switch (i) {
    case 1,2:
       ...
       break;
    case 3:
       ...
       break;
    default:
       ...
    }

    struct name {
       char *first;
    }

There is one space between the keyword and the open parentheses. Braces are in the same line like the keywords. They should be used even if it is not necessary. Function calls do not contain spaces between the function name and the open parentheses.

### Declarations

The format of a function prototype should be equivalent with the function definition.

    static void sge_set_ls_fds(lListElem *this_ls, fd_set *fds)
    {
       int i, k, l;
       int j = -1;
       int name[3] = { LS_out, LS_in, LS_err };
       FILE *file;
       ...

Multiple variables are declared in one line. Each pre-initialized variable has its own line. The asterisk of a pointer declaration is part of the variable name. The space has to be put in between the type name an the asterisk.

### Clean use of C Constructs

Past experience leads us to some best-practice coding advices:

Huge parameter lists or function bodies are an indicator that it is time to split a function into some smaller functions which are easier to read and understand.

Try to avoid nested expressions where multiple assignments or the ?-operators are envolved.

Use #if 0 to disable code sections and add a short comment why this code was disabled.

### Naming

Names for variables, functions, macros etc. should be composed of words separated by underscores. Upper case letters are reserved for macros, enum constants and for name prefixes that follow a uniform convention. For variable names, we suggest simply to adopt to the unwritten naming conventions used in different source code areas, the names always have to be or have to relate to English terms and expressions.