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.5 2001/10/31 18:16:51 swa 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.5 2001/10/31 18:16:51 swa 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. The Internet Junkbuster is an application
38 that provides privacy and security to the user of the world wide web.
41 You can find the latest version of the user manual at <ulink
42 url="http://ijbswa.sourceforge.net/developer-manual/">http://ijbswa.sourceforge.net/developer-manual/</ulink>.
43 Please see the Contact section in the user-manual if you want to contact the developers.
47 Feel free to send a note to the developers at <email>ijbswa-developers@lists.sourceforge.net</email>.
52 <!-- ~~~~~ New section ~~~~~ -->
53 <sect1 id="introduction"><title>Introduction</title>
58 <!-- ~~~~~ New section ~~~~~ -->
59 <sect1 id="quickstart"><title>Quickstart to Junkbuster Development</title>
64 <!-- ~~~~~ New section ~~~~~ -->
65 <sect1 id="documentation"><title>Documentation Guidelines</title>
67 All docs are in SGML format and located in the <computeroutput>doc/source</computeroutput> directory.
70 How do you update the webserver (i.e. the pages on sourceforge)?
71 <orderedlist numeration="arabic">
73 Run <computeroutput>make dok</computeroutput> (which uses the documents in <computeroutput>doc/source</computeroutput> to update all
74 text files in <computeroutput>doc/text</computeroutput> and to update
75 all web documents in <computeroutput>doc/webserver</computeroutput>.
78 Run <computeroutput>make webserver</computeroutput> which copies all files from
79 <computeroutput>doc/webserver</computeroutput> to the sourceforge webserver
86 <!-- <listitem><para>be consistent with the redirect script (i.e. the junkbuster program -->
87 <!-- points via the redirect URL at sf to valid end-points in the document)</para></listitem> -->
89 <!-- ~~~~~ New section ~~~~~ -->
90 <sect1 id="coding"><title>Coding Guidelines</title>
92 <sect2 id="s1"><title>Introduction</title>
94 <para>This set of standards is designed to make our lives easier.
95 It is developed with the simple goal of helping us keep the
96 "new and improved Junkbusters" consistent and reliable. Thus
97 making maintenance easier and increasing chances of success of
100 <para>And that of course comes back to us as individuals. If we
101 can increase our development and product efficiencies then we
102 can solve more of the request for changes/improvements and in
103 general feel good about ourselves. ;-></para>
107 <sect2 id="s2"><title>Using Comments</title>
110 <sect3 id="s3"><title>Comment, Comment, Comment</title>
112 <para><emphasis>Explanation:</emphasis></para>
114 <para>Comment as much as possible without commenting the obvious.
115 For example do not comment "aVariable is equal to bVariable".
116 Instead explain why aVariable should be equal to the bVariable.
117 Just because a person can read code does not mean they will
118 understand why or what is being done. A reader may spend a lot
119 more time figuring out what is going on when a simple comment
120 or explanation would have prevented the extra research. Please
121 help your brother IJB'ers out!</para>
123 <para>The comments will also help justify the intent of the code.
124 If the comment describes something different than what the code
125 is doing then maybe a programming error is occurring.</para>
127 <para><emphasis>Example:</emphasis></para>
129 /* if page size greater than 1k ... */
130 if ( PageLength() > 1024 )
132 ... "block" the page up ...
135 /* if page size is small, send it in blocks */
136 if ( PageLength() > 1024 )
138 ... "block" the page up ...
141 This demonstrates 2 cases of "what not to do". The first is a
142 "syntax comment". The second is a comment that does not fit what
143 is actually being done.
149 <sect3 id="s4"><title>Use blocks for comments</title>
151 <para><emphasis>Explanation:</emphasis></para>
153 <para>Comments can help or they can clutter. They help when they
154 are differentiated from the code they describe. One line
155 comments do not offer effective separation between the comment
156 and the code. Block identifiers do, by surrounding the code
157 with a clear, definable pattern.</para>
159 <para><emphasis>Example:</emphasis></para>
161 /*********************************************************************
162 * This will stand out clearly in your code!
163 *********************************************************************/
164 if ( thisVariable == thatVariable )
166 DoSomethingVeryImportant();
170 /* unfortunately, this may not */
171 if ( thisVariable == thatVariable )
173 DoSomethingVeryImportant();
177 if ( thisVariable == thatVariable ) /* this may not either */
179 DoSomethingVeryImportant();
182 <para><emphasis>Exception:</emphasis></para>
184 <para>If you are trying to add a small logic comment and do not
185 wish to "disrubt" the flow of the code, feel free to use a 1
186 line comment which is NOT on the same line as the code.</para>
192 <sect3 id="s5"><title>Keep Comments on their own line</title>
194 <para><emphasis>Explanation:</emphasis></para>
196 <para>It goes back to the question of readability. If the comment
197 is on the same line as the code it will be harder to read than
198 the comment that is on its own line.</para>
200 <para>There are three exceptions to this rule, which should be
201 violated freely and often: during the definition of variables,
202 at the end of closing braces, when used to comment
205 <para><emphasis>Example:</emphasis></para>
207 /*********************************************************************
208 * This will stand out clearly in your code,
209 * But the second example won't.
210 *********************************************************************/
211 if ( thisVariable == thatVariable )
213 DoSomethingVeryImportant();
216 if ( thisVariable == thatVariable ) /*can you see me?*/
218 DoSomethingVeryImportant(); /*not easily*/
222 /*********************************************************************
223 * But, the encouraged exceptions:
224 *********************************************************************/
225 int urls_read = 0; /* # of urls read + rejected */
226 int urls_rejected = 0; /* # of urls rejected */
230 DoSomethingVeryImportant();
234 short DoSomethingVeryImportant(
235 short firstparam, /* represents something */
236 short nextparam /* represents something else */ )
240 } /* -END- DoSomethingVeryImportant */
245 <sect3 id="s6"><title>Comment each logical step</title>
247 <para><emphasis>Explanation:</emphasis></para>
249 <para>Logical steps should be commented to help others follow the
250 intent of the written code and comments will make the code more
253 <para>If you have 25 lines of code without a comment, you should
254 probably go back into it to see where you forgot to put
257 <para>Most "for", "while", "do", etc... loops _probably_ need a
258 comment. After all, these are usually major logic
265 <sect3 id="s7"><title>Comment All Functions Thoroughly</title>
267 <para><emphasis>Explanation:</emphasis></para>
269 <para>A reader of the code should be able to look at the comments
270 just prior to the beginning of a function and discern the
271 reason for its existence and the consequences of using it. The
272 reader should not have to read through the code to determine if
273 a given function is safe for a desired use. The proper
274 information thoroughly presented at the introduction of a
275 function not only saves time for subsequent maintenance or
276 debugging, it more importantly aids in code reuse by allowing a
277 user to determine the safety and applicability of any function
278 for the problem at hand. As a result of such benefits, all
279 functions should contain the information presented in the
280 addendum section of this document.</para>
286 <sect3 id="s8"><title>Comment at the end of braces if the
287 content is more than one screen length</title>
289 <para><emphasis>Explanation:</emphasis></para>
291 <para>Each closing brace should be followed on the same line by a
292 comment that describes the origination of the brace if the
293 original brace is off of the screen, or otherwise far away from
294 the closing brace. This will simplify the debugging,
295 maintenance, and readability of the code.</para>
297 <para>As a suggestion , use the following flags to make the
298 comment and its brace more readable:</para>
300 <para>use following a closing brace: } /* -END- if() or while ()
303 <para><emphasis>Example:</emphasis></para>
307 DoSomethingVeryImportant();
308 ...some long list of commands...
309 } /* -END- if x is 1 */
315 DoSomethingVeryImportant();
316 ...some long list of commands...
317 } /* -END- if ( 1 == X ) */
323 <sect2 id="s9"><title>Naming Conventions</title>
327 <sect3 id="s10"><title>Variable Names</title>
329 <para><emphasis>Explanation:</emphasis></para>
331 <para>Use all lowercase, and seperate words via an underscore
332 ('_'). Do not start an identifier with an underscore. (ANSI C
333 reserves these for use by the compiler and system headers.) Do
334 not use identifiers which are reserved in ANSI C++. (E.g.
335 template, class, true, false, ...). This is in case we ever
336 decide to port JunkBuster to C++.</para>
338 <para><emphasis>Example:</emphasis></para>
340 int ms_iis5_hack = 0;</programlisting>
342 <para><emphasis>Instead of:</emphasis></para>
346 int msiis5hack = 0; int msIis5Hack = 0;
354 <sect3 id="s11"><title>Function Names</title>
356 <para><emphasis>Explanation:</emphasis></para>
358 <para>Use all lowercase, and seperate words via an underscore
359 ('_'). Do not start an identifier with an underscore. (ANSI C
360 reserves these for use by the compiler and system headers.) Do
361 not use identifiers which are reserved in ANSI C++. (E.g.
362 template, class, true, false, ...). This is in case we ever
363 decide to port JunkBuster to C++.</para>
365 <para><emphasis>Example:</emphasis></para>
367 int load_some_file( struct client_state *csp )</programlisting>
369 <para><emphasis>Instead of:</emphasis></para>
373 int loadsomefile( struct client_state *csp )
374 int loadSomeFile( struct client_state *csp )
382 <sect3 id="s12"><title>Header file prototypes</title>
384 <para><emphasis>Explanation:</emphasis></para>
386 <para>Use a descriptive parameter name in the function prototype
387 in header files. Use the same parameter name in the header file
388 that you use in the c file.</para>
390 <para><emphasis>Example:</emphasis></para>
392 (.h) extern int load_aclfile( struct client_state *csp );
393 (.c) int load_aclfile( struct client_state *csp )</programlisting>
395 <para><emphasis>Instead of:</emphasis>
397 (.h) extern int load_aclfile( struct client_state * ); or
398 (.h) extern int load_aclfile();
399 (.c) int load_aclfile( struct client_state *csp )
407 <sect3 id="s13"><title>Enumerations, and #defines</title>
409 <para><emphasis>Explanation:</emphasis></para>
411 <para>Use all capital letters, with underscores between words. Do
412 not start an identifier with an underscore. (ANSI C reserves
413 these for use by the compiler and system headers.)</para>
415 <para><emphasis>Example:</emphasis></para>
417 (enumeration) : enum Boolean { FALSE, TRUE };
418 (#define) : #define DEFAULT_SIZE 100;</programlisting>
420 <para><emphasis>Note:</emphasis> We have a standard naming scheme for #defines
421 that toggle a feature in the preprocessor: FEATURE_>, where
422 > is a short (preferably 1 or 2 word) description.</para>
424 <para><emphasis>Example:</emphasis></para>
426 #define FEATURE_FORCE 1
429 #define FORCE_PREFIX blah
430 #endif /* def FEATURE_FORCE */
435 <sect3 id="s14"><title>Constants</title>
437 <para><emphasis>Explanation:</emphasis></para>
439 <para>Spell common words out entirely (do not remove vowels).</para>
441 <para>Use only widely-known domain acronyms and abbreviations.
442 Capitalize all letters of an acronym.</para>
444 <para>Use underscore (_) to separate adjacent acronyms and
445 abbreviations. Never terminate a name with an underscore.</para>
447 <para><emphasis>Example:</emphasis></para>
449 #define USE_IMAGE_LIST 1</programlisting>
451 <para><emphasis>Instead of:</emphasis></para>
455 #define USE_IMG_LST 1 or
456 #define _USE_IMAGE_LIST 1 or
457 #define USE_IMAGE_LIST_ 1 or
458 #define use_image_list 1 or
459 #define UseImageList 1
469 <sect2 id="s15"><title>Using Space</title>
473 <sect3 id="s16"><title>Put braces on a line by themselves.</title>
475 <para><emphasis>Explanation:</emphasis></para>
477 <para>The brace needs to be on a line all by itself, not at the
478 end of the statement. Curly braces should line up with the
479 construct that they're associated with. This practice makes it
480 easier to identify the opening and closing braces for a
483 <para><emphasis>Example:</emphasis></para>
490 <para><emphasis>Instead of:</emphasis></para>
492 <para>if ( this == that ) { ... }</para>
496 <para>if ( this == that ) { ... }</para>
498 <para><emphasis>Note:</emphasis> In the special case that the if-statement is
499 inside a loop, and it is trivial, i.e. it tests for a
500 condidtion that is obvious from the purpose of the block,
501 one-liners as above may optically preserve the loop structure
502 and make it easier to read.</para>
504 <para><emphasis>Status:</emphasis> developer-discrection.</para>
506 <para><emphasis>Example exception:</emphasis></para>
508 while ( more lines are read )
510 /* Please document what is/is not a comment line here */
511 if ( it's a comment ) continue;
513 do_something( line );
519 <sect3 id="s17"><title>ALL control statements should have a
522 <para><emphasis>Explanation:</emphasis></para>
524 <para>Using braces to make a block will make your code more
525 readable and less prone to error. All control statements should
526 have a block defined.</para>
528 <para><emphasis>Example:</emphasis></para>
536 <para><emphasis>Instead of:</emphasis></para>
538 <para>if ( this == that ) DoSomething(); DoSomethingElse();</para>
542 <para>if ( this == that ) DoSomething();</para>
544 <para><emphasis>Note:</emphasis> The first example in "Instead of" will execute
545 in a manner other than that which the developer desired (per
546 indentation). Using code braces would have prevented this
547 "feature". The "explanation" and "exception" from the point
548 above also applies.</para>
554 <sect3 id="s18"><title>Do not belabor/blow-up boolean
557 <para><emphasis>Example:</emphasis></para>
559 structure->flag = ( condition );</programlisting>
561 <para><emphasis>Instead of:</emphasis></para>
563 <para>if ( condition ) { structure->flag = 1; } else {
564 structure->flag = 0; }</para>
566 <para><emphasis>Note:</emphasis> The former is readable and consice. The later
567 is wordy and inefficient. Please assume that any developer new
568 to the project has at least a "good" knowledge of C/C++. (Hope
569 I do not offend by that last comment ... 8-)</para>
575 <sect3 id="s19"><title>Use white space freely because it is
578 <para><emphasis>Explanation:</emphasis></para>
580 <para>Make it readable. The notable exception to using white space
581 freely is listed in the next guideline.</para>
583 <para><emphasis>Example:</emphasis></para>
587 int anotherValue = 0;
588 int thisVariable = 0;
590 if ( thisVariable == thatVariable )
592 firstValue = oldValue + ( ( someValue - anotherValue ) - whatever )
597 <sect3 id="s20"><title>Don't use white space around structure
600 <para><emphasis>Explanation:</emphasis></para>
602 <para>- structure pointer operator ( "->" ) - member operator (
603 "." ) - functions and parentheses</para>
605 <para>It is a general coding practice to put pointers, references,
606 and function parentheses next to names. With spaces, the
607 connection between the object and variable/function name is not
610 <para><emphasis>Example:</emphasis></para>
614 FunctionName();</programlisting>
616 <para><emphasis>Instead of:</emphasis> aStruct -> aMember; aStruct . aMember;
617 FunctionName ();</para>
623 <sect3 id="s21"><title>Make the last brace of a function stand
626 <para><emphasis>Example:</emphasis></para>
633 } /* -END- function1 */
638 } /* -END- function2 */
641 <para><emphasis>Instead of:</emphasis></para>
643 <para>int function1( ... ) { ...code... return( retCode ); } int
644 function2( ... ) { }</para>
646 <para><emphasis>Note:</emphasis> Use 1 blank line before the closing brace and 2
647 lines afterwards. This makes the end of function standout to
648 the most casual viewer. Although function comments help
649 seperate functions, this is still a good coding practice. In
650 fact, I follow these rules when using blocks in "for", "while",
651 "do" loops, and long if {} statements too. After all whitespace
654 <para><emphasis>Status:</emphasis> developer-discrection on the number of blank
655 lines. Enforced is the end of function comments.</para>
661 <sect3 id="s22"><title>Use 3 character indentions</title>
663 <para><emphasis>Explanation:</emphasis></para>
665 <para>If some use 8 character TABs and some use 3 character TABs,
666 the code can look *very* ragged. So use 3 character indentions
667 only. If you like to use TABs, pass your code through a filter
668 such as "expand -t3" before checking in your code.</para>
670 <para><emphasis>Example:</emphasis></para>
672 static const char * const url_code_map[256] =
682 return( ALWAYS_TRUE );
686 return( HOW_DID_YOU_GET_HERE );
689 return( NEVER_GETS_HERE );
698 <sect2 id="s23"><title>Initializing</title>
702 <sect3 id="s24"><title>Initialize all variables</title>
704 <para><emphasis>Explanation:</emphasis></para>
706 <para>Do not assume that the variables declared will not be used
707 until after they have been assigned a value somewhere else in
708 the code. Remove the chance of accidentally using an unassigned
711 <para><emphasis>Example:</emphasis></para>
715 struct *ptr = NULL;</programlisting>
717 <para><emphasis>Note:</emphasis> It is much easier to debug a SIGSEGV if the
718 message says you are trying to access memory address 00000000
719 and not 129FA012; or arrayPtr[20] causes a SIGSEV vs.
722 <para><emphasis>Status:</emphasis> developer-discrection if and only if the
723 variable is assigned a value "shortly after" declaration.</para>
729 <sect2 id="s25"><title>Functions</title>
733 <sect3 id="s26"><title>Name functions that return a boolean as a
736 <para><emphasis>Explanation:</emphasis></para>
738 <para>Value should be phrased as a question that would logically
739 be answered as a true or false statement</para>
741 <para><emphasis>Example:</emphasis></para>
750 <sect3 id="s27"><title>Always specify a return type for a
753 <para><emphasis>Explanation:</emphasis></para>
755 <para>The default return for a function is an int. To avoid
756 ambiguity, create a return for a function when the return has a
757 purpose, and create a void return type if the function does not
758 need to return anything.</para>
764 <sect3 id="s28"><title>Minimize function calls when iterating by
765 using variables</title>
767 <para><emphasis>Explanation:</emphasis></para>
769 <para>It is easy to write the following code, and a clear argument
770 can be made that the code is easy to understand:</para>
772 <para><emphasis>Example:</emphasis></para>
774 for ( size_t cnt = 0; cnt < blockListLength(); cnt ++ )
779 <para><emphasis>Note:</emphasis> Unfortunately, this makes a function call for
780 each and every iteration. This increases the overhead in the
781 program, because the compiler has to look up the function each
782 time, call it, and return a value. Depending on what occurs in
783 the blockListLength() call, it might even be creating and
784 destroying structures with each iteration, even though in each
785 case it is comparing "cnt" to the same value, over and over.
786 Remember too - even a call to blockListLength() is a function
787 call, with the same overhead.</para>
789 <para>Instead of using a function call during the iterations,
790 assign the value to a variable, and evaluate using the
793 <para><emphasis>Example:</emphasis></para>
795 size_t len = blockListLength();
797 for ( size_t cnt = 0; cnt < len; cnt ++ )
802 <para><emphasis>Exceptions:</emphasis> if the value of blockListLength() *may*
803 change or could *potentially* change, then you must code the
804 function call in the for/while loop.</para>
810 <sect3 id="s29"><title>Pass and Return by Const Reference</title>
812 <para><emphasis>Explanation:</emphasis></para>
814 <para>This allows a developer to define a const pointer and call
815 your function. If your function does not have the const
816 keyword, we may not be able to use your function. Consider
817 strcmp, if it were defined as: extern int strcmp( char *s1,
820 <para>I could then not use it to compare argv's in main: int main(
821 int argc, const char *argv[] ) { strcmp( argv[0], "junkbusters"
824 <para>Both these pointers are *const*! If the c runtime library
825 maintainers do it, we should too.</para>
831 <sect3 id="s30"><title>Pass and Return by Value</title>
833 <para><emphasis>Explanation:</emphasis></para>
835 <para>Most structures cannot fit onto a normal stack entry (i.e.
836 they are not 4 bytes or less). Aka, a function declaration
837 like: int load_aclfile( struct client_state csp )</para>
839 <para>would not work. So, to be consistent, we should declare all
840 prototypes with "pass by value": int load_aclfile( struct
841 client_state *csp )</para>
847 <sect3 id="s31"><title>Names of include files</title>
849 <para><emphasis>Explanation:</emphasis></para>
851 <para>Your include statements should contain the file name without
852 a path. The path should be listed in the Makefile, using -I as
853 processor directive to search the indicated paths. An exception
854 to this would be for some proprietary software that utilizes a
855 partial path to distinguish their header files from system or
856 other header files.</para>
858 <para><emphasis>Example:</emphasis></para>
860 #include <iostream.h> /* This is not a local include */
861 #include "config.h" /* This IS a local include */
864 <para><emphasis>Exception:</emphasis></para>
868 /* This is not a local include, but requires a path element. */
869 #include <sys/fileName.h>
873 <para><emphasis>Note:</emphasis> Please! do not add "-I." to the Makefile
874 without a _very_ good reason. This duplicates the #include
875 "file.h" behaviour.</para>
881 <sect3 id="s32"><title>Provide multiple inclusion
884 <para><emphasis>Explanation:</emphasis></para>
886 <para>Prevents compiler and linker errors resulting from
887 redefinition of items.</para>
889 <para>Wrap each header file with the following syntax to prevent
890 multiple inclusions of the file. Of course, replace PROJECT_H
891 with your file name, with "." Changed to "_", and make it
894 <para><emphasis>Example:</emphasis></para>
896 #ifndef PROJECT_H_INCLUDED
897 #define PROJECT_H_INCLUDED
899 #endif /* ndef PROJECT_H_INCLUDED */
904 <sect3 id="s33"><title>Use `extern "C"` when appropriate</title>
906 <para><emphasis>Explanation:</emphasis></para>
908 <para>If our headers are included from C++, they must declare our
909 functions as `extern "C"`. This has no cost in C, but increases
910 the potential re-usability of our code.</para>
912 <para><emphasis>Example:</emphasis></para>
917 #endif /* def __cplusplus */
919 ... function definitions here ...
923 #endif /* def __cplusplus */
928 <sect3 id="s34"><title>Where Possible, Use Forward Struct
929 Declaration Instead of Includes</title>
931 <para><emphasis>Explanation:</emphasis></para>
933 <para>Useful in headers that include pointers to other struct's.
934 Modifications to excess header files may cause needless
937 <para><emphasis>Example:</emphasis></para>
939 /*********************************************************************
940 * We're avoiding an include statement here!
941 *********************************************************************/
943 extern file_list *xyz;</programlisting>
945 <para><emphasis>Note:</emphasis> If you declare "file_list xyz;" (without the
946 pointer), then including the proper header file is necessary.
947 If you only want to prototype a pointer, however, the header
948 file is unneccessary.</para>
950 <para><emphasis>Status:</emphasis> Use with discrection.</para>
956 <sect2 id="s35"><title>General Coding Practices</title>
960 <sect3 id="s36"><title>Turn on warnings</title>
962 <para><emphasis>Explanation</emphasis></para>
964 <para>Compiler warnings are meant to help you find bugs. You
965 should turn on as many as possible. With GCC, the switch is
966 "-Wall". Try and fix as many warnings as possible.</para>
972 <sect3 id="s37"><title>Provide a default case for all switch
975 <para><emphasis>Explanation:</emphasis></para>
977 <para>What you think is guaranteed is never really guaranteed. The
978 value that you don't think you need to check is the one that
979 someday will be passed. So, to protect yourself from the
980 unknown, always have a default step in a switch statement.</para>
982 <para><emphasis>Example:</emphasis></para>
984 switch( hash_string( cmd ) )
986 case hash_actions_file :
996 ... anomly code goes here ...
997 continue; / break; / exit( 1 ); / etc ...
999 } /* end switch( hash_string( cmd ) ) */</programlisting>
1001 <para><emphasis>Note:</emphasis> If you already have a default condition, you
1002 are obviously exempt from this point. Of note, most of the
1003 WIN32 code calls `DefWindowProc' after the switch statement.
1004 This API call *should* be included in a default statement.</para>
1006 <para><emphasis>Another Note:</emphasis> This is not so much a readability issue
1007 as a robust programming issue. The "anomly code goes here" may
1008 be no more than a print to the STDERR stream (as in
1009 load_config). Or it may really be an ABEND condition.</para>
1011 <para><emphasis>Status:</emphasis> Programmer discretion is advised.</para>
1017 <sect3 id="s38"><title>Try to avoid falling through cases in a
1018 switch statement.</title>
1020 <para><emphasis>Explanation:</emphasis></para>
1022 <para>In general, you will want to have a 'break' statement within
1023 each 'case' of a switch statement. This allows for the code to
1024 be more readable and understandable, and furthermore can
1025 prevent unwanted surprises if someone else later gets creative
1026 and moves the code around.</para>
1028 <para>The language allows you to plan the fall through from one
1029 case statement to another simply by omitting the break
1030 statement within the case statement. This feature does have
1031 benefits, but should only be used in rare cases. In general,
1032 use a break statement for each case statement.</para>
1034 <para>If you choose to allow fall through, you should comment both
1035 the fact of the fall through and reason why you felt it was
1042 <sect3 id="s39"><title>Use 'long' or 'short' Instead of
1045 <para><emphasis>Explanation:</emphasis></para>
1047 <para>On 32-bit platforms, int usually has the range of long. On
1048 16-bit platforms, int has the range of short.</para>
1050 <para><emphasis>Status:</emphasis> open-to-debate. In the case of most FSF
1051 projects (including X/GNU-Emacs), there are typedefs to int4,
1052 int8, int16, (or equivalence ... I forget the exact typedefs
1053 now). Should we add these to IJB now that we have a "configure"
1060 <sect3 id="s40"><title>Don't mix size_t and other types</title>
1062 <para><emphasis>Explanation:</emphasis></para>
1064 <para>The type of size_t varies across platforms. Do not make
1065 assumptions about whether it is signed or unsigned, or about
1066 how long it is. Do not compare a size_t against another
1067 variable of a different type (or even against a constant)
1068 without casting one of the values. Try to avoid using size_t if
1075 <sect3 id="s41"><title>Declare each variable and struct on its
1078 <para><emphasis>Explanation:</emphasis></para>
1080 <para>It can be tempting to declare a series of variables all on
1081 one line. Don't.</para>
1083 <para><emphasis>Example:</emphasis></para>
1087 long c = 0;</programlisting>
1089 <para><emphasis>Instead of:</emphasis></para>
1091 <para>long a, b, c;</para>
1093 <para><emphasis>Explanation:</emphasis> - there is more room for comments on the
1094 individual variables - easier to add new variables without
1095 messing up the original ones - when searching on a variable to
1096 find its type, there is less clutter to "visually"
1099 <para><emphasis>Exceptions:</emphasis> when you want to declare a bunch of loop
1100 variables or other trivial variables; feel free to declare them
1101 on 1 line. You should, although, provide a good comment on
1102 their functions.</para>
1104 <para><emphasis>Status:</emphasis> developer-discrection.</para>
1110 <sect3 id="s42"><title>Use malloc/zalloc sparingly</title>
1112 <para><emphasis>Explanation:</emphasis></para>
1114 <para>Create a local stuct (on the stack) if the variable will
1115 live and die within the context of one function call.</para>
1117 <para>Only "malloc" a struct (on the heap) if the variable's life
1118 will extend beyond the context of one function call.</para>
1120 <para><emphasis>Example:</emphasis></para>
1122 If a function creates a struct and stores a pointer to it in a
1123 list, then it should definately be allocated via `malloc'.
1128 <sect3 id="s43"><title>The Programmer Who Uses 'malloc' is
1129 Responsible for Ensuring 'free'</title>
1131 <para><emphasis>Explanation:</emphasis></para>
1133 <para>If you have to "malloc" an instance, you are responsible for
1134 insuring that the instance is `free'd, even if the deallocation
1135 event falls within some other programmer's code. You are also
1136 responsible for ensuring that deletion is timely (i.e. not too
1137 soon, not too late). This is known as "low-coupling" and is a
1138 "good thing (tm)". You may need to offer a
1139 free/unload/destuctor type function to accomodate this.</para>
1141 <para><emphasis>Example:</emphasis></para>
1143 int load_re_filterfile( struct client_state *csp ) { ... }
1144 static void unload_re_filterfile( void *f ) { ... }</programlisting>
1146 <para><emphasis>Exceptions:</emphasis></para>
1148 <para>The developer cannot be expected to provide `free'ing
1149 functions for C run-time library functions ... such as
1152 <para><emphasis>Status:</emphasis> developer-discrection. The "main" use of this
1153 standard is for allocating and freeing data structures (complex
1160 <sect3 id="s44"><title>Add loaders to the `file_list' structure
1161 and in order</title>
1163 <para><emphasis>Explanation:</emphasis></para>
1165 <para>I have ordered all of the "blocker" file code to be in alpha
1166 order. It is easier to add/read new blockers when you expect a
1167 certain order.</para>
1169 <para><emphasis>Note:</emphasis> It may appear that the alpha order is broken in
1170 places by POPUP tests coming before PCRS tests. But since
1171 POPUPs can also be referred to as KILLPOPUPs, it is clear that
1172 it should come first.</para>
1178 <sect3 id="s45"><title>"Uncertain" new code and/or changes to
1179 exitinst code, use FIXME</title>
1181 <para><emphasis>Explanation:</emphasis></para>
1183 <para>If you have enough confidence in new code or confidence in
1184 your changes, but are not *quite* sure of the reprocussions,
1187 <para>/* FIXME: this code has a logic error on platform XYZ, *
1188 attempthing to fix */ #ifdef PLATFORM ...changed code here...
1193 <para>/* FIXME: I think the original author really meant this...
1194 */ ...changed code here...</para>
1198 <para>/* FIXME: new code that *may* break something else... */
1199 ...new code here...</para>
1201 <para><emphasis>Note:</emphasis> If you make it clear that this may or may not
1202 be a "good thing (tm)", it will be easier to identify and
1203 include in the project (or conversly exclude from the
1211 <sect2 id="s46"><title>Addendum: Template for files and function
1212 comment blocks:</title>
1214 <para><emphasis>Example for file comments:</emphasis></para>
1216 const char FILENAME_rcs[] = "$Id: developer-manual.sgml,v 1.5 2001/10/31 18:16:51 swa Exp $";
1217 /*********************************************************************
1219 * File : $S<!-- Break CVS Substitution -->ource$
1221 * Purpose : (Fill me in with a good description!)
1223 * Copyright : Written by and Copyright (C) 2001 the SourceForge
1224 * IJBSWA team. http://ijbswa.sourceforge.net
1226 * Based on the Internet Junkbuster originally written
1227 * by and Copyright (C) 1997 Anonymous Coders and
1228 * Junkbusters Corporation. http://www.junkbusters.com
1230 * This program is free software; you can redistribute it
1231 * and/or modify it under the terms of the GNU General
1232 * Public License as published by the Free Software
1233 * Foundation; either version 2 of the License, or (at
1234 * your option) any later version.
1236 * This program is distributed in the hope that it will
1237 * be useful, but WITHOUT ANY WARRANTY; without even the
1238 * implied warranty of MERCHANTABILITY or FITNESS FOR A
1239 * PARTICULAR PURPOSE. See the GNU General Public
1240 * License for more details.
1242 * The GNU General Public License should be included with
1243 * this file. If not, you can view it at
1244 * http://www.gnu.org/copyleft/gpl.html
1245 * or write to the Free Software Foundation, Inc., 59
1246 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1249 * $L<!-- Break CVS Substitution -->og$
1251 *********************************************************************/
1256 ...necessary include files for us to do our work...
1258 const char FILENAME_h_rcs[] = FILENAME_H_VERSION;
1261 <para><emphasis>Note:</emphasis> This declares the rcs variables that should be
1262 added to the "show-proxy-args" page. If this is a brand new
1263 creation by you, you are free to change the "Copyright" section
1264 to represent the rights you wish to maintain.</para>
1266 <para><emphasis>Note:</emphasis> The formfeed character that is present right
1267 after the comment flower box is handy for (X|GNU)Emacs users to
1268 skip the verbige and get to the heart of the code (via
1269 `forward-page' and `backward-page'). Please include it if you
1272 <para><emphasis>Example for file header comments:</emphasis></para>
1276 #define FILENAME_H_VERSION "$Id: developer-manual.sgml,v 1.5 2001/10/31 18:16:51 swa Exp $"
1277 /*********************************************************************
1279 * File : $S<!-- Break CVS Substitution -->ource$
1281 * Purpose : (Fill me in with a good description!)
1283 * Copyright : Written by and Copyright (C) 2001 the SourceForge
1284 * IJBSWA team. http://ijbswa.sourceforge.net
1286 * Based on the Internet Junkbuster originally written
1287 * by and Copyright (C) 1997 Anonymous Coders and
1288 * Junkbusters Corporation. http://www.junkbusters.com
1290 * This program is free software; you can redistribute it
1291 * and/or modify it under the terms of the GNU General
1292 * Public License as published by the Free Software
1293 * Foundation; either version 2 of the License, or (at
1294 * your option) any later version.
1296 * This program is distributed in the hope that it will
1297 * be useful, but WITHOUT ANY WARRANTY; without even the
1298 * implied warranty of MERCHANTABILITY or FITNESS FOR A
1299 * PARTICULAR PURPOSE. See the GNU General Public
1300 * License for more details.
1302 * The GNU General Public License should be included with
1303 * this file. If not, you can view it at
1304 * http://www.gnu.org/copyleft/gpl.html
1305 * or write to the Free Software Foundation, Inc., 59
1306 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1309 * $L<!-- Break CVS Substitution -->og$
1311 *********************************************************************/
1314 #include "project.h"
1320 ... function headers here ...
1323 /* Revision control strings from this header and associated .c file */
1324 extern const char FILENAME_rcs[];
1325 extern const char FILENAME_h_rcs[];
1332 #endif /* ndef _FILENAME_H */
1341 <para><emphasis>Example for function comments:</emphasis></para>
1343 /*********************************************************************
1345 * Function : FUNCTION_NAME
1347 * Description : (Fill me in with a good description!)
1350 * 1 : param1 = pointer to an important thing
1351 * 2 : x = pointer to something else
1353 * Returns : 0 => Ok, everything else is an error.
1355 *********************************************************************/
1356 int FUNCTION_NAME( void *param1, const char *x )
1364 <para><emphasis>Note:</emphasis> If we all follow this practice, we should be
1365 able to parse our code to create a "self-documenting" web
1372 <!-- ~~~~~ New section ~~~~~ -->
1373 <sect1 id="cvs"><title>Version Control Guidelines</title>
1374 <para>To be filled. note on cvs comments. don't comment what you did, comment
1379 <!-- ~~~~~ New section ~~~~~ -->
1380 <sect1 id="testing"><title>Testing Guidelines</title>
1384 <!-- ~~~~~ New section ~~~~~ -->
1385 <sect2 id="testing-plan"><title>Testplan for releases</title>
1387 Explain release numbers. major, minor. developer releases. etc.
1389 <orderedlist numeration="arabic">
1391 Remove any existing rpm with rpm -e
1394 Remove any file that was left over. This includes (but is not limited to)
1396 <listitem><para>/var/log/junkbuster</para></listitem>
1397 <listitem><para>/etc/junkbuster</para></listitem>
1398 <listitem><para>/usr/sbin/junkbuster</para></listitem>
1399 <listitem><para>/etc/init.d/junkbuster</para></listitem>
1400 <listitem><para>/usr/doc/junkbuster*</para></listitem>
1404 Install the rpm. Any error messages?
1406 <listitem><para>start,stop,status junkbuster with the specific script
1407 (e.g. /etc/rc.d/init/junkbuster stop). Reboot your machine. Does
1408 autostart work?</para></listitem>
1409 <listitem><para>Start browsing. Does the junkbuster work? Logfile written?</para></listitem>
1410 <listitem><para>Remove the rpm. Any error messages? All files removed?</para></listitem>
1415 <!-- ~~~~~ New section ~~~~~ -->
1416 <sect2 id="testing-report"><title>Test reports</title>
1418 Please submit test reports only with the <ulink url="http://sourceforge.net/tracker/?func=add&group_id=11118&atid=395005">test form</ulink>
1419 at sourceforge. Three simple steps:
1422 <listitem><para>Select category: the distribution you test on.</para></listitem>
1423 <listitem><para>Select group: the version of Junkbuster that we are about to release.</para></listitem>
1424 <listitem><para>Fill the Summary and Detailed Description with something
1425 intelligent (keep it short and precise).</para>
1428 Do not mail to the mailinglist (we cannot keep track on issues there).
1434 <!-- ~~~~~ New section ~~~~~ -->
1435 <sect1 id="contact"><title>Contact the developers</title>
1436 <para>Please see the user manual for information on how to contact the developers.
1440 <!-- ~~~~~ New section ~~~~~ -->
1441 <sect1 id="copyright"><title>Copyright and History</title>
1442 <para>Please see the user manual for information on Copyright and History.
1446 <!-- ~~~~~ New section ~~~~~ -->
1447 <sect1 id="seealso"><title>See also</title>
1448 <para>Please see the user manual for information on references.
1454 This program is free software; you can redistribute it
1455 and/or modify it under the terms of the GNU General
1456 Public License as published by the Free Software
1457 Foundation; either version 2 of the License, or (at
1458 your option) any later version.
1460 This program is distributed in the hope that it will
1461 be useful, but WITHOUT ANY WARRANTY; without even the
1462 implied warranty of MERCHANTABILITY or FITNESS FOR A
1463 PARTICULAR PURPOSE. See the GNU General Public
1464 License for more details.
1466 The GNU General Public License should be included with
1467 this file. If not, you can view it at
1468 http://www.gnu.org/copyleft/gpl.html
1469 or write to the Free Software Foundation, Inc., 59
1470 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1472 $Log: developer-manual.sgml,v $
1473 Revision 1.5 2001/10/31 18:16:51 swa
1474 documentation added: howto generate docs in text and html
1475 format, howto move stuff to the webserver.
1477 Revision 1.4 2001/09/23 10:13:48 swa
1478 upload process established. run make webserver and
1479 the documentation is moved to the webserver. documents
1480 are now linked correctly.
1482 Revision 1.3 2001/09/13 15:27:40 swa
1485 Revision 1.2 2001/09/13 15:20:17 swa
1486 merged standards into developer manual
1488 Revision 1.1 2001/09/12 15:36:41 swa
1489 source files for junkbuster documentation
1491 Revision 1.3 2001/09/10 17:43:59 swa
1492 first proposal of a structure.
1494 Revision 1.2 2001/06/13 14:28:31 swa
1495 docs should have an author.
1497 Revision 1.1 2001/06/13 14:20:37 swa
1498 first import of project's documentation for the webserver.