blob: 25c676ca22d511d6099b14e6aae30195ce3b779f [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 Whitley9ead6892001-03-03 00:44:55 +000029 - #includes of .h files with angle brackets (<>) around them
30 - #includes of .h files with quotes ("") around them
31 - #defines (if any, note the section below titled "Avoid the Preprocessor")
Mark Whitley9028e2c2000-11-17 21:28:39 +000032 - const and global variables
Mark Whitley40bfc762000-07-24 22:36:06 +000033 - function declarations (if necessary)
34 - function implementations
35
Mark Whitley2368a382000-08-22 00:20:21 +000036
Mark Whitleyd58ff872000-11-22 19:25:39 +000037
38Whitespace and Formatting
39-------------------------
Mark Whitley40bfc762000-07-24 22:36:06 +000040
Mark Whitley2368a382000-08-22 00:20:21 +000041This is everybody's favorite flame topic so let's get it out of the way right
42up front.
43
44
Mark Whitley9028e2c2000-11-17 21:28:39 +000045Tabs vs. Spaces in Line Indentation
Mark Whitleyd58ff872000-11-22 19:25:39 +000046~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mark Whitley2368a382000-08-22 00:20:21 +000047
48The preference in Busybox is to indent lines with tabs. Do not indent lines
49with spaces and do not indents lines using a mixture of tabs and spaces. (The
50indentation style in the Apache and Postfix source does this sort of thing:
51\s\s\s\sif (expr) {\n\tstmt; --ick.) The only exception to this rule is
52multi-line comments that use an asterisk at the beginning of each line, i.e.:
Mark Whitley40bfc762000-07-24 22:36:06 +000053
54 /t/*
55 /t * This is a block comment.
56 /t * Note that it has multiple lines
57 /t * and that the beginning of each line has a tab plus a space
58 /t * except for the opening '/*' line where the slash
59 /t * is used instead of a space.
60 /t */
61
62Furthermore, The preference is that tabs be set to display at four spaces
63wide, but the beauty of using only tabs (and not spaces) at the beginning of
Mark Whitley9028e2c2000-11-17 21:28:39 +000064lines is that you can set your editor to display tabs at *whatever* number of
Mark Whitley40bfc762000-07-24 22:36:06 +000065spaces is desired and the code will still look fine.
66
67
Mark Whitley2368a382000-08-22 00:20:21 +000068Operator Spacing
69~~~~~~~~~~~~~~~~
70
71Put spaces between terms and operators. Example:
Mark Whitley40bfc762000-07-24 22:36:06 +000072
73 Don't do this:
74
75 for(i=0;i<num_items;i++){
76
77 Do this instead:
78
79 for (i = 0; i < num_items; i++) {
80
81 While it extends the line a bit longer, the spaced version is more
82 readable. An allowable exception to this rule is the situation where
83 excluding the spacing makes it more obvious that we are dealing with a
Mark Whitley9028e2c2000-11-17 21:28:39 +000084 single term (even if it is a compound term) such as:
Mark Whitley40bfc762000-07-24 22:36:06 +000085
86 if (str[idx] == '/' && str[idx-1] != '\\')
87
88 or
89
90 if ((argc-1) - (optind+1) > 0)
91
92
Mark Whitley2368a382000-08-22 00:20:21 +000093Bracket Spacing
94~~~~~~~~~~~~~~~
95
96If an opening bracket starts a function, it should be on the
Mark Whitley9028e2c2000-11-17 21:28:39 +000097next line with no spacing before it. However, if a bracket follows an opening
Mark Whitley40bfc762000-07-24 22:36:06 +000098control block, it should be on the same line with a single space (not a tab)
Mark Whitley9028e2c2000-11-17 21:28:39 +000099between it and the opening control block statement. Examples:
Mark Whitley40bfc762000-07-24 22:36:06 +0000100
101 Don't do this:
102
Mark Whitley9028e2c2000-11-17 21:28:39 +0000103 while (!done)
104 {
105
106 do
107 {
108
109 Don't do this either:
110
Mark Whitley40bfc762000-07-24 22:36:06 +0000111 while (!done){
Mark Whitley925edb82001-02-03 00:20:14 +0000112
Mark Whitley40bfc762000-07-24 22:36:06 +0000113 do{
114
Mark Whitley3680c582000-12-20 22:35:12 +0000115 And for heaven's sake, don't do this:
116
117 while (!done)
118 {
Mark Whitley925edb82001-02-03 00:20:14 +0000119
Mark Whitley3680c582000-12-20 22:35:12 +0000120 do
121 {
122
Mark Whitley40bfc762000-07-24 22:36:06 +0000123 Do this instead:
124
125 while (!done) {
Mark Whitley925edb82001-02-03 00:20:14 +0000126
Mark Whitley40bfc762000-07-24 22:36:06 +0000127 do {
128
Mark Whitley2368a382000-08-22 00:20:21 +0000129
Mark Whitley925edb82001-02-03 00:20:14 +0000130Spacing around Parentheses
131~~~~~~~~~~~~~~~~~~~~~~~~~~
Mark Whitley2368a382000-08-22 00:20:21 +0000132
Mark Whitley7ddaf7c2001-03-14 21:04:53 +0000133Put a space between C keywords and left parens, but not between function names
134and the left paren that starts it's parameter list (whether it is being
135declared or called). Examples:
Mark Whitley2368a382000-08-22 00:20:21 +0000136
137 Don't do this:
138
139 while(foo) {
140 for(i = 0; i < n; i++) {
141
142 Do this instead:
143
144 while (foo) {
145 for (i = 0; i < n; i++) {
146
Mark Whitley9028e2c2000-11-17 21:28:39 +0000147 But do functions like this:
Mark Whitley2368a382000-08-22 00:20:21 +0000148
149 static int my_func(int foo, char bar)
150 ...
151 baz = my_func(1, 2);
152
Mark Whitley925edb82001-02-03 00:20:14 +0000153Also, don't put a space between the left paren and the first term, nor between
154the last arg and the right paren.
155
156 Don't do this:
157
158 if ( x < 1 )
159 strcmp( thisstr, thatstr )
160
161 Do this instead:
162
163 if (x < 1)
164 strcmp(thisstr, thatstr)
165
Mark Whitley2368a382000-08-22 00:20:21 +0000166
167Cuddled Elses
168~~~~~~~~~~~~~
169
Mark Whitley9028e2c2000-11-17 21:28:39 +0000170Also, please "cuddle" your else statements by putting the else keyword on the
171same line after the right bracket that closes an 'if' statement.
Mark Whitley40bfc762000-07-24 22:36:06 +0000172
173 Don't do this:
174
175 if (foo) {
176 stmt;
177 }
178 else {
179 stmt;
180 }
181
182 Do this instead:
183
184 if (foo) {
185 stmt;
186 } else {
187 stmt;
188 }
189
Mark Whitley9028e2c2000-11-17 21:28:39 +0000190The exception to this rule is if you want to include a comment before the else
191block. Example:
192
193 if (foo) {
194 stmts...
195 }
196 /* otherwise, we're just kidding ourselves, so re-frob the input */
197 else {
198 other_stmts...
199 }
200
Mark Whitley40bfc762000-07-24 22:36:06 +0000201
Mark Whitleyd58ff872000-11-22 19:25:39 +0000202
Mark Whitley40bfc762000-07-24 22:36:06 +0000203Variable and Function Names
204---------------------------
205
206Use the K&R style with names in all lower-case and underscores occasionally
Mark Whitley9028e2c2000-11-17 21:28:39 +0000207used to separate words (e.g., "variable_name" and "numchars" are both
Mark Whitley40bfc762000-07-24 22:36:06 +0000208acceptable). Using underscores makes variable and function names more readable
209because it looks like whitespace; using lower-case is easy on the eyes.
210
Mark Whitley3680c582000-12-20 22:35:12 +0000211 Frowned upon:
212
213 hitList
214 TotalChars
Mark Whitleya5b55ca2001-01-24 00:18:13 +0000215 szFileName
216 pf_Nfol_TriState
Mark Whitley3680c582000-12-20 22:35:12 +0000217
218 Preferred:
219
220 hit_list
221 total_chars
222 file_name
Mark Whitleya5b55ca2001-01-24 00:18:13 +0000223 sensible_name
Mark Whitley3680c582000-12-20 22:35:12 +0000224
Mark Whitleya5b55ca2001-01-24 00:18:13 +0000225Exceptions:
226
Mark Whitley7ddaf7c2001-03-14 21:04:53 +0000227 - Enums, macros, and constant variables are occasionally written in all
228 upper-case with words optionally seperatedy by underscores (i.e. FIFOTYPE,
229 ISBLKDEV()).
Mark Whitleya5b55ca2001-01-24 00:18:13 +0000230
231 - Nobody is going to get mad at you for using 'pvar' as the name of a
232 variable that is a pointer to 'var'.
Mark Whitley3680c582000-12-20 22:35:12 +0000233
Mark Whitley40bfc762000-07-24 22:36:06 +0000234
Mark Whitley7ddaf7c2001-03-14 21:04:53 +0000235Converting to K&R
236~~~~~~~~~~~~~~~~~
237
238The Busybox codebase is very much a mixture of code gathered from a variety of
239sources. This explains why the current codebase contains such a hodge-podge of
240different naming styles (Java, Pascal, K&R, just-plain-weird, etc.). The K&R
241guideline explained above should therefore be used on new files that are added
242to the repository. Furthermore, the maintainer of an existing file that uses
243alternate naming conventions should, at his own convenience, convert those
244names over to K&R style. Converting variable names is a very low priority
245task.
246
247If you want to do a search-and-replace of a single variable name in different
248files, you can do the following in the busybox directory:
Mark Whitleya5b55ca2001-01-24 00:18:13 +0000249
250 $ perl -pi -e 's/\bOldVar\b/new_var/g' *.[ch]
251
Mark Whitley7ddaf7c2001-03-14 21:04:53 +0000252If you want to convert all the non-K&R vars in your file all at once, follow
253these steps:
254
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000255 - In the busybox directory type 'examples/mk2knr.pl files-to-convert'. This
Mark Whitley7ddaf7c2001-03-14 21:04:53 +0000256 does not do the actual conversion, rather, it generates a script called
257 'convertme.pl' that shows what will be converted, giving you a chance to
258 review the changes beforehand.
259
260 - Review the 'convertme.pl' script that gets generated in the busybox
261 directory and remove / edit any of the substitutions in there. Please
262 especially check for false positives (strings that should not be
263 converted).
264
265 - Type './convertme.pl same-files-as-before' to perform the actual
266 conversion.
267
268 - Compile and see if everything still works.
269
270Please be aware of changes that have cascading effects into other files. For
271example, if you're changing the name of something in, say utility.c, you
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000272should probably run 'examples/mk2knr.pl utility.c' at first, but when you run
Mark Whitley7ddaf7c2001-03-14 21:04:53 +0000273the 'convertme.pl' script you should run it on _all_ files like so:
274'./convertme.pl *.[ch]'.
275
Mark Whitley40bfc762000-07-24 22:36:06 +0000276
Mark Whitley40bfc762000-07-24 22:36:06 +0000277
Mark Whitleyd58ff872000-11-22 19:25:39 +0000278Avoid The Preprocessor
279----------------------
Mark Whitley40bfc762000-07-24 22:36:06 +0000280
Mark Whitleyd58ff872000-11-22 19:25:39 +0000281At best, the preprocessor is a necessary evil, helping us account for platform
282and architecture differences. Using the preprocessor unnecessarily is just
283plain evil.
Mark Whitley2368a382000-08-22 00:20:21 +0000284
Mark Whitley40bfc762000-07-24 22:36:06 +0000285
Mark Whitleyd58ff872000-11-22 19:25:39 +0000286The Folly of #define
287~~~~~~~~~~~~~~~~~~~~
Mark Whitley40bfc762000-07-24 22:36:06 +0000288
Mark Whitleyd58ff872000-11-22 19:25:39 +0000289Use 'const <type> var' for declaring constants.
Mark Whitley40bfc762000-07-24 22:36:06 +0000290
291 Don't do this:
292
Mark Whitleyd58ff872000-11-22 19:25:39 +0000293 #define var 80
294
295 Do this instead, when the variable is in a header file and will be used in
296 several source files:
297
298 const int var = 80;
299
300 Or do this when the variable is used only in a single source file:
301
302 static const int var = 80;
303
304Declaring variables as '[static] const' gives variables an actual type and
305makes the compiler do type checking for you; the preprocessor does _no_ type
306checking whatsoever, making it much more error prone. Declaring variables with
307'[static] const' also makes debugging programs much easier since the value of
308the variable can be easily queried and displayed.
309
310
311The Folly of Macros
312~~~~~~~~~~~~~~~~~~~
313
314Use 'static inline' instead of a macro.
315
316 Don't do this:
317
318 #define mini_func(param1, param2) (param1 << param2)
Mark Whitley40bfc762000-07-24 22:36:06 +0000319
320 Do this instead:
321
Mark Whitleyd58ff872000-11-22 19:25:39 +0000322 static inline int mini_func(int param1, param2)
Mark Whitley40bfc762000-07-24 22:36:06 +0000323 {
Mark Whitleyd58ff872000-11-22 19:25:39 +0000324 return (param1 << param2);
325 }
Mark Whitley40bfc762000-07-24 22:36:06 +0000326
Mark Whitleyd58ff872000-11-22 19:25:39 +0000327Static inline functions are greatly preferred over macros. They provide type
Mark Whitley7ddaf7c2001-03-14 21:04:53 +0000328safety, have no length limitations, no formatting limitations, have an actual
329return value, and under gcc they are as cheap as macros. Besides, really long
330macros with backslashes at the end of each line are ugly as sin.
Mark Whitleyd58ff872000-11-22 19:25:39 +0000331
332
333The Folly of #ifdef
334~~~~~~~~~~~~~~~~~~~
335
336Code cluttered with ifdefs is difficult to read and maintain. Don't do it.
Mark Whitley7ddaf7c2001-03-14 21:04:53 +0000337Instead, put your ifdefs at the top of your .c file (or in a header), and
338conditionally define 'static inline' functions, (or *maybe* macros), which are
339used in the code.
Mark Whitleyd58ff872000-11-22 19:25:39 +0000340
341 Don't do this:
342
343 ret = my_func(bar, baz);
344 if (!ret)
345 return -1;
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000346 #ifdef CONFIG_FEATURE_FUNKY
Mark Whitleyd58ff872000-11-22 19:25:39 +0000347 maybe_do_funky_stuff(bar, baz);
348 #endif
349
350 Do this instead:
351
352 (in .h header file)
353
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000354 #ifdef CONFIG_FEATURE_FUNKY
Mark Whitleyd238a7b2001-02-09 00:28:59 +0000355 static inline void maybe_do_funky_stuff (int bar, int baz)
356 {
357 /* lotsa code in here */
358 }
359 #else
Mark Whitleyd58ff872000-11-22 19:25:39 +0000360 static inline void maybe_do_funky_stuff (int bar, int baz) {}
361 #endif
362
363 (in the .c source file)
364
365 ret = my_func(bar, baz);
366 if (!ret)
367 return -1;
368 maybe_do_funky_stuff(bar, baz);
369
370The great thing about this approach is that the compiler will optimize away
Mark Whitleyd238a7b2001-02-09 00:28:59 +0000371the "no-op" case (the empty function) when the feature is turned off.
Mark Whitleyd58ff872000-11-22 19:25:39 +0000372
373Note also the use of the word 'maybe' in the function name to indicate
374conditional execution.
375
376
377
378Notes on Strings
379----------------
380
381Strings in C can get a little thorny. Here's some guidelines for dealing with
382strings in Busybox. (There is surely more that could be added to this
383section.)
384
385
386String Files
387~~~~~~~~~~~~
388
389Put all help/usage messages in usage.c. Put other strings in messages.c.
390Putting these strings into their own file is a calculated decision designed to
391confine spelling errors to a single place and aid internationalization
392efforts, if needed. (Side Note: we might want to use a single file - maybe
393called 'strings.c' - instead of two, food for thought).
394
395
396Testing String Equivalence
397~~~~~~~~~~~~~~~~~~~~~~~~~~
398
399There's a right way and a wrong way to test for sting equivalence with
400strcmp():
401
402 The wrong way:
403
404 if (!strcmp(string, "foo")) {
405 ...
406
407 The right way:
408
409 if (strcmp(string, "foo") == 0){
410 ...
411
412The use of the "equals" (==) operator in the latter example makes it much more
413obvious that you are testing for equivalence. The former example with the
414"not" (!) operator makes it look like you are testing for an error. In a more
415perfect world, we would have a streq() function in the string library, but
416that ain't the world we're living in.
417
418
Mark Whitleya5b55ca2001-01-24 00:18:13 +0000419Avoid Dangerous String Functions
420~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
421
422Unfortunately, the way C handles strings makes them prone to overruns when
423certain library functions are (mis)used. The following table offers a summary
424of some of the more notorious troublemakers:
425
426function overflows preferred
427----------------------------------------
428strcpy dest string strncpy
429strcat dest string strncat
430gets string it gets fgets
431getwd buf string getcwd
432[v]sprintf str buffer [v]snprintf
433realpath path buffer use with pathconf
434[vf]scanf its arguments just avoid it
435
436
437The above is by no means a complete list. Be careful out there.
438
439
440
441Avoid Big Static Buffers
442------------------------
443
444First, some background to put this discussion in context: Static buffers look
445like this in code:
446
447 /* in a .c file outside any functions */
448 static char *buffer[BUFSIZ]; /* happily used by any function in this file,
449 but ick! big! */
450
451The problem with these is that any time any busybox app is run, you pay a
452memory penalty for this buffer, even if the applet that uses said buffer is
453not run. This can be fixed, thusly:
454
Eric Andersend35c2152001-01-25 23:49:09 +0000455 static char *buffer;
Mark Whitleya5b55ca2001-01-24 00:18:13 +0000456 ...
457 other_func()
458 {
459 strcpy(buffer, lotsa_chars); /* happily uses global *buffer */
460 ...
461 foo_main()
462 {
463 buffer = xmalloc(sizeof(char)*BUFSIZ);
464 ...
465
466However, this approach trades bss segment for text segment. Rather than
467mallocing the buffers (and thus growing the text size), buffers can be
468declared on the stack in the *_main() function and made available globally by
469assigning them to a global pointer thusly:
470
Eric Andersend35c2152001-01-25 23:49:09 +0000471 static char *pbuffer;
Mark Whitleya5b55ca2001-01-24 00:18:13 +0000472 ...
473 other_func()
474 {
475 strcpy(pbuffer, lotsa_chars); /* happily uses global *pbuffer */
476 ...
477 foo_main()
478 {
479 char *buffer[BUFSIZ]; /* declared locally, on stack */
480 pbuffer = buffer; /* but available globally */
481 ...
482
Eric Andersend35c2152001-01-25 23:49:09 +0000483This last approach has some advantages (low code size, space not used until
484it's needed), but can be a problem in some low resource machines that have
Mark Whitleyd238a7b2001-02-09 00:28:59 +0000485very limited stack space (e.g., uCLinux).
486
487A macro is declared in busybox.h that implements compile-time selection
488between xmalloc() and stack creation, so you can code the line in question as
489
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000490 RESERVE_CONFIG_BUFFER(buffer, BUFSIZ);
Mark Whitleyd238a7b2001-02-09 00:28:59 +0000491
492and the right thing will happen, based on your configuration.
Mark Whitleya5b55ca2001-01-24 00:18:13 +0000493
494
Mark Whitleyd58ff872000-11-22 19:25:39 +0000495
496Miscellaneous Coding Guidelines
497-------------------------------
498
499The following are important items that don't fit into any of the above
500sections.
501
502
503Model Busybox Applets After GNU Counterparts
504~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
505
506When in doubt about the proper behavior of a Busybox program (output,
507formatting, options, etc.), model it after the equivalent GNU program.
508Doesn't matter how that program behaves on some other flavor of *NIX; doesn't
509matter what the POSIX standard says or doesn't say, just model Busybox
Mark Whitley7ddaf7c2001-03-14 21:04:53 +0000510programs after their GNU counterparts and it will make life easier on (nearly)
511everyone.
Mark Whitleyd58ff872000-11-22 19:25:39 +0000512
513The only time we deviate from emulating the GNU behavior is when:
514
515 - We are deliberately not supporting a feature (such as a command line
516 switch)
517 - Emulating the GNU behavior is prohibitively expensive (lots more code
518 would be required, lots more memory would be used, etc.)
Eric Andersen07309432000-11-29 22:12:19 +0000519 - The difference is minor or cosmetic
Mark Whitleyd58ff872000-11-22 19:25:39 +0000520
521A note on the 'cosmetic' case: Output differences might be considered
522cosmetic, but if the output is significant enough to break other scripts that
523use the output, it should really be fixed.
524
525
526Scope
527~~~~~
528
529If a const variable is used only in a single source file, put it in the source
530file and not in a header file. Likewise, if a const variable is used in only
531one function, do not make it global to the file. Instead, declare it inside
Eric Andersen07309432000-11-29 22:12:19 +0000532the function body. Bottom line: Make a conscious effort to limit declarations
Mark Whitleyd58ff872000-11-22 19:25:39 +0000533to the smallest scope possible.
534
535Inside applet files, all functions should be declared static so as to keep the
536global name space clean. The only exception to this rule is the "applet_main"
537function which must be declared extern.
538
539If you write a function that performs a task that could be useful outside the
540immediate file, turn it into a general-purpose function with no ties to any
541applet and put it in the utility.c file instead.
542
543
544Brackets Are Your Friends
545~~~~~~~~~~~~~~~~~~~~~~~~~
546
547Please use brackets on all if and else statements, even if it is only one
548line. Example:
Mark Whitley40bfc762000-07-24 22:36:06 +0000549
550 Don't do this:
551
552 if (foo)
Mark Whitley3680c582000-12-20 22:35:12 +0000553 stmt1;
554 stmt2
555 stmt3;
Mark Whitley40bfc762000-07-24 22:36:06 +0000556
557 Do this instead:
558
559 if (foo) {
Mark Whitley3680c582000-12-20 22:35:12 +0000560 stmt1;
Mark Whitley40bfc762000-07-24 22:36:06 +0000561 }
Mark Whitley3680c582000-12-20 22:35:12 +0000562 stmt2
563 stmt3;
Mark Whitley40bfc762000-07-24 22:36:06 +0000564
Mark Whitleyd58ff872000-11-22 19:25:39 +0000565The "bracketless" approach is error prone because someday you might add a line
566like this:
Mark Whitley40bfc762000-07-24 22:36:06 +0000567
568 if (foo)
Mark Whitley3680c582000-12-20 22:35:12 +0000569 stmt1;
Mark Whitley40bfc762000-07-24 22:36:06 +0000570 new_line();
Mark Whitley3680c582000-12-20 22:35:12 +0000571 stmt2
572 stmt3;
Mark Whitley40bfc762000-07-24 22:36:06 +0000573
Mark Whitleyd58ff872000-11-22 19:25:39 +0000574And the resulting behavior of your program would totally bewilder you. (Don't
575laugh, it happens to us all.) Remember folks, this is C, not Python.
576
577
578Function Declarations
579~~~~~~~~~~~~~~~~~~~~~
580
581Do not use old-style function declarations that declare variable types between
582the parameter list and opening bracket. Example:
583
584 Don't do this:
585
586 int foo(parm1, parm2)
587 char parm1;
588 float parm2;
589 {
590 ....
591
592 Do this instead:
593
594 int foo(char parm1, float parm2)
595 {
596 ....
597
598The only time you would ever need to use the old declaration syntax is to
Eric Andersen07309432000-11-29 22:12:19 +0000599support ancient, antediluvian compilers. To our good fortune, we have access
Mark Whitleyd58ff872000-11-22 19:25:39 +0000600to more modern compilers and the old declaration syntax is neither necessary
601nor desired.
602
Mark Whitley3680c582000-12-20 22:35:12 +0000603
604Emphasizing Logical Blocks
605~~~~~~~~~~~~~~~~~~~~~~~~~~
606
607Organization and readability are improved by putting extra newlines around
608blocks of code that perform a single task. These are typically blocks that
609begin with a C keyword, but not always.
610
611Furthermore, you should put a single comment (not necessarily one line, just
612one comment) before the block, rather than commenting each and every line.
613There is an optimal ammount of commenting that a program can have; you can
614comment too much as well as too little.
615
Mark Whitley7ddaf7c2001-03-14 21:04:53 +0000616A picture is really worth a thousand words here, the following example
617illustrates how to emphasize logical blocks:
Mark Whitley3680c582000-12-20 22:35:12 +0000618
619 while (line = get_line_from_file(fp)) {
620
621 /* eat the newline, if any */
Mark Whitley7ddaf7c2001-03-14 21:04:53 +0000622 chomp(line);
Mark Whitley3680c582000-12-20 22:35:12 +0000623
624 /* ignore blank lines */
625 if (strlen(file_to_act_on) == 0) {
626 continue;
627 }
628
629 /* if the search string is in this line, print it,
630 * unless we were told to be quiet */
631 if (strstr(line, search) && !be_quiet) {
632 puts(line);
633 }
634
635 /* clean up */
636 free(line);
637 }
Mark Whitley9ead6892001-03-03 00:44:55 +0000638
639
640Processing Options with getopt
641~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
642
643If your applet needs to process command-line switches, please use getopt() to
644do so. Numerous examples can be seen in many of the existing applets, but
645basically it boils down to two things: at the top of the .c file, have this
646line in the midst of your #includes:
647
648 #include <getopt.h>
649
650And a code block similar to the following near the top of your applet_main()
651routine:
652
653 while ((opt = getopt(argc, argv, "abc")) > 0) {
654 switch (opt) {
655 case 'a':
656 do_a_opt = 1;
657 break;
658 case 'b':
659 do_b_opt = 1;
660 break;
661 case 'c':
662 do_c_opt = 1;
663 break;
664 default:
665 show_usage(); /* in utility.c */
666 }
667 }
668
669If your applet takes no options (such as 'init'), there should be a line
670somewhere in the file reads:
671
672 /* no options, no getopt */
673
674That way, when people go grepping to see which applets need to be converted to
675use getopt, they won't get false positives.
676
677Additional Note: Do not use the getopt_long library function and do not try to
678hand-roll your own long option parsing. Busybox applets should only support
Mark Whitley7ddaf7c2001-03-14 21:04:53 +0000679short options. Explanations and examples of the short options should be
680documented in usage.h.