Mercurial > ~dholland > hg > ag > index.cgi
diff doc/devel/style.txt @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children | 12171da8943f |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/devel/style.txt Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,216 @@ +Style guidelines for AnaGram source +----------------------------------- + +Purpose: + + These guidelines are *guidelines*, not commandments. Legibility and + maintainability are more important than mindless adherence to + regulations. + + Note: patches that reindent or reformat will be rejected. Patches + whose only purpose is to reindent or reformat will be rejected + extra-fast. If you think a section of code needs reformatting, + write a message saying so and explain your reasoning. Illegibility + and violation of the principle of least surprise are good reasons. + Lack of strict conformance to these guidelines is not. + + Note: some source files have DOS-style end of line (CR/LF) and + others have Unix-style end of line (just LF) - for the most part + this should be transparent. So leave things the way they are in + this regard. + +Basic layout guidelines, in order of decreasing generality: + + - 2-space indent. + - Lines do not exceed 79 columns. + - Don't indent preprocessor directives. + - In a multi-line /* */ comment, the beginning and ending tokens + get their own lines, and all the stars should line up. + - Left braces go at the end of the line. + - Right braces get their own line. + - 'else' starts a new line. + - Use braces with if, else, while, do/while, and for. + - If violating the previous rule, always put the subordinate + statement on the same line. + - Violate said rule for conciseness only when: + - a single if (no else) has a very short conditional and a + very short subordinate statement; + - a while statement ditto; + - or a for statement has no body. + - Never violate said rule for a do/while statement. + - Put the while part of a do/while statement on the same line as + the closing brace, to keep them from getting separated. + - Switch case labels should be indented two spaces, and code + indented two spaces further. + - Each switch case label should get its own line. + - Switch code should not be on the same line as a switch case. + - Condensed switches (one line total per case) should only be used + if all or nearly all the switch can be formatted thus and some + benefit to legibility accrues. + - Infinite loops should be written as "while (1)", not "for (;;)". + +Please do not: + + - Misgroup tokens when declaring pointers. "char* s" is wrong. It + should be "char *s". + - Write your comparisons backwards. "if (0 == x)" is really + unnatural to read. + - Leave off the space after while, for, and if, or, conversely, + insert a space between a function name and its arguments. while, + for, and if are not functions. + - Use gratuitous parentheses with return to make it look like a + function call. + + +Include files: + + - Include files should be grouped in this order: + - standard C includes + - OS, compiler, or GUI-specific includes + - AG's own includes + + - Within these groupings, headers should appear in alphabetical + order. (Why...? Why not?) + + - Exceptions: any <sys/*.h> should come before other standard + headers. And if any <sys/*.h> are used, <sys/types.h> should come + first. Also, "pf.h" should be included after any standard headers. + + - Further exceptions: AG's log header should come last, and should + be preceded by a commented-out "#define INCLUDE_LOGGING". + Examples abound. + + - To the extent practical, don't use (even within AG_ON_UNIX) + header files that aren't standard or standardish Unix, or that + would require build-time tests in the configure script to make + work right. + + - Each AG header file should be idempotent, that is, a source file + that just includes it should be compilable and its compilation + should not be affected by whether other headers have been + included or in what order. + + - Each header should have an #ifndef guard in the standard form to + protect against repeated inclusion. + + - Do not use the standard <assert.h> within AG - only use AG's own + "assert.h". + + +ifdefs: + + - Use #ifdef AG_ON_UNIX and #ifdef AG_ON_WINDOWS for + platform-specific code. Don't use compiler ifdefs for this; + in the long run compilers are more portable than you think. + + - Don't use #ifndef AG_ON_UNIX or #ifndef AG_ON_WINDOWS, unless + it's to issue a #error. + + - Don't use #if defined() in place of #ifdef. + + - Do mark #endifs with the symbol from their matching #ifdef, + #ifndef, or #if, unless that directive is only a few lines above + and easily recognizable. + + - Use compiler-specific ifdefs only where you have to. If possible, + abstract the construct out to minimize the amount of conditional + code. + + - If a compiler doesn't have a well-known, safe, and/or easily + recognizable symbol to #ifdef on, adjust the makefiles to set + one when that compiler is used, rather than litter the code with + possibly flaky ifdefs. + + - Don't use processor-specific ifdefs. Write portable code. + + +C++ language restrictions: + + - Do not use STL headers. + + - Do not use << >> operators for I/O. + + - Declare functions with no arguments as explicitly taking void, + like you would in C. + + - Don't do wild things with templates. + + - Don't do "for (int i=0; ...)" - we have a compiler that uses the + really old scoping semantics for this. + + - Use your common sense. Neither the language nor compiler has any. + + +Portability concerns: + + - When using fopen, always use "b" with binary files. Don't use "t" + for text files, as this is nonstandard and at least one Windows + compiler's library objects to it. + + - When using open(), always use either O_BINARY or O_TEXT. + + - The proper type associated with strlen() and sizeof() is size_t. + Don't use "int" or "unsigned". The signed return value of Unix + read() and write() has type "ssize_t". Cast that back to size_t + after checking it for being an error return. + + - When using printf, don't use the C99 %-specifier for size_t; + always cast size_t to unsigned long and print with %lu. + + - Assume that time_t may be 64 bits wide, even on 32-bit platforms. + If you need to print one literally, use %lld and cast to long + long. + + - Don't assume that all pointers are the same size, or that + pointers are the same size as either int or long. + + - In the mainline AG code avoid using anything that might be + locale-dependent, as the user interface might have set some crazy + locale. + + - Don't blindly slice filename strings using path separator + characters. Use appropriate functions instead. And avoid slicing + filename strings unless necessary. + + - Always pull the name component out of a pathname before looking + for any filename suffix. Otherwise you lose on names like + "foo.d/bar". + + +Robustness concerns: + + - If you mean to fall through the bottom of a switch case (one that + has code) put /* FALLTHROUGH */ there. + + - If you have virtual functions in a class, declare the destructor + virtual too. + + - If you have functions in a class that are virtual because they're + declared that way by a base (ancestor) class, declare them + explicitly virtual yourself too. + + - Don't define virtual functions inline, unless there's no other + practical place to put the definition. + + - Use parentheses when mixing && and ||, or &, |, and ^, or in + other cases where operator precedence is easily confused. + + - If you need an assignment inside a conditional, wrap the + assignment in parentheses and an explicit comparison. (Not just + extra parentheses.) But don't do this unless there's a reason for + it. + + - If using qsort() from <stdlib.h>, be sure your compare function + only returns 0 for identical objects. If the objects aren't + identical, always pick *something* to distinguish by, so the sort + is deterministic. + + +Idioms: + + - YES: if (!strcmp(a, b)) + NO: if (strcmp(a, b) == 0) + + - YES: if (strcmp(a, b) != 0) + NO: if (strcmp(a, b)) +