|
| 1 | +Formatting rules for Motion code. |
| 2 | + |
| 3 | +Motion is coded in accordance with the K&R formatting style. Indentation is |
| 4 | +TAB based but done so that formatting never depends upon how a text editor or |
| 5 | +text viewer represents a TAB. |
| 6 | + |
| 7 | +Some people assume a tab is always at multiples of 8 positions, but many |
| 8 | +others choose to use 4 or 6. If the source file does not take this into |
| 9 | +consideration, the text alignment looks awful when viewed with a tab setting |
| 10 | +which differs from the original. |
| 11 | + |
| 12 | +We want to ensure that no matter which motion source file you look at, the |
| 13 | +style looks the same. In order to do that, the Motion project enforces some |
| 14 | +additional rules. |
| 15 | + |
| 16 | +Here are the basic rules. |
| 17 | + |
| 18 | +Note: To understand them you must view this document with spaces and tabs |
| 19 | +visible. |
| 20 | + |
| 21 | +-------------------- |
| 22 | +RULE 1 |
| 23 | +Code is generally indented using TABS |
| 24 | + |
| 25 | +Example1 |
| 26 | + |
| 27 | +/* allocate some memory and check if that succeeded or not. If it failed |
| 28 | + * do some error logging and bail out |
| 29 | + */ |
| 30 | +void * mymalloc(size_t nbytes) |
| 31 | +{ |
| 32 | + void *dummy = malloc(nbytes); |
| 33 | + if (!dummy) { |
| 34 | + printf("Could not allocate %llu bytes of memory!\n", (unsigned long long) nbytes); |
| 35 | + syslog(LOG_EMERG, "Could not allocate %llu bytes of memory!", (unsigned long long) nbytes); |
| 36 | + exit(1); |
| 37 | + } |
| 38 | + |
| 39 | + return dummy; |
| 40 | +} |
| 41 | + |
| 42 | +-------------------- |
| 43 | +RULE 2 |
| 44 | +If a line or statement is broken into two lines you will normally want the text |
| 45 | +in the 2nd line to align with text in the first line. This alignment must be |
| 46 | +done by following these rules: |
| 47 | + 1. On the continuation line, first you put tabs to reach the same |
| 48 | + indentation level as the line above. |
| 49 | + 2. Then you align with SPACES until the text in the 2nd line is aligned |
| 50 | + with the desired text above. |
| 51 | + |
| 52 | +Example 2 |
| 53 | +/* allocate some memory and check if that succeeded or not. If it failed |
| 54 | + * do some error logging and bail out |
| 55 | + */ |
| 56 | +void * mymalloc(size_t nbytes) |
| 57 | +{ |
| 58 | + void *dummy = malloc(nbytes); |
| 59 | + if (!dummy) { |
| 60 | + printf("Could not allocate %llu bytes of memory!\n", |
| 61 | + (unsigned long long) nbytes); |
| 62 | + syslog(LOG_EMERG, "Could not allocate %llu bytes of memory!", |
| 63 | + (unsigned long long) nbytes); |
| 64 | + exit(1); |
| 65 | + } |
| 66 | + |
| 67 | + return dummy; |
| 68 | +} |
| 69 | + |
| 70 | +Never do this: |
| 71 | +WRONG EXAMPLE |
| 72 | + printf("Could not allocate %llu bytes of memory!\n", |
| 73 | + (unsigned long long) nbytes); |
| 74 | + |
| 75 | +The reason is that the 3rd tab will be shown with whatever width is given by |
| 76 | +the editor or viewer. The result is that you never know where the text ends. |
| 77 | +The alignment of the text is very important for the readability of the code. |
| 78 | + |
| 79 | + |
| 80 | +GOOD EXAMPLE |
| 81 | + cnt->sql_mask = cnt->conf.sql_log_image * (FTYPE_IMAGE + FTYPE_IMAGE_MOTION) + |
| 82 | + cnt->conf.sql_log_snapshot * FTYPE_IMAGE_SNAPSHOT + |
| 83 | + cnt->conf.sql_log_mpeg * (FTYPE_MPEG + FTYPE_MPEG_MOTION) + |
| 84 | + cnt->conf.sql_log_timelapse * FTYPE_MPEG_TIMELAPSE; |
| 85 | + |
| 86 | +BAD EXAMPLE |
| 87 | + cnt->sql_mask = cnt->conf.sql_log_image * (FTYPE_IMAGE + FTYPE_IMAGE_MOTION) + |
| 88 | + cnt->conf.sql_log_snapshot * FTYPE_IMAGE_SNAPSHOT + |
| 89 | + cnt->conf.sql_log_mpeg * (FTYPE_MPEG + FTYPE_MPEG_MOTION) + |
| 90 | + cnt->conf.sql_log_timelapse * FTYPE_MPEG_TIMELAPSE; |
| 91 | + |
| 92 | + |
| 93 | +GOOD EXAMPLE |
| 94 | + char msg[] = "This is a very long message which we would like to break" |
| 95 | + "into two lines or more because otherwise the line gets" |
| 96 | + "too long to read. We align them below each other for readability" |
| 97 | + |
| 98 | +BAD EXAMPLE |
| 99 | + char msg[] = "This is a very long message which we would like to break" |
| 100 | + "into two lines or more because otherwise the line gets" |
| 101 | + "too long to read. We align them below each other for readability" |
| 102 | + |
| 103 | +Again, a different tab setting destroys alignment. |
| 104 | + |
| 105 | +-------------------- |
| 106 | +RULE 3 |
| 107 | +Never use TABS to align anything other than the start of line indentation. |
| 108 | + |
| 109 | +WRONG EXAMPLE |
| 110 | + * |
| 111 | + * cnt Pointer to the motion context structure |
| 112 | + * level logging level for the 'syslog' function |
| 113 | + * (-1 implies no syslog message should be produced) |
| 114 | + * errno_flag if set, the log message should be followed by the |
| 115 | + * error message. |
| 116 | + * fmt the format string for producing the message |
| 117 | + * ap variable-length argument list |
| 118 | + |
| 119 | +THE CORRECT WAY |
| 120 | + * |
| 121 | + * cnt Pointer to the motion context structure |
| 122 | + * level logging level for the 'syslog' function |
| 123 | + * (-1 implies no syslog message should be produced) |
| 124 | + * errno_flag if set, the log message should be followed by the |
| 125 | + * error message. |
| 126 | + * fmt the format string for producing the message |
| 127 | + * ap variable-length argument list |
| 128 | + |
| 129 | +Again the reason is that the aligment of the text when using tabs is |
| 130 | +depending on the tab settings in editor or viewer. |
| 131 | + |
| 132 | +BAD EXAMPLE |
| 133 | + |
| 134 | +void function_a(void someparam) |
| 135 | +{ |
| 136 | + int myvar1 /* explanation */ |
| 137 | + char hellomyvar2 /* explanation */ |
| 138 | + |
| 139 | +In this bad example the variable names will not align if the tab setting is |
| 140 | +not 8 positions. At 4 positions, for example, the variable names (as well as |
| 141 | +the comments) are no longer aligned. |
| 142 | + |
| 143 | +GOOD EXAMPLE |
| 144 | +void function_a(void someparam) |
| 145 | +{ |
| 146 | + int myvar1 /* explanation */ |
| 147 | + char hellomyvar2 /* explanation */ |
| 148 | + |
| 149 | +Don't try and align variables. It does not become very readable when one type |
| 150 | +is int and another is unsigned long long int. There is too much white space |
| 151 | +between a short type name and the variable name. Comments after the variable |
| 152 | +name look good, provided that you use spaces to align them. |
| 153 | + |
| 154 | +-------------------- |
| 155 | +RULE 4 |
| 156 | +Functions should be written with this syntax. |
| 157 | + |
| 158 | +GOOD EXAMPLE |
| 159 | +/* Comment block |
| 160 | + * A comment block should be at least one line saying what the function does. |
| 161 | + * It is better to make several lines explaining what it does, what it takes |
| 162 | + * for arguments and what it returns. It is a bad idea to try to use tabs to |
| 163 | + * align text in the comment block |
| 164 | + */ |
| 165 | +type function_name(parameters) |
| 166 | +{ |
| 167 | + declarations |
| 168 | + declarations |
| 169 | + |
| 170 | + statements |
| 171 | + statements |
| 172 | +} |
| 173 | + |
| 174 | +Do not split the function declaration into two lines. |
| 175 | +Do not put the '{' after the function declaration. Put it on an empty line |
| 176 | +right after. Note that this rule is only for functions. |
| 177 | + |
| 178 | +BAD EXAMPLE |
| 179 | + |
| 180 | +type |
| 181 | +function_name(parameters) { |
| 182 | + declarations |
| 183 | + declarations |
| 184 | + |
| 185 | + statements |
| 186 | + statements |
| 187 | +} |
| 188 | + |
| 189 | +-------------------- |
| 190 | +RULE 5 |
| 191 | +Blocks follow K&R. |
| 192 | +Kenneth Lavrsen actually hates the K&R syntax, but it is the most generally |
| 193 | +accepted way, it was the way Motion was coded when Kenneth took over the |
| 194 | +project and it is now the way in which we will continue. |
| 195 | + |
| 196 | +GOOD EXAMPLE |
| 197 | + |
| 198 | +if ((picture=fopen(cnt->conf.mask_file, "r"))) { |
| 199 | + cnt->imgs.mask=get_pgm(cnt, picture, cnt->imgs.width, cnt->imgs.height); |
| 200 | + fclose(picture); |
| 201 | +} else { |
| 202 | + put_fixed_mask(cnt, cnt->conf.mask_file); |
| 203 | + printf("Hello world\n"); |
| 204 | +} |
| 205 | + |
| 206 | + |
| 207 | +BAD EXAMPLE (even though Kenneth loves this one personally) |
| 208 | +if ((picture=fopen(cnt->conf.mask_file, "r"))) |
| 209 | +{ |
| 210 | + cnt->imgs.mask=get_pgm(cnt, picture, cnt->imgs.width, cnt->imgs.height); |
| 211 | + fclose(picture); |
| 212 | +} |
| 213 | +else |
| 214 | +{ |
| 215 | + put_fixed_mask(cnt, cnt->conf.mask_file); |
| 216 | + printf("Hello world\n"); |
| 217 | +} |
| 218 | + |
| 219 | +-------------------- |
| 220 | +RULE 6 |
| 221 | +Whitespace. |
| 222 | +To ensure that Motion code looks homogeneous and to enhance readability: |
| 223 | + 1. Do not use a space before a comma |
| 224 | + 2. Always leave at least one space after a comma |
| 225 | + 3. Use one space between a block start statement and a '{' |
| 226 | + 4. Do not use a space between a function name and the '(' |
| 227 | + 5. Use spaces to enhance readability (a non objective rule but at least |
| 228 | + think about it) |
| 229 | + 6. The '*' for pointers should be just before the variable name with no |
| 230 | + space. |
| 231 | + |
| 232 | +BAD EXAMPLES |
| 233 | +int function_name (int * par1 , int par2,int par3){ |
| 234 | +if (var1==2||var2==3){ |
| 235 | + |
| 236 | +GOOD EXAMPLES |
| 237 | +int function_name(int *par1, int par2, int par3) { |
| 238 | +if (var1==2 || var2==3) { |
| 239 | + |
| 240 | +-------------------- |
| 241 | +RULE 7 |
| 242 | +Comment your code |
| 243 | +That's worth repeating - PLEASE, PLEASE comment your code. |
| 244 | +We receive far too much code which is completely uncommented and where |
| 245 | +variable names are short and say nothing about their function. |
| 246 | +Use /* This style of comment for permament comments */ or |
| 247 | +/* |
| 248 | + * This style of comment for comments which |
| 249 | + * require more that one line |
| 250 | + */ |
| 251 | +Use // this style comments for something you add temporarily while testing and |
| 252 | +FIXME type comments. It is much easier to spot the temporary comments this way. |
| 253 | + |
| 254 | +-------------------- |
| 255 | +RULE 8 |
| 256 | +Use variable names that say what the variable is used for. |
| 257 | +Avoid x,t,vt type variable names. |
| 258 | +Use names like image, image_buffer, image_height, output_buffer |
| 259 | +Short names like i and j for loop index variable are a known good practice. |
| 260 | +Variable and function names are in lower case. Use '_' to separate words. |
| 261 | +MACROS are in uppercase. |
| 262 | +camelCase (mix of upper and lower case) is not allowed because it creates too |
| 263 | +many typos for many two finger typers. |
| 264 | + |
| 265 | + |
| 266 | +-------------------- |
| 267 | + |
| 268 | +BEST PRACTICES |
| 269 | +Not rules, but these suggestions make code easier to read. |
| 270 | + |
| 271 | +Use lots of white space and empty lines to group code. |
| 272 | +For example, large if statements are easier to read when there is an empty |
| 273 | +line before and after them. |
| 274 | + |
| 275 | +Use an empty line before a comment which describes the code lines below. |
| 276 | + |
| 277 | +Always use spaces in statements like |
| 278 | +thisvar->thismember>thisvar->thisothermember (bad) |
| 279 | +thisvar->thismember > thisvar->thisothermember (good) |
| 280 | + |
| 281 | +if (cnt->event_nr==cnt->prev_event||cnt->makemovie) (bad) |
| 282 | +if (cnt->event_nr == cnt->prev_event || cnt->makemovie) (good) |
| 283 | + |
| 284 | +frame_delay=(1000000L/cnt->conf.low_cpu)-frame_delay-elapsedtime; (bad) |
| 285 | +frame_delay = (1000000L/cnt->conf.low_cpu) - frame_delay - elapsedtime; (good) |
| 286 | + |
| 287 | + |
| 288 | +-------------------- |
| 289 | + |
| 290 | +This document can probably be enhanced more as time goes by. |
| 291 | +Hope it helps developers to understand the ideas. |
| 292 | + |
| 293 | +What happens if I do not follow the rules? |
| 294 | +Your code will probably be accepted, but Kenneth will have to spend a lot of |
| 295 | +time rewriting the code to follow the standard. If this happens, he may make |
| 296 | +a less-than-complimentary remark. Please help Kenneth by at least trying to |
| 297 | +follow the spirit of this document. We all have our coding preferences, but |
| 298 | +if Motion is coded in 40 different styles, readability (and at the end |
| 299 | +quality) will become bad. |
| 300 | + |
| 301 | + |
0 commit comments