[8769] | 1 | This document describes guidelines for code which is to be |
---|
| 2 | incorporated into the Athena source tree. Here are the areas covered: |
---|
| 3 | |
---|
[9541] | 4 | Conventions for C code |
---|
| 5 | Conventions for shell scripts |
---|
[9298] | 6 | Software engineering practices |
---|
[9301] | 7 | Symbol namespaces |
---|
[8769] | 8 | Portability considerations for code we maintain |
---|
| 9 | Portability considerations for code we release |
---|
| 10 | Portability considerations for code we get from third parties |
---|
| 11 | |
---|
[9541] | 12 | Conventions for C code |
---|
| 13 | ---------------------- |
---|
[9298] | 14 | |
---|
| 15 | If you are working on an existing module which does not follow these |
---|
| 16 | conventions, be consistent with the existent source code rather than |
---|
| 17 | these conventions. |
---|
| 18 | |
---|
| 19 | You should follow the section on "Writing C" in the Gnu coding |
---|
| 20 | standards (available in emacs info under "standards"), with the |
---|
| 21 | following changes: |
---|
| 22 | |
---|
| 23 | * When making a function call, do not put a space before the |
---|
| 24 | open parenthesis. Do put spaces before the open parenthesis |
---|
| 25 | after "while", "if", or "for", though. |
---|
| 26 | |
---|
| 27 | * When defining a function, do not drop to the next line for |
---|
| 28 | the name of the function; put the function name on the same |
---|
| 29 | line as the return type. |
---|
| 30 | |
---|
[11778] | 31 | * Don't insert form feed characters into source files to |
---|
| 32 | divide programs into pages. |
---|
[9298] | 33 | |
---|
| 34 | * Ignore the sections on "Portability between System Types" |
---|
| 35 | and "Portability between CPUs"; see the sections on |
---|
| 36 | portability in this file instead. Also ignore the section |
---|
| 37 | on "Internationalization." |
---|
| 38 | |
---|
| 39 | * In the section "Calling System Functions," ignore everything |
---|
| 40 | about string functions. These days you can assume that |
---|
| 41 | using "#include <string.h>", strchr(), and strrchr() will |
---|
| 42 | work on just about all platforms. |
---|
| 43 | |
---|
| 44 | You can use "M-x set-c-style" "GNU" in emacs to have emacs take care |
---|
[11993] | 45 | of the gnu-style indentation for you. (This is the default on Athena |
---|
| 46 | if you haven't set it to something else in your .emacs.) Remember to |
---|
| 47 | drop to the next line before each open brace. |
---|
[9298] | 48 | |
---|
| 49 | When writing return statements, do not put parentheses around the |
---|
[12062] | 50 | return value; just write "return foo;". (This convention is not |
---|
[9298] | 51 | specified in the Gnu coding standards, but is consistent with the |
---|
[12062] | 52 | examples in the standards.) |
---|
[9298] | 53 | |
---|
[12062] | 54 | Put braces around the bodies of control constructs (if, while, for, |
---|
| 55 | do, switch) if they are more than one line long. |
---|
| 56 | |
---|
[9298] | 57 | Each C source file should begin with an MIT copyright statement, a |
---|
| 58 | comment describing what the file does, and a line: |
---|
| 59 | |
---|
[9541] | 60 | static char rcsid[] = "$Id$"; |
---|
[9298] | 61 | |
---|
| 62 | Each C header file should begin with: |
---|
| 63 | |
---|
[9541] | 64 | /* $Id$ */ |
---|
[9298] | 65 | |
---|
| 66 | followed by an MIT copyright statement and a comment describing what |
---|
[9541] | 67 | the file does. MIT copyright statements may be omitted for source |
---|
| 68 | code which is not distributed outside of MIT. |
---|
[9298] | 69 | |
---|
| 70 | The preferred convention for comments is |
---|
| 71 | |
---|
| 72 | /* comment text */ |
---|
| 73 | |
---|
| 74 | for one line comments, and |
---|
| 75 | |
---|
| 76 | /* comment text line 1 |
---|
| 77 | * comment text line 2 |
---|
| 78 | */ |
---|
| 79 | |
---|
[11993] | 80 | for multi-line comments. (To make "M-q" in Emacs leave the closing |
---|
| 81 | "*/" on a line by itself, set the variable c-hanging-comment-ender-p |
---|
| 82 | to nil.) As recommended in the Gnu coding standards, your comments |
---|
| 83 | should normally be complete, capitalized sentences ending with a |
---|
| 84 | period. |
---|
[9298] | 85 | |
---|
[9340] | 86 | Write prototypes for all of your functions. Include argument names in |
---|
| 87 | your prototypes, to help the reader understand what they mean. |
---|
| 88 | |
---|
[9541] | 89 | Conventions for shell scripts |
---|
| 90 | ----------------------------- |
---|
| 91 | |
---|
| 92 | Use /bin/sh to write shell scripts, not csh. |
---|
| 93 | |
---|
| 94 | Begin each shell script with: |
---|
| 95 | |
---|
| 96 | #!/bin/sh |
---|
| 97 | # $Id$ |
---|
| 98 | |
---|
| 99 | followed by an MIT copyright if the shell script will be distributed |
---|
| 100 | outside of MIT. |
---|
| 101 | |
---|
[14431] | 102 | Use two spaces for indentation. Avoid putting the result or |
---|
| 103 | alternative parts of an if statement on the same line as the "if" or |
---|
| 104 | "else". Avoid creating lines longer than 79 characters. Write case |
---|
| 105 | statements according to the format: |
---|
[9541] | 106 | |
---|
| 107 | case expression in |
---|
| 108 | pattern) |
---|
[18491] | 109 | statements |
---|
| 110 | ;; |
---|
[9541] | 111 | esac |
---|
| 112 | |
---|
| 113 | Environment variable names should be in all capitals; shell variable |
---|
| 114 | names should be in all lowercase. Avoid writing ${varname} for |
---|
| 115 | variable expansion except when necessary; just write $varname. In |
---|
| 116 | most cases, if you intend to expand a variable as a single word, you |
---|
[13158] | 117 | should write "$varname" with double quotes. This is not necessary in |
---|
| 118 | the switch expression of a case statement or in variable assignments, |
---|
| 119 | though. |
---|
[9541] | 120 | |
---|
[13158] | 121 | Test expressions in shell scripts can be a mine field of ungraceful |
---|
| 122 | failures if the variables being tested are empty, contain spaces or |
---|
[17738] | 123 | glob characters, or have a value of "!". To handle all such corner |
---|
[13158] | 124 | cases gracefully without adding unnecessary hair, use the following |
---|
| 125 | test expressions: |
---|
| 126 | |
---|
| 127 | To test if a variable is... Write |
---|
| 128 | --------------------------- ----- |
---|
| 129 | empty -z "$varname" |
---|
| 130 | non-empty -n "$varname" |
---|
[17738] | 131 | equal to a literal literal = "$varname" |
---|
| 132 | equal to another variable "x$varname" = "x$othervarname" |
---|
[13215] | 133 | set "${varname+set}" = set |
---|
| 134 | not set "${varname+set}" != set |
---|
[13158] | 135 | |
---|
[9298] | 136 | Software engineering practices |
---|
| 137 | ------------------------------ |
---|
| 138 | |
---|
| 139 | The following software engineering practices are strongly encouraged: |
---|
| 140 | |
---|
| 141 | * Restricting the operations which can access a given type of |
---|
[9572] | 142 | data object, and grouping them together. |
---|
[9298] | 143 | |
---|
| 144 | * Documenting data invariants (i.e. conditions on the |
---|
| 145 | representations of data objects which are assumed to always |
---|
| 146 | be true) and the meaning of data representations. |
---|
| 147 | |
---|
| 148 | * Documenting non-obvious requirements and effects of |
---|
| 149 | procedures. |
---|
| 150 | |
---|
| 151 | * Use of prototypes for all functions. |
---|
| 152 | |
---|
| 153 | * Automated testing of both program components ("unit |
---|
| 154 | testing") and whole programs ("integration testing"). |
---|
| 155 | |
---|
| 156 | The following software engineering practices are discouraged: |
---|
| 157 | |
---|
| 158 | * Use of global variables. Remember that the complexity of |
---|
| 159 | any function's interface is increased by the global |
---|
| 160 | variables it uses, even if that doesn't show up in the |
---|
| 161 | function prototype. Global variables are marginally |
---|
| 162 | acceptable to represent configuration parameters determined |
---|
| 163 | by command-line arguments or a configuration file, but even |
---|
[11778] | 164 | then it is preferable to find an alternative. |
---|
[9298] | 165 | |
---|
| 166 | * Use of global process state. You should avoid using |
---|
| 167 | alarm(), and you should avoid using getuid() or getenv() |
---|
| 168 | inside libraries or other "deep" interfaces. Code that uses |
---|
| 169 | global process state tends to interact poorly with other |
---|
| 170 | code in large programs. |
---|
| 171 | |
---|
[9301] | 172 | Symbol namespaces |
---|
| 173 | ----------------- |
---|
| 174 | |
---|
| 175 | If you are writing a library, you should pick a prefix for your |
---|
| 176 | library. You should ensure that all symbols which interact with the |
---|
| 177 | application's namespace (both at link time and on inclusion of the |
---|
| 178 | header file) begin with your prefix (or the all-caps form of your |
---|
| 179 | prefix, in the case of preprocessor symbols and enumeration constants) |
---|
| 180 | followed by an underscore. Symbols which are not intended for use by |
---|
[11778] | 181 | the application should begin with your prefix followed by two |
---|
[9301] | 182 | underscores. |
---|
| 183 | |
---|
| 184 | For instance, if your prefix is "hes", then functions exported to the |
---|
| 185 | user should begin with "hes_" (e.g. "hes_resolve"). Functions used |
---|
| 186 | internally by the library should begin with "hes__" |
---|
| 187 | (e.g. "hes__resolve" for the internal resolver function). |
---|
| 188 | Preprocessor symbols intended for use by the application should begin |
---|
| 189 | with "HES_" (e.g. "HES_ER_OK"); preprocessor symbols not intended for |
---|
| 190 | use by the application should begin with "HES__" (e.g. |
---|
| 191 | "HES__HESIOD_H", used to protect hesiod.h from multiple |
---|
| 192 | inclusion). |
---|
| 193 | |
---|
| 194 | Names of structures should begin with your prefix, but structure |
---|
| 195 | fields don't need to. Strictly speaking, structure fields interact |
---|
| 196 | with the user's namespace because the user might have "#define"'d them |
---|
| 197 | to something before including your header file, but applications |
---|
| 198 | generally shouldn't be "#define"ing lots of lowercase symbols, so this |
---|
| 199 | is not a real worry. |
---|
| 200 | |
---|
[8769] | 201 | Portability considerations for code we maintain |
---|
| 202 | ----------------------------------------------- |
---|
| 203 | |
---|
[9040] | 204 | In general, your code should assume a POSIX-compliant and ANSI |
---|
[9572] | 205 | C-compliant development environment, except to work around specific |
---|
| 206 | bugs in platforms we care about. |
---|
[8769] | 207 | |
---|
[9572] | 208 | You should use Autoconf to handle portability concerns; see the file |
---|
| 209 | "build-system" in this directory for how a package in the athena |
---|
| 210 | hierarchy should use autoconf. If you must perform an operating |
---|
| 211 | system test (because you are using a plain Makefile, typically for |
---|
| 212 | something in the packs hierarchy), do it in two steps; for instance: |
---|
[8769] | 213 | |
---|
| 214 | #define HAVE_STRERROR |
---|
[9460] | 215 | #if defined(sun) && !defined(SOLARIS) |
---|
[8769] | 216 | /* SunOS 4.1.3_U1 doesn't have strerror(). Use sys_errlist |
---|
| 217 | * instead. */ |
---|
| 218 | #undef HAVE_STRERROR |
---|
| 219 | #endif |
---|
| 220 | |
---|
| 221 | #ifndef HAVE_STRERROR |
---|
| 222 | extern const char *const sys_errlist[]; |
---|
| 223 | #define strerror(x) (sys_errlist[x]) |
---|
| 224 | #endif |
---|
| 225 | |
---|
| 226 | This way, if the source tree is ever converted to use feature tests, |
---|
| 227 | the person porting the code will know exactly what needs to be tested |
---|
| 228 | for. If you can anticipate the preprocessor symbol which would be |
---|
| 229 | used with Autoconf (as in this example), that's even better. Note |
---|
| 230 | particularly the comment instead the operating system test; it should |
---|
[9298] | 231 | specify: |
---|
[8769] | 232 | |
---|
| 233 | * What special consideration is needed for that operating |
---|
| 234 | system. |
---|
| 235 | |
---|
| 236 | * The version number of the operating system for which this |
---|
[9298] | 237 | approach was determined to be necessary. |
---|
[8769] | 238 | |
---|
| 239 | This will help future maintainers determine if one can eliminate the |
---|
| 240 | special consideration altogether when an OS upgrade has happened. |
---|
| 241 | |
---|
| 242 | Following is a list of appropriate preprocessor symbols to use to |
---|
[9460] | 243 | detect platforms we care about, when using plain Makefiles: |
---|
[8769] | 244 | |
---|
[9460] | 245 | SunOS: #if defined(sun) && !defined(SOLARIS) |
---|
[8769] | 246 | Solaris: #ifdef SOLARIS |
---|
| 247 | IRIX #ifdef sgi |
---|
| 248 | Linux: #ifdef linux |
---|
| 249 | NetBSD: #ifdef __NetBSD__ |
---|
| 250 | or #include <sys/param.h> and #ifdef BSD4_4 |
---|
| 251 | if applicable to all BSD 4.4 systems. |
---|
| 252 | |
---|
| 253 | SOLARIS is not automatically defined by the compiler on Solaris |
---|
[9460] | 254 | systems; we make sure it's defined when we build code not using |
---|
| 255 | autoconf. There are no reliable automatically defined constants for |
---|
| 256 | Solaris systems. |
---|
[8769] | 257 | |
---|
[11778] | 258 | For some highly non-portable operations you may need to do a platform |
---|
[9460] | 259 | test even when using Autoconf. In that case, use AC_CANONICAL_HOST |
---|
| 260 | rather than the above ifdefs. |
---|
| 261 | |
---|
[8769] | 262 | Portability considerations for code we release |
---|
| 263 | ---------------------------------------------- |
---|
| 264 | |
---|
[9298] | 265 | All of the standards in the previous section apply; however, we |
---|
| 266 | generally care about more platforms for code we release to the outside |
---|
| 267 | works. It is discouraged, but acceptable, to care about platforms |
---|
| 268 | which are not POSIX-compliant. Code that cares about such platforms |
---|
| 269 | should determine whether the platform supports POSIX interfaces by |
---|
| 270 | using AC_CHECK_HEADERS(unistd.h) to determine whether it can #include |
---|
[9460] | 271 | <unistd.h>, and then checking whether _POSIX_VERSION is defined. Such |
---|
| 272 | code should always use POSIX interfaces rather than less portable |
---|
| 273 | interfaces when they are available. |
---|
[8769] | 274 | |
---|
| 275 | Portability considerations for code we get from third parties |
---|
| 276 | ------------------------------------------------------------- |
---|
| 277 | |
---|
[9298] | 278 | The overriding principle for code obtained from third parties is to |
---|
| 279 | make as few changes as possible. A lot of third-party code has a very |
---|
| 280 | bad approach to portability, or cares about a lot of platforms we |
---|
| 281 | don't care about. You should attempt to follow the portability |
---|
| 282 | approach used by the rest of the program, such as it may be. Ideally, |
---|
| 283 | any changes you make should be made in such a manner that they can be |
---|
[8769] | 284 | incorporated into the source tree maintained by the third party. |
---|