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