blob: 9ea2360241d68d5e79d56688f75b0f79a5fc4115 [file] [log] [blame]
Mark Whitley40bfc762000-07-24 22:36:06 +00001Busybox Style Guide
2===================
3
4This document describes the coding style conventions used in Busybox. If you
5add a new file to Busybox or are editing an existing file, please format your
6code according to this style. If you are the maintainer of a file that does
7not follow these guidelines, please -- at your own convenience -- modify the
8file(s) you maintain to bring them into conformance with this style guide.
9Please note that this is a low priority task.
10
11To help you format the whitespace of your programs, an ".indent.pro" file is
12included in the main Busybox source directory that contains option flags to
13format code as per this style guide. This way you can run GNU indent on your
14files by typing 'indent myfile.c myfile.h' and it will magically apply all the
15right formatting rules to your file. Please _do_not_ run this on all the files
16in the directory, just your own.
17
Mark Whitley2368a382000-08-22 00:20:21 +000018
Mark Whitleyd58ff872000-11-22 19:25:39 +000019
Mark Whitley40bfc762000-07-24 22:36:06 +000020Declaration Order
21-----------------
22
23Here is the order in which code should be laid out in a file:
24
Mark Whitley9028e2c2000-11-17 21:28:39 +000025 - commented program name and one-line description
Mark Whitley40bfc762000-07-24 22:36:06 +000026 - commented author name and email address(es)
27 - commented GPL boilerplate
Mark Whitley9028e2c2000-11-17 21:28:39 +000028 - commented longer description / notes for the program (if needed)
Mark Whitley40bfc762000-07-24 22:36:06 +000029 - #includes and #defines
Mark Whitley9028e2c2000-11-17 21:28:39 +000030 - const and global variables
Mark Whitley40bfc762000-07-24 22:36:06 +000031 - function declarations (if necessary)
32 - function implementations
33
Mark Whitley2368a382000-08-22 00:20:21 +000034
Mark Whitleyd58ff872000-11-22 19:25:39 +000035
36Whitespace and Formatting
37-------------------------
Mark Whitley40bfc762000-07-24 22:36:06 +000038
Mark Whitley2368a382000-08-22 00:20:21 +000039This is everybody's favorite flame topic so let's get it out of the way right
40up front.
41
42
Mark Whitley9028e2c2000-11-17 21:28:39 +000043Tabs vs. Spaces in Line Indentation
Mark Whitleyd58ff872000-11-22 19:25:39 +000044~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mark Whitley2368a382000-08-22 00:20:21 +000045
46The preference in Busybox is to indent lines with tabs. Do not indent lines
47with spaces and do not indents lines using a mixture of tabs and spaces. (The
48indentation style in the Apache and Postfix source does this sort of thing:
49\s\s\s\sif (expr) {\n\tstmt; --ick.) The only exception to this rule is
50multi-line comments that use an asterisk at the beginning of each line, i.e.:
Mark Whitley40bfc762000-07-24 22:36:06 +000051
52 /t/*
53 /t * This is a block comment.
54 /t * Note that it has multiple lines
55 /t * and that the beginning of each line has a tab plus a space
56 /t * except for the opening '/*' line where the slash
57 /t * is used instead of a space.
58 /t */
59
60Furthermore, The preference is that tabs be set to display at four spaces
61wide, but the beauty of using only tabs (and not spaces) at the beginning of
Mark Whitley9028e2c2000-11-17 21:28:39 +000062lines is that you can set your editor to display tabs at *whatever* number of
Mark Whitley40bfc762000-07-24 22:36:06 +000063spaces is desired and the code will still look fine.
64
65
Mark Whitley2368a382000-08-22 00:20:21 +000066Operator Spacing
67~~~~~~~~~~~~~~~~
68
69Put spaces between terms and operators. Example:
Mark Whitley40bfc762000-07-24 22:36:06 +000070
71 Don't do this:
72
73 for(i=0;i<num_items;i++){
74
75 Do this instead:
76
77 for (i = 0; i < num_items; i++) {
78
79 While it extends the line a bit longer, the spaced version is more
80 readable. An allowable exception to this rule is the situation where
81 excluding the spacing makes it more obvious that we are dealing with a
Mark Whitley9028e2c2000-11-17 21:28:39 +000082 single term (even if it is a compound term) such as:
Mark Whitley40bfc762000-07-24 22:36:06 +000083
84 if (str[idx] == '/' && str[idx-1] != '\\')
85
86 or
87
88 if ((argc-1) - (optind+1) > 0)
89
90
Mark Whitley2368a382000-08-22 00:20:21 +000091Bracket Spacing
92~~~~~~~~~~~~~~~
93
94If an opening bracket starts a function, it should be on the
Mark Whitley9028e2c2000-11-17 21:28:39 +000095next line with no spacing before it. However, if a bracket follows an opening
Mark Whitley40bfc762000-07-24 22:36:06 +000096control block, it should be on the same line with a single space (not a tab)
Mark Whitley9028e2c2000-11-17 21:28:39 +000097between it and the opening control block statement. Examples:
Mark Whitley40bfc762000-07-24 22:36:06 +000098
99 Don't do this:
100
Mark Whitley9028e2c2000-11-17 21:28:39 +0000101 while (!done)
102 {
103
104 do
105 {
106
107 Don't do this either:
108
Mark Whitley40bfc762000-07-24 22:36:06 +0000109 while (!done){
110 do{
111
112 Do this instead:
113
114 while (!done) {
115 do {
116
Mark Whitley2368a382000-08-22 00:20:21 +0000117
118Paren Spacing
119~~~~~~~~~~~~~
120
121Put a space between C keywords and left parens, but not between
122function names and the left paren that starts it's parameter list (whether it
123is being declared or called). Examples:
124
125 Don't do this:
126
127 while(foo) {
128 for(i = 0; i < n; i++) {
129
130 Do this instead:
131
132 while (foo) {
133 for (i = 0; i < n; i++) {
134
Mark Whitley9028e2c2000-11-17 21:28:39 +0000135 But do functions like this:
Mark Whitley2368a382000-08-22 00:20:21 +0000136
137 static int my_func(int foo, char bar)
138 ...
139 baz = my_func(1, 2);
140
141
142Cuddled Elses
143~~~~~~~~~~~~~
144
Mark Whitley9028e2c2000-11-17 21:28:39 +0000145Also, please "cuddle" your else statements by putting the else keyword on the
146same line after the right bracket that closes an 'if' statement.
Mark Whitley40bfc762000-07-24 22:36:06 +0000147
148 Don't do this:
149
150 if (foo) {
151 stmt;
152 }
153 else {
154 stmt;
155 }
156
157 Do this instead:
158
159 if (foo) {
160 stmt;
161 } else {
162 stmt;
163 }
164
Mark Whitley9028e2c2000-11-17 21:28:39 +0000165The exception to this rule is if you want to include a comment before the else
166block. Example:
167
168 if (foo) {
169 stmts...
170 }
171 /* otherwise, we're just kidding ourselves, so re-frob the input */
172 else {
173 other_stmts...
174 }
175
Mark Whitley40bfc762000-07-24 22:36:06 +0000176
Mark Whitleyd58ff872000-11-22 19:25:39 +0000177
Mark Whitley40bfc762000-07-24 22:36:06 +0000178Variable and Function Names
179---------------------------
180
181Use the K&R style with names in all lower-case and underscores occasionally
Mark Whitley9028e2c2000-11-17 21:28:39 +0000182used to separate words (e.g., "variable_name" and "numchars" are both
Mark Whitley40bfc762000-07-24 22:36:06 +0000183acceptable). Using underscores makes variable and function names more readable
184because it looks like whitespace; using lower-case is easy on the eyes.
185
186Note: The Busybox codebase is very much a mixture of code gathered from a
Mark Whitley9028e2c2000-11-17 21:28:39 +0000187variety of sources. This explains why the current codebase contains such a
188hodge-podge of different naming styles (Java, Pascal, K&R, just-plain-weird,
Mark Whitley40bfc762000-07-24 22:36:06 +0000189etc.). The K&R guideline explained above should therefore be used on new files
190that are added to the repository. Furthermore, the maintainer of an existing
Mark Whitley9028e2c2000-11-17 21:28:39 +0000191file that uses alternate naming conventions should -- at his own convenience --
192convert those names over to K&R style; converting variable names is a very low
193priority task. Perhaps in the future we will include some magical Perl script
194that can go through and convert files -- left as an exercise to the reader for
195now.
Mark Whitley40bfc762000-07-24 22:36:06 +0000196
197
Mark Whitley40bfc762000-07-24 22:36:06 +0000198
Mark Whitleyd58ff872000-11-22 19:25:39 +0000199Avoid The Preprocessor
200----------------------
Mark Whitley40bfc762000-07-24 22:36:06 +0000201
Mark Whitleyd58ff872000-11-22 19:25:39 +0000202At best, the preprocessor is a necessary evil, helping us account for platform
203and architecture differences. Using the preprocessor unnecessarily is just
204plain evil.
Mark Whitley2368a382000-08-22 00:20:21 +0000205
Mark Whitley40bfc762000-07-24 22:36:06 +0000206
Mark Whitleyd58ff872000-11-22 19:25:39 +0000207The Folly of #define
208~~~~~~~~~~~~~~~~~~~~
Mark Whitley40bfc762000-07-24 22:36:06 +0000209
Mark Whitleyd58ff872000-11-22 19:25:39 +0000210Use 'const <type> var' for declaring constants.
Mark Whitley40bfc762000-07-24 22:36:06 +0000211
212 Don't do this:
213
Mark Whitleyd58ff872000-11-22 19:25:39 +0000214 #define var 80
215
216 Do this instead, when the variable is in a header file and will be used in
217 several source files:
218
219 const int var = 80;
220
221 Or do this when the variable is used only in a single source file:
222
223 static const int var = 80;
224
225Declaring variables as '[static] const' gives variables an actual type and
226makes the compiler do type checking for you; the preprocessor does _no_ type
227checking whatsoever, making it much more error prone. Declaring variables with
228'[static] const' also makes debugging programs much easier since the value of
229the variable can be easily queried and displayed.
230
231
232The Folly of Macros
233~~~~~~~~~~~~~~~~~~~
234
235Use 'static inline' instead of a macro.
236
237 Don't do this:
238
239 #define mini_func(param1, param2) (param1 << param2)
Mark Whitley40bfc762000-07-24 22:36:06 +0000240
241 Do this instead:
242
Mark Whitleyd58ff872000-11-22 19:25:39 +0000243 static inline int mini_func(int param1, param2)
Mark Whitley40bfc762000-07-24 22:36:06 +0000244 {
Mark Whitleyd58ff872000-11-22 19:25:39 +0000245 return (param1 << param2);
246 }
Mark Whitley40bfc762000-07-24 22:36:06 +0000247
Mark Whitleyd58ff872000-11-22 19:25:39 +0000248Static inline functions are greatly preferred over macros. They provide type
249safety, have no length limitations, no formatting limitations, and under gcc
250they are as cheap as macros. Besides, really long macros with backslashes at
251the end of each line are ugly as sin.
252
253
254The Folly of #ifdef
255~~~~~~~~~~~~~~~~~~~
256
257Code cluttered with ifdefs is difficult to read and maintain. Don't do it.
258Instead, put your ifdefs in a header, and conditionally define 'static inline'
259functions, (or *maybe* macros), which are used in the code.
260
261 Don't do this:
262
263 ret = my_func(bar, baz);
264 if (!ret)
265 return -1;
266 #ifdef BB_FEATURE_FUNKY
267 maybe_do_funky_stuff(bar, baz);
268 #endif
269
270 Do this instead:
271
272 (in .h header file)
273
274 #ifndef BB_FEATURE_FUNKY
275 static inline void maybe_do_funky_stuff (int bar, int baz) {}
276 #endif
277
278 (in the .c source file)
279
280 ret = my_func(bar, baz);
281 if (!ret)
282 return -1;
283 maybe_do_funky_stuff(bar, baz);
284
285The great thing about this approach is that the compiler will optimize away
286the "no-op" case when the feature is turned off.
287
288Note also the use of the word 'maybe' in the function name to indicate
289conditional execution.
290
291
292
293Notes on Strings
294----------------
295
296Strings in C can get a little thorny. Here's some guidelines for dealing with
297strings in Busybox. (There is surely more that could be added to this
298section.)
299
300
301String Files
302~~~~~~~~~~~~
303
304Put all help/usage messages in usage.c. Put other strings in messages.c.
305Putting these strings into their own file is a calculated decision designed to
306confine spelling errors to a single place and aid internationalization
307efforts, if needed. (Side Note: we might want to use a single file - maybe
308called 'strings.c' - instead of two, food for thought).
309
310
311Testing String Equivalence
312~~~~~~~~~~~~~~~~~~~~~~~~~~
313
314There's a right way and a wrong way to test for sting equivalence with
315strcmp():
316
317 The wrong way:
318
319 if (!strcmp(string, "foo")) {
320 ...
321
322 The right way:
323
324 if (strcmp(string, "foo") == 0){
325 ...
326
327The use of the "equals" (==) operator in the latter example makes it much more
328obvious that you are testing for equivalence. The former example with the
329"not" (!) operator makes it look like you are testing for an error. In a more
330perfect world, we would have a streq() function in the string library, but
331that ain't the world we're living in.
332
333
334
335Miscellaneous Coding Guidelines
336-------------------------------
337
338The following are important items that don't fit into any of the above
339sections.
340
341
342Model Busybox Applets After GNU Counterparts
343~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
344
345When in doubt about the proper behavior of a Busybox program (output,
346formatting, options, etc.), model it after the equivalent GNU program.
347Doesn't matter how that program behaves on some other flavor of *NIX; doesn't
348matter what the POSIX standard says or doesn't say, just model Busybox
349programs after their GNU counterparts and nobody has to get hurt.
350
351The only time we deviate from emulating the GNU behavior is when:
352
353 - We are deliberately not supporting a feature (such as a command line
354 switch)
355 - Emulating the GNU behavior is prohibitively expensive (lots more code
356 would be required, lots more memory would be used, etc.)
357 - The differce is minor or cosmetic
358
359A note on the 'cosmetic' case: Output differences might be considered
360cosmetic, but if the output is significant enough to break other scripts that
361use the output, it should really be fixed.
362
363
364Scope
365~~~~~
366
367If a const variable is used only in a single source file, put it in the source
368file and not in a header file. Likewise, if a const variable is used in only
369one function, do not make it global to the file. Instead, declare it inside
370the function body. Bottom line: Make a concious effort to limit declarations
371to the smallest scope possible.
372
373Inside applet files, all functions should be declared static so as to keep the
374global name space clean. The only exception to this rule is the "applet_main"
375function which must be declared extern.
376
377If you write a function that performs a task that could be useful outside the
378immediate file, turn it into a general-purpose function with no ties to any
379applet and put it in the utility.c file instead.
380
381
382Brackets Are Your Friends
383~~~~~~~~~~~~~~~~~~~~~~~~~
384
385Please use brackets on all if and else statements, even if it is only one
386line. Example:
Mark Whitley40bfc762000-07-24 22:36:06 +0000387
388 Don't do this:
389
390 if (foo)
391 stmt;
392 else
393 stmt;
394
395 Do this instead:
396
397 if (foo) {
398 stmt;
399 } else {
400 stmt;
401 }
402
Mark Whitleyd58ff872000-11-22 19:25:39 +0000403The "bracketless" approach is error prone because someday you might add a line
404like this:
Mark Whitley40bfc762000-07-24 22:36:06 +0000405
406 if (foo)
407 stmt;
408 new_line();
409 else
410 stmt;
411
Mark Whitleyd58ff872000-11-22 19:25:39 +0000412And the resulting behavior of your program would totally bewilder you. (Don't
413laugh, it happens to us all.) Remember folks, this is C, not Python.
414
415
416Function Declarations
417~~~~~~~~~~~~~~~~~~~~~
418
419Do not use old-style function declarations that declare variable types between
420the parameter list and opening bracket. Example:
421
422 Don't do this:
423
424 int foo(parm1, parm2)
425 char parm1;
426 float parm2;
427 {
428 ....
429
430 Do this instead:
431
432 int foo(char parm1, float parm2)
433 {
434 ....
435
436The only time you would ever need to use the old declaration syntax is to
437support ancient, antedeluvian compilers. To our good fortune, we have access
438to more modern compilers and the old declaration syntax is neither necessary
439nor desired.
440