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