Added info to changelog about bootroom update
[legacy-proxmark3.git] / HACKING.txt
blobfb68142e9897b78af2a42ca81634797efe42ea83
1         "Coding styles are like assholes, everyone has one and no one likes anyone elses."
2         --Eric Warmenhoven
4 The Proxmark3 codebase is pretty messy and in the process of being cleaned up,
5 so we don't have clear guidelines on how to place new code just yet. However,
6 please don't make things worse.
8 However, we have established a set of coding style guidelines in order to
9 clean up the code consistently and keep it consistent in the future. Use common
10 sense and good taste. If breaking a rule leads to cleaner code, you can do so,
11 but laziness is not an excuse.
13 === INDENTATION ===
15 Use tabs for indentation, but use spaces for alignment:
17         if (foo(this, that, there)
18             && bar == baz)
19         {
20                 dostuff();
21         }
23 Notice it's like this (T___ for tab, S for space, for a 4-char tab setting):
25 T___if (foo(this, that, there)
26 T___SSSS&& bar == baz)
28 Another example:
30 #define THIS            0x10
31 #define THAT_THING      0x20
32 #define SOMETHING_ELSE  0x80
34 These should look good no matter what your editor's tab setting is, so go nuts
35 and pick whatever you like best.
37 === WIDTH ===
39 Try to keep lines to a reasonable length. 80 characters is a good mark; using an
40 editor that shows a vertical line is a great idea. However, don't break a line
41 just because you're slightly over, it's not worth it. No 200-character lines,
42 though.
44 === MACROS ===
46 #defines, function-like or not, are all UPPERCASE unless you're emulating a
47 well-known function name.
49 === IDENTIFIERS ===
51 Functions, local variables, and arguments are all named using
52 underscores_as_spaces. Global variables are Evil and are prepended with g_ to
53 distinguish them. Avoid them.
55 Single-character variables are a bad idea. Exceptions: loop iterators and maybe
56 simple byte pointers (*p) in very obvious places. If you have more than one
57 such pointer, use a real name. If you have more than a couple nested loops,
58 complex logic, or indices that differ in interpretation or purpose, use real
59 names instead of i,j,k.
61 === DATA TYPES ===
63 Use stdint.h types (uint32_t and friends) unless you have a reason not to. Don't
64 use microsoft-style DWORD and the like, we're getting rid of those. Avoid char
65 for buffers, uint8_t is more obvious when you're not working with strings. Use
66 'const' where things are const. Try to use size_t for sizes.
68 Pointers are:
69         void *ptr;
70 not:
71         void* ptr;
72 otherwise you're tempted to write:
73         void* in, out;
74 and you'll fail.
76 === EXPRESSIONS ===
78 In general, use whitespace around binary operators - no unspaced blobs of an
79 expression. This rule may be broken if it makes things clearer. For example,
81         if (5*a < b && some_bool_var)
83 but not
85         if (5*a<b&&some_bool_var)
87 For equality with constants, use i == 0xF00, not 0xF00 == i. The compiler warns
88 you about = vs == anyway, and you shouldn't be screwing that one up by now
89 anyway.
91 === IF / FOR / WHILE / etc. ===
93 Put the opening brace on the same line, with a space before it. Exception: if
94 the if/for/while condition/whatever are split over several lines, it might be
95 more appealing to put the opening brace on its own line, so use your own
96 judgement there:
98         if (foo(this, that, there)
99             && bar == baz)
100         {
101                 dostuff();
102         }
104 If you do split the condition, put the binary operators that join the lines at
105 the beginning of the following lines (as above), not at the end of the prior
106 lines.
108 There should be a space between the construct name (if/for/whatever) and the
109 opening parenthesis, and there should be a space between the closing parenthesis
110 and the opening brace.
112 For generic for() iterator variables, declare them in-line:
114         for (int i = 0; i < 10; i++) {
115                 ...
116         }
118 Note the spaces after the semicolons.
120 if/else should be laid out as follows:
122         if (foo) {
123                 ...
124         } else if (bar) {
125                 ...
126         } else {
127                 ...
128         }
132         if (foo)
133                 ...
134         else if (bar)
135                 ...
136         else
137                 ...
139 Don't mix braces vs. no braces. If any of your bodies are > 1 line, put braces
140 around them all.
142 === FUNCTIONS ===
144 Functions with no arguments are declared as f(void), not f(). Put the return
145 type on the same line. Use static for functions that aren't exported, and put
146 exported functions in a header file (one header file per source file with
147 exported functions usually, no huge headers with all functions). Put a space
148 after a comma in argument lists.
150 void foo(int a_thing, int something_else)
152         ...
155 void baz(void)
157         foo(bluh, blah);
160 Function names should be separated_with_underscores(), except for standard
161 functions (memcpy, etc.). It may make sense to break this rule for very common,
162 generic functions that look like library functions (e.g. dprintf()).
164 Don't use single-character arguments. Exception: very short functions with one
165 argument that's really obvious:
167 static int ascii(char c)
169         if (c < 0x20 || c >= 0x7f)
170                 return '.';
171         else
172                 return c;
177 static void hexdump(void *buf, size_t len)
179         ...
182 As a general guideline, functions shouldn't usually be much more than 30-50
183 lines. Above, the general algorithm won't be easily apparent, and you're
184 probably missing some factoring/restructuring opportunity.
186 === STRUCTS / UNIONS / ENUMS ===
188 Use typedefs when defining structs. The type should be named something_t.
190 typedef struct {
191         blah blah;
192 } prox_cmd_t;
194 You can use anonymous enums to replace lots of sequential or mostly-sequential
195 #defines.
197 === SWITCH ===
199 Indent once for the case: labels, then again for the body. Like this:
201 switch(bar) {
202         case OPTION_A:
203                 do_stuff();
204                 break;
205         case OPTION_B:
206                 do_other_stuff();
207                 break;
210 If you fall through into another case, add an explicit comment; otherwise, it
211 can look confusing.
213 If your switch() is too long or has too many cases, it should be cleaned up.
214 Split off the cases into functions, break the switch() into parent and children
215 switches (e.g. command and subcommand), or use an array of function pointers or
216 the like. In other words, use common sense and your brain.
218 If you need local scope variables for a case, you can add braces:
220 switch(bar) {
221         case OPTION_A: {
222                 int baz = 5*bar;
223                 do_stuff(baz);
224                 break;
225         }
226         ...
228 But at that point you should probably consider using a separate function.
230 === COMMENTS ===
232 Use //, it's shorter:
234 // this does foo
237 // baz:
238 // This does blah blah blah .....
239 // blah blah...
241 /* */ can be used to comment blocks of code, but you should probably remove
242 them anyway - we have version control, it's easy to fetch old code if needed,
243 so avoid committing commented out chunks of code. The same goes for #if 0.
245 === FILE ===
247 Please use common sense and restrain yourself from having a thousands+++ line
248 file. Functions in a file should have something *specific* in common. Over time
249 sub-categories can arise and should therefore yield to file splitting.
251 For these reasons, vague and general filenames (e.g. util.*, global.*, misc.*,
252 main.*, and the like) should be very limited, if not prohibited.
254 === FILE HEADERS ===
256 License/description header first:
258 //-----------------------------------------------------------------------------
259 // YOUR COPYRIGHT LINE GOES HERE
261 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
262 // at your option, any later version. See the LICENSE.txt file for the text of
263 // the license.
264 //-----------------------------------------------------------------------------
265 // FILE DESCRIPTION GOES HERE
266 //-----------------------------------------------------------------------------
268 If you modify a file in any non-trivial way (add code, etc.), add your copyright
269 to the top.
271 === HEADER FILES ===
273 Use the following include guard format:
275 #ifndef FOOBAR_H__
276 #define FOOBAR_H__
280 #endif // FOOBAR_H__
282 Keep in mind that __FOOBAR_H would be reserved by the implementation and thus
283 you shouldn't use it (same for _FOOBAR_H).
285 === WHITESPACE ===
287 Avoid trailing whitespace (no line should end in tab or space). People forget
288 this all the time if their editor doesn't handle it, but don't be surprised if
289 you see someone fixing it from time to time.
291 Keep a newline (blank line) at the end of each file.