===========================================================================
 Freeciv Style Guide
===========================================================================

If you want to hack Freeciv, and want your patches to be accepted, it
helps to follow some simple style rules. Yes, some of these are a bit 
nit-picky, but wars are fought over the silliest things...

- Freeciv is programmed in plain C (except the BEOS client). This
  means that C++ features like:
    - C++-style comments (i.e., // comments) and
    - declaration variables in the middle of the function body
  are forbidden.

- Use K&R indentation style with indentation 2 (if in doubt, use
  "indent -kr -i2 -l77").  However, do not re-indent areas of code you
  are not modifying or creating. Here are the most important properties:
    - lines are at most 77 chars long
    - spaces are inserted before and after operators ("int i, j, k;"
      instead of "int a,b,c;" and "if (foo <= bar) c = a + b;" instead
      of "if(foo<=bar) c=a+b;")
    - function braces begin and end in the first column.
        int foo()
        {
          return 0;
        }
      instead of
        int foo() {
          return 0;
        }
    - the tab width is 8
    - the indentation is 2 columns per level

- An empty line should be placed between two separate blocks of code.

================================
 Comments
================================

- Every function should have a comment header. It should be above the 
  function's implementation, not the prototype:

/*************************************************************************
 the description of the function should be here
 any information is helpful, such as who calls this function, etc.
 do _not_ introduce a new function without some sort of comment.
*************************************************************************/
int the_function_starts_here(int value) 
{
  ...
}

- One line comments. Comments should be indented correctly and 
  placed above the code being commented upon:

  int x;

  /* I am a single line comment */
  x = 3;

- Multiline comments. Asterisks should be placed in front of the 
  comment line like so:

  /* I am a multiline
   * comment, blah 
   * blah blah */

- Comments in declarations. If you need to comment a declared variable,
  it should be as such:

  struct foo {
    int bar;                    /* bar is used for ....
                                 * in ..... way */
    int blah;                   /* blah is used for .... */
  };

- Comments in conditionals. If you need a comment to show program flow,
  it should be below the if or else:

  if(is_barbarian(pplayer)) {
    x++;
  } else {
    /* If not barbarian, ... */
    x--;
  }

- Comments to translators are stored before the N_(), _() or Q_() marked
  string, and are preceded by "TRANS:".  These comments are copied to the
  translators file.  Use them whenever you think the translators may need
  some more information:

    /* TRANS: Don't translate "commandname". */
    printf(_("commandname <arg> [-o <optarg>]"));

================================
 Declaring variables
================================

- Variables can be initialized as soon as they're declared:

int foo(struct unit *punit)
{
  int x = punit->x;
  int foo = x;
  char *blah;

  ...
}

- After variables are declared, there should be an empty line before the
  rest of the function body.

- Merging declarations. Variables do not have to be declared one per line;
  however, they should only be grouped by similar function.

int foo(struct city *pcity)
{
  int i, j, k;
  int total, cost;
  int build = pcity->shield_stock;
}

================================
 Bracing
================================

- Extra braces on iterates. Note that the *_iterate_end; should be placed 
  on the same line as the end brace:

  unit_list_iterate(pcity->units_supported, punit) {
    kill(punit);
  } unit_list_iterate_end;

- In switch statements, braces should only be placed where needed, i.e. to
  protect local variables.

- Braces shall be used after conditionals:

  if (x == 3) {
    return;
  }

 and 

  if (x == 3) {
    return 1;
  } else {
    return 0;
  }

 not

  if (x == 3)
    return 1;  /* BAD! */

================================
 Other stuff
================================

- If an empty block is needed you should put an explanatory comment in
  an empty block (i.e. {}):

  while(*i++) {
    /* nothing */
  }

- Order include files consistently:  First state all system include
  files with <> in alphabetic order, then all Freeciv include files
  with "", sorted by directory (common, server, ...) and then by
  alphabetic order, with a blank line between the sections.  This helps
  to avoid adding unnecessary or duplicated include files.

- If you use a system specific feature, don't add #ifdef __CRAY__ or
  something like that.  Rather write a check for that feature for
  both configure.in and configure.ac, and use a meaningful macro name 
  in the source.

- Always prototype global functions in the appropriate header file.
  Local functions should always be declared as static. To catch and
  some other problems please use the following warning options "-Wall
  -Wpointer-arith -Wcast-align -Wmissing-prototypes -Wmissing-declarations 
  -Wstrict-prototypes -Wnested-externs" if you use gcc.

- If you send patches, use "diff -u" (or "diff -r -u", or "cvs diff -u").
  For further information, see <http://www.freeciv.org/contribute.html>.
  Also, name patch files descriptively (e.g. "fix-foo-bug-0.diff" is good,
  but "freeciv.diff" is not).

- When doing a "diff" for a patch, be sure to exclude unnecessary files
  by using the "-X" argument to "diff".  E.g.:

    % diff -ruN -Xdiff_ignore freeciv_cvs freeciv >/tmp/fix-foo-bug-0.diff

  A suggested "diff_ignore" file is included in the Freeciv distribution.

===========================================================================
