upload process established. run make webserver and
[privoxy.git] / doc / source / developer-manual.sgml
1 <!DOCTYPE Article PUBLIC "-//OASIS//DTD DocBook V3.1//EN">
2 <!--
3 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
4  File        :  $Source: /cvsroot/ijbswa/current/doc/source/developer-manual.sgml,v $
5
6  Purpose     :  developer manual
7                 This file belongs into
8                 ijbswa.sourceforge.net:/home/groups/i/ij/ijbswa/htdocs/
9                 
10  $Id: developer-manual.sgml,v 1.3 2001/09/13 15:27:40 swa Exp $
11
12  Written by and Copyright (C) 2001 the SourceForge
13  IJBSWA team.  http://ijbswa.sourceforge.net
14
15  Based on the Internet Junkbuster originally written
16  by and Copyright (C) 1997 Anonymous Coders and 
17  Junkbusters Corporation.  http://www.junkbusters.com
18 -->
19
20 <article id="index">
21   <artheader>
22     <title>Junkbuster Developer Manual</title>
23
24     <pubdate>$Id: developer-manual.sgml,v 1.3 2001/09/13 15:27:40 swa Exp $</pubdate>
25
26     <authorgroup>
27       <author>
28         <affiliation>
29           <orgname>By: Junkbuster Developers</orgname>
30         </affiliation>
31       </author>
32     </authorgroup>
33
34     <abstract>
35       <para>
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.
40  </para>
41       <para>
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.
45  </para>
46
47       <para>
48   Feel free to send a note to the developers at <email>ijbswa-developers@lists.sourceforge.net</email>.
49  </para>
50     </abstract>
51   </artheader>
52
53   <!--   ~~~~~       New section      ~~~~~     -->
54   <sect1 id="introduction"><title>Introduction</title>
55     <para>To be filled.
56 </para>
57   </sect1>
58
59   <!--   ~~~~~       New section      ~~~~~     -->
60   <sect1 id="quickstart"><title>Quickstart to Junkbuster Development</title>
61     <para>To be filled.
62 </para>
63   </sect1>
64
65   <!--   ~~~~~       New section      ~~~~~     -->
66   <sect1 id="documentation"><title>Documentation Guidelines</title>
67     <para>
68 All docs should be ...
69 <ItemizedList>
70         <ListItem>
71           <Para>in a format that is widely used. I propose HTML.
72   </Para>
73         </ListItem>
74         <ListItem>
75           <Para>we either
76   <ItemizedList>
77               <ListItem>
78                 <Para>generate man pages from the documentation (let's _NOT_
79 write them manually), or</Para>
80               </ListItem>
81               <ListItem><Para>we have a man page that points to the
82               documentation (I propose this option)
83               </Para></ListItem>
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>
90   </ItemizedList>
91   </para>
92   </sect1>
93
94   <!--   ~~~~~       New section      ~~~~~     -->
95   <sect1 id="coding"><title>Coding Guidelines</title>
96
97     <sect2 id="s1"><title>Introduction</title>
98
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
103     the project.</para>
104
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>
109
110   </sect2>
111
112     <sect2 id="s2"><title>Using Comments</title>
113  
114
115     <sect3 id="s3"><title>Comment, Comment, Comment</title>
116
117     <para><emphasis>Explanation:</></para>
118
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>
127
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>
131
132     <para><emphasis>Example:</></para>
133 <programlisting>
134 /* if page size greater than 1k ... */
135 if ( PageLength() > 1024 )
136 {
137     ... "block" the page up ...
138 }
139
140 /* if page size is small, send it in blocks */
141 if ( PageLength() > 1024 )
142 {
143     ... "block" the page up ...
144 }
145
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.
149 </programlisting>
150   </sect3>
151
152     
153
154     <sect3 id="s4"><title>Use blocks for comments</title>
155
156     <para><emphasis>Explanation:</></para>
157
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>
163
164     <para><emphasis>Example:</></para>
165 <programlisting>
166 /*********************************************************************
167  * This will stand out clearly in your code!
168  *********************************************************************/
169 if ( thisVariable == thatVariable )
170 {
171    DoSomethingVeryImportant();
172 }
173
174
175 /* unfortunately, this may not */
176 if ( thisVariable == thatVariable )
177 {
178    DoSomethingVeryImportant();
179 }
180
181
182 if ( thisVariable == thatVariable ) /* this may not either */
183 {
184    DoSomethingVeryImportant();
185 }</programlisting>
186
187     <para><emphasis>Exception:</></para>
188
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>
192
193     
194   </sect3>
195     
196
197     <sect3 id="s5"><title>Keep Comments on their own line</title>
198
199     <para><emphasis>Explanation:</></para>
200
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>
204
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
208     parameters.</para>
209
210     <para><emphasis>Example:</></para>
211 <programlisting>
212 /*********************************************************************
213  * This will stand out clearly in your code,
214  * But the second example won't.
215  *********************************************************************/
216 if ( thisVariable == thatVariable )
217 {
218    DoSomethingVeryImportant();
219 }
220
221 if ( thisVariable == thatVariable ) /*can you see me?*/
222 {
223    DoSomethingVeryImportant(); /*not easily*/
224 }
225
226
227 /*********************************************************************
228  * But, the encouraged exceptions:
229  *********************************************************************/
230 int urls_read     = 0;     /* # of urls read + rejected */
231 int urls_rejected = 0;     /* # of urls rejected */
232
233 if ( 1 == X )
234 {
235    DoSomethingVeryImportant();
236 }
237
238
239 short DoSomethingVeryImportant(
240    short firstParam,   /* represents something */
241    short nextParam     /* represents something else */ )
242 {
243    ...code here...
244
245 }   /* -END- DoSomethingVeryImportant */
246 </programlisting>
247   </sect3>
248     
249
250     <sect3 id="s6"><title>Comment each logical step</title>
251
252     <para><emphasis>Explanation:</></para>
253
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
256     readable.</para>
257
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
260     one.</para>
261
262     <para>Most "for", "while", "do", etc... loops _probably_ need a
263     comment. After all, these are usually major logic
264     containers.</para>
265
266     
267   </sect3>
268     
269
270     <sect3 id="s7"><title>Comment All Functions Thoroughly</title>
271
272     <para><emphasis>Explanation:</></para>
273
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>
286
287     
288   </sect3>
289     
290
291     <sect3 id="s8"><title>Comment at the end of braces if the
292     content is more than one screen length</title>
293
294     <para><emphasis>Explanation:</></para>
295
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>
301
302     <para>As a suggestion , use the following flags to make the
303     comment and its brace more readable:</para>
304
305     <para>use following a closing brace: } /* -END- if() or while ()
306     or etc... */</para>
307
308     <para><emphasis>Example:</></para>
309 <programlisting>
310 if ( 1 == X )
311 {
312    DoSomethingVeryImportant();
313    ...some long list of commands...
314 } /* -END- if x is 1 */
315
316 or:
317
318 if ( 1 == X )
319 {
320    DoSomethingVeryImportant();
321    ...some long list of commands...
322 } /* -END- if ( 1 == X ) */
323 </programlisting>
324   </sect3>
325     
326   </sect2>
327
328     <sect2 id="s9"><title>Naming Conventions</title>
329
330     
331
332     <sect3 id="s10"><title>Variable Names</title>
333
334     <para><emphasis>Explanation:</></para>
335
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>
342
343     <para><emphasis>Example:</></para>
344 <programlisting>
345 int ms_iis5_hack = 0;</programlisting>
346
347     <para><emphasis>Instead of:</></para>
348
349     <para>
350 <programlisting>
351 int msiis5hack = 0; int msIis5Hack = 0;
352 </programlisting>
353 </para>
354
355     
356
357   </sect3>    
358
359     <sect3 id="s11"><title>Function Names</title>
360
361     <para><emphasis>Explanation:</></para>
362
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>
369
370     <para><emphasis>Example:</></para>
371 <programlisting>
372 int load_some_file( struct client_state *csp )</programlisting>
373
374     <para><emphasis>Instead of:</></para>
375
376     <para>
377 <programlisting>
378 int loadsomefile( struct client_state *csp )
379 int loadSomeFile( struct client_state *csp )
380 </programlisting>
381 </para>
382
383     
384   </sect3>
385     
386
387     <sect3 id="s12"><title>Header file prototypes</title>
388
389     <para><emphasis>Explanation:</></para>
390
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>
394
395     <para><emphasis>Example:</></para>
396 <programlisting>
397 (.h) extern int load_aclfile( struct client_state *csp );
398 (.c) int load_aclfile( struct client_state *csp )</programlisting>
399
400     <para><emphasis>Instead of:</>
401 <programlisting>
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 )
405 </programlisting>
406 </para>
407
408     
409   </sect3>
410     
411
412     <sect3 id="s13"><title>Enumerations, and #defines</title>
413
414     <para><emphasis>Explanation:</></para>
415
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>
419
420     <para><emphasis>Example:</></para>
421 <programlisting>
422 (enumeration) : enum Boolean { FALSE, TRUE };
423 (#define) : #define DEFAULT_SIZE 100;</programlisting>
424
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>
428
429     <para><emphasis>Example:</></para>
430 <programlisting>
431 #define FEATURE_FORCE 1
432
433 #ifdef FEATURE_FORCE
434 #define FORCE_PREFIX blah
435 #endif /* def FEATURE_FORCE */
436 </programlisting>
437   </sect3>
438     
439
440     <sect3 id="s14"><title>Constants</title>
441
442     <para><emphasis>Explanation:</></para>
443
444     <para>Spell common words out entirely (do not remove vowels).</para>
445
446     <para>Use only widely-known domain acronyms and abbreviations.
447     Capitalize all letters of an acronym.</para>
448
449     <para>Use underscore (_) to separate adjacent acronyms and
450     abbreviations. Never terminate a name with an underscore.</para>
451
452     <para><emphasis>Example:</></para>
453 <programlisting>
454 #define USE_IMAGE_LIST 1</programlisting>
455
456     <para><emphasis>Instead of:</></para>
457
458     <para>
459 <programlisting>
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
465 </programlisting>
466 </para>
467
468     
469   </sect3>
470
471   </sect2>
472     
473
474     <sect2 id="s15"><title>Using Space</title>
475
476     
477
478     <sect3 id="s16"><title>Put braces on a line by themselves.</title>
479
480     <para><emphasis>Explanation:</></para>
481
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
486     block.</para>
487
488     <para><emphasis>Example:</></para>
489 <programlisting>
490 if ( this == that )
491 {
492    ...
493 }</programlisting>
494
495     <para><emphasis>Instead of:</></para>
496
497     <para>if ( this == that ) { ... }</para>
498
499     <para>or</para>
500
501     <para>if ( this == that ) { ... }</para>
502
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>
508
509     <para><emphasis>Status:</> developer-discrection.</para>
510
511     <para><emphasis>Example exception:</></para>
512 <programlisting>
513 while ( more lines are read )
514 {
515    /* Please document what is/is not a comment line here */
516    if ( it's a comment ) continue;
517
518    do_something( line );
519 }
520 </programlisting>
521   </sect3>
522     
523
524     <sect3 id="s17"><title>ALL control statements should have a
525     block</title>
526
527     <para><emphasis>Explanation:</></para>
528
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>
532
533     <para><emphasis>Example:</></para>
534 <programlisting>
535 if ( this == that )
536 {
537    DoSomething();
538    DoSomethingElse();
539 }</programlisting>
540
541     <para><emphasis>Instead of:</></para>
542
543     <para>if ( this == that ) DoSomething(); DoSomethingElse();</para>
544
545     <para>or</para>
546
547     <para>if ( this == that ) DoSomething();</para>
548
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>
554
555     
556   </sect3>
557     
558
559     <sect3 id="s18"><title>Do not belabor/blow-up boolean
560     expressions</title>
561
562     <para><emphasis>Example:</></para>
563 <programlisting>
564 structure->flag = ( condition );</programlisting>
565
566     <para><emphasis>Instead of:</></para>
567
568     <para>if ( condition ) { structure->flag = 1; } else {
569     structure->flag = 0; }</para>
570
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>
575
576     
577   </sect3>
578     
579
580     <sect3 id="s19"><title>Use white space freely because it is
581     free</title>
582
583     <para><emphasis>Explanation:</></para>
584
585     <para>Make it readable. The notable exception to using white space
586     freely is listed in the next guideline.</para>
587
588     <para><emphasis>Example:</></para>
589 <programlisting>
590 int firstValue   = 0;
591 int someValue    = 0;
592 int anotherValue = 0;
593 int thisVariable = 0;
594
595 if ( thisVariable == thatVariable )
596
597 firstValue = oldValue + ( ( someValue - anotherValue ) - whatever )
598 </programlisting>
599   </sect3>
600     
601
602     <sect3 id="s20"><title>Don't use white space around structure
603     operators</title>
604
605     <para><emphasis>Explanation:</></para>
606
607     <para>- structure pointer operator ( "->" ) - member operator (
608     "." ) - functions and parentheses</para>
609
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
613     as clear.</para>
614
615     <para><emphasis>Example:</></para>
616 <programlisting>
617 aStruct->aMember;
618 aStruct.aMember;
619 FunctionName();</programlisting>
620
621     <para><emphasis>Instead of:</> aStruct -> aMember; aStruct . aMember;
622     FunctionName ();</para>
623
624     
625   </sect3>
626     
627
628     <sect3 id="s21"><title>Make the last brace of a function stand
629     out</title>
630
631     <para><emphasis>Example:</></para>
632 <programlisting>
633 int function1( ... )
634 {
635    ...code...
636    return( retCode );
637
638 }   /* -END- function1 */
639
640
641 int function2( ... )
642 {
643 }   /* -END- function2 */
644 </programlisting>
645
646     <para><emphasis>Instead of:</></para>
647
648     <para>int function1( ... ) { ...code... return( retCode ); } int
649     function2( ... ) { }</para>
650
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
657     is free!</para>
658
659     <para><emphasis>Status:</> developer-discrection on the number of blank
660     lines. Enforced is the end of function comments.</para>
661
662     
663   </sect3>
664     
665
666     <sect3 id="s22"><title>Use 3 character indentions</title>
667
668     <para><emphasis>Explanation:</></para>
669
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>
674
675     <para><emphasis>Example:</></para>
676 <programlisting>
677 static const char * const url_code_map[256] =
678 {
679    NULL, ...
680 };
681
682
683 int function1( ... )
684 {
685    if ( 1 )
686    {
687       return( ALWAYS_TRUE );
688    }
689    else
690    {
691       return( HOW_DID_YOU_GET_HERE );
692    }
693
694    return( NEVER_GETS_HERE );
695
696 }
697 </programlisting>
698   </sect3>
699
700   </sect2>
701     
702
703     <sect2 id="s23"><title>Initializing</title>
704
705     
706
707     <sect3 id="s24"><title>Initialize all variables</title>
708
709     <para><emphasis>Explanation:</></para>
710
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
714     variable.</para>
715
716     <para><emphasis>Example:</></para>
717 <programlisting>
718 short anShort = 0;
719 float aFloat  = 0;
720 struct *ptr = NULL;</programlisting>
721
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.
725     arrayPtr[0].</para>
726
727     <para><emphasis>Status:</> developer-discrection if and only if the
728     variable is assigned a value "shortly after" declaration.</para>
729
730   </sect3>
731   </sect2>
732     
733
734     <sect2 id="s25"><title>Functions</title>
735
736     
737
738     <sect3 id="s26"><title>Name functions that return a boolean as a
739     question.</title>
740
741     <para><emphasis>Explanation:</></para>
742
743     <para>Value should be phrased as a question that would logically
744     be answered as a true or false statement</para>
745
746     <para><emphasis>Example:</></para>
747 <programlisting>
748 ShouldWeBlockThis();
749 ContainsAnImage();
750 IsWebPageBlank();
751 </programlisting>
752   </sect3>
753     
754
755     <sect3 id="s27"><title>Always specify a return type for a
756     function.</title>
757
758     <para><emphasis>Explanation:</></para>
759
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>
764
765     
766   </sect3>
767     
768
769     <sect3 id="s28"><title>Minimize function calls when iterating by
770     using variables</title>
771
772     <para><emphasis>Explanation:</></para>
773
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>
776
777     <para><emphasis>Example:</></para>
778 <programlisting>
779 for ( size_t cnt = 0; cnt < blockListLength(); cnt ++ )
780 {
781    ....
782 }</programlisting>
783
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>
793
794     <para>Instead of using a function call during the iterations,
795     assign the value to a variable, and evaluate using the
796     variable.</para>
797
798     <para><emphasis>Example:</></para>
799 <programlisting>
800 size_t len = blockListLength();
801
802 for ( size_t cnt = 0; cnt < len; cnt ++ )
803 {
804    ....
805 }</programlisting>
806
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>
810
811     
812   </sect3>
813     
814
815     <sect3 id="s29"><title>Pass and Return by Const Reference</title>
816
817     <para><emphasis>Explanation:</></para>
818
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,
823     char *s2 );</para>
824
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"
827     ); }</para>
828
829     <para>Both these pointers are *const*! If the c runtime library
830     maintainers do it, we should too.</para>
831
832     
833   </sect3>
834     
835
836     <sect3 id="s30"><title>Pass and Return by Value</title>
837
838     <para><emphasis>Explanation:</></para>
839
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>
843
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>
847
848     
849   </sect3>
850     
851
852     <sect3 id="s31"><title>Names of include files</title>
853
854     <para><emphasis>Explanation:</></para>
855
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>
862
863     <para><emphasis>Example:</></para>
864 <programlisting>
865 #include &lt;iostream.h&gt;     /* This is not a local include */
866 #include "config.h"       /* This IS a local include */
867 </programlisting>
868
869     <para><emphasis>Exception:</></para>
870
871     <para>
872 <programlisting>
873 /* This is not a local include, but requires a path element. */ 
874 #include &lt;sys/fileName.h&gt;
875 </programlisting>
876 </para>
877
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>
881
882     
883   </sect3>
884     
885
886     <sect3 id="s32"><title>Provide multiple inclusion
887     protection</title>
888
889     <para><emphasis>Explanation:</></para>
890
891     <para>Prevents compiler and linker errors resulting from
892     redefinition of items.</para>
893
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
897     uppercase.</para>
898
899     <para><emphasis>Example:</></para>
900 <programlisting>
901 #ifndef PROJECT_H_INCLUDED
902 #define PROJECT_H_INCLUDED
903  ...
904 #endif /* ndef PROJECT_H_INCLUDED */
905 </programlisting>
906   </sect3>
907     
908
909     <sect3 id="s33"><title>Use `extern "C"` when appropriate</title>
910
911     <para><emphasis>Explanation:</></para>
912
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>
916
917     <para><emphasis>Example:</></para>
918 <programlisting>
919 #ifdef __cplusplus
920 extern "C"
921 {
922 #endif /* def __cplusplus */
923
924 ... function definitions here ...
925
926 #ifdef __cplusplus
927 }
928 #endif /* def __cplusplus */
929 </programlisting>
930   </sect3>
931     
932
933     <sect3 id="s34"><title>Where Possible, Use Forward Struct
934     Declaration Instead of Includes</title>
935
936     <para><emphasis>Explanation:</></para>
937
938     <para>Useful in headers that include pointers to other struct's.
939     Modifications to excess header files may cause needless
940     compiles.</para>
941
942     <para><emphasis>Example:</></para>
943 <programlisting>
944 /*********************************************************************
945  * We're avoiding an include statement here!
946  *********************************************************************/
947 struct file_list;
948 extern file_list *xyz;</programlisting>
949
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>
954
955     <para><emphasis>Status:</> Use with discrection.</para>
956
957     
958   </sect3>
959   </sect2>
960
961     <sect2 id="s35"><title>General Coding Practices</title>
962
963     
964
965     <sect3 id="s36"><title>Turn on warnings</title>
966
967     <para><emphasis>Explanation</></para>
968
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>
972
973     
974   </sect3>
975     
976
977     <sect3 id="s37"><title>Provide a default case for all switch
978     statements</title>
979
980     <para><emphasis>Explanation:</></para>
981
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>
986
987     <para><emphasis>Example:</></para>
988 <programlisting>
989 switch( hash_string( cmd ) )
990 {
991    case hash_actions_file :
992       ... code ...
993       break;
994
995    case hash_confdir :
996       ... code ...
997       break;
998
999    default :
1000       log_error( ... );
1001       ... anomly code goes here ...
1002       continue; / break; / exit( 1 ); / etc ...
1003
1004 } /* end switch( hash_string( cmd ) ) */</programlisting>
1005
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>
1010
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>
1015
1016     <para><emphasis>Status:</> Programmer discretion is advised.</para>
1017
1018     
1019   </sect3>
1020     
1021
1022     <sect3 id="s38"><title>Try to avoid falling through cases in a
1023     switch statement.</title>
1024
1025     <para><emphasis>Explanation:</></para>
1026
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>
1032
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>
1038
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
1041     necessary.</para>
1042
1043     
1044   </sect3>
1045     
1046
1047     <sect3 id="s39"><title>Use 'long' or 'short' Instead of
1048     'int'</title>
1049
1050     <para><emphasis>Explanation:</></para>
1051
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>
1054
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"
1059     script?</para>
1060
1061     
1062   </sect3>
1063     
1064
1065     <sect3 id="s40"><title>Don't mix size_t and other types</title>
1066
1067     <para><emphasis>Explanation:</></para>
1068
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
1074     you can.</para>
1075
1076     
1077   </sect3>
1078     
1079
1080     <sect3 id="s41"><title>Declare each variable and struct on its
1081     own line.</title>
1082
1083     <para><emphasis>Explanation:</></para>
1084
1085     <para>It can be tempting to declare a series of variables all on
1086     one line. Don't.</para>
1087
1088     <para><emphasis>Example:</></para>
1089 <programlisting>
1090 long a = 0;
1091 long b = 0;
1092 long c = 0;</programlisting>
1093
1094     <para><emphasis>Instead of:</></para>
1095
1096     <para>long a, b, c;</para>
1097
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"
1102     eliminate</para>
1103
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>
1108
1109     <para><emphasis>Status:</> developer-discrection.</para>
1110
1111     
1112   </sect3>
1113     
1114
1115     <sect3 id="s42"><title>Use malloc/zalloc sparingly</title>
1116
1117     <para><emphasis>Explanation:</></para>
1118
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>
1121
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>
1124
1125     <para><emphasis>Example:</></para>
1126 <programlisting>
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'.
1129 </programlisting>
1130   </sect3>
1131     
1132
1133     <sect3 id="s43"><title>The Programmer Who Uses 'malloc' is
1134     Responsible for Ensuring 'free'</title>
1135
1136     <para><emphasis>Explanation:</></para>
1137
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>
1145
1146     <para><emphasis>Example:</></para>
1147 <programlisting>
1148 int load_re_filterfile( struct client_state *csp ) { ... }
1149 static void unload_re_filterfile( void *f ) { ... }</programlisting>
1150
1151     <para><emphasis>Exceptions:</></para>
1152
1153     <para>The developer cannot be expected to provide `free'ing
1154     functions for C run-time library functions ... such as
1155     `strdup'.</para>
1156
1157     <para><emphasis>Status:</> developer-discrection. The "main" use of this
1158     standard is for allocating and freeing data structures (complex
1159     or nested).</para>
1160
1161     
1162   </sect3>
1163     
1164
1165     <sect3 id="s44"><title>Add loaders to the `file_list' structure
1166     and in order</title>
1167
1168     <para><emphasis>Explanation:</></para>
1169
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>
1173
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>
1178
1179     
1180   </sect3>
1181     
1182
1183     <sect3 id="s45"><title>"Uncertain" new code and/or changes to
1184     exitinst code, use FIXME</title>
1185
1186     <para><emphasis>Explanation:</></para>
1187
1188     <para>If you have enough confidence in new code or confidence in
1189     your changes, but are not *quite* sure of the reprocussions,
1190     add this:</para>
1191
1192     <para>/* FIXME: this code has a logic error on platform XYZ, *
1193     attempthing to fix */ #ifdef PLATFORM ...changed code here...
1194     #endif</para>
1195
1196     <para>or:</para>
1197
1198     <para>/* FIXME: I think the original author really meant this...
1199     */ ...changed code here...</para>
1200
1201     <para>or:</para>
1202
1203     <para>/* FIXME: new code that *may* break something else... */
1204     ...new code here...</para>
1205
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
1209     project).</para>
1210
1211     
1212   </sect3>
1213
1214   </sect2>
1215
1216     <sect2 id="s46"><title>Addendum: Template for files and function
1217     comment blocks:</title>
1218
1219     <para><emphasis>Example for file comments:</></para>
1220 <programlisting>
1221 const char FILENAME_rcs[] = "$Id: developer-manual.sgml,v 1.3 2001/09/13 15:27:40 swa Exp $";
1222 /*********************************************************************
1223  *
1224  * File        :  $S<!-- Break CVS Substitution -->ource$
1225  *
1226  * Purpose     :  (Fill me in with a good description!)
1227  *
1228  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
1229  *                IJBSWA team.  http://ijbswa.sourceforge.net
1230  *
1231  *                Based on the Internet Junkbuster originally written
1232  *                by and Copyright (C) 1997 Anonymous Coders and
1233  *                Junkbusters Corporation.  http://www.junkbusters.com
1234  *
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.
1240  *
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.
1246  *
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.
1252  *
1253  * Revisions   :
1254  *    $L<!-- Break CVS Substitution -->og$
1255  *
1256  *********************************************************************/
1257
1258
1259 #include "config.h"
1260
1261    ...necessary include files for us to do our work...
1262
1263 const char FILENAME_h_rcs[] = FILENAME_H_VERSION;
1264 </programlisting>
1265
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>
1270
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
1275     can.</para>
1276
1277     <para><emphasis>Example for file header comments:</></para>
1278 <programlisting>
1279 #ifndef _FILENAME_H
1280 #define _FILENAME_H
1281 #define FILENAME_H_VERSION "$Id: developer-manual.sgml,v 1.3 2001/09/13 15:27:40 swa Exp $"
1282 /*********************************************************************
1283  *
1284  * File        :  $S<!-- Break CVS Substitution -->ource$
1285  *
1286  * Purpose     :  (Fill me in with a good description!)
1287  *
1288  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
1289  *                IJBSWA team.  http://ijbswa.sourceforge.net
1290  *
1291  *                Based on the Internet Junkbuster originally written
1292  *                by and Copyright (C) 1997 Anonymous Coders and
1293  *                Junkbusters Corporation.  http://www.junkbusters.com
1294  *
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.
1300  *
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.
1306  *
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.
1312  *
1313  * Revisions   :
1314  *    $L<!-- Break CVS Substitution -->og$
1315  *
1316  *********************************************************************/
1317
1318
1319 #include "project.h"
1320
1321 #ifdef __cplusplus
1322 extern "C" {
1323 #endif
1324
1325    ... function headers here ...
1326
1327
1328 /* Revision control strings from this header and associated .c file */
1329 extern const char FILENAME_rcs[];
1330 extern const char FILENAME_h_rcs[];
1331
1332
1333 #ifdef __cplusplus
1334 } /* extern "C" */
1335 #endif
1336
1337 #endif /* ndef _FILENAME_H */
1338
1339 /*
1340   Local Variables:
1341   tab-width: 3
1342   end:
1343 */
1344 </programlisting>
1345
1346     <para><emphasis>Example for function comments:</></para>
1347 <programlisting>
1348 /*********************************************************************
1349  *
1350  * Function    :  FUNCTION_NAME
1351  *
1352  * Description :  (Fill me in with a good description!)
1353  *
1354  * Parameters  :
1355  *          1  :  param1 = pointer to an important thing
1356  *          2  :  x      = pointer to something else
1357  *
1358  * Returns     :  0 => Ok, everything else is an error.
1359  *
1360  *********************************************************************/
1361 int FUNCTION_NAME( void *param1, const char *x )
1362 {
1363    ...
1364    return( 0 );
1365
1366 }
1367 </programlisting>
1368
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
1371     page.</para>
1372
1373   </sect2>
1374
1375   </sect1>
1376
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
1380 why you did it.
1381 </para>
1382   </sect1>
1383
1384   <!--   ~~~~~       New section      ~~~~~     -->
1385   <sect1 id="testing"><title>Testing Guidelines</title>
1386     <para>To be filled.
1387 </para>
1388
1389     <!--   ~~~~~       New section      ~~~~~     -->
1390     <sect2 id="testing-plan"><title>Testplan for releases</title>
1391       <para>
1392 Explain release numbers. major, minor. developer releases. etc.
1393
1394 <OrderedList Numeration="Arabic">
1395           <ListItem><Para>
1396 Remove any existing rpm with rpm -e
1397 </Para></ListItem>
1398           <ListItem><Para>
1399 Remove any file that was left over. This includes (but is not limited to)
1400       <ItemizedList>
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>
1406               </ItemizedList>
1407 </Para></ListItem>
1408           <ListItem><Para>
1409 Install the rpm. Any error messages?
1410 </Para></ListItem>
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>
1416         </OrderedList>
1417 </para>
1418     </sect2>
1419
1420     <!--   ~~~~~       New section      ~~~~~     -->
1421     <sect2 id="testing-report"><title>Test reports</title>
1422       <para>
1423 Please submit test reports only with the <ulink url="http://sourceforge.net/tracker/?func=add&amp;group_id=11118&amp;atid=395005">test form</ulink>
1424 at sourceforge. Three simple steps:
1425         <ItemizedList>
1426           
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>
1431           </ListItem>
1432         </ItemizedList>
1433         Do not mail to the mailinglist (we cannot keep track on issues there).
1434       </para>
1435     </sect2>
1436     
1437   </sect1>
1438   
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.
1442     </para>
1443   </sect1>
1444   
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.
1448     </para>
1449   </sect1>
1450   
1451   <!--   ~~~~~       New section      ~~~~~     -->
1452   <sect1 id="seealso"><title>See also</title>
1453     <para>Please see the user manual for information on references.
1454     </para>
1455   </sect1>
1456
1457   <!--
1458
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.
1464
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.
1470
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.
1476
1477   $Log: developer-manual.sgml,v $
1478   Revision 1.3  2001/09/13 15:27:40  swa
1479   cosmetics
1480
1481   Revision 1.2  2001/09/13 15:20:17  swa
1482   merged standards into developer manual
1483
1484   Revision 1.1  2001/09/12 15:36:41  swa
1485   source files for junkbuster documentation
1486
1487   Revision 1.3  2001/09/10 17:43:59  swa
1488   first proposal of a structure.
1489
1490   Revision 1.2  2001/06/13 14:28:31  swa
1491   docs should have an author.
1492
1493   Revision 1.1  2001/06/13 14:20:37  swa
1494   first import of project's documentation for the webserver.
1495
1496   -->
1497
1498 </article>