1 <!DOCTYPE Article PUBLIC "-//OASIS//DTD DocBook V3.1//EN">
3 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
4 File : $Source: /cvsroot/ijbswa/current/doc/source/developer-manual.sgml,v $
6 Purpose : developer manual
8 ijbswa.sourceforge.net:/home/groups/i/ij/ijbswa/htdocs/
10 $Id: developer-manual.sgml,v 1.3 2001/09/13 15:27:40 swa Exp $
12 Written by and Copyright (C) 2001 the SourceForge
13 IJBSWA team. http://ijbswa.sourceforge.net
15 Based on the Internet Junkbuster originally written
16 by and Copyright (C) 1997 Anonymous Coders and
17 Junkbusters Corporation. http://www.junkbusters.com
22 <title>Junkbuster Developer Manual</title>
24 <pubdate>$Id: developer-manual.sgml,v 1.3 2001/09/13 15:27:40 swa Exp $</pubdate>
29 <orgname>By: Junkbuster Developers</orgname>
36 The developer manual gives the users information on how to help the developer
37 team. It provides guidance on coding, testing, documentation and other
38 issues. The Internet Junkbuster is an application
39 that provides privacy and security to the user of the world wide web.
42 You can find the latest version of the user manual at <ulink
43 url="http://ijbswa.sourceforge.net/developer-manual/">http://ijbswa.sourceforge.net/developer-manual/</ulink>.
44 Please see the Contact section in the user-manual if you want to contact the developers.
48 Feel free to send a note to the developers at <email>ijbswa-developers@lists.sourceforge.net</email>.
53 <!-- ~~~~~ New section ~~~~~ -->
54 <sect1 id="introduction"><title>Introduction</title>
59 <!-- ~~~~~ New section ~~~~~ -->
60 <sect1 id="quickstart"><title>Quickstart to Junkbuster Development</title>
65 <!-- ~~~~~ New section ~~~~~ -->
66 <sect1 id="documentation"><title>Documentation Guidelines</title>
68 All docs should be ...
71 <Para>in a format that is widely used. I propose HTML.
78 <Para>generate man pages from the documentation (let's _NOT_
79 write them manually), or</Para>
81 <ListItem><Para>we have a man page that points to the
82 documentation (I propose this option)
84 </ItemizedList></Para></ListItem>
85 <ListItem><Para>have a consistent layout</Para></ListItem>
86 <ListItem><Para>have a link to the latest version of the document (i.e. point to a URL at sf)</Para></ListItem>
87 <ListItem><Para>be consistent with the redirect script (i.e. the junkbuster program
88 points via the redirect URL at sf to valid end-points in the document)</Para></ListItem>
89 <ListItem><Para>started from scratch but recycle parts from the original junkbuster documents</Para></ListItem>
94 <!-- ~~~~~ New section ~~~~~ -->
95 <sect1 id="coding"><title>Coding Guidelines</title>
97 <sect2 id="s1"><title>Introduction</title>
99 <para>This set of standards is designed to make our lives easier.
100 It is developed with the simple goal of helping us keep the
101 "new and improved Junkbusters" consistent and reliable. Thus
102 making maintenance easier and increasing chances of success of
105 <para>And that of course comes back to us as individuals. If we
106 can increase our development and product efficiencies then we
107 can solve more of the request for changes/improvements and in
108 general feel good about ourselves. ;-></para>
112 <sect2 id="s2"><title>Using Comments</title>
115 <sect3 id="s3"><title>Comment, Comment, Comment</title>
117 <para><emphasis>Explanation:</></para>
119 <para>Comment as much as possible without commenting the obvious.
120 For example do not comment "aVariable is equal to bVariable".
121 Instead explain why aVariable should be equal to the bVariable.
122 Just because a person can read code does not mean they will
123 understand why or what is being done. A reader may spend a lot
124 more time figuring out what is going on when a simple comment
125 or explanation would have prevented the extra research. Please
126 help your brother IJB'ers out!</para>
128 <para>The comments will also help justify the intent of the code.
129 If the comment describes something different than what the code
130 is doing then maybe a programming error is occurring.</para>
132 <para><emphasis>Example:</></para>
134 /* if page size greater than 1k ... */
135 if ( PageLength() > 1024 )
137 ... "block" the page up ...
140 /* if page size is small, send it in blocks */
141 if ( PageLength() > 1024 )
143 ... "block" the page up ...
146 This demonstrates 2 cases of "what not to do". The first is a
147 "syntax comment". The second is a comment that does not fit what
148 is actually being done.
154 <sect3 id="s4"><title>Use blocks for comments</title>
156 <para><emphasis>Explanation:</></para>
158 <para>Comments can help or they can clutter. They help when they
159 are differentiated from the code they describe. One line
160 comments do not offer effective separation between the comment
161 and the code. Block identifiers do, by surrounding the code
162 with a clear, definable pattern.</para>
164 <para><emphasis>Example:</></para>
166 /*********************************************************************
167 * This will stand out clearly in your code!
168 *********************************************************************/
169 if ( thisVariable == thatVariable )
171 DoSomethingVeryImportant();
175 /* unfortunately, this may not */
176 if ( thisVariable == thatVariable )
178 DoSomethingVeryImportant();
182 if ( thisVariable == thatVariable ) /* this may not either */
184 DoSomethingVeryImportant();
187 <para><emphasis>Exception:</></para>
189 <para>If you are trying to add a small logic comment and do not
190 wish to "disrubt" the flow of the code, feel free to use a 1
191 line comment which is NOT on the same line as the code.</para>
197 <sect3 id="s5"><title>Keep Comments on their own line</title>
199 <para><emphasis>Explanation:</></para>
201 <para>It goes back to the question of readability. If the comment
202 is on the same line as the code it will be harder to read than
203 the comment that is on its own line.</para>
205 <para>There are three exceptions to this rule, which should be
206 violated freely and often: during the definition of variables,
207 at the end of closing braces, when used to comment
210 <para><emphasis>Example:</></para>
212 /*********************************************************************
213 * This will stand out clearly in your code,
214 * But the second example won't.
215 *********************************************************************/
216 if ( thisVariable == thatVariable )
218 DoSomethingVeryImportant();
221 if ( thisVariable == thatVariable ) /*can you see me?*/
223 DoSomethingVeryImportant(); /*not easily*/
227 /*********************************************************************
228 * But, the encouraged exceptions:
229 *********************************************************************/
230 int urls_read = 0; /* # of urls read + rejected */
231 int urls_rejected = 0; /* # of urls rejected */
235 DoSomethingVeryImportant();
239 short DoSomethingVeryImportant(
240 short firstParam, /* represents something */
241 short nextParam /* represents something else */ )
245 } /* -END- DoSomethingVeryImportant */
250 <sect3 id="s6"><title>Comment each logical step</title>
252 <para><emphasis>Explanation:</></para>
254 <para>Logical steps should be commented to help others follow the
255 intent of the written code and comments will make the code more
258 <para>If you have 25 lines of code without a comment, you should
259 probably go back into it to see where you forgot to put
262 <para>Most "for", "while", "do", etc... loops _probably_ need a
263 comment. After all, these are usually major logic
270 <sect3 id="s7"><title>Comment All Functions Thoroughly</title>
272 <para><emphasis>Explanation:</></para>
274 <para>A reader of the code should be able to look at the comments
275 just prior to the beginning of a function and discern the
276 reason for its existence and the consequences of using it. The
277 reader should not have to read through the code to determine if
278 a given function is safe for a desired use. The proper
279 information thoroughly presented at the introduction of a
280 function not only saves time for subsequent maintenance or
281 debugging, it more importantly aids in code reuse by allowing a
282 user to determine the safety and applicability of any function
283 for the problem at hand. As a result of such benefits, all
284 functions should contain the information presented in the
285 addendum section of this document.</para>
291 <sect3 id="s8"><title>Comment at the end of braces if the
292 content is more than one screen length</title>
294 <para><emphasis>Explanation:</></para>
296 <para>Each closing brace should be followed on the same line by a
297 comment that describes the origination of the brace if the
298 original brace is off of the screen, or otherwise far away from
299 the closing brace. This will simplify the debugging,
300 maintenance, and readability of the code.</para>
302 <para>As a suggestion , use the following flags to make the
303 comment and its brace more readable:</para>
305 <para>use following a closing brace: } /* -END- if() or while ()
308 <para><emphasis>Example:</></para>
312 DoSomethingVeryImportant();
313 ...some long list of commands...
314 } /* -END- if x is 1 */
320 DoSomethingVeryImportant();
321 ...some long list of commands...
322 } /* -END- if ( 1 == X ) */
328 <sect2 id="s9"><title>Naming Conventions</title>
332 <sect3 id="s10"><title>Variable Names</title>
334 <para><emphasis>Explanation:</></para>
336 <para>Use all lowercase, and seperate words via an underscore
337 ('_'). Do not start an identifier with an underscore. (ANSI C
338 reserves these for use by the compiler and system headers.) Do
339 not use identifiers which are reserved in ANSI C++. (E.g.
340 template, class, true, false, ...). This is in case we ever
341 decide to port JunkBuster to C++.</para>
343 <para><emphasis>Example:</></para>
345 int ms_iis5_hack = 0;</programlisting>
347 <para><emphasis>Instead of:</></para>
351 int msiis5hack = 0; int msIis5Hack = 0;
359 <sect3 id="s11"><title>Function Names</title>
361 <para><emphasis>Explanation:</></para>
363 <para>Use all lowercase, and seperate words via an underscore
364 ('_'). Do not start an identifier with an underscore. (ANSI C
365 reserves these for use by the compiler and system headers.) Do
366 not use identifiers which are reserved in ANSI C++. (E.g.
367 template, class, true, false, ...). This is in case we ever
368 decide to port JunkBuster to C++.</para>
370 <para><emphasis>Example:</></para>
372 int load_some_file( struct client_state *csp )</programlisting>
374 <para><emphasis>Instead of:</></para>
378 int loadsomefile( struct client_state *csp )
379 int loadSomeFile( struct client_state *csp )
387 <sect3 id="s12"><title>Header file prototypes</title>
389 <para><emphasis>Explanation:</></para>
391 <para>Use a descriptive parameter name in the function prototype
392 in header files. Use the same parameter name in the header file
393 that you use in the c file.</para>
395 <para><emphasis>Example:</></para>
397 (.h) extern int load_aclfile( struct client_state *csp );
398 (.c) int load_aclfile( struct client_state *csp )</programlisting>
400 <para><emphasis>Instead of:</>
402 (.h) extern int load_aclfile( struct client_state * ); or
403 (.h) extern int load_aclfile();
404 (.c) int load_aclfile( struct client_state *csp )
412 <sect3 id="s13"><title>Enumerations, and #defines</title>
414 <para><emphasis>Explanation:</></para>
416 <para>Use all capital letters, with underscores between words. Do
417 not start an identifier with an underscore. (ANSI C reserves
418 these for use by the compiler and system headers.)</para>
420 <para><emphasis>Example:</></para>
422 (enumeration) : enum Boolean { FALSE, TRUE };
423 (#define) : #define DEFAULT_SIZE 100;</programlisting>
425 <para><emphasis>Note:</> We have a standard naming scheme for #defines
426 that toggle a feature in the preprocessor: FEATURE_>, where
427 > is a short (preferably 1 or 2 word) description.</para>
429 <para><emphasis>Example:</></para>
431 #define FEATURE_FORCE 1
434 #define FORCE_PREFIX blah
435 #endif /* def FEATURE_FORCE */
440 <sect3 id="s14"><title>Constants</title>
442 <para><emphasis>Explanation:</></para>
444 <para>Spell common words out entirely (do not remove vowels).</para>
446 <para>Use only widely-known domain acronyms and abbreviations.
447 Capitalize all letters of an acronym.</para>
449 <para>Use underscore (_) to separate adjacent acronyms and
450 abbreviations. Never terminate a name with an underscore.</para>
452 <para><emphasis>Example:</></para>
454 #define USE_IMAGE_LIST 1</programlisting>
456 <para><emphasis>Instead of:</></para>
460 #define USE_IMG_LST 1 or
461 #define _USE_IMAGE_LIST 1 or
462 #define USE_IMAGE_LIST_ 1 or
463 #define use_image_list 1 or
464 #define UseImageList 1
474 <sect2 id="s15"><title>Using Space</title>
478 <sect3 id="s16"><title>Put braces on a line by themselves.</title>
480 <para><emphasis>Explanation:</></para>
482 <para>The brace needs to be on a line all by itself, not at the
483 end of the statement. Curly braces should line up with the
484 construct that they're associated with. This practice makes it
485 easier to identify the opening and closing braces for a
488 <para><emphasis>Example:</></para>
495 <para><emphasis>Instead of:</></para>
497 <para>if ( this == that ) { ... }</para>
501 <para>if ( this == that ) { ... }</para>
503 <para><emphasis>Note:</> In the special case that the if-statement is
504 inside a loop, and it is trivial, i.e. it tests for a
505 condidtion that is obvious from the purpose of the block,
506 one-liners as above may optically preserve the loop structure
507 and make it easier to read.</para>
509 <para><emphasis>Status:</> developer-discrection.</para>
511 <para><emphasis>Example exception:</></para>
513 while ( more lines are read )
515 /* Please document what is/is not a comment line here */
516 if ( it's a comment ) continue;
518 do_something( line );
524 <sect3 id="s17"><title>ALL control statements should have a
527 <para><emphasis>Explanation:</></para>
529 <para>Using braces to make a block will make your code more
530 readable and less prone to error. All control statements should
531 have a block defined.</para>
533 <para><emphasis>Example:</></para>
541 <para><emphasis>Instead of:</></para>
543 <para>if ( this == that ) DoSomething(); DoSomethingElse();</para>
547 <para>if ( this == that ) DoSomething();</para>
549 <para><emphasis>Note:</> The first example in "Instead of" will execute
550 in a manner other than that which the developer desired (per
551 indentation). Using code braces would have prevented this
552 "feature". The "explanation" and "exception" from the point
553 above also applies.</para>
559 <sect3 id="s18"><title>Do not belabor/blow-up boolean
562 <para><emphasis>Example:</></para>
564 structure->flag = ( condition );</programlisting>
566 <para><emphasis>Instead of:</></para>
568 <para>if ( condition ) { structure->flag = 1; } else {
569 structure->flag = 0; }</para>
571 <para><emphasis>Note:</> The former is readable and consice. The later
572 is wordy and inefficient. Please assume that any developer new
573 to the project has at least a "good" knowledge of C/C++. (Hope
574 I do not offend by that last comment ... 8-)</para>
580 <sect3 id="s19"><title>Use white space freely because it is
583 <para><emphasis>Explanation:</></para>
585 <para>Make it readable. The notable exception to using white space
586 freely is listed in the next guideline.</para>
588 <para><emphasis>Example:</></para>
592 int anotherValue = 0;
593 int thisVariable = 0;
595 if ( thisVariable == thatVariable )
597 firstValue = oldValue + ( ( someValue - anotherValue ) - whatever )
602 <sect3 id="s20"><title>Don't use white space around structure
605 <para><emphasis>Explanation:</></para>
607 <para>- structure pointer operator ( "->" ) - member operator (
608 "." ) - functions and parentheses</para>
610 <para>It is a general coding practice to put pointers, references,
611 and function parentheses next to names. With spaces, the
612 connection between the object and variable/function name is not
615 <para><emphasis>Example:</></para>
619 FunctionName();</programlisting>
621 <para><emphasis>Instead of:</> aStruct -> aMember; aStruct . aMember;
622 FunctionName ();</para>
628 <sect3 id="s21"><title>Make the last brace of a function stand
631 <para><emphasis>Example:</></para>
638 } /* -END- function1 */
643 } /* -END- function2 */
646 <para><emphasis>Instead of:</></para>
648 <para>int function1( ... ) { ...code... return( retCode ); } int
649 function2( ... ) { }</para>
651 <para><emphasis>Note:</> Use 1 blank line before the closing brace and 2
652 lines afterwards. This makes the end of function standout to
653 the most casual viewer. Although function comments help
654 seperate functions, this is still a good coding practice. In
655 fact, I follow these rules when using blocks in "for", "while",
656 "do" loops, and long if {} statements too. After all whitespace
659 <para><emphasis>Status:</> developer-discrection on the number of blank
660 lines. Enforced is the end of function comments.</para>
666 <sect3 id="s22"><title>Use 3 character indentions</title>
668 <para><emphasis>Explanation:</></para>
670 <para>If some use 8 character TABs and some use 3 character TABs,
671 the code can look *very* ragged. So use 3 character indentions
672 only. If you like to use TABs, pass your code through a filter
673 such as "expand -t3" before checking in your code.</para>
675 <para><emphasis>Example:</></para>
677 static const char * const url_code_map[256] =
687 return( ALWAYS_TRUE );
691 return( HOW_DID_YOU_GET_HERE );
694 return( NEVER_GETS_HERE );
703 <sect2 id="s23"><title>Initializing</title>
707 <sect3 id="s24"><title>Initialize all variables</title>
709 <para><emphasis>Explanation:</></para>
711 <para>Do not assume that the variables declared will not be used
712 until after they have been assigned a value somewhere else in
713 the code. Remove the chance of accidentally using an unassigned
716 <para><emphasis>Example:</></para>
720 struct *ptr = NULL;</programlisting>
722 <para><emphasis>Note:</> It is much easier to debug a SIGSEGV if the
723 message says you are trying to access memory address 00000000
724 and not 129FA012; or arrayPtr[20] causes a SIGSEV vs.
727 <para><emphasis>Status:</> developer-discrection if and only if the
728 variable is assigned a value "shortly after" declaration.</para>
734 <sect2 id="s25"><title>Functions</title>
738 <sect3 id="s26"><title>Name functions that return a boolean as a
741 <para><emphasis>Explanation:</></para>
743 <para>Value should be phrased as a question that would logically
744 be answered as a true or false statement</para>
746 <para><emphasis>Example:</></para>
755 <sect3 id="s27"><title>Always specify a return type for a
758 <para><emphasis>Explanation:</></para>
760 <para>The default return for a function is an int. To avoid
761 ambiguity, create a return for a function when the return has a
762 purpose, and create a void return type if the function does not
763 need to return anything.</para>
769 <sect3 id="s28"><title>Minimize function calls when iterating by
770 using variables</title>
772 <para><emphasis>Explanation:</></para>
774 <para>It is easy to write the following code, and a clear argument
775 can be made that the code is easy to understand:</para>
777 <para><emphasis>Example:</></para>
779 for ( size_t cnt = 0; cnt < blockListLength(); cnt ++ )
784 <para><emphasis>Note:</> Unfortunately, this makes a function call for
785 each and every iteration. This increases the overhead in the
786 program, because the compiler has to look up the function each
787 time, call it, and return a value. Depending on what occurs in
788 the blockListLength() call, it might even be creating and
789 destroying structures with each iteration, even though in each
790 case it is comparing "cnt" to the same value, over and over.
791 Remember too - even a call to blockListLength() is a function
792 call, with the same overhead.</para>
794 <para>Instead of using a function call during the iterations,
795 assign the value to a variable, and evaluate using the
798 <para><emphasis>Example:</></para>
800 size_t len = blockListLength();
802 for ( size_t cnt = 0; cnt < len; cnt ++ )
807 <para><emphasis>Exceptions:</> if the value of blockListLength() *may*
808 change or could *potentially* change, then you must code the
809 function call in the for/while loop.</para>
815 <sect3 id="s29"><title>Pass and Return by Const Reference</title>
817 <para><emphasis>Explanation:</></para>
819 <para>This allows a developer to define a const pointer and call
820 your function. If your function does not have the const
821 keyword, we may not be able to use your function. Consider
822 strcmp, if it were defined as: extern int strcmp( char *s1,
825 <para>I could then not use it to compare argv's in main: int main(
826 int argc, const char *argv[] ) { strcmp( argv[0], "junkbusters"
829 <para>Both these pointers are *const*! If the c runtime library
830 maintainers do it, we should too.</para>
836 <sect3 id="s30"><title>Pass and Return by Value</title>
838 <para><emphasis>Explanation:</></para>
840 <para>Most structures cannot fit onto a normal stack entry (i.e.
841 they are not 4 bytes or less). Aka, a function declaration
842 like: int load_aclfile( struct client_state csp )</para>
844 <para>would not work. So, to be consistent, we should declare all
845 prototypes with "pass by value": int load_aclfile( struct
846 client_state *csp )</para>
852 <sect3 id="s31"><title>Names of include files</title>
854 <para><emphasis>Explanation:</></para>
856 <para>Your include statements should contain the file name without
857 a path. The path should be listed in the Makefile, using -I as
858 processor directive to search the indicated paths. An exception
859 to this would be for some proprietary software that utilizes a
860 partial path to distinguish their header files from system or
861 other header files.</para>
863 <para><emphasis>Example:</></para>
865 #include <iostream.h> /* This is not a local include */
866 #include "config.h" /* This IS a local include */
869 <para><emphasis>Exception:</></para>
873 /* This is not a local include, but requires a path element. */
874 #include <sys/fileName.h>
878 <para><emphasis>Note:</> Please! do not add "-I." to the Makefile
879 without a _very_ good reason. This duplicates the #include
880 "file.h" behaviour.</para>
886 <sect3 id="s32"><title>Provide multiple inclusion
889 <para><emphasis>Explanation:</></para>
891 <para>Prevents compiler and linker errors resulting from
892 redefinition of items.</para>
894 <para>Wrap each header file with the following syntax to prevent
895 multiple inclusions of the file. Of course, replace PROJECT_H
896 with your file name, with "." Changed to "_", and make it
899 <para><emphasis>Example:</></para>
901 #ifndef PROJECT_H_INCLUDED
902 #define PROJECT_H_INCLUDED
904 #endif /* ndef PROJECT_H_INCLUDED */
909 <sect3 id="s33"><title>Use `extern "C"` when appropriate</title>
911 <para><emphasis>Explanation:</></para>
913 <para>If our headers are included from C++, they must declare our
914 functions as `extern "C"`. This has no cost in C, but increases
915 the potential re-usability of our code.</para>
917 <para><emphasis>Example:</></para>
922 #endif /* def __cplusplus */
924 ... function definitions here ...
928 #endif /* def __cplusplus */
933 <sect3 id="s34"><title>Where Possible, Use Forward Struct
934 Declaration Instead of Includes</title>
936 <para><emphasis>Explanation:</></para>
938 <para>Useful in headers that include pointers to other struct's.
939 Modifications to excess header files may cause needless
942 <para><emphasis>Example:</></para>
944 /*********************************************************************
945 * We're avoiding an include statement here!
946 *********************************************************************/
948 extern file_list *xyz;</programlisting>
950 <para><emphasis>Note:</> If you declare "file_list xyz;" (without the
951 pointer), then including the proper header file is necessary.
952 If you only want to prototype a pointer, however, the header
953 file is unneccessary.</para>
955 <para><emphasis>Status:</> Use with discrection.</para>
961 <sect2 id="s35"><title>General Coding Practices</title>
965 <sect3 id="s36"><title>Turn on warnings</title>
967 <para><emphasis>Explanation</></para>
969 <para>Compiler warnings are meant to help you find bugs. You
970 should turn on as many as possible. With GCC, the switch is
971 "-Wall". Try and fix as many warnings as possible.</para>
977 <sect3 id="s37"><title>Provide a default case for all switch
980 <para><emphasis>Explanation:</></para>
982 <para>What you think is guaranteed is never really guaranteed. The
983 value that you don't think you need to check is the one that
984 someday will be passed. So, to protect yourself from the
985 unknown, always have a default step in a switch statement.</para>
987 <para><emphasis>Example:</></para>
989 switch( hash_string( cmd ) )
991 case hash_actions_file :
1001 ... anomly code goes here ...
1002 continue; / break; / exit( 1 ); / etc ...
1004 } /* end switch( hash_string( cmd ) ) */</programlisting>
1006 <para><emphasis>Note:</> If you already have a default condition, you
1007 are obviously exempt from this point. Of note, most of the
1008 WIN32 code calls `DefWindowProc' after the switch statement.
1009 This API call *should* be included in a default statement.</para>
1011 <para><emphasis>Another Note:</> This is not so much a readability issue
1012 as a robust programming issue. The "anomly code goes here" may
1013 be no more than a print to the STDERR stream (as in
1014 load_config). Or it may really be an ABEND condition.</para>
1016 <para><emphasis>Status:</> Programmer discretion is advised.</para>
1022 <sect3 id="s38"><title>Try to avoid falling through cases in a
1023 switch statement.</title>
1025 <para><emphasis>Explanation:</></para>
1027 <para>In general, you will want to have a 'break' statement within
1028 each 'case' of a switch statement. This allows for the code to
1029 be more readable and understandable, and furthermore can
1030 prevent unwanted surprises if someone else later gets creative
1031 and moves the code around.</para>
1033 <para>The language allows you to plan the fall through from one
1034 case statement to another simply by omitting the break
1035 statement within the case statement. This feature does have
1036 benefits, but should only be used in rare cases. In general,
1037 use a break statement for each case statement.</para>
1039 <para>If you choose to allow fall through, you should comment both
1040 the fact of the fall through and reason why you felt it was
1047 <sect3 id="s39"><title>Use 'long' or 'short' Instead of
1050 <para><emphasis>Explanation:</></para>
1052 <para>On 32-bit platforms, int usually has the range of long. On
1053 16-bit platforms, int has the range of short.</para>
1055 <para><emphasis>Status:</> open-to-debate. In the case of most FSF
1056 projects (including X/GNU-Emacs), there are typedefs to int4,
1057 int8, int16, (or equivalence ... I forget the exact typedefs
1058 now). Should we add these to IJB now that we have a "configure"
1065 <sect3 id="s40"><title>Don't mix size_t and other types</title>
1067 <para><emphasis>Explanation:</></para>
1069 <para>The type of size_t varies across platforms. Do not make
1070 assumptions about whether it is signed or unsigned, or about
1071 how long it is. Do not compare a size_t against another
1072 variable of a different type (or even against a constant)
1073 without casting one of the values. Try to avoid using size_t if
1080 <sect3 id="s41"><title>Declare each variable and struct on its
1083 <para><emphasis>Explanation:</></para>
1085 <para>It can be tempting to declare a series of variables all on
1086 one line. Don't.</para>
1088 <para><emphasis>Example:</></para>
1092 long c = 0;</programlisting>
1094 <para><emphasis>Instead of:</></para>
1096 <para>long a, b, c;</para>
1098 <para><emphasis>Explanation:</> - there is more room for comments on the
1099 individual variables - easier to add new variables without
1100 messing up the original ones - when searching on a variable to
1101 find its type, there is less clutter to "visually"
1104 <para><emphasis>Exceptions:</> when you want to declare a bunch of loop
1105 variables or other trivial variables; feel free to declare them
1106 on 1 line. You should, although, provide a good comment on
1107 their functions.</para>
1109 <para><emphasis>Status:</> developer-discrection.</para>
1115 <sect3 id="s42"><title>Use malloc/zalloc sparingly</title>
1117 <para><emphasis>Explanation:</></para>
1119 <para>Create a local stuct (on the stack) if the variable will
1120 live and die within the context of one function call.</para>
1122 <para>Only "malloc" a struct (on the heap) if the variable's life
1123 will extend beyond the context of one function call.</para>
1125 <para><emphasis>Example:</></para>
1127 If a function creates a struct and stores a pointer to it in a
1128 list, then it should definately be allocated via `malloc'.
1133 <sect3 id="s43"><title>The Programmer Who Uses 'malloc' is
1134 Responsible for Ensuring 'free'</title>
1136 <para><emphasis>Explanation:</></para>
1138 <para>If you have to "malloc" an instance, you are responsible for
1139 insuring that the instance is `free'd, even if the deallocation
1140 event falls within some other programmer's code. You are also
1141 responsible for ensuring that deletion is timely (i.e. not too
1142 soon, not too late). This is known as "low-coupling" and is a
1143 "good thing (tm)". You may need to offer a
1144 free/unload/destuctor type function to accomodate this.</para>
1146 <para><emphasis>Example:</></para>
1148 int load_re_filterfile( struct client_state *csp ) { ... }
1149 static void unload_re_filterfile( void *f ) { ... }</programlisting>
1151 <para><emphasis>Exceptions:</></para>
1153 <para>The developer cannot be expected to provide `free'ing
1154 functions for C run-time library functions ... such as
1157 <para><emphasis>Status:</> developer-discrection. The "main" use of this
1158 standard is for allocating and freeing data structures (complex
1165 <sect3 id="s44"><title>Add loaders to the `file_list' structure
1166 and in order</title>
1168 <para><emphasis>Explanation:</></para>
1170 <para>I have ordered all of the "blocker" file code to be in alpha
1171 order. It is easier to add/read new blockers when you expect a
1172 certain order.</para>
1174 <para><emphasis>Note:</> It may appear that the alpha order is broken in
1175 places by POPUP tests coming before PCRS tests. But since
1176 POPUPs can also be referred to as KILLPOPUPs, it is clear that
1177 it should come first.</para>
1183 <sect3 id="s45"><title>"Uncertain" new code and/or changes to
1184 exitinst code, use FIXME</title>
1186 <para><emphasis>Explanation:</></para>
1188 <para>If you have enough confidence in new code or confidence in
1189 your changes, but are not *quite* sure of the reprocussions,
1192 <para>/* FIXME: this code has a logic error on platform XYZ, *
1193 attempthing to fix */ #ifdef PLATFORM ...changed code here...
1198 <para>/* FIXME: I think the original author really meant this...
1199 */ ...changed code here...</para>
1203 <para>/* FIXME: new code that *may* break something else... */
1204 ...new code here...</para>
1206 <para><emphasis>Note:</> If you make it clear that this may or may not
1207 be a "good thing (tm)", it will be easier to identify and
1208 include in the project (or conversly exclude from the
1216 <sect2 id="s46"><title>Addendum: Template for files and function
1217 comment blocks:</title>
1219 <para><emphasis>Example for file comments:</></para>
1221 const char FILENAME_rcs[] = "$Id: developer-manual.sgml,v 1.3 2001/09/13 15:27:40 swa Exp $";
1222 /*********************************************************************
1224 * File : $S<!-- Break CVS Substitution -->ource$
1226 * Purpose : (Fill me in with a good description!)
1228 * Copyright : Written by and Copyright (C) 2001 the SourceForge
1229 * IJBSWA team. http://ijbswa.sourceforge.net
1231 * Based on the Internet Junkbuster originally written
1232 * by and Copyright (C) 1997 Anonymous Coders and
1233 * Junkbusters Corporation. http://www.junkbusters.com
1235 * This program is free software; you can redistribute it
1236 * and/or modify it under the terms of the GNU General
1237 * Public License as published by the Free Software
1238 * Foundation; either version 2 of the License, or (at
1239 * your option) any later version.
1241 * This program is distributed in the hope that it will
1242 * be useful, but WITHOUT ANY WARRANTY; without even the
1243 * implied warranty of MERCHANTABILITY or FITNESS FOR A
1244 * PARTICULAR PURPOSE. See the GNU General Public
1245 * License for more details.
1247 * The GNU General Public License should be included with
1248 * this file. If not, you can view it at
1249 * http://www.gnu.org/copyleft/gpl.html
1250 * or write to the Free Software Foundation, Inc., 59
1251 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1254 * $L<!-- Break CVS Substitution -->og$
1256 *********************************************************************/
1261 ...necessary include files for us to do our work...
1263 const char FILENAME_h_rcs[] = FILENAME_H_VERSION;
1266 <para><emphasis>Note:</> This declares the rcs variables that should be
1267 added to the "show-proxy-args" page. If this is a brand new
1268 creation by you, you are free to change the "Copyright" section
1269 to represent the rights you wish to maintain.</para>
1271 <para><emphasis>Note:</> The formfeed character that is present right
1272 after the comment flower box is handy for (X|GNU)Emacs users to
1273 skip the verbige and get to the heart of the code (via
1274 `forward-page' and `backward-page'). Please include it if you
1277 <para><emphasis>Example for file header comments:</></para>
1281 #define FILENAME_H_VERSION "$Id: developer-manual.sgml,v 1.3 2001/09/13 15:27:40 swa Exp $"
1282 /*********************************************************************
1284 * File : $S<!-- Break CVS Substitution -->ource$
1286 * Purpose : (Fill me in with a good description!)
1288 * Copyright : Written by and Copyright (C) 2001 the SourceForge
1289 * IJBSWA team. http://ijbswa.sourceforge.net
1291 * Based on the Internet Junkbuster originally written
1292 * by and Copyright (C) 1997 Anonymous Coders and
1293 * Junkbusters Corporation. http://www.junkbusters.com
1295 * This program is free software; you can redistribute it
1296 * and/or modify it under the terms of the GNU General
1297 * Public License as published by the Free Software
1298 * Foundation; either version 2 of the License, or (at
1299 * your option) any later version.
1301 * This program is distributed in the hope that it will
1302 * be useful, but WITHOUT ANY WARRANTY; without even the
1303 * implied warranty of MERCHANTABILITY or FITNESS FOR A
1304 * PARTICULAR PURPOSE. See the GNU General Public
1305 * License for more details.
1307 * The GNU General Public License should be included with
1308 * this file. If not, you can view it at
1309 * http://www.gnu.org/copyleft/gpl.html
1310 * or write to the Free Software Foundation, Inc., 59
1311 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1314 * $L<!-- Break CVS Substitution -->og$
1316 *********************************************************************/
1319 #include "project.h"
1325 ... function headers here ...
1328 /* Revision control strings from this header and associated .c file */
1329 extern const char FILENAME_rcs[];
1330 extern const char FILENAME_h_rcs[];
1337 #endif /* ndef _FILENAME_H */
1346 <para><emphasis>Example for function comments:</></para>
1348 /*********************************************************************
1350 * Function : FUNCTION_NAME
1352 * Description : (Fill me in with a good description!)
1355 * 1 : param1 = pointer to an important thing
1356 * 2 : x = pointer to something else
1358 * Returns : 0 => Ok, everything else is an error.
1360 *********************************************************************/
1361 int FUNCTION_NAME( void *param1, const char *x )
1369 <para><emphasis>Note:</> If we all follow this practice, we should be
1370 able to parse our code to create a "self-documenting" web
1377 <!-- ~~~~~ New section ~~~~~ -->
1378 <sect1 id="cvs"><title>Version Control Guidelines</title>
1379 <para>To be filled. note on cvs comments. don't comment what you did, comment
1384 <!-- ~~~~~ New section ~~~~~ -->
1385 <sect1 id="testing"><title>Testing Guidelines</title>
1389 <!-- ~~~~~ New section ~~~~~ -->
1390 <sect2 id="testing-plan"><title>Testplan for releases</title>
1392 Explain release numbers. major, minor. developer releases. etc.
1394 <OrderedList Numeration="Arabic">
1396 Remove any existing rpm with rpm -e
1399 Remove any file that was left over. This includes (but is not limited to)
1401 <ListItem><Para>/var/log/junkbuster</Para></ListItem>
1402 <ListItem><Para>/etc/junkbuster</Para></ListItem>
1403 <ListItem><Para>/usr/sbin/junkbuster</Para></ListItem>
1404 <ListItem><Para>/etc/init.d/junkbuster</Para></ListItem>
1405 <ListItem><Para>/usr/doc/junkbuster*</Para></ListItem>
1409 Install the rpm. Any error messages?
1411 <ListItem><Para>start,stop,status junkbuster with the specific script
1412 (e.g. /etc/rc.d/init/junkbuster stop). Reboot your machine. Does
1413 autostart work?</Para></ListItem>
1414 <ListItem><Para>Start browsing. Does the junkbuster work? Logfile written?</Para></ListItem>
1415 <ListItem><Para>Remove the rpm. Any error messages? All files removed?</Para></ListItem>
1420 <!-- ~~~~~ New section ~~~~~ -->
1421 <sect2 id="testing-report"><title>Test reports</title>
1423 Please submit test reports only with the <ulink url="http://sourceforge.net/tracker/?func=add&group_id=11118&atid=395005">test form</ulink>
1424 at sourceforge. Three simple steps:
1427 <ListItem><Para>Select category: the distribution you test on.</Para></ListItem>
1428 <ListItem><Para>Select group: the version of Junkbuster that we are about to release.</Para></ListItem>
1429 <ListItem><Para>Fill the Summary and Detailed Description with something
1430 intelligent (keep it short and precise).</Para>
1433 Do not mail to the mailinglist (we cannot keep track on issues there).
1439 <!-- ~~~~~ New section ~~~~~ -->
1440 <sect1 id="contact"><title>Contact the developers</title>
1441 <para>Please see the user manual for information on how to contact the developers.
1445 <!-- ~~~~~ New section ~~~~~ -->
1446 <sect1 id="copyright"><title>Copyright and History</title>
1447 <para>Please see the user manual for information on Copyright and History.
1451 <!-- ~~~~~ New section ~~~~~ -->
1452 <sect1 id="seealso"><title>See also</title>
1453 <para>Please see the user manual for information on references.
1459 This program is free software; you can redistribute it
1460 and/or modify it under the terms of the GNU General
1461 Public License as published by the Free Software
1462 Foundation; either version 2 of the License, or (at
1463 your option) any later version.
1465 This program is distributed in the hope that it will
1466 be useful, but WITHOUT ANY WARRANTY; without even the
1467 implied warranty of MERCHANTABILITY or FITNESS FOR A
1468 PARTICULAR PURPOSE. See the GNU General Public
1469 License for more details.
1471 The GNU General Public License should be included with
1472 this file. If not, you can view it at
1473 http://www.gnu.org/copyleft/gpl.html
1474 or write to the Free Software Foundation, Inc., 59
1475 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1477 $Log: developer-manual.sgml,v $
1478 Revision 1.3 2001/09/13 15:27:40 swa
1481 Revision 1.2 2001/09/13 15:20:17 swa
1482 merged standards into developer manual
1484 Revision 1.1 2001/09/12 15:36:41 swa
1485 source files for junkbuster documentation
1487 Revision 1.3 2001/09/10 17:43:59 swa
1488 first proposal of a structure.
1490 Revision 1.2 2001/06/13 14:28:31 swa
1491 docs should have an author.
1493 Revision 1.1 2001/06/13 14:20:37 swa
1494 first import of project's documentation for the webserver.