Initial commit of RMR Library
[ric-plt/lib/rmr.git] / src / STYLE
1
2 Coding conventions/style for the ricmsg library.
3
4 Line width
5 A hard line width will not be enforced, but a soft maximum of 150
6 characters is preferred.
7
8
9 Indention
10 Indention is with TABS. Tab width is 4. Please ensure the line
11                 // :vi ts=4 sw=4 noet:
12 is include in any new source file.
13         
14
15 Comments
16 A "two column" approach is preferred so as to prevent small comments from
17 disrupting the "flow" of the logic; for example:
18
19         switch( *(tokens[0]) ) {
20                 case 'n':                                                                                               // newrt|{start|end}
21                         if( strcmp( tokens[1], "end" ) == 0 ) {                         // wrap up the table we were building
22                                 if( nrt ) {
23                                         uta_rt_drop( ctx->old_rtable );                         // time to drop one that was previously replaced
24                                         ctx->old_rtable = ctx->rtable;                          // currently active becomes old and allowed to 'drain'
25                                         ctx->rtable = nrt;                                                      // one we've been adding to becomes active
26                                         nrt = NULL;
27                                 } else {
28                                         nrt = NULL;
29                                 }
30                         } else {                                                                                        // start a new table.
31                                 if( nrt != NULL ) {                                                             // one in progress?  this forces it out
32                                         uta_rt_drop( nrt );
33                                 }       
34
35 Comment Blocks
36 Major sections of code may be commented with multi-line blocks. These comments
37 should be enclosed in /* and */, indented to match the current top line of the block.
38 Each line should NOT contain a leading * or #, and a row of dashes at the top
39 and bottom should only be used for critical comments.  For example:
40
41         /*
42                 Return true if routing table is initialised etc. and app can send/receive.
43         */
44
45 Function Headers
46 All functions should have a header comment block which describes:
47         - the purpose of the function
48         - any non-obvious parameters
49         - parameter limits/values where applicable
50         - general caution or warning statement to future programmers
51
52
53 Parenthesess and Brackets
54 When parentheses are used on function calls, if and while statements, there should be
55 a single space between the opening paraen and first token, and a similar space 
56 between the end of the last token and the closing paren; this makes the code easier
57 to read in a monochrome environment. 
58
59 Parentheses used for expressions and type casting should abutt the tokens in the expression, 
60 and further helps to make the code readable when an expression is used in an if/while. 
61 To illustrate:
62
63         if( (ctx = (uta_ctx_t *) vctx) == NULL ) {              // this is readable
64         if((ctx=(uta_ctx_t *)vctx) == NULL) {                   // this is not
65
66 Opening parens should NOT be separated from the function or keyword token; 'if(' not 
67 'if ('.
68
69 Return is NOT a function, and thus the return value should NOT be placed in parens.
70
71
72 Curly Brace Enclosed Blocks
73 Go's enforced curly brace policy actually makes senes, so that is used here. The bodies 
74 of ALL if statements, even when just a single line, are to be enclosed in curly braces. 
75 Further, curly braces are placed on the same line as the if and else tokens.  The final 
76 closing curly brace is aligned with the corresponding if. For example:
77
78         if( key_len < 10 ) {                                    // TESTING -- use dummy seed function as nn_rcv likley never to find a publisher
79                 mlen = dummy_nn_rtg_rcv( mbuf );        // TESTING ONLY -- get a seed table
80                 key_len = 16;                                           // after seeding, we can wait
81         } else {
82         mlen = nn_recv( nn_sock, mbuf, sizeof( mbuf )-1, 0 );           // blocks until next buffer
83         }
84
85 Functions
86 Function types should be placed on the same line as the function name as this allows
87 for simple generation of prototype statements in the header files.
88
89 Variable Declaration and Type Specification
90 C's variable declaration opens the programmer to a world of accdental maintence bugs
91 when multple varlables are defined using a comma operator.  Therefore, one variable 
92 definition, per line is to be used here.  Further, pointer types are to be declared 
93 as 'type* var'  rather than 'type *var' because the variable type is a pointer and
94 declaring it this way envforces it.  Yes, this can lead to issues as 'int* k,n'
95 isn't what you probalby want, but is exactly why using multiple declarations on a
96 single line is considered bad.  Again, Go's approach to variable declaration got 
97 this correct.
98
99 When declaring types (typedef) the preferred convention is to add "_t" to the type 
100 name; e.g. msg_t.   On the other hand, variable names should NOT indicate the type
101 (state_b is wrong as state might not always be boolean).
102
103 All variables for a function should be declared at the TOP of the function. This makes
104 maintenence easier, and modern compilers are good at allocating variables as they 
105 enter/leave scope, so there is no reason to allocate variables "script style".
106 It is also wise to initialise all variables at allocation; use your best judgement.
107
108 Camel Case
109 Sucks; use underbars.  
110         This_is_easy_to_read
111         ThisIsNotEasyToRead
112
113 External names and contants
114 All outward facing external names and constants will begin with rmr_ or RMR_ as approprate.
115
116
117 Mk and Makefile confentions
118 Not much here other than there should be 2 "cleanup" rules: clean and nuke. Clean should
119 remove all intermediate files, leaving desired output (libraries, .ps or .pdf files). The
120 nuke rule should remove everything that can be built including libraries, binaries, .pdf
121 files etc.
122
123 Mk is preferred as the recipes are easier to define and maintain (no silly end of line
124 continuation, mkfile variables are passed, etc.).  However, both mkfiles and Makefiles 
125 should be created so as not to require mk.  Yes this is duplicate work, and dropping 
126 make support is certainly acceptable :)