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