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