updated.
[privoxy.git] / doc / text / developer-manual.txt
1
2 Junkbuster Developer Manual
3
4    By: Junkbuster Developers
5    
6    $Id: developer-manual.sgml,v 1.6 2002/02/24 14:25:06 jongfoster Exp $
7    
8    The developer manual gives the users information on how to help the
9    developer team. It provides guidance on coding, testing, documentation
10    and other issues. The Internet Junkbuster is an application that
11    provides privacy and security to the user of the world wide web.
12    
13    You can find the latest version of the user manual at
14    [1]http://ijbswa.sourceforge.net/developer-manual/. Please see the
15    Contact section in the user-manual if you want to contact the
16    developers.
17    
18    Feel free to send a note to the developers at
19    <[2]ijbswa-developers@lists.sourceforge.net>.
20      _________________________________________________________________
21    
22    Table of Contents
23    1. [3]Introduction
24    2. [4]Quickstart to Junkbuster Development
25    3. [5]Documentation Guidelines
26    4. [6]Coding Guidelines
27           
28         4.1. [7]Introduction
29         4.2. [8]Using Comments
30                 
31               4.2.1. [9]Comment, Comment, Comment
32               4.2.2. [10]Use blocks for comments
33               4.2.3. [11]Keep Comments on their own line
34               4.2.4. [12]Comment each logical step
35               4.2.5. [13]Comment All Functions Thoroughly
36               4.2.6. [14]Comment at the end of braces if the content is
37                       more than one screen length
38                       
39         4.3. [15]Naming Conventions
40                 
41               4.3.1. [16]Variable Names
42               4.3.2. [17]Function Names
43               4.3.3. [18]Header file prototypes
44               4.3.4. [19]Enumerations, and #defines
45               4.3.5. [20]Constants
46                       
47         4.4. [21]Using Space
48                 
49               4.4.1. [22]Put braces on a line by themselves.
50               4.4.2. [23]ALL control statements should have a block
51               4.4.3. [24]Do not belabor/blow-up boolean expressions
52               4.4.4. [25]Use white space freely because it is free
53               4.4.5. [26]Don't use white space around structure operators
54               4.4.6. [27]Make the last brace of a function stand out
55               4.4.7. [28]Use 3 character indentions
56                       
57         4.5. [29]Initializing
58                 
59               4.5.1. [30]Initialize all variables
60                       
61         4.6. [31]Functions
62                 
63               4.6.1. [32]Name functions that return a boolean as a
64                       question.
65                       
66               4.6.2. [33]Always specify a return type for a function.
67               4.6.3. [34]Minimize function calls when iterating by using
68                       variables
69                       
70               4.6.4. [35]Pass and Return by Const Reference
71               4.6.5. [36]Pass and Return by Value
72               4.6.6. [37]Names of include files
73               4.6.7. [38]Provide multiple inclusion protection
74               4.6.8. [39]Use `extern "C"` when appropriate
75               4.6.9. [40]Where Possible, Use Forward Struct Declaration
76                       Instead of Includes
77                       
78         4.7. [41]General Coding Practices
79                 
80               4.7.1. [42]Turn on warnings
81               4.7.2. [43]Provide a default case for all switch statements
82               4.7.3. [44]Try to avoid falling through cases in a switch
83                       statement.
84                       
85               4.7.4. [45]Use 'long' or 'short' Instead of 'int'
86               4.7.5. [46]Don't mix size_t and other types
87               4.7.6. [47]Declare each variable and struct on its own
88                       line.
89                       
90               4.7.7. [48]Use malloc/zalloc sparingly
91               4.7.8. [49]The Programmer Who Uses 'malloc' is Responsible
92                       for Ensuring 'free'
93                       
94               4.7.9. [50]Add loaders to the `file_list' structure and in
95                       order
96                       
97               4.7.10. [51]"Uncertain" new code and/or changes to exitinst
98                       code, use FIXME
99                       
100         4.8. [52]Addendum: Template for files and function comment
101                 blocks:
102                 
103    5. [53]Version Control Guidelines
104    6. [54]Testing Guidelines
105           
106         6.1. [55]Testplan for releases
107         6.2. [56]Test reports
108                 
109    7. [57]Contact the developers
110    8. [58]Copyright and History
111    9. [59]See also
112           
113 1. Introduction
114
115    To be filled.
116      _________________________________________________________________
117    
118 2. Quickstart to Junkbuster Development
119
120    To be filled.
121      _________________________________________________________________
122    
123 3. Documentation Guidelines
124
125    All docs are in SGML format and located in the doc/source directory.
126    
127    How do you update the webserver (i.e. the pages on sourceforge)?
128    
129     1. Run make dok (which uses the documents in doc/source to update all
130        text files in doc/text and to update all web documents in
131        doc/webserver.
132     2. Run make webserver which copies all files from doc/webserver to
133        the sourceforge webserver via scp.
134      _________________________________________________________________
135    
136 4. Coding Guidelines
137
138 4.1. Introduction
139
140    This set of standards is designed to make our lives easier. It is
141    developed with the simple goal of helping us keep the "new and
142    improved Junkbusters" consistent and reliable. Thus making maintenance
143    easier and increasing chances of success of the project.
144    
145    And that of course comes back to us as individuals. If we can increase
146    our development and product efficiencies then we can solve more of the
147    request for changes/improvements and in general feel good about
148    ourselves. ;->
149      _________________________________________________________________
150    
151 4.2. Using Comments
152
153 4.2.1. Comment, Comment, Comment
154
155    Explanation:
156    
157    Comment as much as possible without commenting the obvious. For
158    example do not comment "aVariable is equal to bVariable". Instead
159    explain why aVariable should be equal to the bVariable. Just because a
160    person can read code does not mean they will understand why or what is
161    being done. A reader may spend a lot more time figuring out what is
162    going on when a simple comment or explanation would have prevented the
163    extra research. Please help your brother IJB'ers out!
164    
165    The comments will also help justify the intent of the code. If the
166    comment describes something different than what the code is doing then
167    maybe a programming error is occurring.
168    
169    Example:
170 /* if page size greater than 1k ... */
171 if ( PageLength() > 1024 )
172 {
173     ... "block" the page up ...
174 }
175
176 /* if page size is small, send it in blocks */
177 if ( PageLength() > 1024 )
178 {
179     ... "block" the page up ...
180 }
181
182 This demonstrates 2 cases of "what not to do".  The first is a
183 "syntax comment".  The second is a comment that does not fit what
184 is actually being done.
185      _________________________________________________________________
186    
187 4.2.2. Use blocks for comments
188
189    Explanation:
190    
191    Comments can help or they can clutter. They help when they are
192    differentiated from the code they describe. One line comments do not
193    offer effective separation between the comment and the code. Block
194    identifiers do, by surrounding the code with a clear, definable
195    pattern.
196    
197    Example:
198 /*********************************************************************
199  * This will stand out clearly in your code!
200  *********************************************************************/
201 if ( thisVariable == thatVariable )
202 {
203    DoSomethingVeryImportant();
204 }
205
206
207 /* unfortunately, this may not */
208 if ( thisVariable == thatVariable )
209 {
210    DoSomethingVeryImportant();
211 }
212
213
214 if ( thisVariable == thatVariable ) /* this may not either */
215 {
216    DoSomethingVeryImportant();
217 }
218
219    Exception:
220    
221    If you are trying to add a small logic comment and do not wish to
222    "disrubt" the flow of the code, feel free to use a 1 line comment
223    which is NOT on the same line as the code.
224      _________________________________________________________________
225    
226 4.2.3. Keep Comments on their own line
227
228    Explanation:
229    
230    It goes back to the question of readability. If the comment is on the
231    same line as the code it will be harder to read than the comment that
232    is on its own line.
233    
234    There are three exceptions to this rule, which should be violated
235    freely and often: during the definition of variables, at the end of
236    closing braces, when used to comment parameters.
237    
238    Example:
239 /*********************************************************************
240  * This will stand out clearly in your code,
241  * But the second example won't.
242  *********************************************************************/
243 if ( thisVariable == thatVariable )
244 {
245    DoSomethingVeryImportant();
246 }
247
248 if ( thisVariable == thatVariable ) /*can you see me?*/
249 {
250    DoSomethingVeryImportant(); /*not easily*/
251 }
252
253
254 /*********************************************************************
255  * But, the encouraged exceptions:
256  *********************************************************************/
257 int urls_read     = 0;     /* # of urls read + rejected */
258 int urls_rejected = 0;     /* # of urls rejected */
259
260 if ( 1 == X )
261 {
262    DoSomethingVeryImportant();
263 }
264
265
266 short DoSomethingVeryImportant(
267    short firstparam,   /* represents something */
268    short nextparam     /* represents something else */ )
269 {
270    ...code here...
271
272 }   /* -END- DoSomethingVeryImportant */
273      _________________________________________________________________
274    
275 4.2.4. Comment each logical step
276
277    Explanation:
278    
279    Logical steps should be commented to help others follow the intent of
280    the written code and comments will make the code more readable.
281    
282    If you have 25 lines of code without a comment, you should probably go
283    back into it to see where you forgot to put one.
284    
285    Most "for", "while", "do", etc... loops _probably_ need a comment.
286    After all, these are usually major logic containers.
287      _________________________________________________________________
288    
289 4.2.5. Comment All Functions Thoroughly
290
291    Explanation:
292    
293    A reader of the code should be able to look at the comments just prior
294    to the beginning of a function and discern the reason for its
295    existence and the consequences of using it. The reader should not have
296    to read through the code to determine if a given function is safe for
297    a desired use. The proper information thoroughly presented at the
298    introduction of a function not only saves time for subsequent
299    maintenance or debugging, it more importantly aids in code reuse by
300    allowing a user to determine the safety and applicability of any
301    function for the problem at hand. As a result of such benefits, all
302    functions should contain the information presented in the addendum
303    section of this document.
304      _________________________________________________________________
305    
306 4.2.6. Comment at the end of braces if the content is more than one screen
307 length
308
309    Explanation:
310    
311    Each closing brace should be followed on the same line by a comment
312    that describes the origination of the brace if the original brace is
313    off of the screen, or otherwise far away from the closing brace. This
314    will simplify the debugging, maintenance, and readability of the code.
315    
316    As a suggestion , use the following flags to make the comment and its
317    brace more readable:
318    
319    use following a closing brace: } /* -END- if() or while () or etc...
320    */
321    
322    Example:
323 if ( 1 == X )
324 {
325    DoSomethingVeryImportant();
326    ...some long list of commands...
327 } /* -END- if x is 1 */
328
329 or:
330
331 if ( 1 == X )
332 {
333    DoSomethingVeryImportant();
334    ...some long list of commands...
335 } /* -END- if ( 1 == X ) */
336      _________________________________________________________________
337    
338 4.3. Naming Conventions
339
340 4.3.1. Variable Names
341
342    Explanation:
343    
344    Use all lowercase, and seperate words via an underscore ('_'). Do not
345    start an identifier with an underscore. (ANSI C reserves these for use
346    by the compiler and system headers.) Do not use identifiers which are
347    reserved in ANSI C++. (E.g. template, class, true, false, ...). This
348    is in case we ever decide to port JunkBuster to C++.
349    
350    Example:
351 int ms_iis5_hack = 0;
352
353    Instead of:
354    
355 int msiis5hack = 0; int msIis5Hack = 0;
356      _________________________________________________________________
357    
358 4.3.2. Function Names
359
360    Explanation:
361    
362    Use all lowercase, and seperate words via an underscore ('_'). Do not
363    start an identifier with an underscore. (ANSI C reserves these for use
364    by the compiler and system headers.) Do not use identifiers which are
365    reserved in ANSI C++. (E.g. template, class, true, false, ...). This
366    is in case we ever decide to port JunkBuster to C++.
367    
368    Example:
369 int load_some_file( struct client_state *csp )
370
371    Instead of:
372    
373 int loadsomefile( struct client_state *csp )
374 int loadSomeFile( struct client_state *csp )
375      _________________________________________________________________
376    
377 4.3.3. Header file prototypes
378
379    Explanation:
380    
381    Use a descriptive parameter name in the function prototype in header
382    files. Use the same parameter name in the header file that you use in
383    the c file.
384    
385    Example:
386 (.h) extern int load_aclfile( struct client_state *csp );
387 (.c) int load_aclfile( struct client_state *csp )
388
389    Instead of:
390 (.h) extern int load_aclfile( struct client_state * ); or
391 (.h) extern int load_aclfile();
392 (.c) int load_aclfile( struct client_state *csp )
393      _________________________________________________________________
394    
395 4.3.4. Enumerations, and #defines
396
397    Explanation:
398    
399    Use all capital letters, with underscores between words. Do not start
400    an identifier with an underscore. (ANSI C reserves these for use by
401    the compiler and system headers.)
402    
403    Example:
404 (enumeration) : enum Boolean { FALSE, TRUE };
405 (#define) : #define DEFAULT_SIZE 100;
406
407    Note: We have a standard naming scheme for #defines that toggle a
408    feature in the preprocessor: FEATURE_>, where > is a short (preferably
409    1 or 2 word) description.
410    
411    Example:
412 #define FEATURE_FORCE 1
413
414 #ifdef FEATURE_FORCE
415 #define FORCE_PREFIX blah
416 #endif /* def FEATURE_FORCE */
417      _________________________________________________________________
418    
419 4.3.5. Constants
420
421    Explanation:
422    
423    Spell common words out entirely (do not remove vowels).
424    
425    Use only widely-known domain acronyms and abbreviations. Capitalize
426    all letters of an acronym.
427    
428    Use underscore (_) to separate adjacent acronyms and abbreviations.
429    Never terminate a name with an underscore.
430    
431    Example:
432 #define USE_IMAGE_LIST 1
433
434    Instead of:
435    
436 #define USE_IMG_LST 1 or
437 #define _USE_IMAGE_LIST 1 or
438 #define USE_IMAGE_LIST_ 1 or
439 #define use_image_list 1 or
440 #define UseImageList 1
441      _________________________________________________________________
442    
443 4.4. Using Space
444
445 4.4.1. Put braces on a line by themselves.
446
447    Explanation:
448    
449    The brace needs to be on a line all by itself, not at the end of the
450    statement. Curly braces should line up with the construct that they're
451    associated with. This practice makes it easier to identify the opening
452    and closing braces for a block.
453    
454    Example:
455 if ( this == that )
456 {
457    ...
458 }
459
460    Instead of:
461    
462    if ( this == that ) { ... }
463    
464    or
465    
466    if ( this == that ) { ... }
467    
468    Note: In the special case that the if-statement is inside a loop, and
469    it is trivial, i.e. it tests for a condidtion that is obvious from the
470    purpose of the block, one-liners as above may optically preserve the
471    loop structure and make it easier to read.
472    
473    Status: developer-discrection.
474    
475    Example exception:
476 while ( more lines are read )
477 {
478    /* Please document what is/is not a comment line here */
479    if ( it's a comment ) continue;
480
481    do_something( line );
482 }
483      _________________________________________________________________
484    
485 4.4.2. ALL control statements should have a block
486
487    Explanation:
488    
489    Using braces to make a block will make your code more readable and
490    less prone to error. All control statements should have a block
491    defined.
492    
493    Example:
494 if ( this == that )
495 {
496    DoSomething();
497    DoSomethingElse();
498 }
499
500    Instead of:
501    
502    if ( this == that ) DoSomething(); DoSomethingElse();
503    
504    or
505    
506    if ( this == that ) DoSomething();
507    
508    Note: The first example in "Instead of" will execute in a manner other
509    than that which the developer desired (per indentation). Using code
510    braces would have prevented this "feature". The "explanation" and
511    "exception" from the point above also applies.
512      _________________________________________________________________
513    
514 4.4.3. Do not belabor/blow-up boolean expressions
515
516    Example:
517 structure->flag = ( condition );
518
519    Instead of:
520    
521    if ( condition ) { structure->flag = 1; } else { structure->flag = 0;
522    }
523    
524    Note: The former is readable and consice. The later is wordy and
525    inefficient. Please assume that any developer new to the project has
526    at least a "good" knowledge of C/C++. (Hope I do not offend by that
527    last comment ... 8-)
528      _________________________________________________________________
529    
530 4.4.4. Use white space freely because it is free
531
532    Explanation:
533    
534    Make it readable. The notable exception to using white space freely is
535    listed in the next guideline.
536    
537    Example:
538 int firstValue   = 0;
539 int someValue    = 0;
540 int anotherValue = 0;
541 int thisVariable = 0;
542
543 if ( thisVariable == thatVariable )
544
545 firstValue = oldValue + ( ( someValue - anotherValue ) - whatever )
546      _________________________________________________________________
547    
548 4.4.5. Don't use white space around structure operators
549
550    Explanation:
551    
552    - structure pointer operator ( "->" ) - member operator ( "." ) -
553    functions and parentheses
554    
555    It is a general coding practice to put pointers, references, and
556    function parentheses next to names. With spaces, the connection
557    between the object and variable/function name is not as clear.
558    
559    Example:
560 aStruct->aMember;
561 aStruct.aMember;
562 FunctionName();
563
564    Instead of: aStruct -> aMember; aStruct . aMember; FunctionName ();
565      _________________________________________________________________
566    
567 4.4.6. Make the last brace of a function stand out
568
569    Example:
570 int function1( ... )
571 {
572    ...code...
573    return( retCode );
574
575 }   /* -END- function1 */
576
577
578 int function2( ... )
579 {
580 }   /* -END- function2 */
581
582    Instead of:
583    
584    int function1( ... ) { ...code... return( retCode ); } int function2(
585    ... ) { }
586    
587    Note: Use 1 blank line before the closing brace and 2 lines
588    afterwards. This makes the end of function standout to the most casual
589    viewer. Although function comments help seperate functions, this is
590    still a good coding practice. In fact, I follow these rules when using
591    blocks in "for", "while", "do" loops, and long if {} statements too.
592    After all whitespace is free!
593    
594    Status: developer-discrection on the number of blank lines. Enforced
595    is the end of function comments.
596      _________________________________________________________________
597    
598 4.4.7. Use 3 character indentions
599
600    Explanation:
601    
602    If some use 8 character TABs and some use 3 character TABs, the code
603    can look *very* ragged. So use 3 character indentions only. If you
604    like to use TABs, pass your code through a filter such as "expand -t3"
605    before checking in your code.
606    
607    Example:
608 static const char * const url_code_map[256] =
609 {
610    NULL, ...
611 };
612
613
614 int function1( ... )
615 {
616    if ( 1 )
617    {
618       return( ALWAYS_TRUE );
619    }
620    else
621    {
622       return( HOW_DID_YOU_GET_HERE );
623    }
624
625    return( NEVER_GETS_HERE );
626
627 }
628      _________________________________________________________________
629    
630 4.5. Initializing
631
632 4.5.1. Initialize all variables
633
634    Explanation:
635    
636    Do not assume that the variables declared will not be used until after
637    they have been assigned a value somewhere else in the code. Remove the
638    chance of accidentally using an unassigned variable.
639    
640    Example:
641 short anShort = 0;
642 float aFloat  = 0;
643 struct *ptr = NULL;
644
645    Note: It is much easier to debug a SIGSEGV if the message says you are
646    trying to access memory address 00000000 and not 129FA012; or
647    arrayPtr[20] causes a SIGSEV vs. arrayPtr[0].
648    
649    Status: developer-discrection if and only if the variable is assigned
650    a value "shortly after" declaration.
651      _________________________________________________________________
652    
653 4.6. Functions
654
655 4.6.1. Name functions that return a boolean as a question.
656
657    Explanation:
658    
659    Value should be phrased as a question that would logically be answered
660    as a true or false statement
661    
662    Example:
663 ShouldWeBlockThis();
664 ContainsAnImage();
665 IsWebPageBlank();
666      _________________________________________________________________
667    
668 4.6.2. Always specify a return type for a function.
669
670    Explanation:
671    
672    The default return for a function is an int. To avoid ambiguity,
673    create a return for a function when the return has a purpose, and
674    create a void return type if the function does not need to return
675    anything.
676      _________________________________________________________________
677    
678 4.6.3. Minimize function calls when iterating by using variables
679
680    Explanation:
681    
682    It is easy to write the following code, and a clear argument can be
683    made that the code is easy to understand:
684    
685    Example:
686 for ( size_t cnt = 0; cnt < blockListLength(); cnt ++ )
687 {
688    ....
689 }
690
691    Note: Unfortunately, this makes a function call for each and every
692    iteration. This increases the overhead in the program, because the
693    compiler has to look up the function each time, call it, and return a
694    value. Depending on what occurs in the blockListLength() call, it
695    might even be creating and destroying structures with each iteration,
696    even though in each case it is comparing "cnt" to the same value, over
697    and over. Remember too - even a call to blockListLength() is a
698    function call, with the same overhead.
699    
700    Instead of using a function call during the iterations, assign the
701    value to a variable, and evaluate using the variable.
702    
703    Example:
704 size_t len = blockListLength();
705
706 for ( size_t cnt = 0; cnt < len; cnt ++ )
707 {
708    ....
709 }
710
711    Exceptions: if the value of blockListLength() *may* change or could
712    *potentially* change, then you must code the function call in the
713    for/while loop.
714      _________________________________________________________________
715    
716 4.6.4. Pass and Return by Const Reference
717
718    Explanation:
719    
720    This allows a developer to define a const pointer and call your
721    function. If your function does not have the const keyword, we may not
722    be able to use your function. Consider strcmp, if it were defined as:
723    extern int strcmp( char *s1, char *s2 );
724    
725    I could then not use it to compare argv's in main: int main( int argc,
726    const char *argv[] ) { strcmp( argv[0], "junkbusters" ); }
727    
728    Both these pointers are *const*! If the c runtime library maintainers
729    do it, we should too.
730      _________________________________________________________________
731    
732 4.6.5. Pass and Return by Value
733
734    Explanation:
735    
736    Most structures cannot fit onto a normal stack entry (i.e. they are
737    not 4 bytes or less). Aka, a function declaration like: int
738    load_aclfile( struct client_state csp )
739    
740    would not work. So, to be consistent, we should declare all prototypes
741    with "pass by value": int load_aclfile( struct client_state *csp )
742      _________________________________________________________________
743    
744 4.6.6. Names of include files
745
746    Explanation:
747    
748    Your include statements should contain the file name without a path.
749    The path should be listed in the Makefile, using -I as processor
750    directive to search the indicated paths. An exception to this would be
751    for some proprietary software that utilizes a partial path to
752    distinguish their header files from system or other header files.
753    
754    Example:
755 #include <iostream.h>     /* This is not a local include */
756 #include "config.h"       /* This IS a local include */
757
758    Exception:
759    
760 /* This is not a local include, but requires a path element. */
761 #include <sys/fileName.h>
762
763    Note: Please! do not add "-I." to the Makefile without a _very_ good
764    reason. This duplicates the #include "file.h" behaviour.
765      _________________________________________________________________
766    
767 4.6.7. Provide multiple inclusion protection
768
769    Explanation:
770    
771    Prevents compiler and linker errors resulting from redefinition of
772    items.
773    
774    Wrap each header file with the following syntax to prevent multiple
775    inclusions of the file. Of course, replace PROJECT_H with your file
776    name, with "." Changed to "_", and make it uppercase.
777    
778    Example:
779 #ifndef PROJECT_H_INCLUDED
780 #define PROJECT_H_INCLUDED
781  ...
782 #endif /* ndef PROJECT_H_INCLUDED */
783      _________________________________________________________________
784    
785 4.6.8. Use `extern "C"` when appropriate
786
787    Explanation:
788    
789    If our headers are included from C++, they must declare our functions
790    as `extern "C"`. This has no cost in C, but increases the potential
791    re-usability of our code.
792    
793    Example:
794 #ifdef __cplusplus
795 extern "C"
796 {
797 #endif /* def __cplusplus */
798
799 ... function definitions here ...
800
801 #ifdef __cplusplus
802 }
803 #endif /* def __cplusplus */
804      _________________________________________________________________
805    
806 4.6.9. Where Possible, Use Forward Struct Declaration Instead of Includes
807
808    Explanation:
809    
810    Useful in headers that include pointers to other struct's.
811    Modifications to excess header files may cause needless compiles.
812    
813    Example:
814 /*********************************************************************
815  * We're avoiding an include statement here!
816  *********************************************************************/
817 struct file_list;
818 extern file_list *xyz;
819
820    Note: If you declare "file_list xyz;" (without the pointer), then
821    including the proper header file is necessary. If you only want to
822    prototype a pointer, however, the header file is unneccessary.
823    
824    Status: Use with discrection.
825      _________________________________________________________________
826    
827 4.7. General Coding Practices
828
829 4.7.1. Turn on warnings
830
831    Explanation
832    
833    Compiler warnings are meant to help you find bugs. You should turn on
834    as many as possible. With GCC, the switch is "-Wall". Try and fix as
835    many warnings as possible.
836      _________________________________________________________________
837    
838 4.7.2. Provide a default case for all switch statements
839
840    Explanation:
841    
842    What you think is guaranteed is never really guaranteed. The value
843    that you don't think you need to check is the one that someday will be
844    passed. So, to protect yourself from the unknown, always have a
845    default step in a switch statement.
846    
847    Example:
848 switch( hash_string( cmd ) )
849 {
850    case hash_actions_file :
851       ... code ...
852       break;
853
854    case hash_confdir :
855       ... code ...
856       break;
857
858    default :
859       log_error( ... );
860       ... anomly code goes here ...
861       continue; / break; / exit( 1 ); / etc ...
862
863 } /* end switch( hash_string( cmd ) ) */
864
865    Note: If you already have a default condition, you are obviously
866    exempt from this point. Of note, most of the WIN32 code calls
867    `DefWindowProc' after the switch statement. This API call *should* be
868    included in a default statement.
869    
870    Another Note: This is not so much a readability issue as a robust
871    programming issue. The "anomly code goes here" may be no more than a
872    print to the STDERR stream (as in load_config). Or it may really be an
873    ABEND condition.
874    
875    Status: Programmer discretion is advised.
876      _________________________________________________________________
877    
878 4.7.3. Try to avoid falling through cases in a switch statement.
879
880    Explanation:
881    
882    In general, you will want to have a 'break' statement within each
883    'case' of a switch statement. This allows for the code to be more
884    readable and understandable, and furthermore can prevent unwanted
885    surprises if someone else later gets creative and moves the code
886    around.
887    
888    The language allows you to plan the fall through from one case
889    statement to another simply by omitting the break statement within the
890    case statement. This feature does have benefits, but should only be
891    used in rare cases. In general, use a break statement for each case
892    statement.
893    
894    If you choose to allow fall through, you should comment both the fact
895    of the fall through and reason why you felt it was necessary.
896      _________________________________________________________________
897    
898 4.7.4. Use 'long' or 'short' Instead of 'int'
899
900    Explanation:
901    
902    On 32-bit platforms, int usually has the range of long. On 16-bit
903    platforms, int has the range of short.
904    
905    Status: open-to-debate. In the case of most FSF projects (including
906    X/GNU-Emacs), there are typedefs to int4, int8, int16, (or equivalence
907    ... I forget the exact typedefs now). Should we add these to IJB now
908    that we have a "configure" script?
909      _________________________________________________________________
910    
911 4.7.5. Don't mix size_t and other types
912
913    Explanation:
914    
915    The type of size_t varies across platforms. Do not make assumptions
916    about whether it is signed or unsigned, or about how long it is. Do
917    not compare a size_t against another variable of a different type (or
918    even against a constant) without casting one of the values. Try to
919    avoid using size_t if you can.
920      _________________________________________________________________
921    
922 4.7.6. Declare each variable and struct on its own line.
923
924    Explanation:
925    
926    It can be tempting to declare a series of variables all on one line.
927    Don't.
928    
929    Example:
930 long a = 0;
931 long b = 0;
932 long c = 0;
933
934    Instead of:
935    
936    long a, b, c;
937    
938    Explanation: - there is more room for comments on the individual
939    variables - easier to add new variables without messing up the
940    original ones - when searching on a variable to find its type, there
941    is less clutter to "visually" eliminate
942    
943    Exceptions: when you want to declare a bunch of loop variables or
944    other trivial variables; feel free to declare them on 1 line. You
945    should, although, provide a good comment on their functions.
946    
947    Status: developer-discrection.
948      _________________________________________________________________
949    
950 4.7.7. Use malloc/zalloc sparingly
951
952    Explanation:
953    
954    Create a local stuct (on the stack) if the variable will live and die
955    within the context of one function call.
956    
957    Only "malloc" a struct (on the heap) if the variable's life will
958    extend beyond the context of one function call.
959    
960    Example:
961 If a function creates a struct and stores a pointer to it in a
962 list, then it should definately be allocated via `malloc'.
963      _________________________________________________________________
964    
965 4.7.8. The Programmer Who Uses 'malloc' is Responsible for Ensuring 'free'
966
967    Explanation:
968    
969    If you have to "malloc" an instance, you are responsible for insuring
970    that the instance is `free'd, even if the deallocation event falls
971    within some other programmer's code. You are also responsible for
972    ensuring that deletion is timely (i.e. not too soon, not too late).
973    This is known as "low-coupling" and is a "good thing (tm)". You may
974    need to offer a free/unload/destuctor type function to accomodate
975    this.
976    
977    Example:
978 int load_re_filterfile( struct client_state *csp ) { ... }
979 static void unload_re_filterfile( void *f ) { ... }
980
981    Exceptions:
982    
983    The developer cannot be expected to provide `free'ing functions for C
984    run-time library functions ... such as `strdup'.
985    
986    Status: developer-discrection. The "main" use of this standard is for
987    allocating and freeing data structures (complex or nested).
988      _________________________________________________________________
989    
990 4.7.9. Add loaders to the `file_list' structure and in order
991
992    Explanation:
993    
994    I have ordered all of the "blocker" file code to be in alpha order. It
995    is easier to add/read new blockers when you expect a certain order.
996    
997    Note: It may appear that the alpha order is broken in places by POPUP
998    tests coming before PCRS tests. But since POPUPs can also be referred
999    to as KILLPOPUPs, it is clear that it should come first.
1000      _________________________________________________________________
1001    
1002 4.7.10. "Uncertain" new code and/or changes to exitinst code, use FIXME
1003
1004    Explanation:
1005    
1006    If you have enough confidence in new code or confidence in your
1007    changes, but are not *quite* sure of the reprocussions, add this:
1008    
1009    /* FIXME: this code has a logic error on platform XYZ, * attempthing
1010    to fix */ #ifdef PLATFORM ...changed code here... #endif
1011    
1012    or:
1013    
1014    /* FIXME: I think the original author really meant this... */
1015    ...changed code here...
1016    
1017    or:
1018    
1019    /* FIXME: new code that *may* break something else... */ ...new code
1020    here...
1021    
1022    Note: If you make it clear that this may or may not be a "good thing
1023    (tm)", it will be easier to identify and include in the project (or
1024    conversly exclude from the project).
1025      _________________________________________________________________
1026    
1027 4.8. Addendum: Template for files and function comment blocks:
1028
1029    Example for file comments:
1030 const char FILENAME_rcs[] = "$Id: developer-manual.sgml,v 1.6 2002/02/24 14:25:
1031 06 jongfoster Exp $";
1032 /*********************************************************************
1033  *
1034  * File        :  $Source$
1035  *
1036  * Purpose     :  (Fill me in with a good description!)
1037  *
1038  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
1039  *                IJBSWA team.  http://ijbswa.sourceforge.net
1040  *
1041  *                Based on the Internet Junkbuster originally written
1042  *                by and Copyright (C) 1997 Anonymous Coders and
1043  *                Junkbusters Corporation.  http://www.junkbusters.com
1044  *
1045  *                This program is free software; you can redistribute it
1046  *                and/or modify it under the terms of the GNU General
1047  *                Public License as published by the Free Software
1048  *                Foundation; either version 2 of the License, or (at
1049  *                your option) any later version.
1050  *
1051  *                This program is distributed in the hope that it will
1052  *                be useful, but WITHOUT ANY WARRANTY; without even the
1053  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
1054  *                PARTICULAR PURPOSE.  See the GNU General Public
1055  *                License for more details.
1056  *
1057  *                The GNU General Public License should be included with
1058  *                this file.  If not, you can view it at
1059  *                http://www.gnu.org/copyleft/gpl.html
1060  *                or write to the Free Software Foundation, Inc., 59
1061  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
1062  *
1063  * Revisions   :
1064  *    $Log$
1065  *
1066  *********************************************************************/
1067
1068
1069 #include "config.h"
1070
1071    ...necessary include files for us to do our work...
1072
1073 const char FILENAME_h_rcs[] = FILENAME_H_VERSION;
1074
1075    Note: This declares the rcs variables that should be added to the
1076    "show-proxy-args" page. If this is a brand new creation by you, you
1077    are free to change the "Copyright" section to represent the rights you
1078    wish to maintain.
1079    
1080    Note: The formfeed character that is present right after the comment
1081    flower box is handy for (X|GNU)Emacs users to skip the verbige and get
1082    to the heart of the code (via `forward-page' and `backward-page').
1083    Please include it if you can.
1084    
1085    Example for file header comments:
1086 #ifndef _FILENAME_H
1087 #define _FILENAME_H
1088 #define FILENAME_H_VERSION "$Id: developer-manual.sgml,v 1.6 2002/02/24 14:25:0
1089 6 jongfoster Exp $"
1090 /*********************************************************************
1091  *
1092  * File        :  $Source$
1093  *
1094  * Purpose     :  (Fill me in with a good description!)
1095  *
1096  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
1097  *                IJBSWA team.  http://ijbswa.sourceforge.net
1098  *
1099  *                Based on the Internet Junkbuster originally written
1100  *                by and Copyright (C) 1997 Anonymous Coders and
1101  *                Junkbusters Corporation.  http://www.junkbusters.com
1102  *
1103  *                This program is free software; you can redistribute it
1104  *                and/or modify it under the terms of the GNU General
1105  *                Public License as published by the Free Software
1106  *                Foundation; either version 2 of the License, or (at
1107  *                your option) any later version.
1108  *
1109  *                This program is distributed in the hope that it will
1110  *                be useful, but WITHOUT ANY WARRANTY; without even the
1111  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
1112  *                PARTICULAR PURPOSE.  See the GNU General Public
1113  *                License for more details.
1114  *
1115  *                The GNU General Public License should be included with
1116  *                this file.  If not, you can view it at
1117  *                http://www.gnu.org/copyleft/gpl.html
1118  *                or write to the Free Software Foundation, Inc., 59
1119  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
1120  *
1121  * Revisions   :
1122  *    $Log$
1123  *
1124  *********************************************************************/
1125
1126
1127 #include "project.h"
1128
1129 #ifdef __cplusplus
1130 extern "C" {
1131 #endif
1132
1133    ... function headers here ...
1134
1135
1136 /* Revision control strings from this header and associated .c file */
1137 extern const char FILENAME_rcs[];
1138 extern const char FILENAME_h_rcs[];
1139
1140
1141 #ifdef __cplusplus
1142 } /* extern "C" */
1143 #endif
1144
1145 #endif /* ndef _FILENAME_H */
1146
1147 /*
1148   Local Variables:
1149   tab-width: 3
1150   end:
1151 */
1152
1153    Example for function comments:
1154 /*********************************************************************
1155  *
1156  * Function    :  FUNCTION_NAME
1157  *
1158  * Description :  (Fill me in with a good description!)
1159  *
1160  * parameters  :
1161  *          1  :  param1 = pointer to an important thing
1162  *          2  :  x      = pointer to something else
1163  *
1164  * Returns     :  0 => Ok, everything else is an error.
1165  *
1166  *********************************************************************/
1167 int FUNCTION_NAME( void *param1, const char *x )
1168 {
1169    ...
1170    return( 0 );
1171
1172 }
1173
1174    Note: If we all follow this practice, we should be able to parse our
1175    code to create a "self-documenting" web page.
1176      _________________________________________________________________
1177    
1178 5. Version Control Guidelines
1179
1180    To be filled. note on cvs comments. don't comment what you did,
1181    comment why you did it.
1182      _________________________________________________________________
1183    
1184 6. Testing Guidelines
1185
1186    To be filled.
1187      _________________________________________________________________
1188    
1189 6.1. Testplan for releases
1190
1191    Explain release numbers. major, minor. developer releases. etc.
1192    
1193     1. Remove any existing rpm with rpm -e
1194     2. Remove any file that was left over. This includes (but is not
1195        limited to)
1196           + /var/log/junkbuster
1197           + /etc/junkbuster
1198           + /usr/sbin/junkbuster
1199           + /etc/init.d/junkbuster
1200           + /usr/doc/junkbuster*
1201     3. Install the rpm. Any error messages?
1202     4. start,stop,status junkbuster with the specific script (e.g.
1203        /etc/rc.d/init/junkbuster stop). Reboot your machine. Does
1204        autostart work?
1205     5. Start browsing. Does the junkbuster work? Logfile written?
1206     6. Remove the rpm. Any error messages? All files removed?
1207      _________________________________________________________________
1208    
1209 6.2. Test reports
1210
1211    Please submit test reports only with the [60]test form at sourceforge.
1212    Three simple steps:
1213    
1214      * Select category: the distribution you test on.
1215      * Select group: the version of Junkbuster that we are about to
1216        release.
1217      * Fill the Summary and Detailed Description with something
1218        intelligent (keep it short and precise).
1219        
1220    Do not mail to the mailinglist (we cannot keep track on issues there).
1221      _________________________________________________________________
1222    
1223 7. Contact the developers
1224
1225    Please see the user manual for information on how to contact the
1226    developers.
1227      _________________________________________________________________
1228    
1229 8. Copyright and History
1230
1231    Please see the user manual for information on Copyright and History.
1232      _________________________________________________________________
1233    
1234 9. See also
1235
1236    Please see the user manual for information on references.
1237
1238 References
1239
1240    1. http://ijbswa.sourceforge.net/developer-manual/
1241    2. mailto:ijbswa-developers@lists.sourceforge.net
1242    3. file://localhost/home/swa/sf/current/doc/source/tmp.html#INTRODUCTION
1243    4. file://localhost/home/swa/sf/current/doc/source/tmp.html#QUICKSTART
1244    5. file://localhost/home/swa/sf/current/doc/source/tmp.html#DOCUMENTATION
1245    6. file://localhost/home/swa/sf/current/doc/source/tmp.html#CODING
1246    7. file://localhost/home/swa/sf/current/doc/source/tmp.html#S1
1247    8. file://localhost/home/swa/sf/current/doc/source/tmp.html#S2
1248    9. file://localhost/home/swa/sf/current/doc/source/tmp.html#S3
1249   10. file://localhost/home/swa/sf/current/doc/source/tmp.html#S4
1250   11. file://localhost/home/swa/sf/current/doc/source/tmp.html#S5
1251   12. file://localhost/home/swa/sf/current/doc/source/tmp.html#S6
1252   13. file://localhost/home/swa/sf/current/doc/source/tmp.html#S7
1253   14. file://localhost/home/swa/sf/current/doc/source/tmp.html#S8
1254   15. file://localhost/home/swa/sf/current/doc/source/tmp.html#S9
1255   16. file://localhost/home/swa/sf/current/doc/source/tmp.html#S10
1256   17. file://localhost/home/swa/sf/current/doc/source/tmp.html#S11
1257   18. file://localhost/home/swa/sf/current/doc/source/tmp.html#S12
1258   19. file://localhost/home/swa/sf/current/doc/source/tmp.html#S13
1259   20. file://localhost/home/swa/sf/current/doc/source/tmp.html#S14
1260   21. file://localhost/home/swa/sf/current/doc/source/tmp.html#S15
1261   22. file://localhost/home/swa/sf/current/doc/source/tmp.html#S16
1262   23. file://localhost/home/swa/sf/current/doc/source/tmp.html#S17
1263   24. file://localhost/home/swa/sf/current/doc/source/tmp.html#S18
1264   25. file://localhost/home/swa/sf/current/doc/source/tmp.html#S19
1265   26. file://localhost/home/swa/sf/current/doc/source/tmp.html#S20
1266   27. file://localhost/home/swa/sf/current/doc/source/tmp.html#S21
1267   28. file://localhost/home/swa/sf/current/doc/source/tmp.html#S22
1268   29. file://localhost/home/swa/sf/current/doc/source/tmp.html#S23
1269   30. file://localhost/home/swa/sf/current/doc/source/tmp.html#S24
1270   31. file://localhost/home/swa/sf/current/doc/source/tmp.html#S25
1271   32. file://localhost/home/swa/sf/current/doc/source/tmp.html#S26
1272   33. file://localhost/home/swa/sf/current/doc/source/tmp.html#S27
1273   34. file://localhost/home/swa/sf/current/doc/source/tmp.html#S28
1274   35. file://localhost/home/swa/sf/current/doc/source/tmp.html#S29
1275   36. file://localhost/home/swa/sf/current/doc/source/tmp.html#S30
1276   37. file://localhost/home/swa/sf/current/doc/source/tmp.html#S31
1277   38. file://localhost/home/swa/sf/current/doc/source/tmp.html#S32
1278   39. file://localhost/home/swa/sf/current/doc/source/tmp.html#S33
1279   40. file://localhost/home/swa/sf/current/doc/source/tmp.html#S34
1280   41. file://localhost/home/swa/sf/current/doc/source/tmp.html#S35
1281   42. file://localhost/home/swa/sf/current/doc/source/tmp.html#S36
1282   43. file://localhost/home/swa/sf/current/doc/source/tmp.html#S37
1283   44. file://localhost/home/swa/sf/current/doc/source/tmp.html#S38
1284   45. file://localhost/home/swa/sf/current/doc/source/tmp.html#S39
1285   46. file://localhost/home/swa/sf/current/doc/source/tmp.html#S40
1286   47. file://localhost/home/swa/sf/current/doc/source/tmp.html#S41
1287   48. file://localhost/home/swa/sf/current/doc/source/tmp.html#S42
1288   49. file://localhost/home/swa/sf/current/doc/source/tmp.html#S43
1289   50. file://localhost/home/swa/sf/current/doc/source/tmp.html#S44
1290   51. file://localhost/home/swa/sf/current/doc/source/tmp.html#S45
1291   52. file://localhost/home/swa/sf/current/doc/source/tmp.html#S46
1292   53. file://localhost/home/swa/sf/current/doc/source/tmp.html#CVS
1293   54. file://localhost/home/swa/sf/current/doc/source/tmp.html#TESTING
1294   55. file://localhost/home/swa/sf/current/doc/source/tmp.html#TESTING-PLAN
1295   56. file://localhost/home/swa/sf/current/doc/source/tmp.html#TESTING-REPORT
1296   57. file://localhost/home/swa/sf/current/doc/source/tmp.html#CONTACT
1297   58. file://localhost/home/swa/sf/current/doc/source/tmp.html#COPYRIGHT
1298   59. file://localhost/home/swa/sf/current/doc/source/tmp.html#SEEALSO
1299   60. http://sourceforge.net/tracker/?func=add&group_id=11118&atid=395005