consistent look. reuse of copyright, history et. al.
[privoxy.git] / doc / source / developer-manual.sgml
1 <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V3.1//EN"[
2 <!entity % dummy "INCLUDE"> 
3 <!entity supported SYSTEM "supported.sgml">
4 <!entity newfeatures SYSTEM "newfeatures.sgml">
5 <!entity p-intro SYSTEM "privoxy.sgml">
6 <!entity history SYSTEM "history.sgml">
7 <!entity seealso SYSTEM "seealso.sgml">
8 <!entity contacting SYSTEM "contacting.sgml">
9 <!entity copyright SYSTEM "copyright.sgml">
10 <!entity p-version "2.9.13">
11 <!entity p-status "BETA">
12 <!entity % p-not-stable "INCLUDE"> <!-- set to IGNORE for stable release  -->
13 <!entity % p-stable "IGNORE">      <!-- set INCLUDE for stable release    -->
14 <!entity % p-text "IGNORE">        <!-- define we are not a text only doc -->
15 <!entity % p-doc "INCLUDE">        <!-- and we are a formal doc           -->
16 ]>
17 <!--
18  File        :  $Source: /cvsroot/ijbswa/current/doc/source/developer-manual.sgml,v $
19
20  Purpose     :  developer manual
21                 This file belongs into
22                 ijbswa.sourceforge.net:/home/groups/i/ij/ijbswa/htdocs/
23                 
24  $Id: developer-manual.sgml,v 1.22 2002/04/04 17:27:56 swa Exp $
25
26  Written by and Copyright (C) 2001 the SourceForge
27  Privoxy team. http://www.privoxy.org/
28
29  Based on the Internet Junkbuster originally written
30  by and Copyright (C) 1997 Anonymous Coders and 
31  Junkbusters Corporation.  http://www.junkbusters.com
32 -->
33
34 <article id="index">
35   <artheader>
36     <title>Privoxy Developer Manual</title>
37
38     <pubdate>$Id: developer-manual.sgml,v 1.22 2002/04/04 17:27:56 swa Exp $</pubdate>
39
40     <authorgroup>
41       <author>
42         <affiliation>
43           <orgname>By: Privoxy Developers</orgname>
44         </affiliation>
45       </author>
46     </authorgroup>
47
48     <abstract>
49 <![%dummy;[
50  <para>
51  <comment>
52   This is here to keep vim syntax file from breaking :/
53   If I knew enough to fix it, I would.
54   PLEASE DO NOT REMOVE! HB: hal@foobox.net
55  </comment>
56  </para>
57  ]]>
58 <para>
59  The developer manual gives the users information on how to help the developer
60  team. It provides guidance on coding, testing, documentation and other
61  issues. 
62  </para>
63
64 <!-- Include privoxy.sgml boilerplate text: -->
65
66  &p-intro;
67
68 <!-- end boilerplate -->
69
70 <para>
71  You can find the latest version of the this manual at <ulink
72  url="http://www.privoxy.org/developer-manual/">http://www.privoxy.org/developer-manual/</ulink>.
73  Please see the Contact section on how to contact the developers.
74 </para>
75
76 <!--        <para> -->
77 <!--    Feel free to send a note to the developers at <email>ijbswa-developers@lists.sourceforge.net</email>. -->
78 <!--   </para> -->
79
80     </abstract>
81   </artheader>
82
83 <!--   ~~~~~       New section      ~~~~~     -->
84 <sect1 id="intro" label=""><title></title>
85 <!-- dummy section to force TOC on page by itself -->
86 <!-- DO NOT REMOVE! please ;) -->
87 <para> </para>
88 </sect1>
89
90 <!--   ~~~~~       New section      ~~~~~     -->
91
92
93 <!--   ~~~~~       New section      ~~~~~     -->
94   <sect1 label="1" id="introduction"><title>Introduction</title>
95 <!--
96
97  I don't like seeing blank space :) So added *something* here.
98
99  --> 
100     <para>
101      <application>Privoxy</application>, as an heir to
102      <application>Junkbuster</application>, is an Open Source project 
103      and licensed under the GPL. As such, <application>Privoxy</application>
104      development is potentially open to anyone who has the time, knowledge,
105      and desire to contribute in any capacity. Our goals are simply to
106      continue the mission, to improve <application>Privoxy</application>, and
107      to make it available to as wide an audience as possible. 
108     </para>
109     <para>
110      One does not have to be a programmer to contribute. Packaging, testing,
111      and porting, are all important jobs as well.
112     </para>
113   </sect1>
114
115   <!--   ~~~~~       New section      ~~~~~     -->
116   <sect1 id="quickstart"><title>Quickstart to Privoxy Development</title>
117     <para>
118 You'll need an account on <ulink
119 url="http://sourceforge.net">Sourceforge</ulink> to support our development.
120 Mail your ID to the list and wait until a project manager has added you.
121 </para>
122
123 <para>
124 For the time being (read, this section is under construction), please note the
125 following guidelines for changing stuff in the code. If it is
126         <orderedlist numeration="arabic">
127                 <listitem><para>
128                 A bugfix / clean-up / cosmetic thing: shoot
129                 </para></listitem>
130                 <listitem><para>
131                 A new feature that can be turned off: shoot
132                 </para></listitem>
133                 <listitem><para>
134                 A clear improvement w/o side effects on other parts of the code: shoot
135                 </para></listitem>
136                 <listitem><para>
137                 A matter of taste: ask the list
138                 </para></listitem>
139                 <listitem><para>
140                 A major redesign of some part of the code: ask the list
141                 </para></listitem>
142         </orderedlist>  
143  </para>                
144 </sect1>        
145         
146   <!--   ~~~~~       New section      ~~~~~     -->
147   <sect1 id="documentation"><title>Documentation Guidelines</title>
148     <para>
149         All formal documents are maintained in docbook SGML and located
150         in the <computeroutput>doc/source</computeroutput> directory. You will
151         need <ulink url="http://www.docbook.org">docbook</ulink> and the
152         docbook stylesheets (or comparable alternatives), and either 
153         <application>jade</application> or <application>openjade</application> 
154         installed in order to build docs from source. Currently there is 
155         <ulink
156         url="../user-manual/index.html"><citetitle>user-manual</citetitle></ulink>,
157         <ulink
158         url="../faq/index.html"><citetitle>FAQ</citetitle></ulink>,
159         and, of course this, the <citetitle>developer-manual</citetitle> in
160         this format.
161         </para>
162         <para>
163          Other, less formal documents (e.g. README, LICENSE) are 
164          maintained as plain text files in the toplevel source 
165          directory.
166         </para>
167         <para>
168          Packagers are encouraged to include this documentation. For those
169          without the ability to build the docs locally, text versions of 
170          each are kept in CVS. Or HTML versions can be downloaded from the <ulink
171          url="http://www.privoxy.org">www.privoxy.org</ulink> website, which
172          should be fairly current.
173         </para>
174         <para>
175           Formal documents are built with the Makefile targets of 
176           <computeroutput>make dok</computeroutput>, or alternately
177           <computeroutput>make redhat-dok</computeroutput>. If you 
178           have problems, try both. The build process uses the document 
179           SGML sources in <computeroutput>doc/source</computeroutput> to
180           update all text files in <computeroutput>doc/text</computeroutput>
181           and to update all HTML documents in
182           <computeroutput>doc/webserver</computeroutput>.
183         </para>
184         <para>
185          Documentation writers should please make sure documents build 
186          successfully before committing to CVS.
187         </para>
188         <para>
189         How do you update the webserver (i.e. the pages on privoxy.org)?
190         <orderedlist numeration="arabic">
191                 <listitem><para>
192         First, build the docs by running <computeroutput>make
193         dok</computeroutput> (or alternately <computeroutput>make
194         redhat-dok</computeroutput>).                 
195                 </para></listitem>
196                 <listitem><para>
197         Run <computeroutput>make webserver</computeroutput> which copies all files from
198 <computeroutput>doc/webserver</computeroutput> to the sourceforge webserver
199 via scp.
200                 </para></listitem>
201         </orderedlist>
202   </para>
203  </sect1>
204
205 <!--     <listitem><para>be consistent with the redirect script (i.e. the <application>Privoxy</application> program -->
206 <!--       points via the redirect URL at sf to valid end-points in the document)</para></listitem> -->
207
208   <!--   ~~~~~       New section      ~~~~~     -->
209   <sect1 id="coding"><title>Coding Guidelines</title>
210
211     <sect2 id="s1"><title>Introduction</title>
212
213     <para>This set of standards is designed to make our lives easier.  It is
214     developed with the simple goal of helping us keep the "new and improved
215     <application>Privoxy</application>" consistent and reliable. Thus making
216     maintenance easier and increasing chances of success of the
217     project.</para>
218
219     <para>And that of course comes back to us as individuals. If we can
220     increase our development and product efficiencies then we can solve more
221     of the request for changes/improvements and in general feel good about
222     ourselves. ;-></para>
223
224   </sect2>
225
226     <sect2 id="s2"><title>Using Comments</title>
227  
228
229     <sect3 id="s3"><title>Comment, Comment, Comment</title>
230
231     <para><emphasis>Explanation:</emphasis></para>
232
233     <para>Comment as much as possible without commenting the obvious.
234     For example do not comment "aVariable is equal to bVariable".
235     Instead explain why aVariable should be equal to the bVariable.
236     Just because a person can read code does not mean they will
237     understand why or what is being done. A reader may spend a lot
238     more time figuring out what is going on when a simple comment
239     or explanation would have prevented the extra research. Please
240     help your brother IJB'ers out!</para>
241
242     <para>The comments will also help justify the intent of the code.
243     If the comment describes something different than what the code
244     is doing then maybe a programming error is occurring.</para>
245
246     <para><emphasis>Example:</emphasis></para>
247 <programlisting>
248 /* if page size greater than 1k ... */
249 if ( PageLength() > 1024 )
250 {
251     ... "block" the page up ...
252 }
253
254 /* if page size is small, send it in blocks */
255 if ( PageLength() > 1024 )
256 {
257     ... "block" the page up ...
258 }
259
260 This demonstrates 2 cases of "what not to do".  The first is a
261 "syntax comment".  The second is a comment that does not fit what
262 is actually being done.
263 </programlisting>
264   </sect3>
265
266     
267
268     <sect3 id="s4"><title>Use blocks for comments</title>
269
270     <para><emphasis>Explanation:</emphasis></para>
271
272     <para>Comments can help or they can clutter. They help when they
273     are differentiated from the code they describe. One line
274     comments do not offer effective separation between the comment
275     and the code. Block identifiers do, by surrounding the code
276     with a clear, definable pattern.</para>
277
278     <para><emphasis>Example:</emphasis></para>
279 <programlisting>
280 /*********************************************************************
281  * This will stand out clearly in your code!
282  *********************************************************************/
283 if ( thisVariable == thatVariable )
284 {
285    DoSomethingVeryImportant();
286 }
287
288
289 /* unfortunately, this may not */
290 if ( thisVariable == thatVariable )
291 {
292    DoSomethingVeryImportant();
293 }
294
295
296 if ( thisVariable == thatVariable ) /* this may not either */
297 {
298    DoSomethingVeryImportant();
299 }</programlisting>
300
301     <para><emphasis>Exception:</emphasis></para>
302
303     <para>If you are trying to add a small logic comment and do not
304     wish to "disrubt" the flow of the code, feel free to use a 1
305     line comment which is NOT on the same line as the code.</para>
306
307     
308   </sect3>
309     
310
311     <sect3 id="s5"><title>Keep Comments on their own line</title>
312
313     <para><emphasis>Explanation:</emphasis></para>
314
315     <para>It goes back to the question of readability. If the comment
316     is on the same line as the code it will be harder to read than
317     the comment that is on its own line.</para>
318
319     <para>There are three exceptions to this rule, which should be
320     violated freely and often: during the definition of variables,
321     at the end of closing braces, when used to comment
322     parameters.</para>
323
324     <para><emphasis>Example:</emphasis></para>
325 <programlisting>
326 /*********************************************************************
327  * This will stand out clearly in your code,
328  * But the second example won't.
329  *********************************************************************/
330 if ( thisVariable == thatVariable )
331 {
332    DoSomethingVeryImportant();
333 }
334
335 if ( thisVariable == thatVariable ) /*can you see me?*/
336 {
337    DoSomethingVeryImportant(); /*not easily*/
338 }
339
340
341 /*********************************************************************
342  * But, the encouraged exceptions:
343  *********************************************************************/
344 int urls_read     = 0;     /* # of urls read + rejected */
345 int urls_rejected = 0;     /* # of urls rejected */
346
347 if ( 1 == X )
348 {
349    DoSomethingVeryImportant();
350 }
351
352
353 short DoSomethingVeryImportant(
354    short firstparam,   /* represents something */
355    short nextparam     /* represents something else */ )
356 {
357    ...code here...
358
359 }   /* -END- DoSomethingVeryImportant */
360 </programlisting>
361   </sect3>
362     
363
364     <sect3 id="s6"><title>Comment each logical step</title>
365
366     <para><emphasis>Explanation:</emphasis></para>
367
368     <para>Logical steps should be commented to help others follow the
369     intent of the written code and comments will make the code more
370     readable.</para>
371
372     <para>If you have 25 lines of code without a comment, you should
373     probably go back into it to see where you forgot to put
374     one.</para>
375
376     <para>Most "for", "while", "do", etc... loops _probably_ need a
377     comment. After all, these are usually major logic
378     containers.</para>
379
380     
381   </sect3>
382     
383
384     <sect3 id="s7"><title>Comment All Functions Thoroughly</title>
385
386     <para><emphasis>Explanation:</emphasis></para>
387
388     <para>A reader of the code should be able to look at the comments
389     just prior to the beginning of a function and discern the
390     reason for its existence and the consequences of using it. The
391     reader should not have to read through the code to determine if
392     a given function is safe for a desired use. The proper
393     information thoroughly presented at the introduction of a
394     function not only saves time for subsequent maintenance or
395     debugging, it more importantly aids in code reuse by allowing a
396     user to determine the safety and applicability of any function
397     for the problem at hand. As a result of such benefits, all
398     functions should contain the information presented in the
399     addendum section of this document.</para>
400
401     
402   </sect3>
403     
404
405     <sect3 id="s8"><title>Comment at the end of braces if the
406     content is more than one screen length</title>
407
408     <para><emphasis>Explanation:</emphasis></para>
409
410     <para>Each closing brace should be followed on the same line by a
411     comment that describes the origination of the brace if the
412     original brace is off of the screen, or otherwise far away from
413     the closing brace. This will simplify the debugging,
414     maintenance, and readability of the code.</para>
415
416     <para>As a suggestion , use the following flags to make the
417     comment and its brace more readable:</para>
418
419     <para>use following a closing brace: } /* -END- if() or while ()
420     or etc... */</para>
421
422     <para><emphasis>Example:</emphasis></para>
423 <programlisting>
424 if ( 1 == X )
425 {
426    DoSomethingVeryImportant();
427    ...some long list of commands...
428 } /* -END- if x is 1 */
429
430 or:
431
432 if ( 1 == X )
433 {
434    DoSomethingVeryImportant();
435    ...some long list of commands...
436 } /* -END- if ( 1 == X ) */
437 </programlisting>
438   </sect3>
439     
440   </sect2>
441
442     <sect2 id="s9"><title>Naming Conventions</title>
443
444     
445
446     <sect3 id="s10"><title>Variable Names</title>
447
448     <para><emphasis>Explanation:</emphasis></para>
449
450     <para>Use all lowercase, and seperate words via an underscore
451     ('_'). Do not start an identifier with an underscore. (ANSI C
452     reserves these for use by the compiler and system headers.) Do
453     not use identifiers which are reserved in ANSI C++. (E.g.
454     template, class, true, false, ...). This is in case we ever
455     decide to port Privoxy to C++.</para>
456
457     <para><emphasis>Example:</emphasis></para>
458 <programlisting>
459 int ms_iis5_hack = 0;</programlisting>
460
461     <para><emphasis>Instead of:</emphasis></para>
462
463     <para>
464 <programlisting>
465 int msiis5hack = 0; int msIis5Hack = 0;
466 </programlisting>
467 </para>
468
469     
470
471   </sect3>    
472
473     <sect3 id="s11"><title>Function Names</title>
474
475     <para><emphasis>Explanation:</emphasis></para>
476
477     <para>Use all lowercase, and seperate words via an underscore
478     ('_'). Do not start an identifier with an underscore. (ANSI C
479     reserves these for use by the compiler and system headers.) Do
480     not use identifiers which are reserved in ANSI C++. (E.g.
481     template, class, true, false, ...). This is in case we ever
482     decide to port Privoxy to C++.</para>
483
484     <para><emphasis>Example:</emphasis></para>
485 <programlisting>
486 int load_some_file( struct client_state *csp )</programlisting>
487
488     <para><emphasis>Instead of:</emphasis></para>
489
490     <para>
491 <programlisting>
492 int loadsomefile( struct client_state *csp )
493 int loadSomeFile( struct client_state *csp )
494 </programlisting>
495 </para>
496
497     
498   </sect3>
499     
500
501     <sect3 id="s12"><title>Header file prototypes</title>
502
503     <para><emphasis>Explanation:</emphasis></para>
504
505     <para>Use a descriptive parameter name in the function prototype
506     in header files. Use the same parameter name in the header file
507     that you use in the c file.</para>
508
509     <para><emphasis>Example:</emphasis></para>
510 <programlisting>
511 (.h) extern int load_aclfile( struct client_state *csp );
512 (.c) int load_aclfile( struct client_state *csp )</programlisting>
513
514     <para><emphasis>Instead of:</emphasis>
515 <programlisting>
516 (.h) extern int load_aclfile( struct client_state * ); or 
517 (.h) extern int load_aclfile(); 
518 (.c) int load_aclfile( struct client_state *csp )
519 </programlisting>
520 </para>
521
522     
523   </sect3>
524     
525
526     <sect3 id="s13"><title>Enumerations, and #defines</title>
527
528     <para><emphasis>Explanation:</emphasis></para>
529
530     <para>Use all capital letters, with underscores between words. Do
531     not start an identifier with an underscore. (ANSI C reserves
532     these for use by the compiler and system headers.)</para>
533
534     <para><emphasis>Example:</emphasis></para>
535 <programlisting>
536 (enumeration) : enum Boolean { FALSE, TRUE };
537 (#define) : #define DEFAULT_SIZE 100;</programlisting>
538
539     <para><emphasis>Note:</emphasis> We have a standard naming scheme for #defines
540     that toggle a feature in the preprocessor: FEATURE_>, where
541     > is a short (preferably 1 or 2 word) description.</para>
542
543     <para><emphasis>Example:</emphasis></para>
544 <programlisting>
545 #define FEATURE_FORCE 1
546
547 #ifdef FEATURE_FORCE
548 #define FORCE_PREFIX blah
549 #endif /* def FEATURE_FORCE */
550 </programlisting>
551   </sect3>
552     
553
554     <sect3 id="s14"><title>Constants</title>
555
556     <para><emphasis>Explanation:</emphasis></para>
557
558     <para>Spell common words out entirely (do not remove vowels).</para>
559
560     <para>Use only widely-known domain acronyms and abbreviations.
561     Capitalize all letters of an acronym.</para>
562
563     <para>Use underscore (_) to separate adjacent acronyms and
564     abbreviations. Never terminate a name with an underscore.</para>
565
566     <para><emphasis>Example:</emphasis></para>
567 <programlisting>
568 #define USE_IMAGE_LIST 1</programlisting>
569
570     <para><emphasis>Instead of:</emphasis></para>
571
572     <para>
573 <programlisting>
574 #define USE_IMG_LST 1 or 
575 #define _USE_IMAGE_LIST 1 or
576 #define USE_IMAGE_LIST_ 1 or 
577 #define use_image_list 1 or
578 #define UseImageList 1
579 </programlisting>
580 </para>
581
582     
583   </sect3>
584
585   </sect2>
586     
587
588     <sect2 id="s15"><title>Using Space</title>
589
590     
591
592     <sect3 id="s16"><title>Put braces on a line by themselves.</title>
593
594     <para><emphasis>Explanation:</emphasis></para>
595
596     <para>The brace needs to be on a line all by itself, not at the
597     end of the statement. Curly braces should line up with the
598     construct that they're associated with. This practice makes it
599     easier to identify the opening and closing braces for a
600     block.</para>
601
602     <para><emphasis>Example:</emphasis></para>
603 <programlisting>
604 if ( this == that )
605 {
606    ...
607 }</programlisting>
608
609     <para><emphasis>Instead of:</emphasis></para>
610
611     <para>if ( this == that ) { ... }</para>
612
613     <para>or</para>
614
615     <para>if ( this == that ) { ... }</para>
616
617     <para><emphasis>Note:</emphasis> In the special case that the if-statement is
618     inside a loop, and it is trivial, i.e. it tests for a
619     condidtion that is obvious from the purpose of the block,
620     one-liners as above may optically preserve the loop structure
621     and make it easier to read.</para>
622
623     <para><emphasis>Status:</emphasis> developer-discrection.</para>
624
625     <para><emphasis>Example exception:</emphasis></para>
626 <programlisting>
627 while ( more lines are read )
628 {
629    /* Please document what is/is not a comment line here */
630    if ( it's a comment ) continue;
631
632    do_something( line );
633 }
634 </programlisting>
635   </sect3>
636     
637
638     <sect3 id="s17"><title>ALL control statements should have a
639     block</title>
640
641     <para><emphasis>Explanation:</emphasis></para>
642
643     <para>Using braces to make a block will make your code more
644     readable and less prone to error. All control statements should
645     have a block defined.</para>
646
647     <para><emphasis>Example:</emphasis></para>
648 <programlisting>
649 if ( this == that )
650 {
651    DoSomething();
652    DoSomethingElse();
653 }</programlisting>
654
655     <para><emphasis>Instead of:</emphasis></para>
656
657     <para>if ( this == that ) DoSomething(); DoSomethingElse();</para>
658
659     <para>or</para>
660
661     <para>if ( this == that ) DoSomething();</para>
662
663     <para><emphasis>Note:</emphasis> The first example in "Instead of" will execute
664     in a manner other than that which the developer desired (per
665     indentation). Using code braces would have prevented this
666     "feature". The "explanation" and "exception" from the point
667     above also applies.</para>
668
669     
670   </sect3>
671     
672
673     <sect3 id="s18"><title>Do not belabor/blow-up boolean
674     expressions</title>
675
676     <para><emphasis>Example:</emphasis></para>
677 <programlisting>
678 structure->flag = ( condition );</programlisting>
679
680     <para><emphasis>Instead of:</emphasis></para>
681
682     <para>if ( condition ) { structure->flag = 1; } else {
683     structure->flag = 0; }</para>
684
685     <para><emphasis>Note:</emphasis> The former is readable and consice. The later
686     is wordy and inefficient. Please assume that any developer new
687     to the project has at least a "good" knowledge of C/C++. (Hope
688     I do not offend by that last comment ... 8-)</para>
689
690     
691   </sect3>
692     
693
694     <sect3 id="s19"><title>Use white space freely because it is
695     free</title>
696
697     <para><emphasis>Explanation:</emphasis></para>
698
699     <para>Make it readable. The notable exception to using white space
700     freely is listed in the next guideline.</para>
701
702     <para><emphasis>Example:</emphasis></para>
703 <programlisting>
704 int firstValue   = 0;
705 int someValue    = 0;
706 int anotherValue = 0;
707 int thisVariable = 0;
708
709 if ( thisVariable == thatVariable )
710
711 firstValue = oldValue + ( ( someValue - anotherValue ) - whatever )
712 </programlisting>
713   </sect3>
714     
715
716     <sect3 id="s20"><title>Don't use white space around structure
717     operators</title>
718
719     <para><emphasis>Explanation:</emphasis></para>
720
721     <para>- structure pointer operator ( "->" ) - member operator (
722     "." ) - functions and parentheses</para>
723
724     <para>It is a general coding practice to put pointers, references,
725     and function parentheses next to names. With spaces, the
726     connection between the object and variable/function name is not
727     as clear.</para>
728
729     <para><emphasis>Example:</emphasis></para>
730 <programlisting>
731 aStruct->aMember;
732 aStruct.aMember;
733 FunctionName();</programlisting>
734
735     <para><emphasis>Instead of:</emphasis> aStruct -> aMember; aStruct . aMember;
736     FunctionName ();</para>
737
738     
739   </sect3>
740     
741
742     <sect3 id="s21"><title>Make the last brace of a function stand
743     out</title>
744
745     <para><emphasis>Example:</emphasis></para>
746 <programlisting>
747 int function1( ... )
748 {
749    ...code...
750    return( retCode );
751
752 }   /* -END- function1 */
753
754
755 int function2( ... )
756 {
757 }   /* -END- function2 */
758 </programlisting>
759
760     <para><emphasis>Instead of:</emphasis></para>
761
762     <para>int function1( ... ) { ...code... return( retCode ); } int
763     function2( ... ) { }</para>
764
765     <para><emphasis>Note:</emphasis> Use 1 blank line before the closing brace and 2
766     lines afterwards. This makes the end of function standout to
767     the most casual viewer. Although function comments help
768     seperate functions, this is still a good coding practice. In
769     fact, I follow these rules when using blocks in "for", "while",
770     "do" loops, and long if {} statements too. After all whitespace
771     is free!</para>
772
773     <para><emphasis>Status:</emphasis> developer-discrection on the number of blank
774     lines. Enforced is the end of function comments.</para>
775
776     
777   </sect3>
778     
779
780     <sect3 id="s22"><title>Use 3 character indentions</title>
781
782     <para><emphasis>Explanation:</emphasis></para>
783
784     <para>If some use 8 character TABs and some use 3 character TABs,
785     the code can look *very* ragged. So use 3 character indentions
786     only. If you like to use TABs, pass your code through a filter
787     such as "expand -t3" before checking in your code.</para>
788
789     <para><emphasis>Example:</emphasis></para>
790 <programlisting>
791 static const char * const url_code_map[256] =
792 {
793    NULL, ...
794 };
795
796
797 int function1( ... )
798 {
799    if ( 1 )
800    {
801       return( ALWAYS_TRUE );
802    }
803    else
804    {
805       return( HOW_DID_YOU_GET_HERE );
806    }
807
808    return( NEVER_GETS_HERE );
809
810 }
811 </programlisting>
812   </sect3>
813
814   </sect2>
815     
816
817     <sect2 id="s23"><title>Initializing</title>
818
819     
820
821     <sect3 id="s24"><title>Initialize all variables</title>
822
823     <para><emphasis>Explanation:</emphasis></para>
824
825     <para>Do not assume that the variables declared will not be used
826     until after they have been assigned a value somewhere else in
827     the code. Remove the chance of accidentally using an unassigned
828     variable.</para>
829
830     <para><emphasis>Example:</emphasis></para>
831 <programlisting>
832 short anShort = 0;
833 float aFloat  = 0;
834 struct *ptr = NULL;</programlisting>
835
836     <para><emphasis>Note:</emphasis> It is much easier to debug a SIGSEGV if the
837     message says you are trying to access memory address 00000000
838     and not 129FA012; or arrayPtr[20] causes a SIGSEV vs.
839     arrayPtr[0].</para>
840
841     <para><emphasis>Status:</emphasis> developer-discrection if and only if the
842     variable is assigned a value "shortly after" declaration.</para>
843
844   </sect3>
845   </sect2>
846     
847
848     <sect2 id="s25"><title>Functions</title>
849
850     
851
852     <sect3 id="s26"><title>Name functions that return a boolean as a
853     question.</title>
854
855     <para><emphasis>Explanation:</emphasis></para>
856
857     <para>Value should be phrased as a question that would logically
858     be answered as a true or false statement</para>
859
860     <para><emphasis>Example:</emphasis></para>
861 <programlisting>
862 ShouldWeBlockThis();
863 ContainsAnImage();
864 IsWebPageBlank();
865 </programlisting>
866   </sect3>
867     
868
869     <sect3 id="s27"><title>Always specify a return type for a
870     function.</title>
871
872     <para><emphasis>Explanation:</emphasis></para>
873
874     <para>The default return for a function is an int. To avoid
875     ambiguity, create a return for a function when the return has a
876     purpose, and create a void return type if the function does not
877     need to return anything.</para>
878
879     
880   </sect3>
881     
882
883     <sect3 id="s28"><title>Minimize function calls when iterating by
884     using variables</title>
885
886     <para><emphasis>Explanation:</emphasis></para>
887
888     <para>It is easy to write the following code, and a clear argument
889     can be made that the code is easy to understand:</para>
890
891     <para><emphasis>Example:</emphasis></para>
892 <programlisting>
893 for ( size_t cnt = 0; cnt &lt; blockListLength(); cnt ++ )
894 {
895    ....
896 }</programlisting>
897
898     <para><emphasis>Note:</emphasis> Unfortunately, this makes a function call for
899     each and every iteration. This increases the overhead in the
900     program, because the compiler has to look up the function each
901     time, call it, and return a value. Depending on what occurs in
902     the blockListLength() call, it might even be creating and
903     destroying structures with each iteration, even though in each
904     case it is comparing "cnt" to the same value, over and over.
905     Remember too - even a call to blockListLength() is a function
906     call, with the same overhead.</para>
907
908     <para>Instead of using a function call during the iterations,
909     assign the value to a variable, and evaluate using the
910     variable.</para>
911
912     <para><emphasis>Example:</emphasis></para>
913 <programlisting>
914 size_t len = blockListLength();
915
916 for ( size_t cnt = 0; cnt &lt; len; cnt ++ )
917 {
918    ....
919 }</programlisting>
920
921     <para><emphasis>Exceptions:</emphasis> if the value of blockListLength() *may*
922     change or could *potentially* change, then you must code the
923     function call in the for/while loop.</para>
924
925     
926   </sect3>
927     
928
929     <sect3 id="s29"><title>Pass and Return by Const Reference</title>
930
931     <para><emphasis>Explanation:</emphasis></para>
932
933     <para>This allows a developer to define a const pointer and call
934     your function. If your function does not have the const
935     keyword, we may not be able to use your function. Consider
936     strcmp, if it were defined as: extern int strcmp( char *s1,
937     char *s2 );</para>
938
939     <para>I could then not use it to compare argv's in main: int main(
940     int argc, const char *argv[] ) { strcmp( argv[0], "privoxy"
941     ); }</para>
942
943     <para>Both these pointers are *const*! If the c runtime library
944     maintainers do it, we should too.</para>
945
946     
947   </sect3>
948     
949
950     <sect3 id="s30"><title>Pass and Return by Value</title>
951
952     <para><emphasis>Explanation:</emphasis></para>
953
954     <para>Most structures cannot fit onto a normal stack entry (i.e.
955     they are not 4 bytes or less). Aka, a function declaration
956     like: int load_aclfile( struct client_state csp )</para>
957
958     <para>would not work. So, to be consistent, we should declare all
959     prototypes with "pass by value": int load_aclfile( struct
960     client_state *csp )</para>
961
962     
963   </sect3>
964     
965
966     <sect3 id="s31"><title>Names of include files</title>
967
968     <para><emphasis>Explanation:</emphasis></para>
969
970     <para>Your include statements should contain the file name without
971     a path. The path should be listed in the Makefile, using -I as
972     processor directive to search the indicated paths. An exception
973     to this would be for some proprietary software that utilizes a
974     partial path to distinguish their header files from system or
975     other header files.</para>
976
977     <para><emphasis>Example:</emphasis></para>
978 <programlisting>
979 #include &lt;iostream.h&gt;     /* This is not a local include */
980 #include "config.h"       /* This IS a local include */
981 </programlisting>
982
983     <para><emphasis>Exception:</emphasis></para>
984
985     <para>
986 <programlisting>
987 /* This is not a local include, but requires a path element. */ 
988 #include &lt;sys/fileName.h&gt;
989 </programlisting>
990 </para>
991
992     <para><emphasis>Note:</emphasis> Please! do not add "-I." to the Makefile
993     without a _very_ good reason. This duplicates the #include
994     "file.h" behaviour.</para>
995
996     
997   </sect3>
998     
999
1000     <sect3 id="s32"><title>Provide multiple inclusion
1001     protection</title>
1002
1003     <para><emphasis>Explanation:</emphasis></para>
1004
1005     <para>Prevents compiler and linker errors resulting from
1006     redefinition of items.</para>
1007
1008     <para>Wrap each header file with the following syntax to prevent
1009     multiple inclusions of the file. Of course, replace PROJECT_H
1010     with your file name, with "." Changed to "_", and make it
1011     uppercase.</para>
1012
1013     <para><emphasis>Example:</emphasis></para>
1014 <programlisting>
1015 #ifndef PROJECT_H_INCLUDED
1016 #define PROJECT_H_INCLUDED
1017  ...
1018 #endif /* ndef PROJECT_H_INCLUDED */
1019 </programlisting>
1020   </sect3>
1021     
1022
1023     <sect3 id="s33"><title>Use `extern "C"` when appropriate</title>
1024
1025     <para><emphasis>Explanation:</emphasis></para>
1026
1027     <para>If our headers are included from C++, they must declare our
1028     functions as `extern "C"`. This has no cost in C, but increases
1029     the potential re-usability of our code.</para>
1030
1031     <para><emphasis>Example:</emphasis></para>
1032 <programlisting>
1033 #ifdef __cplusplus
1034 extern "C"
1035 {
1036 #endif /* def __cplusplus */
1037
1038 ... function definitions here ...
1039
1040 #ifdef __cplusplus
1041 }
1042 #endif /* def __cplusplus */
1043 </programlisting>
1044   </sect3>
1045     
1046
1047     <sect3 id="s34"><title>Where Possible, Use Forward Struct
1048     Declaration Instead of Includes</title>
1049
1050     <para><emphasis>Explanation:</emphasis></para>
1051
1052     <para>Useful in headers that include pointers to other struct's.
1053     Modifications to excess header files may cause needless
1054     compiles.</para>
1055
1056     <para><emphasis>Example:</emphasis></para>
1057 <programlisting>
1058 /*********************************************************************
1059  * We're avoiding an include statement here!
1060  *********************************************************************/
1061 struct file_list;
1062 extern file_list *xyz;</programlisting>
1063
1064     <para><emphasis>Note:</emphasis> If you declare "file_list xyz;" (without the
1065     pointer), then including the proper header file is necessary.
1066     If you only want to prototype a pointer, however, the header
1067     file is unneccessary.</para>
1068
1069     <para><emphasis>Status:</emphasis> Use with discrection.</para>
1070
1071     
1072   </sect3>
1073   </sect2>
1074
1075     <sect2 id="s35"><title>General Coding Practices</title>
1076
1077     
1078
1079     <sect3 id="s36"><title>Turn on warnings</title>
1080
1081     <para><emphasis>Explanation</emphasis></para>
1082
1083     <para>Compiler warnings are meant to help you find bugs. You
1084     should turn on as many as possible. With GCC, the switch is
1085     "-Wall". Try and fix as many warnings as possible.</para>
1086
1087     
1088   </sect3>
1089     
1090
1091     <sect3 id="s37"><title>Provide a default case for all switch
1092     statements</title>
1093
1094     <para><emphasis>Explanation:</emphasis></para>
1095
1096     <para>What you think is guaranteed is never really guaranteed. The
1097     value that you don't think you need to check is the one that
1098     someday will be passed. So, to protect yourself from the
1099     unknown, always have a default step in a switch statement.</para>
1100
1101     <para><emphasis>Example:</emphasis></para>
1102 <programlisting>
1103 switch( hash_string( cmd ) )
1104 {
1105    case hash_actions_file :
1106       ... code ...
1107       break;
1108
1109    case hash_confdir :
1110       ... code ...
1111       break;
1112
1113    default :
1114       log_error( ... );
1115       ... anomly code goes here ...
1116       continue; / break; / exit( 1 ); / etc ...
1117
1118 } /* end switch( hash_string( cmd ) ) */</programlisting>
1119
1120     <para><emphasis>Note:</emphasis> If you already have a default condition, you
1121     are obviously exempt from this point. Of note, most of the
1122     WIN32 code calls `DefWindowProc' after the switch statement.
1123     This API call *should* be included in a default statement.</para>
1124
1125     <para><emphasis>Another Note:</emphasis> This is not so much a readability issue
1126     as a robust programming issue. The "anomly code goes here" may
1127     be no more than a print to the STDERR stream (as in
1128     load_config). Or it may really be an ABEND condition.</para>
1129
1130     <para><emphasis>Status:</emphasis> Programmer discretion is advised.</para>
1131
1132     
1133   </sect3>
1134     
1135
1136     <sect3 id="s38"><title>Try to avoid falling through cases in a
1137     switch statement.</title>
1138
1139     <para><emphasis>Explanation:</emphasis></para>
1140
1141     <para>In general, you will want to have a 'break' statement within
1142     each 'case' of a switch statement. This allows for the code to
1143     be more readable and understandable, and furthermore can
1144     prevent unwanted surprises if someone else later gets creative
1145     and moves the code around.</para>
1146
1147     <para>The language allows you to plan the fall through from one
1148     case statement to another simply by omitting the break
1149     statement within the case statement. This feature does have
1150     benefits, but should only be used in rare cases. In general,
1151     use a break statement for each case statement.</para>
1152
1153     <para>If you choose to allow fall through, you should comment both
1154     the fact of the fall through and reason why you felt it was
1155     necessary.</para>
1156
1157     
1158   </sect3>
1159     
1160
1161     <sect3 id="s39"><title>Use 'long' or 'short' Instead of
1162     'int'</title>
1163
1164     <para><emphasis>Explanation:</emphasis></para>
1165
1166     <para>On 32-bit platforms, int usually has the range of long. On
1167     16-bit platforms, int has the range of short.</para>
1168
1169     <para><emphasis>Status:</emphasis> open-to-debate. In the case of most FSF
1170     projects (including X/GNU-Emacs), there are typedefs to int4,
1171     int8, int16, (or equivalence ... I forget the exact typedefs
1172     now). Should we add these to IJB now that we have a "configure"
1173     script?</para>
1174
1175     
1176   </sect3>
1177     
1178
1179     <sect3 id="s40"><title>Don't mix size_t and other types</title>
1180
1181     <para><emphasis>Explanation:</emphasis></para>
1182
1183     <para>The type of size_t varies across platforms. Do not make
1184     assumptions about whether it is signed or unsigned, or about
1185     how long it is. Do not compare a size_t against another
1186     variable of a different type (or even against a constant)
1187     without casting one of the values. Try to avoid using size_t if
1188     you can.</para>
1189
1190     
1191   </sect3>
1192     
1193
1194     <sect3 id="s41"><title>Declare each variable and struct on its
1195     own line.</title>
1196
1197     <para><emphasis>Explanation:</emphasis></para>
1198
1199     <para>It can be tempting to declare a series of variables all on
1200     one line. Don't.</para>
1201
1202     <para><emphasis>Example:</emphasis></para>
1203 <programlisting>
1204 long a = 0;
1205 long b = 0;
1206 long c = 0;</programlisting>
1207
1208     <para><emphasis>Instead of:</emphasis></para>
1209
1210     <para>long a, b, c;</para>
1211
1212     <para><emphasis>Explanation:</emphasis> - there is more room for comments on the
1213     individual variables - easier to add new variables without
1214     messing up the original ones - when searching on a variable to
1215     find its type, there is less clutter to "visually"
1216     eliminate</para>
1217
1218     <para><emphasis>Exceptions:</emphasis> when you want to declare a bunch of loop
1219     variables or other trivial variables; feel free to declare them
1220     on 1 line. You should, although, provide a good comment on
1221     their functions.</para>
1222
1223     <para><emphasis>Status:</emphasis> developer-discrection.</para>
1224
1225     
1226   </sect3>
1227     
1228
1229     <sect3 id="s42"><title>Use malloc/zalloc sparingly</title>
1230
1231     <para><emphasis>Explanation:</emphasis></para>
1232
1233     <para>Create a local stuct (on the stack) if the variable will
1234     live and die within the context of one function call.</para>
1235
1236     <para>Only "malloc" a struct (on the heap) if the variable's life
1237     will extend beyond the context of one function call.</para>
1238
1239     <para><emphasis>Example:</emphasis></para>
1240 <programlisting>
1241 If a function creates a struct and stores a pointer to it in a
1242 list, then it should definately be allocated via `malloc'.
1243 </programlisting>
1244   </sect3>
1245     
1246
1247     <sect3 id="s43"><title>The Programmer Who Uses 'malloc' is
1248     Responsible for Ensuring 'free'</title>
1249
1250     <para><emphasis>Explanation:</emphasis></para>
1251
1252     <para>If you have to "malloc" an instance, you are responsible for
1253     insuring that the instance is `free'd, even if the deallocation
1254     event falls within some other programmer's code. You are also
1255     responsible for ensuring that deletion is timely (i.e. not too
1256     soon, not too late). This is known as "low-coupling" and is a
1257     "good thing (tm)". You may need to offer a
1258     free/unload/destuctor type function to accomodate this.</para>
1259
1260     <para><emphasis>Example:</emphasis></para>
1261 <programlisting>
1262 int load_re_filterfile( struct client_state *csp ) { ... }
1263 static void unload_re_filterfile( void *f ) { ... }</programlisting>
1264
1265     <para><emphasis>Exceptions:</emphasis></para>
1266
1267     <para>The developer cannot be expected to provide `free'ing
1268     functions for C run-time library functions ... such as
1269     `strdup'.</para>
1270
1271     <para><emphasis>Status:</emphasis> developer-discrection. The "main" use of this
1272     standard is for allocating and freeing data structures (complex
1273     or nested).</para>
1274
1275     
1276   </sect3>
1277     
1278
1279     <sect3 id="s44"><title>Add loaders to the `file_list' structure
1280     and in order</title>
1281
1282     <para><emphasis>Explanation:</emphasis></para>
1283
1284     <para>I have ordered all of the "blocker" file code to be in alpha
1285     order. It is easier to add/read new blockers when you expect a
1286     certain order.</para>
1287
1288     <para><emphasis>Note:</emphasis> It may appear that the alpha order is broken in
1289     places by POPUP tests coming before PCRS tests. But since
1290     POPUPs can also be referred to as KILLPOPUPs, it is clear that
1291     it should come first.</para>
1292
1293     
1294   </sect3>
1295     
1296
1297     <sect3 id="s45"><title>"Uncertain" new code and/or changes to
1298     exitinst code, use FIXME</title>
1299
1300     <para><emphasis>Explanation:</emphasis></para>
1301
1302     <para>If you have enough confidence in new code or confidence in
1303     your changes, but are not *quite* sure of the reprocussions,
1304     add this:</para>
1305
1306     <para>/* FIXME: this code has a logic error on platform XYZ, *
1307     attempthing to fix */ #ifdef PLATFORM ...changed code here...
1308     #endif</para>
1309
1310     <para>or:</para>
1311
1312     <para>/* FIXME: I think the original author really meant this...
1313     */ ...changed code here...</para>
1314
1315     <para>or:</para>
1316
1317     <para>/* FIXME: new code that *may* break something else... */
1318     ...new code here...</para>
1319
1320     <para><emphasis>Note:</emphasis> If you make it clear that this may or may not
1321     be a "good thing (tm)", it will be easier to identify and
1322     include in the project (or conversly exclude from the
1323     project).</para>
1324
1325     
1326   </sect3>
1327
1328   </sect2>
1329
1330     <sect2 id="s46"><title>Addendum: Template for files and function
1331     comment blocks:</title>
1332
1333     <para><emphasis>Example for file comments:</emphasis></para>
1334 <programlisting>
1335 const char FILENAME_rcs[] = "$Id: developer-manual.sgml,v 1.22 2002/04/04 17:27:56 swa Exp $";
1336 /*********************************************************************
1337  *
1338  * File        :  $S<!-- Break CVS Substitution -->ource$
1339  *
1340  * Purpose     :  (Fill me in with a good description!)
1341  *
1342  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
1343  *                Privoxy team. http://www.privoxy.org/
1344  *
1345  *                Based on the Internet Junkbuster originally written
1346  *                by and Copyright (C) 1997 Anonymous Coders and
1347  *                Junkbusters Corporation.  http://www.junkbusters.com
1348  *
1349  *                This program is free software; you can redistribute it
1350  *                and/or modify it under the terms of the GNU General
1351  *                Public License as published by the Free Software
1352  *                Foundation; either version 2 of the License, or (at
1353  *                your option) any later version.
1354  *
1355  *                This program is distributed in the hope that it will
1356  *                be useful, but WITHOUT ANY WARRANTY; without even the
1357  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
1358  *                PARTICULAR PURPOSE.  See the GNU General Public
1359  *                License for more details.
1360  *
1361  *                The GNU General Public License should be included with
1362  *                this file.  If not, you can view it at
1363  *                http://www.gnu.org/copyleft/gpl.html
1364  *                or write to the Free Software Foundation, Inc., 59
1365  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
1366  *
1367  * Revisions   :
1368  *    $L<!-- Break CVS Substitution -->og$
1369  *
1370  *********************************************************************/
1371
1372
1373 #include "config.h"
1374
1375    ...necessary include files for us to do our work...
1376
1377 const char FILENAME_h_rcs[] = FILENAME_H_VERSION;
1378 </programlisting>
1379
1380     <para><emphasis>Note:</emphasis> This declares the rcs variables that should be
1381     added to the "show-proxy-args" page. If this is a brand new
1382     creation by you, you are free to change the "Copyright" section
1383     to represent the rights you wish to maintain.</para>
1384
1385     <para><emphasis>Note:</emphasis> The formfeed character that is present right
1386     after the comment flower box is handy for (X|GNU)Emacs users to
1387     skip the verbige and get to the heart of the code (via
1388     `forward-page' and `backward-page'). Please include it if you
1389     can.</para>
1390
1391     <para><emphasis>Example for file header comments:</emphasis></para>
1392 <programlisting>
1393 #ifndef _FILENAME_H
1394 #define _FILENAME_H
1395 #define FILENAME_H_VERSION "$Id: developer-manual.sgml,v 1.22 2002/04/04 17:27:56 swa Exp $"
1396 /*********************************************************************
1397  *
1398  * File        :  $S<!-- Break CVS Substitution -->ource$
1399  *
1400  * Purpose     :  (Fill me in with a good description!)
1401  *
1402  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
1403  *                Privoxy team. http://www.privoxy.org/
1404  *
1405  *                Based on the Internet Junkbuster originally written
1406  *                by and Copyright (C) 1997 Anonymous Coders and
1407  *                Junkbusters Corporation.  http://www.junkbusters.com
1408  *
1409  *                This program is free software; you can redistribute it
1410  *                and/or modify it under the terms of the GNU General
1411  *                Public License as published by the Free Software
1412  *                Foundation; either version 2 of the License, or (at
1413  *                your option) any later version.
1414  *
1415  *                This program is distributed in the hope that it will
1416  *                be useful, but WITHOUT ANY WARRANTY; without even the
1417  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
1418  *                PARTICULAR PURPOSE.  See the GNU General Public
1419  *                License for more details.
1420  *
1421  *                The GNU General Public License should be included with
1422  *                this file.  If not, you can view it at
1423  *                http://www.gnu.org/copyleft/gpl.html
1424  *                or write to the Free Software Foundation, Inc., 59
1425  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
1426  *
1427  * Revisions   :
1428  *    $L<!-- Break CVS Substitution -->og$
1429  *
1430  *********************************************************************/
1431
1432
1433 #include "project.h"
1434
1435 #ifdef __cplusplus
1436 extern "C" {
1437 #endif
1438
1439    ... function headers here ...
1440
1441
1442 /* Revision control strings from this header and associated .c file */
1443 extern const char FILENAME_rcs[];
1444 extern const char FILENAME_h_rcs[];
1445
1446
1447 #ifdef __cplusplus
1448 } /* extern "C" */
1449 #endif
1450
1451 #endif /* ndef _FILENAME_H */
1452
1453 /*
1454   Local Variables:
1455   tab-width: 3
1456   end:
1457 */
1458 </programlisting>
1459
1460     <para><emphasis>Example for function comments:</emphasis></para>
1461 <programlisting>
1462 /*********************************************************************
1463  *
1464  * Function    :  FUNCTION_NAME
1465  *
1466  * Description :  (Fill me in with a good description!)
1467  *
1468  * parameters  :
1469  *          1  :  param1 = pointer to an important thing
1470  *          2  :  x      = pointer to something else
1471  *
1472  * Returns     :  0 => Ok, everything else is an error.
1473  *
1474  *********************************************************************/
1475 int FUNCTION_NAME( void *param1, const char *x )
1476 {
1477    ...
1478    return( 0 );
1479
1480 }
1481 </programlisting>
1482
1483     <para><emphasis>Note:</emphasis> If we all follow this practice, we should be
1484     able to parse our code to create a "self-documenting" web
1485     page.</para>
1486
1487   </sect2>
1488
1489   </sect1>
1490
1491   <!--   ~~~~~       New section      ~~~~~     -->
1492   <sect1 id="cvs"><title>Version Control Guidelines</title>
1493     <para>To be filled. note on cvs comments. Don't only comment what you did,
1494     but also why you did it!
1495 </para>
1496   </sect1>
1497
1498   <!--   ~~~~~       New section      ~~~~~     -->
1499   <sect1 id="testing"><title>Testing Guidelines</title>
1500     <para>To be filled.
1501 </para>
1502
1503     <!--   ~~~~~       New section      ~~~~~     -->
1504     <sect2 id="testing-plan"><title>Testplan for releases</title>
1505       <para>
1506        Explain release numbers. major, minor. developer releases. etc.
1507
1508 <orderedlist numeration="arabic">
1509           <listitem><para>
1510 Remove any existing rpm with rpm -e
1511 </para></listitem>
1512           <listitem><para>
1513 Remove any file that was left over. This includes (but is not limited to)
1514       <itemizedlist>
1515                 <listitem><para>/var/log/privoxy</para></listitem>
1516                 <listitem><para>/etc/privoxy</para></listitem>
1517                 <listitem><para>/usr/sbin/privoxy</para></listitem>
1518                 <listitem><para>/etc/init.d/privoxy</para></listitem>
1519                 <listitem><para>/usr/doc/privoxy*</para></listitem>
1520               </itemizedlist>
1521 </para></listitem>
1522           <listitem><para>
1523 Install the rpm. Any error messages?
1524 </para></listitem>
1525           <listitem><para>start,stop,status <application>Privoxy</application> with the specific script
1526       (e.g. /etc/rc.d/init/privoxy stop). Reboot your machine. Does
1527       autostart work?</para></listitem>
1528           <listitem><para>Start browsing. Does <application>Privoxy</application> work? Logfile written?</para></listitem>
1529           <listitem><para>Remove the rpm. Any error messages? All files removed?</para></listitem>
1530         </orderedlist>
1531 </para>
1532     </sect2>
1533
1534     <!--   ~~~~~       New section      ~~~~~     -->
1535     <sect2 id="testing-report"><title>Test reports</title>
1536       <para>
1537 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>
1538 at sourceforge. Three simple steps:
1539         <itemizedlist>
1540           
1541           <listitem><para>Select category: the distribution you test on.</para></listitem>
1542           <listitem><para>Select group: the version of <application>Privoxy</application> that we are about to release.</para></listitem>
1543           <listitem><para>Fill the Summary and Detailed Description with something
1544               intelligent (keep it short and precise).</para>
1545           </listitem>
1546         </itemizedlist>
1547         Do not mail to the mailinglist (we cannot keep track on issues there).
1548       </para>
1549     </sect2>
1550     
1551   </sect1>
1552
1553   <!--   ~~~~~       New section      ~~~~~     -->
1554   <sect1 id="newrelease"><title>Releasing a new version</title>
1555     <para>
1556         To minimize trouble with distribution contents, webpage
1557         errors and the like, we strongly encourage you
1558         to follow this section if you prepare a new release of
1559         code or new pages on the webserver.
1560     </para>
1561     <para>
1562         The following programs are required to follow this process:
1563         <filename>ncftpput</filename> (ncftp), <filename>scp</filename> (ssh),
1564 <filename>gmake</filename> (GNU's version of make), autoconf, cvs, ???.
1565     </para>
1566      
1567     <sect2 id="beforerelease">
1568     <title>Before the Release</title>
1569      <para>
1570        The following <emphasis>must be done by one of the
1571        developers</emphasis> prior to each new release:
1572      </para>
1573      <para>
1574       <itemizedlist>
1575        <listitem>
1576         <para>
1577          Make sure that everybody who has worked on the code in the last
1578          couple of days has had a chance to yell <quote>no!</quote> in case
1579          they have pending changes/fixes in their pipelines.
1580         </para>
1581       </listitem> 
1582       <listitem>
1583        <para>
1584          Increment the version number in <filename>configure.in</filename> in
1585          CVS. Also, the RPM release number in
1586          <filename>configure.in</filename>. Do NOT touch version information
1587          after export from CVS. <emphasis>All packages</emphasis> will use the
1588          version and release data from <filename>configure.in</filename>.
1589          Local files should not be changed, except prior to a CVS commit!!!
1590          This way we are all on the same page!
1591        </para>
1592       </listitem> 
1593       <listitem>
1594        <para>
1595         If the default actionsfile has changed since last release,
1596         bump up its version info in this line:
1597        </para>
1598        <para> 
1599         <programlisting>
1600   {+add-header{X-Actions-File-Version: A.B} -filter -no-popups}
1601         </programlisting>
1602        </para>
1603        <para> 
1604         Then change the version info in doc/webserver/actions/index.php,
1605         line: '$required_actions_file_version = "A.B";'
1606        </para>
1607       </listitem> 
1608       <listitem>
1609        <para>
1610         Tag all files in CVS with the version number with
1611         <quote><command>cvs tag v_X_Y_Z</command></quote> (where X = major, Y
1612         = minor, Z = point). Don't use vX_Y_Z, ver_X_Y_Z, v_X.Y.Z (won't work)
1613         etc.
1614        </para>
1615       </listitem> 
1616       <listitem>
1617        <para>
1618         The first package uploaded should be the official
1619         <quote>tarball</quote> release. This is built with the
1620         <quote><command>make tarball-dist</command></quote> Makefile 
1621         target, and then can be uploaded with 
1622         <quote><command>make tarball-upload</command></quote> (see below).
1623        </para>
1624       </listitem> 
1625       </itemizedlist>
1626      </para> 
1627     </sect2>
1628     
1629     <sect2 id="newrelease-web"><title>Update the webserver</title>
1630       <para>
1631         All files must be group-readable and group-writable (or no one else
1632         will be able to change them). To update the webserver, create any
1633         pages locally in the <filename>doc/webserver</filename> directory (or
1634         create new directories under <filename>doc/webserver</filename>), then do
1635         </para>
1636         <para>
1637         <programlisting>
1638   make webserver
1639         </programlisting>
1640         </para>
1641         <para>
1642         Note that <quote><command>make dok</command></quote> 
1643      (or <quote><command>make redhat-dok</command></quote>) creates
1644         <filename>doc/webserver/user-manual</filename>,
1645         <filename>doc/webserver/developer-manual</filename>,
1646         <filename>doc/webserver/faq</filename> and
1647         <filename>doc/webserver/man-page</filename> automatically.
1648       </para>
1649       <para>
1650       Please do NOT use any other means of transferring files to the
1651       webserver. <quote><command>make webserver</command></quote> not only
1652       uploads, but will make sure that the appropriate permissions are 
1653       preserved for shared group access.
1654       </para>
1655     </sect2>
1656
1657     <sect2 id="newrelease-rpm"><title>SuSE or Red Hat</title>
1658       <para>
1659         Ensure that you have the latest code version. Hence run:
1660         </para>
1661         <para>
1662         <programlisting>
1663   cd current
1664   cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login
1665   cvs -z3  -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa export -r  v_X_Y_Z current
1666         </programlisting>
1667         </para>
1668         <para>
1669          first. 
1670         </para>
1671         <para>
1672         <programlisting>
1673   autoheader && autoconf && ./configure
1674         </programlisting>
1675         </para>
1676         <para>
1677         Then do
1678         </para>
1679         <para>
1680         <programlisting>
1681   make suse-dist or make redhat-dist
1682         </programlisting>
1683         </para>
1684         <para>
1685         To upload the package to Sourceforge, simply issue
1686         </para>
1687         <para>
1688         <programlisting>
1689   make suse-upload or make redhat-upload
1690         </programlisting>
1691         </para>
1692         <para>
1693         Go to the displayed URL and release the file publicly on Sourceforge.
1694       </para>
1695     </sect2>
1696
1697     <sect2 id="newrelease-os2"><title>OS/2</title>
1698       <para>
1699         Ensure that you have the latest code version. Hence run:
1700         </para>
1701         <para>
1702         <programlisting>
1703   cd current
1704   cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login
1705   cvs -z3 -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa export -r  v_X_Y_Z current
1706   cd ..
1707   cvs -z3 -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa co os2setup
1708         </programlisting>
1709         </para>
1710         <para>
1711         You will need a mix of development tools.
1712         The main compilation takes place with IBM Visual Age C++.
1713         Some ancillary work takes place with GNU tools, available from
1714         various sources like hobbes.nmsu.edu.
1715         Specificially, you will need <filename>autoheader</filename>,
1716         <filename>autoconf</filename> and <filename>sh</filename> tools.
1717         The packaging takes place with WarpIN, available from various sources, including
1718         its home page: <ulink url="http://www.xworkplace.org/">xworkplace</ulink>.
1719         </para>
1720         <para>
1721         Change directory to the <filename>os2setup</filename> directory.
1722         Edit the os2build.cmd file to set the final executable filename.
1723         For example, 
1724         <programlisting>
1725   installExeName='privoxyos2_setup_X.Y.Z.exe'
1726         </programlisting>
1727         Next, edit the <filename>IJB.wis</filename> file so the release number matches
1728         in the <filename>PACKAGEID</filename> section:
1729         <programlisting>
1730   PACKAGEID="Privoxy Team\Privoxy\Privoxy Package\X\Y\Z"
1731         </programlisting>
1732         You're now ready to build.  Run:
1733         <programlisting>
1734   os2build
1735         </programlisting>
1736      And in the <filename>./files</filename> directory you will have the
1737      WarpIN-installable executable. 
1738      Upload this anonymously to
1739      <filename>uploads.sourceforge.net/incoming</filename>, create a release
1740      for it, and you're done.
1741         </para>
1742     </sect2>
1743
1744     <sect2 id="newrelease-solaris"><title>Solaris</title>
1745       <para>
1746         Login to Sourceforge's compilefarm via ssh
1747         </para>
1748         <para>
1749         <programlisting>
1750   ssh cf.sourceforge.net
1751         </programlisting>
1752         </para>
1753         <para>
1754         Choose the right operating system (not the Debian one). If you have
1755         downloaded <application>Privoxy</application> before,
1756         </para>
1757         <para>
1758         <programlisting>
1759   cd current
1760   cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login
1761   cvs -z3  -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa export -r  v_X_Y_Z current
1762         </programlisting>
1763         </para>
1764         <para>
1765         If not, please <ulink
1766         url="http://www.privoxy.org/user-manual/user-manual/installation.html#INSTALLATION-SOURCE">checkout
1767         Privoxy via CVS first</ulink>. Run:
1768         </para>
1769         <para>
1770         <programlisting>
1771   autoheader && autoconf && ./configure
1772         </programlisting>
1773         </para>
1774         <para>
1775         Then run
1776         </para>
1777         <para>
1778         <programlisting>
1779   gmake solaris-dist
1780         </programlisting>
1781         </para>
1782         <para>
1783         which creates a gzip'ed tar archive. Sadly, you cannot use <command>make
1784         solaris-upload</command> on the Sourceforge machine (no ncftpput). You now have
1785         to manually upload the archive to Sourceforge's ftp server and release
1786         the file publicly.
1787         </para>
1788     </sect2>
1789
1790     <sect2 id="newrelease-windows"><title>Windows</title>
1791       <para>
1792         Ensure that you have the latest code version. Hence run
1793         </para>
1794         <para>
1795         <programlisting>
1796   cd current
1797   cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login
1798   cvs -z3  -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa export -r  v_X_Y_Z current
1799         </programlisting>
1800         </para>
1801         <para>
1802          Run:
1803         </para>
1804         <para>
1805         <programlisting>
1806   autoheader && autoconf && ./configure
1807         </programlisting>
1808         </para>
1809         <para>
1810         Then do FIXME.
1811         </para>
1812     </sect2>
1813
1814     <sect2 id="newrelease-debian"><title>Debian</title>
1815       <para>
1816         Ensure that you have the latest code version. Hence run:
1817         </para>
1818         <para>
1819         <programlisting>
1820   cd current
1821   cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login
1822   cvs -z3  -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa export -r  v_X_Y_Z current
1823         </programlisting>
1824         </para>
1825         <para>
1826         first. Run:
1827         </para>
1828         <para>
1829         <programlisting>
1830   autoheader && autoconf && ./configure
1831         </programlisting>
1832         </para>
1833         <para>
1834         Then do FIXME.
1835         </para>
1836     </sect2>
1837
1838     <sect2 id="newrelease-macosx"><title>Mac OSX</title>
1839       <para>
1840         Ensure that you have the latest code version. Hence run:
1841         </para>
1842         <para>
1843         <programlisting>
1844   cd current
1845   cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login
1846   cvs -z3 -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa export -r  v_X_Y_Z current
1847   cd ..
1848   cvs -z3 -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa co osxsetup
1849         </programlisting>
1850         </para>
1851         <para>
1852         From the osxsetup directory, run:
1853         <programlisting>
1854   build
1855         </programlisting>
1856         </para>
1857         <para>
1858         This will run <filename>autoheader</filename>, <filename>autoconf</filename> and
1859         <filename>configure</filename> as well as <filename>make</filename>.
1860         Finally, it will copy over the necessary files to the ./osxsetup/files directory
1861         for further processing by <filename>PackageMaker</filename>.
1862         </para>
1863         <para>
1864         Bring up PackageMaker with the PrivoxyPackage.pmsp definition file, modify the package
1865         name to match the release, and hit the "Create package" button.
1866         If you specify ./Privoxy.pkg as the output package name, you can then create
1867         the distributable zip file with the command:
1868         <programlisting>
1869 zip -r privoxyosx_setup_x.y.z.zip Privoxy.pkg
1870         </programlisting>
1871         You can then upload <filename>privoxyosx_setup_x.y.z.zip</filename> anonymously to 
1872         <filename>uploads.sourceforge.net/incoming</filename>,
1873         create a release for it, and you're done.
1874         </para>
1875     </sect2>
1876
1877     <sect2 id="newrelease-freebsd"><title>FreeBSD</title>
1878       <para>
1879         Change the version number of <application>Privoxy</application> in the
1880         configure.in file. Run:
1881         <programlisting>
1882   autoheader && autoconf && ./configure
1883         </programlisting>
1884         Then ...
1885       </para>
1886       <para>
1887         Login to Sourceforge's compilefarm via ssh:
1888         </para>
1889         <para>
1890         <programlisting>
1891   ssh cf.sourceforge.net
1892         </programlisting>
1893         </para>
1894         <para>
1895         Choose the right operating system. If you have downloaded Privoxy
1896         before,
1897         </para>
1898         <para>
1899         <programlisting>
1900   cd current
1901   cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login
1902   cvs -z3  -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa export -r  v_X_Y_Z current
1903         </programlisting>
1904         </para>
1905         <para>
1906         If not, please <ulink
1907         url="http://www.privoxy.org/user-manual/user-manual/installation.html#INSTALLATION-SOURCE">checkout
1908         Privoxy via CVS first</ulink>. Run:
1909         </para>
1910         <para>
1911         <programlisting>
1912   autoheader && autoconf && ./configure
1913         </programlisting>
1914         </para>
1915         <para>
1916         Then run:
1917         </para>
1918         <para>
1919         <programlisting>
1920   gmake freebsd-dist
1921         </programlisting>
1922         </para>
1923         <para>
1924         which creates a gzip'ed tar archive. Sadly, you cannot use <command>make
1925         freebsd-upload</command> on the Sourceforge machine (no ncftpput). You now have
1926         to manually upload the archive to Sourceforge's ftp server and release
1927         the file publicly.
1928         </para>
1929     </sect2>
1930
1931     <sect2 id="newrelease-tarball"><title>Tarball</title>
1932       <para>
1933         Ensure that you have the latest code version. Hence run:
1934         </para>
1935         <para>
1936         <programlisting>
1937   cd current
1938   cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login
1939   cvs -z3  -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa export -r  v_X_Y_Z current
1940         </programlisting>
1941         </para>
1942         <para>
1943         first. Run:
1944         </para>
1945         <para>
1946         <programlisting>
1947   make clobber
1948   autoheader && autoconf && ./configure
1949         </programlisting>
1950         </para>
1951         <para>
1952         Then do:
1953         </para>
1954         <para>
1955         <programlisting>
1956   make tarball-dist
1957         </programlisting>
1958         </para>
1959         <para>
1960         To upload the package to Sourceforge, simply issue
1961         </para>
1962         <para>
1963         <programlisting>
1964   make tarball-upload
1965         </programlisting>
1966         </para>
1967         <para>
1968         Goto the displayed URL and release the file publicly on Sourceforge.
1969       </para>
1970     </sect2>
1971
1972     <sect2 id="newrelease-hpux"><title>HP-UX 11</title>
1973       <para>
1974         Ensure that you have the latest code version. Hence run:
1975         </para>
1976         <para>
1977         <programlisting>
1978   cd current
1979   cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login
1980   cvs -z3  -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa export -r  v_X_Y_Z current
1981         </programlisting>
1982         </para>
1983         <para>
1984         first. Run:
1985         </para>
1986         <para>
1987         <programlisting>
1988   autoheader && autoconf && ./configure
1989         </programlisting>
1990         </para>
1991         <para>
1992         Then do FIXME.
1993         </para>
1994     </sect2>
1995
1996     <sect2 id="newrelease-amiga"><title>Amiga OS</title>
1997       <para>
1998         Ensure that you have the latest code version. Hence run:
1999         </para>
2000         <para>
2001         <programlisting>
2002   cd current
2003   cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login
2004   cvs -z3  -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa export -r  v_X_Y_Z current
2005         </programlisting>
2006         </para>
2007         <para>
2008         first. Run:
2009         </para>
2010         <para>
2011         <programlisting>
2012   autoheader && autoconf && ./configure
2013         </programlisting>
2014         </para>
2015         <para>
2016         Then do FIXME.
2017         </para>
2018     </sect2>
2019
2020     <sect2 id="newrelease-aix"><title>AIX</title>
2021       <para>
2022         Login to Sourceforge's compilefarm via ssh:
2023         </para>
2024         <para>
2025         <programlisting>
2026   ssh cf.sourceforge.net
2027         </programlisting>
2028         </para>
2029         <para>
2030         Choose the right operating system. If you have downloaded Privoxy
2031         before:
2032         </para>
2033         <para>
2034         <programlisting>
2035   cd current
2036   cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login
2037   cvs -z3  -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa export -r  v_X_Y_Z current
2038         </programlisting>
2039         </para>
2040         <para>
2041         If not, please <ulink
2042         url="http://www.privoxy.org/user-manual/user-manual/installation.html#INSTALLATION-SOURCE">checkout
2043         Privoxy via CVS first</ulink>. Run:
2044         </para>
2045         <para>
2046         <programlisting>
2047   autoheader && autoconf && ./configure
2048         </programlisting>
2049         </para>
2050         <para>
2051         Then run:
2052         </para>
2053         <para>
2054         <programlisting>
2055   make aix-dist
2056         </programlisting>
2057         </para>
2058         <para>
2059         which creates a gzip'ed tar archive. Sadly, you cannot use <command>make
2060         aix-upload</command> on the Sourceforge machine (no ncftpput). You now have
2061         to manually upload the archive to Sourceforge's ftp server and release
2062         the file publicly.
2063         </para>
2064     </sect2>
2065
2066   </sect1>
2067   
2068   <!--   ~~~~~       New section      ~~~~~     -->
2069   <sect1 id="contact"><title>Contacting the developers, Bug Reporting and Feature Requests</title>
2070 <!-- Include contacting.sgml  -->
2071  &contacting;
2072 <!-- end contacting -->
2073   </sect1>
2074   
2075   <!--   ~~~~~       New section      ~~~~~     -->
2076   <sect1 id="copyright"><title>Copyright and History</title>
2077
2078 <sect2><title>Copyright</title>
2079 <!-- Include copyright.sgml -->
2080  &copyright;
2081 <!-- end -->
2082 </sect2>
2083
2084 <sect2><title>History</title>
2085 <!-- Include history.sgml -->
2086  &history;
2087 <!-- end -->
2088 </sect2>
2089
2090   </sect1>
2091   
2092   <!--   ~~~~~       New section      ~~~~~     -->
2093   <sect1 id="seealso"><title>See also</title>
2094 <!-- Include seealso.sgml -->
2095  &seealso;
2096 <!-- end  -->
2097
2098   </sect1>
2099
2100   <!--
2101
2102   This program is free software; you can redistribute it 
2103   and/or modify it under the terms of the GNU General
2104   Public License as published by the Free Software
2105   Foundation; either version 2 of the License, or (at
2106   your option) any later version.
2107
2108   This program is distributed in the hope that it will
2109   be useful, but WITHOUT ANY WARRANTY; without even the
2110   implied warranty of MERCHANTABILITY or FITNESS FOR A
2111   PARTICULAR PURPOSE.  See the GNU General Public
2112   License for more details.
2113
2114   The GNU General Public License should be included with
2115   this file.  If not, you can view it at
2116   http://www.gnu.org/copyleft/gpl.html
2117   or write to the Free Software Foundation, Inc., 59
2118   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
2119
2120   $Log: developer-manual.sgml,v $
2121   Revision 1.22  2002/04/04 17:27:56  swa
2122   more single file to be included at multiple points. make maintaining easier
2123
2124   Revision 1.21  2002/04/04 06:48:37  hal9
2125   Structural changes to allow for conditional inclusion/exclusion of content
2126   based on entity toggles, e.g. 'entity % p-not-stable  "INCLUDE"'. And
2127   definition of internal entities, e.g. 'entity p-version "2.9.13"' that will
2128   eventually be set by Makefile.
2129   More boilerplate text for use across multiple docs.
2130
2131   Revision 1.20  2002/04/04 03:28:27  david__schmidt
2132   Add Mac OSX section
2133
2134   Revision 1.19  2002/04/03 15:09:42  david__schmidt
2135   Add OS/2 build section
2136
2137   Revision 1.18  2002/04/03 03:51:48  hal9
2138   Touch ups.
2139
2140   Revision 1.17  2002/04/03 01:21:17  hal9
2141   Implementing Andreas's suggestions for Release sections.
2142
2143   Revision 1.16  2002/03/31 23:04:40  hal9
2144   Fleshed out the doc section, and added something for an intro so it was not
2145   blank.
2146
2147   Revision 1.15  2002/03/30 22:29:47  swa
2148   wrong make flavour
2149
2150   Revision 1.14  2002/03/30 19:04:08  swa
2151   people release differently. no good.
2152   I want to make parts of the docs only.
2153
2154   Revision 1.13  2002/03/27 01:16:41  hal9
2155   ditto
2156
2157   Revision 1.12  2002/03/27 01:02:51  hal9
2158   Touch up on name change...
2159
2160   Revision 1.11  2002/03/26 22:29:55  swa
2161   we have a new homepage!
2162
2163   Revision 1.10  2002/03/24 12:33:01  swa
2164   more additions.
2165
2166   Revision 1.9  2002/03/24 11:01:05  swa
2167   name change
2168
2169   Revision 1.8  2002/03/23 15:13:11  swa
2170   renamed every reference to the old name with foobar.
2171   fixed "application foobar application" tag, fixed
2172   "the foobar" with "foobar". left junkbustser in cvs
2173   comments and remarks to history untouched.
2174
2175   Revision 1.7  2002/03/11 13:13:27  swa
2176   correct feedback channels
2177
2178   Revision 1.6  2002/02/24 14:25:06  jongfoster
2179   Formatting changes.  Now changing the doctype to DocBook XML 4.1
2180   will work - no other changes are needed.
2181
2182   Revision 1.5  2001/10/31 18:16:51  swa
2183   documentation added: howto generate docs in text and html
2184   format, howto move stuff to the webserver.
2185
2186   Revision 1.4  2001/09/23 10:13:48  swa
2187   upload process established. run make webserver and
2188   the documentation is moved to the webserver. documents
2189   are now linked correctly.
2190
2191   Revision 1.3  2001/09/13 15:27:40  swa
2192   cosmetics
2193
2194   Revision 1.2  2001/09/13 15:20:17  swa
2195   merged standards into developer manual
2196
2197   Revision 1.1  2001/09/12 15:36:41  swa
2198   source files for junkbuster documentation
2199
2200   Revision 1.3  2001/09/10 17:43:59  swa
2201   first proposal of a structure.
2202
2203   Revision 1.2  2001/06/13 14:28:31  swa
2204   docs should have an author.
2205
2206   Revision 1.1  2001/06/13 14:20:37  swa
2207   first import of project's documentation for the webserver.
2208
2209   -->
2210
2211 </article>