1 <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V3.1//EN">
3 File : $Source: /cvsroot/ijbswa/current/doc/source/developer-manual.sgml,v $
5 Purpose : developer manual
7 ijbswa.sourceforge.net:/home/groups/i/ij/ijbswa/htdocs/
9 $Id: developer-manual.sgml,v 1.6 2002/02/24 14:25:06 jongfoster Exp $
11 Written by and Copyright (C) 2001 the SourceForge
12 IJBSWA team. http://ijbswa.sourceforge.net
14 Based on the Internet Junkbuster originally written
15 by and Copyright (C) 1997 Anonymous Coders and
16 Junkbusters Corporation. http://www.junkbusters.com
21 <title>Junkbuster Developer Manual</title>
23 <pubdate>$Id: developer-manual.sgml,v 1.6 2002/02/24 14:25:06 jongfoster Exp $</pubdate>
28 <orgname>By: Junkbuster Developers</orgname>
35 The developer manual gives the users information on how to help the developer
36 team. It provides guidance on coding, testing, documentation and other
37 issues. <application>Internet Junkbuster</application> is a web proxy with
38 advanced filtering capabilities for protecting privacy, filtering web page
39 content, managing cookies, controlling access, and removing ads, banners,
40 pop-ups and other obnoxious Internet Junk. Junkbuster has a very flexible
41 configuration and can be customized to suit individual needs and
42 tastes. <application>Internet Junkbuster</application> has application for
43 both stand-alone systems and multi-user networks.
46 You can find the latest version of the user manual at <ulink
47 url="http://ijbswa.sourceforge.net/developer-manual/">http://ijbswa.sourceforge.net/developer-manual/</ulink>.
48 Please see the Contact section in the user-manual if you want to contact the developers.
52 <!-- Feel free to send a note to the developers at <email>ijbswa-developers@lists.sourceforge.net</email>. -->
58 <!-- ~~~~~ New section ~~~~~ -->
59 <sect1 id="introduction"><title>Introduction</title>
64 <!-- ~~~~~ New section ~~~~~ -->
65 <sect1 id="quickstart"><title>Quickstart to Junkbuster Development</title>
70 <!-- ~~~~~ New section ~~~~~ -->
71 <sect1 id="documentation"><title>Documentation Guidelines</title>
73 All docs are in SGML format and located in the <computeroutput>doc/source</computeroutput> directory.
76 How do you update the webserver (i.e. the pages on sourceforge)?
77 <orderedlist numeration="arabic">
79 Run <computeroutput>make dok</computeroutput> (which uses the documents in <computeroutput>doc/source</computeroutput> to update all
80 text files in <computeroutput>doc/text</computeroutput> and to update
81 all web documents in <computeroutput>doc/webserver</computeroutput>.
84 Run <computeroutput>make webserver</computeroutput> which copies all files from
85 <computeroutput>doc/webserver</computeroutput> to the sourceforge webserver
92 <!-- <listitem><para>be consistent with the redirect script (i.e. the junkbuster program -->
93 <!-- points via the redirect URL at sf to valid end-points in the document)</para></listitem> -->
95 <!-- ~~~~~ New section ~~~~~ -->
96 <sect1 id="coding"><title>Coding Guidelines</title>
98 <sect2 id="s1"><title>Introduction</title>
100 <para>This set of standards is designed to make our lives easier.
101 It is developed with the simple goal of helping us keep the
102 "new and improved Junkbusters" consistent and reliable. Thus
103 making maintenance easier and increasing chances of success of
106 <para>And that of course comes back to us as individuals. If we
107 can increase our development and product efficiencies then we
108 can solve more of the request for changes/improvements and in
109 general feel good about ourselves. ;-></para>
113 <sect2 id="s2"><title>Using Comments</title>
116 <sect3 id="s3"><title>Comment, Comment, Comment</title>
118 <para><emphasis>Explanation:</emphasis></para>
120 <para>Comment as much as possible without commenting the obvious.
121 For example do not comment "aVariable is equal to bVariable".
122 Instead explain why aVariable should be equal to the bVariable.
123 Just because a person can read code does not mean they will
124 understand why or what is being done. A reader may spend a lot
125 more time figuring out what is going on when a simple comment
126 or explanation would have prevented the extra research. Please
127 help your brother IJB'ers out!</para>
129 <para>The comments will also help justify the intent of the code.
130 If the comment describes something different than what the code
131 is doing then maybe a programming error is occurring.</para>
133 <para><emphasis>Example:</emphasis></para>
135 /* if page size greater than 1k ... */
136 if ( PageLength() > 1024 )
138 ... "block" the page up ...
141 /* if page size is small, send it in blocks */
142 if ( PageLength() > 1024 )
144 ... "block" the page up ...
147 This demonstrates 2 cases of "what not to do". The first is a
148 "syntax comment". The second is a comment that does not fit what
149 is actually being done.
155 <sect3 id="s4"><title>Use blocks for comments</title>
157 <para><emphasis>Explanation:</emphasis></para>
159 <para>Comments can help or they can clutter. They help when they
160 are differentiated from the code they describe. One line
161 comments do not offer effective separation between the comment
162 and the code. Block identifiers do, by surrounding the code
163 with a clear, definable pattern.</para>
165 <para><emphasis>Example:</emphasis></para>
167 /*********************************************************************
168 * This will stand out clearly in your code!
169 *********************************************************************/
170 if ( thisVariable == thatVariable )
172 DoSomethingVeryImportant();
176 /* unfortunately, this may not */
177 if ( thisVariable == thatVariable )
179 DoSomethingVeryImportant();
183 if ( thisVariable == thatVariable ) /* this may not either */
185 DoSomethingVeryImportant();
188 <para><emphasis>Exception:</emphasis></para>
190 <para>If you are trying to add a small logic comment and do not
191 wish to "disrubt" the flow of the code, feel free to use a 1
192 line comment which is NOT on the same line as the code.</para>
198 <sect3 id="s5"><title>Keep Comments on their own line</title>
200 <para><emphasis>Explanation:</emphasis></para>
202 <para>It goes back to the question of readability. If the comment
203 is on the same line as the code it will be harder to read than
204 the comment that is on its own line.</para>
206 <para>There are three exceptions to this rule, which should be
207 violated freely and often: during the definition of variables,
208 at the end of closing braces, when used to comment
211 <para><emphasis>Example:</emphasis></para>
213 /*********************************************************************
214 * This will stand out clearly in your code,
215 * But the second example won't.
216 *********************************************************************/
217 if ( thisVariable == thatVariable )
219 DoSomethingVeryImportant();
222 if ( thisVariable == thatVariable ) /*can you see me?*/
224 DoSomethingVeryImportant(); /*not easily*/
228 /*********************************************************************
229 * But, the encouraged exceptions:
230 *********************************************************************/
231 int urls_read = 0; /* # of urls read + rejected */
232 int urls_rejected = 0; /* # of urls rejected */
236 DoSomethingVeryImportant();
240 short DoSomethingVeryImportant(
241 short firstparam, /* represents something */
242 short nextparam /* represents something else */ )
246 } /* -END- DoSomethingVeryImportant */
251 <sect3 id="s6"><title>Comment each logical step</title>
253 <para><emphasis>Explanation:</emphasis></para>
255 <para>Logical steps should be commented to help others follow the
256 intent of the written code and comments will make the code more
259 <para>If you have 25 lines of code without a comment, you should
260 probably go back into it to see where you forgot to put
263 <para>Most "for", "while", "do", etc... loops _probably_ need a
264 comment. After all, these are usually major logic
271 <sect3 id="s7"><title>Comment All Functions Thoroughly</title>
273 <para><emphasis>Explanation:</emphasis></para>
275 <para>A reader of the code should be able to look at the comments
276 just prior to the beginning of a function and discern the
277 reason for its existence and the consequences of using it. The
278 reader should not have to read through the code to determine if
279 a given function is safe for a desired use. The proper
280 information thoroughly presented at the introduction of a
281 function not only saves time for subsequent maintenance or
282 debugging, it more importantly aids in code reuse by allowing a
283 user to determine the safety and applicability of any function
284 for the problem at hand. As a result of such benefits, all
285 functions should contain the information presented in the
286 addendum section of this document.</para>
292 <sect3 id="s8"><title>Comment at the end of braces if the
293 content is more than one screen length</title>
295 <para><emphasis>Explanation:</emphasis></para>
297 <para>Each closing brace should be followed on the same line by a
298 comment that describes the origination of the brace if the
299 original brace is off of the screen, or otherwise far away from
300 the closing brace. This will simplify the debugging,
301 maintenance, and readability of the code.</para>
303 <para>As a suggestion , use the following flags to make the
304 comment and its brace more readable:</para>
306 <para>use following a closing brace: } /* -END- if() or while ()
309 <para><emphasis>Example:</emphasis></para>
313 DoSomethingVeryImportant();
314 ...some long list of commands...
315 } /* -END- if x is 1 */
321 DoSomethingVeryImportant();
322 ...some long list of commands...
323 } /* -END- if ( 1 == X ) */
329 <sect2 id="s9"><title>Naming Conventions</title>
333 <sect3 id="s10"><title>Variable Names</title>
335 <para><emphasis>Explanation:</emphasis></para>
337 <para>Use all lowercase, and seperate words via an underscore
338 ('_'). Do not start an identifier with an underscore. (ANSI C
339 reserves these for use by the compiler and system headers.) Do
340 not use identifiers which are reserved in ANSI C++. (E.g.
341 template, class, true, false, ...). This is in case we ever
342 decide to port JunkBuster to C++.</para>
344 <para><emphasis>Example:</emphasis></para>
346 int ms_iis5_hack = 0;</programlisting>
348 <para><emphasis>Instead of:</emphasis></para>
352 int msiis5hack = 0; int msIis5Hack = 0;
360 <sect3 id="s11"><title>Function Names</title>
362 <para><emphasis>Explanation:</emphasis></para>
364 <para>Use all lowercase, and seperate words via an underscore
365 ('_'). Do not start an identifier with an underscore. (ANSI C
366 reserves these for use by the compiler and system headers.) Do
367 not use identifiers which are reserved in ANSI C++. (E.g.
368 template, class, true, false, ...). This is in case we ever
369 decide to port JunkBuster to C++.</para>
371 <para><emphasis>Example:</emphasis></para>
373 int load_some_file( struct client_state *csp )</programlisting>
375 <para><emphasis>Instead of:</emphasis></para>
379 int loadsomefile( struct client_state *csp )
380 int loadSomeFile( struct client_state *csp )
388 <sect3 id="s12"><title>Header file prototypes</title>
390 <para><emphasis>Explanation:</emphasis></para>
392 <para>Use a descriptive parameter name in the function prototype
393 in header files. Use the same parameter name in the header file
394 that you use in the c file.</para>
396 <para><emphasis>Example:</emphasis></para>
398 (.h) extern int load_aclfile( struct client_state *csp );
399 (.c) int load_aclfile( struct client_state *csp )</programlisting>
401 <para><emphasis>Instead of:</emphasis>
403 (.h) extern int load_aclfile( struct client_state * ); or
404 (.h) extern int load_aclfile();
405 (.c) int load_aclfile( struct client_state *csp )
413 <sect3 id="s13"><title>Enumerations, and #defines</title>
415 <para><emphasis>Explanation:</emphasis></para>
417 <para>Use all capital letters, with underscores between words. Do
418 not start an identifier with an underscore. (ANSI C reserves
419 these for use by the compiler and system headers.)</para>
421 <para><emphasis>Example:</emphasis></para>
423 (enumeration) : enum Boolean { FALSE, TRUE };
424 (#define) : #define DEFAULT_SIZE 100;</programlisting>
426 <para><emphasis>Note:</emphasis> We have a standard naming scheme for #defines
427 that toggle a feature in the preprocessor: FEATURE_>, where
428 > is a short (preferably 1 or 2 word) description.</para>
430 <para><emphasis>Example:</emphasis></para>
432 #define FEATURE_FORCE 1
435 #define FORCE_PREFIX blah
436 #endif /* def FEATURE_FORCE */
441 <sect3 id="s14"><title>Constants</title>
443 <para><emphasis>Explanation:</emphasis></para>
445 <para>Spell common words out entirely (do not remove vowels).</para>
447 <para>Use only widely-known domain acronyms and abbreviations.
448 Capitalize all letters of an acronym.</para>
450 <para>Use underscore (_) to separate adjacent acronyms and
451 abbreviations. Never terminate a name with an underscore.</para>
453 <para><emphasis>Example:</emphasis></para>
455 #define USE_IMAGE_LIST 1</programlisting>
457 <para><emphasis>Instead of:</emphasis></para>
461 #define USE_IMG_LST 1 or
462 #define _USE_IMAGE_LIST 1 or
463 #define USE_IMAGE_LIST_ 1 or
464 #define use_image_list 1 or
465 #define UseImageList 1
475 <sect2 id="s15"><title>Using Space</title>
479 <sect3 id="s16"><title>Put braces on a line by themselves.</title>
481 <para><emphasis>Explanation:</emphasis></para>
483 <para>The brace needs to be on a line all by itself, not at the
484 end of the statement. Curly braces should line up with the
485 construct that they're associated with. This practice makes it
486 easier to identify the opening and closing braces for a
489 <para><emphasis>Example:</emphasis></para>
496 <para><emphasis>Instead of:</emphasis></para>
498 <para>if ( this == that ) { ... }</para>
502 <para>if ( this == that ) { ... }</para>
504 <para><emphasis>Note:</emphasis> In the special case that the if-statement is
505 inside a loop, and it is trivial, i.e. it tests for a
506 condidtion that is obvious from the purpose of the block,
507 one-liners as above may optically preserve the loop structure
508 and make it easier to read.</para>
510 <para><emphasis>Status:</emphasis> developer-discrection.</para>
512 <para><emphasis>Example exception:</emphasis></para>
514 while ( more lines are read )
516 /* Please document what is/is not a comment line here */
517 if ( it's a comment ) continue;
519 do_something( line );
525 <sect3 id="s17"><title>ALL control statements should have a
528 <para><emphasis>Explanation:</emphasis></para>
530 <para>Using braces to make a block will make your code more
531 readable and less prone to error. All control statements should
532 have a block defined.</para>
534 <para><emphasis>Example:</emphasis></para>
542 <para><emphasis>Instead of:</emphasis></para>
544 <para>if ( this == that ) DoSomething(); DoSomethingElse();</para>
548 <para>if ( this == that ) DoSomething();</para>
550 <para><emphasis>Note:</emphasis> The first example in "Instead of" will execute
551 in a manner other than that which the developer desired (per
552 indentation). Using code braces would have prevented this
553 "feature". The "explanation" and "exception" from the point
554 above also applies.</para>
560 <sect3 id="s18"><title>Do not belabor/blow-up boolean
563 <para><emphasis>Example:</emphasis></para>
565 structure->flag = ( condition );</programlisting>
567 <para><emphasis>Instead of:</emphasis></para>
569 <para>if ( condition ) { structure->flag = 1; } else {
570 structure->flag = 0; }</para>
572 <para><emphasis>Note:</emphasis> The former is readable and consice. The later
573 is wordy and inefficient. Please assume that any developer new
574 to the project has at least a "good" knowledge of C/C++. (Hope
575 I do not offend by that last comment ... 8-)</para>
581 <sect3 id="s19"><title>Use white space freely because it is
584 <para><emphasis>Explanation:</emphasis></para>
586 <para>Make it readable. The notable exception to using white space
587 freely is listed in the next guideline.</para>
589 <para><emphasis>Example:</emphasis></para>
593 int anotherValue = 0;
594 int thisVariable = 0;
596 if ( thisVariable == thatVariable )
598 firstValue = oldValue + ( ( someValue - anotherValue ) - whatever )
603 <sect3 id="s20"><title>Don't use white space around structure
606 <para><emphasis>Explanation:</emphasis></para>
608 <para>- structure pointer operator ( "->" ) - member operator (
609 "." ) - functions and parentheses</para>
611 <para>It is a general coding practice to put pointers, references,
612 and function parentheses next to names. With spaces, the
613 connection between the object and variable/function name is not
616 <para><emphasis>Example:</emphasis></para>
620 FunctionName();</programlisting>
622 <para><emphasis>Instead of:</emphasis> aStruct -> aMember; aStruct . aMember;
623 FunctionName ();</para>
629 <sect3 id="s21"><title>Make the last brace of a function stand
632 <para><emphasis>Example:</emphasis></para>
639 } /* -END- function1 */
644 } /* -END- function2 */
647 <para><emphasis>Instead of:</emphasis></para>
649 <para>int function1( ... ) { ...code... return( retCode ); } int
650 function2( ... ) { }</para>
652 <para><emphasis>Note:</emphasis> Use 1 blank line before the closing brace and 2
653 lines afterwards. This makes the end of function standout to
654 the most casual viewer. Although function comments help
655 seperate functions, this is still a good coding practice. In
656 fact, I follow these rules when using blocks in "for", "while",
657 "do" loops, and long if {} statements too. After all whitespace
660 <para><emphasis>Status:</emphasis> developer-discrection on the number of blank
661 lines. Enforced is the end of function comments.</para>
667 <sect3 id="s22"><title>Use 3 character indentions</title>
669 <para><emphasis>Explanation:</emphasis></para>
671 <para>If some use 8 character TABs and some use 3 character TABs,
672 the code can look *very* ragged. So use 3 character indentions
673 only. If you like to use TABs, pass your code through a filter
674 such as "expand -t3" before checking in your code.</para>
676 <para><emphasis>Example:</emphasis></para>
678 static const char * const url_code_map[256] =
688 return( ALWAYS_TRUE );
692 return( HOW_DID_YOU_GET_HERE );
695 return( NEVER_GETS_HERE );
704 <sect2 id="s23"><title>Initializing</title>
708 <sect3 id="s24"><title>Initialize all variables</title>
710 <para><emphasis>Explanation:</emphasis></para>
712 <para>Do not assume that the variables declared will not be used
713 until after they have been assigned a value somewhere else in
714 the code. Remove the chance of accidentally using an unassigned
717 <para><emphasis>Example:</emphasis></para>
721 struct *ptr = NULL;</programlisting>
723 <para><emphasis>Note:</emphasis> It is much easier to debug a SIGSEGV if the
724 message says you are trying to access memory address 00000000
725 and not 129FA012; or arrayPtr[20] causes a SIGSEV vs.
728 <para><emphasis>Status:</emphasis> developer-discrection if and only if the
729 variable is assigned a value "shortly after" declaration.</para>
735 <sect2 id="s25"><title>Functions</title>
739 <sect3 id="s26"><title>Name functions that return a boolean as a
742 <para><emphasis>Explanation:</emphasis></para>
744 <para>Value should be phrased as a question that would logically
745 be answered as a true or false statement</para>
747 <para><emphasis>Example:</emphasis></para>
756 <sect3 id="s27"><title>Always specify a return type for a
759 <para><emphasis>Explanation:</emphasis></para>
761 <para>The default return for a function is an int. To avoid
762 ambiguity, create a return for a function when the return has a
763 purpose, and create a void return type if the function does not
764 need to return anything.</para>
770 <sect3 id="s28"><title>Minimize function calls when iterating by
771 using variables</title>
773 <para><emphasis>Explanation:</emphasis></para>
775 <para>It is easy to write the following code, and a clear argument
776 can be made that the code is easy to understand:</para>
778 <para><emphasis>Example:</emphasis></para>
780 for ( size_t cnt = 0; cnt < blockListLength(); cnt ++ )
785 <para><emphasis>Note:</emphasis> Unfortunately, this makes a function call for
786 each and every iteration. This increases the overhead in the
787 program, because the compiler has to look up the function each
788 time, call it, and return a value. Depending on what occurs in
789 the blockListLength() call, it might even be creating and
790 destroying structures with each iteration, even though in each
791 case it is comparing "cnt" to the same value, over and over.
792 Remember too - even a call to blockListLength() is a function
793 call, with the same overhead.</para>
795 <para>Instead of using a function call during the iterations,
796 assign the value to a variable, and evaluate using the
799 <para><emphasis>Example:</emphasis></para>
801 size_t len = blockListLength();
803 for ( size_t cnt = 0; cnt < len; cnt ++ )
808 <para><emphasis>Exceptions:</emphasis> if the value of blockListLength() *may*
809 change or could *potentially* change, then you must code the
810 function call in the for/while loop.</para>
816 <sect3 id="s29"><title>Pass and Return by Const Reference</title>
818 <para><emphasis>Explanation:</emphasis></para>
820 <para>This allows a developer to define a const pointer and call
821 your function. If your function does not have the const
822 keyword, we may not be able to use your function. Consider
823 strcmp, if it were defined as: extern int strcmp( char *s1,
826 <para>I could then not use it to compare argv's in main: int main(
827 int argc, const char *argv[] ) { strcmp( argv[0], "junkbusters"
830 <para>Both these pointers are *const*! If the c runtime library
831 maintainers do it, we should too.</para>
837 <sect3 id="s30"><title>Pass and Return by Value</title>
839 <para><emphasis>Explanation:</emphasis></para>
841 <para>Most structures cannot fit onto a normal stack entry (i.e.
842 they are not 4 bytes or less). Aka, a function declaration
843 like: int load_aclfile( struct client_state csp )</para>
845 <para>would not work. So, to be consistent, we should declare all
846 prototypes with "pass by value": int load_aclfile( struct
847 client_state *csp )</para>
853 <sect3 id="s31"><title>Names of include files</title>
855 <para><emphasis>Explanation:</emphasis></para>
857 <para>Your include statements should contain the file name without
858 a path. The path should be listed in the Makefile, using -I as
859 processor directive to search the indicated paths. An exception
860 to this would be for some proprietary software that utilizes a
861 partial path to distinguish their header files from system or
862 other header files.</para>
864 <para><emphasis>Example:</emphasis></para>
866 #include <iostream.h> /* This is not a local include */
867 #include "config.h" /* This IS a local include */
870 <para><emphasis>Exception:</emphasis></para>
874 /* This is not a local include, but requires a path element. */
875 #include <sys/fileName.h>
879 <para><emphasis>Note:</emphasis> Please! do not add "-I." to the Makefile
880 without a _very_ good reason. This duplicates the #include
881 "file.h" behaviour.</para>
887 <sect3 id="s32"><title>Provide multiple inclusion
890 <para><emphasis>Explanation:</emphasis></para>
892 <para>Prevents compiler and linker errors resulting from
893 redefinition of items.</para>
895 <para>Wrap each header file with the following syntax to prevent
896 multiple inclusions of the file. Of course, replace PROJECT_H
897 with your file name, with "." Changed to "_", and make it
900 <para><emphasis>Example:</emphasis></para>
902 #ifndef PROJECT_H_INCLUDED
903 #define PROJECT_H_INCLUDED
905 #endif /* ndef PROJECT_H_INCLUDED */
910 <sect3 id="s33"><title>Use `extern "C"` when appropriate</title>
912 <para><emphasis>Explanation:</emphasis></para>
914 <para>If our headers are included from C++, they must declare our
915 functions as `extern "C"`. This has no cost in C, but increases
916 the potential re-usability of our code.</para>
918 <para><emphasis>Example:</emphasis></para>
923 #endif /* def __cplusplus */
925 ... function definitions here ...
929 #endif /* def __cplusplus */
934 <sect3 id="s34"><title>Where Possible, Use Forward Struct
935 Declaration Instead of Includes</title>
937 <para><emphasis>Explanation:</emphasis></para>
939 <para>Useful in headers that include pointers to other struct's.
940 Modifications to excess header files may cause needless
943 <para><emphasis>Example:</emphasis></para>
945 /*********************************************************************
946 * We're avoiding an include statement here!
947 *********************************************************************/
949 extern file_list *xyz;</programlisting>
951 <para><emphasis>Note:</emphasis> If you declare "file_list xyz;" (without the
952 pointer), then including the proper header file is necessary.
953 If you only want to prototype a pointer, however, the header
954 file is unneccessary.</para>
956 <para><emphasis>Status:</emphasis> Use with discrection.</para>
962 <sect2 id="s35"><title>General Coding Practices</title>
966 <sect3 id="s36"><title>Turn on warnings</title>
968 <para><emphasis>Explanation</emphasis></para>
970 <para>Compiler warnings are meant to help you find bugs. You
971 should turn on as many as possible. With GCC, the switch is
972 "-Wall". Try and fix as many warnings as possible.</para>
978 <sect3 id="s37"><title>Provide a default case for all switch
981 <para><emphasis>Explanation:</emphasis></para>
983 <para>What you think is guaranteed is never really guaranteed. The
984 value that you don't think you need to check is the one that
985 someday will be passed. So, to protect yourself from the
986 unknown, always have a default step in a switch statement.</para>
988 <para><emphasis>Example:</emphasis></para>
990 switch( hash_string( cmd ) )
992 case hash_actions_file :
1002 ... anomly code goes here ...
1003 continue; / break; / exit( 1 ); / etc ...
1005 } /* end switch( hash_string( cmd ) ) */</programlisting>
1007 <para><emphasis>Note:</emphasis> If you already have a default condition, you
1008 are obviously exempt from this point. Of note, most of the
1009 WIN32 code calls `DefWindowProc' after the switch statement.
1010 This API call *should* be included in a default statement.</para>
1012 <para><emphasis>Another Note:</emphasis> This is not so much a readability issue
1013 as a robust programming issue. The "anomly code goes here" may
1014 be no more than a print to the STDERR stream (as in
1015 load_config). Or it may really be an ABEND condition.</para>
1017 <para><emphasis>Status:</emphasis> Programmer discretion is advised.</para>
1023 <sect3 id="s38"><title>Try to avoid falling through cases in a
1024 switch statement.</title>
1026 <para><emphasis>Explanation:</emphasis></para>
1028 <para>In general, you will want to have a 'break' statement within
1029 each 'case' of a switch statement. This allows for the code to
1030 be more readable and understandable, and furthermore can
1031 prevent unwanted surprises if someone else later gets creative
1032 and moves the code around.</para>
1034 <para>The language allows you to plan the fall through from one
1035 case statement to another simply by omitting the break
1036 statement within the case statement. This feature does have
1037 benefits, but should only be used in rare cases. In general,
1038 use a break statement for each case statement.</para>
1040 <para>If you choose to allow fall through, you should comment both
1041 the fact of the fall through and reason why you felt it was
1048 <sect3 id="s39"><title>Use 'long' or 'short' Instead of
1051 <para><emphasis>Explanation:</emphasis></para>
1053 <para>On 32-bit platforms, int usually has the range of long. On
1054 16-bit platforms, int has the range of short.</para>
1056 <para><emphasis>Status:</emphasis> open-to-debate. In the case of most FSF
1057 projects (including X/GNU-Emacs), there are typedefs to int4,
1058 int8, int16, (or equivalence ... I forget the exact typedefs
1059 now). Should we add these to IJB now that we have a "configure"
1066 <sect3 id="s40"><title>Don't mix size_t and other types</title>
1068 <para><emphasis>Explanation:</emphasis></para>
1070 <para>The type of size_t varies across platforms. Do not make
1071 assumptions about whether it is signed or unsigned, or about
1072 how long it is. Do not compare a size_t against another
1073 variable of a different type (or even against a constant)
1074 without casting one of the values. Try to avoid using size_t if
1081 <sect3 id="s41"><title>Declare each variable and struct on its
1084 <para><emphasis>Explanation:</emphasis></para>
1086 <para>It can be tempting to declare a series of variables all on
1087 one line. Don't.</para>
1089 <para><emphasis>Example:</emphasis></para>
1093 long c = 0;</programlisting>
1095 <para><emphasis>Instead of:</emphasis></para>
1097 <para>long a, b, c;</para>
1099 <para><emphasis>Explanation:</emphasis> - there is more room for comments on the
1100 individual variables - easier to add new variables without
1101 messing up the original ones - when searching on a variable to
1102 find its type, there is less clutter to "visually"
1105 <para><emphasis>Exceptions:</emphasis> when you want to declare a bunch of loop
1106 variables or other trivial variables; feel free to declare them
1107 on 1 line. You should, although, provide a good comment on
1108 their functions.</para>
1110 <para><emphasis>Status:</emphasis> developer-discrection.</para>
1116 <sect3 id="s42"><title>Use malloc/zalloc sparingly</title>
1118 <para><emphasis>Explanation:</emphasis></para>
1120 <para>Create a local stuct (on the stack) if the variable will
1121 live and die within the context of one function call.</para>
1123 <para>Only "malloc" a struct (on the heap) if the variable's life
1124 will extend beyond the context of one function call.</para>
1126 <para><emphasis>Example:</emphasis></para>
1128 If a function creates a struct and stores a pointer to it in a
1129 list, then it should definately be allocated via `malloc'.
1134 <sect3 id="s43"><title>The Programmer Who Uses 'malloc' is
1135 Responsible for Ensuring 'free'</title>
1137 <para><emphasis>Explanation:</emphasis></para>
1139 <para>If you have to "malloc" an instance, you are responsible for
1140 insuring that the instance is `free'd, even if the deallocation
1141 event falls within some other programmer's code. You are also
1142 responsible for ensuring that deletion is timely (i.e. not too
1143 soon, not too late). This is known as "low-coupling" and is a
1144 "good thing (tm)". You may need to offer a
1145 free/unload/destuctor type function to accomodate this.</para>
1147 <para><emphasis>Example:</emphasis></para>
1149 int load_re_filterfile( struct client_state *csp ) { ... }
1150 static void unload_re_filterfile( void *f ) { ... }</programlisting>
1152 <para><emphasis>Exceptions:</emphasis></para>
1154 <para>The developer cannot be expected to provide `free'ing
1155 functions for C run-time library functions ... such as
1158 <para><emphasis>Status:</emphasis> developer-discrection. The "main" use of this
1159 standard is for allocating and freeing data structures (complex
1166 <sect3 id="s44"><title>Add loaders to the `file_list' structure
1167 and in order</title>
1169 <para><emphasis>Explanation:</emphasis></para>
1171 <para>I have ordered all of the "blocker" file code to be in alpha
1172 order. It is easier to add/read new blockers when you expect a
1173 certain order.</para>
1175 <para><emphasis>Note:</emphasis> It may appear that the alpha order is broken in
1176 places by POPUP tests coming before PCRS tests. But since
1177 POPUPs can also be referred to as KILLPOPUPs, it is clear that
1178 it should come first.</para>
1184 <sect3 id="s45"><title>"Uncertain" new code and/or changes to
1185 exitinst code, use FIXME</title>
1187 <para><emphasis>Explanation:</emphasis></para>
1189 <para>If you have enough confidence in new code or confidence in
1190 your changes, but are not *quite* sure of the reprocussions,
1193 <para>/* FIXME: this code has a logic error on platform XYZ, *
1194 attempthing to fix */ #ifdef PLATFORM ...changed code here...
1199 <para>/* FIXME: I think the original author really meant this...
1200 */ ...changed code here...</para>
1204 <para>/* FIXME: new code that *may* break something else... */
1205 ...new code here...</para>
1207 <para><emphasis>Note:</emphasis> If you make it clear that this may or may not
1208 be a "good thing (tm)", it will be easier to identify and
1209 include in the project (or conversly exclude from the
1217 <sect2 id="s46"><title>Addendum: Template for files and function
1218 comment blocks:</title>
1220 <para><emphasis>Example for file comments:</emphasis></para>
1222 const char FILENAME_rcs[] = "$Id: developer-manual.sgml,v 1.6 2002/02/24 14:25:06 jongfoster Exp $";
1223 /*********************************************************************
1225 * File : $S<!-- Break CVS Substitution -->ource$
1227 * Purpose : (Fill me in with a good description!)
1229 * Copyright : Written by and Copyright (C) 2001 the SourceForge
1230 * IJBSWA team. http://ijbswa.sourceforge.net
1232 * Based on the Internet Junkbuster originally written
1233 * by and Copyright (C) 1997 Anonymous Coders and
1234 * Junkbusters Corporation. http://www.junkbusters.com
1236 * This program is free software; you can redistribute it
1237 * and/or modify it under the terms of the GNU General
1238 * Public License as published by the Free Software
1239 * Foundation; either version 2 of the License, or (at
1240 * your option) any later version.
1242 * This program is distributed in the hope that it will
1243 * be useful, but WITHOUT ANY WARRANTY; without even the
1244 * implied warranty of MERCHANTABILITY or FITNESS FOR A
1245 * PARTICULAR PURPOSE. See the GNU General Public
1246 * License for more details.
1248 * The GNU General Public License should be included with
1249 * this file. If not, you can view it at
1250 * http://www.gnu.org/copyleft/gpl.html
1251 * or write to the Free Software Foundation, Inc., 59
1252 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1255 * $L<!-- Break CVS Substitution -->og$
1257 *********************************************************************/
1262 ...necessary include files for us to do our work...
1264 const char FILENAME_h_rcs[] = FILENAME_H_VERSION;
1267 <para><emphasis>Note:</emphasis> This declares the rcs variables that should be
1268 added to the "show-proxy-args" page. If this is a brand new
1269 creation by you, you are free to change the "Copyright" section
1270 to represent the rights you wish to maintain.</para>
1272 <para><emphasis>Note:</emphasis> The formfeed character that is present right
1273 after the comment flower box is handy for (X|GNU)Emacs users to
1274 skip the verbige and get to the heart of the code (via
1275 `forward-page' and `backward-page'). Please include it if you
1278 <para><emphasis>Example for file header comments:</emphasis></para>
1282 #define FILENAME_H_VERSION "$Id: developer-manual.sgml,v 1.6 2002/02/24 14:25:06 jongfoster Exp $"
1283 /*********************************************************************
1285 * File : $S<!-- Break CVS Substitution -->ource$
1287 * Purpose : (Fill me in with a good description!)
1289 * Copyright : Written by and Copyright (C) 2001 the SourceForge
1290 * IJBSWA team. http://ijbswa.sourceforge.net
1292 * Based on the Internet Junkbuster originally written
1293 * by and Copyright (C) 1997 Anonymous Coders and
1294 * Junkbusters Corporation. http://www.junkbusters.com
1296 * This program is free software; you can redistribute it
1297 * and/or modify it under the terms of the GNU General
1298 * Public License as published by the Free Software
1299 * Foundation; either version 2 of the License, or (at
1300 * your option) any later version.
1302 * This program is distributed in the hope that it will
1303 * be useful, but WITHOUT ANY WARRANTY; without even the
1304 * implied warranty of MERCHANTABILITY or FITNESS FOR A
1305 * PARTICULAR PURPOSE. See the GNU General Public
1306 * License for more details.
1308 * The GNU General Public License should be included with
1309 * this file. If not, you can view it at
1310 * http://www.gnu.org/copyleft/gpl.html
1311 * or write to the Free Software Foundation, Inc., 59
1312 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1315 * $L<!-- Break CVS Substitution -->og$
1317 *********************************************************************/
1320 #include "project.h"
1326 ... function headers here ...
1329 /* Revision control strings from this header and associated .c file */
1330 extern const char FILENAME_rcs[];
1331 extern const char FILENAME_h_rcs[];
1338 #endif /* ndef _FILENAME_H */
1347 <para><emphasis>Example for function comments:</emphasis></para>
1349 /*********************************************************************
1351 * Function : FUNCTION_NAME
1353 * Description : (Fill me in with a good description!)
1356 * 1 : param1 = pointer to an important thing
1357 * 2 : x = pointer to something else
1359 * Returns : 0 => Ok, everything else is an error.
1361 *********************************************************************/
1362 int FUNCTION_NAME( void *param1, const char *x )
1370 <para><emphasis>Note:</emphasis> If we all follow this practice, we should be
1371 able to parse our code to create a "self-documenting" web
1378 <!-- ~~~~~ New section ~~~~~ -->
1379 <sect1 id="cvs"><title>Version Control Guidelines</title>
1380 <para>To be filled. note on cvs comments. don't comment what you did, comment
1385 <!-- ~~~~~ New section ~~~~~ -->
1386 <sect1 id="testing"><title>Testing Guidelines</title>
1390 <!-- ~~~~~ New section ~~~~~ -->
1391 <sect2 id="testing-plan"><title>Testplan for releases</title>
1393 Explain release numbers. major, minor. developer releases. etc.
1395 <orderedlist numeration="arabic">
1397 Remove any existing rpm with rpm -e
1400 Remove any file that was left over. This includes (but is not limited to)
1402 <listitem><para>/var/log/junkbuster</para></listitem>
1403 <listitem><para>/etc/junkbuster</para></listitem>
1404 <listitem><para>/usr/sbin/junkbuster</para></listitem>
1405 <listitem><para>/etc/init.d/junkbuster</para></listitem>
1406 <listitem><para>/usr/doc/junkbuster*</para></listitem>
1410 Install the rpm. Any error messages?
1412 <listitem><para>start,stop,status junkbuster with the specific script
1413 (e.g. /etc/rc.d/init/junkbuster stop). Reboot your machine. Does
1414 autostart work?</para></listitem>
1415 <listitem><para>Start browsing. Does the junkbuster work? Logfile written?</para></listitem>
1416 <listitem><para>Remove the rpm. Any error messages? All files removed?</para></listitem>
1421 <!-- ~~~~~ New section ~~~~~ -->
1422 <sect2 id="testing-report"><title>Test reports</title>
1424 Please submit test reports only with the <ulink url="http://sourceforge.net/tracker/?func=add&group_id=11118&atid=395005">test form</ulink>
1425 at sourceforge. Three simple steps:
1428 <listitem><para>Select category: the distribution you test on.</para></listitem>
1429 <listitem><para>Select group: the version of Junkbuster that we are about to release.</para></listitem>
1430 <listitem><para>Fill the Summary and Detailed Description with something
1431 intelligent (keep it short and precise).</para>
1434 Do not mail to the mailinglist (we cannot keep track on issues there).
1440 <!-- ~~~~~ New section ~~~~~ -->
1441 <sect1 id="contact"><title>Contact the developers</title>
1442 <para>Please see the user manual for information on how to contact the developers.
1446 <!-- ~~~~~ New section ~~~~~ -->
1447 <sect1 id="copyright"><title>Copyright and History</title>
1448 <para>Please see the user manual for information on Copyright and History.
1452 <!-- ~~~~~ New section ~~~~~ -->
1453 <sect1 id="seealso"><title>See also</title>
1454 <para>Please see the user manual for information on references.
1460 This program is free software; you can redistribute it
1461 and/or modify it under the terms of the GNU General
1462 Public License as published by the Free Software
1463 Foundation; either version 2 of the License, or (at
1464 your option) any later version.
1466 This program is distributed in the hope that it will
1467 be useful, but WITHOUT ANY WARRANTY; without even the
1468 implied warranty of MERCHANTABILITY or FITNESS FOR A
1469 PARTICULAR PURPOSE. See the GNU General Public
1470 License for more details.
1472 The GNU General Public License should be included with
1473 this file. If not, you can view it at
1474 http://www.gnu.org/copyleft/gpl.html
1475 or write to the Free Software Foundation, Inc., 59
1476 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1478 $Log: developer-manual.sgml,v $
1479 Revision 1.6 2002/02/24 14:25:06 jongfoster
1480 Formatting changes. Now changing the doctype to DocBook XML 4.1
1481 will work - no other changes are needed.
1483 Revision 1.5 2001/10/31 18:16:51 swa
1484 documentation added: howto generate docs in text and html
1485 format, howto move stuff to the webserver.
1487 Revision 1.4 2001/09/23 10:13:48 swa
1488 upload process established. run make webserver and
1489 the documentation is moved to the webserver. documents
1490 are now linked correctly.
1492 Revision 1.3 2001/09/13 15:27:40 swa
1495 Revision 1.2 2001/09/13 15:20:17 swa
1496 merged standards into developer manual
1498 Revision 1.1 2001/09/12 15:36:41 swa
1499 source files for junkbuster documentation
1501 Revision 1.3 2001/09/10 17:43:59 swa
1502 first proposal of a structure.
1504 Revision 1.2 2001/06/13 14:28:31 swa
1505 docs should have an author.
1507 Revision 1.1 2001/06/13 14:20:37 swa
1508 first import of project's documentation for the webserver.