2 Privoxy Developer Manual
6 $Id: developer-manual.sgml,v 1.10 2002/03/24 12:33:01 swa Exp $
8 The developer manual gives the users information on how to help the
9 developer team. It provides guidance on coding, testing, documentation
10 and other issues. Privoxy is a web proxy with advanced filtering
11 capabilities for protecting privacy, filtering web page content,
12 managing cookies, controlling access, and removing ads, banners,
13 pop-ups and other obnoxious Internet Junk. Privoxy has a very flexible
14 configuration and can be customized to suit individual needs and
15 tastes. Privoxy has application for both stand-alone systems and
18 You can find the latest version of the user manual at
19 [1]http://www.privoxy.org/developer-manual/. Please see the Contact
20 section in the user-manual if you want to contact the developers.
21 _________________________________________________________________
25 2. [3]Quickstart to Privoxy Development
26 3. [4]Documentation Guidelines
27 4. [5]Coding Guidelines
30 4.2. [7]Using Comments
32 4.2.1. [8]Comment, Comment, Comment
33 4.2.2. [9]Use blocks for comments
34 4.2.3. [10]Keep Comments on their own line
35 4.2.4. [11]Comment each logical step
36 4.2.5. [12]Comment All Functions Thoroughly
37 4.2.6. [13]Comment at the end of braces if the content is
38 more than one screen length
40 4.3. [14]Naming Conventions
42 4.3.1. [15]Variable Names
43 4.3.2. [16]Function Names
44 4.3.3. [17]Header file prototypes
45 4.3.4. [18]Enumerations, and #defines
50 4.4.1. [21]Put braces on a line by themselves.
51 4.4.2. [22]ALL control statements should have a block
52 4.4.3. [23]Do not belabor/blow-up boolean expressions
53 4.4.4. [24]Use white space freely because it is free
54 4.4.5. [25]Don't use white space around structure operators
55 4.4.6. [26]Make the last brace of a function stand out
56 4.4.7. [27]Use 3 character indentions
60 4.5.1. [29]Initialize all variables
64 4.6.1. [31]Name functions that return a boolean as a
67 4.6.2. [32]Always specify a return type for a function.
68 4.6.3. [33]Minimize function calls when iterating by using
71 4.6.4. [34]Pass and Return by Const Reference
72 4.6.5. [35]Pass and Return by Value
73 4.6.6. [36]Names of include files
74 4.6.7. [37]Provide multiple inclusion protection
75 4.6.8. [38]Use `extern "C"` when appropriate
76 4.6.9. [39]Where Possible, Use Forward Struct Declaration
79 4.7. [40]General Coding Practices
81 4.7.1. [41]Turn on warnings
82 4.7.2. [42]Provide a default case for all switch statements
83 4.7.3. [43]Try to avoid falling through cases in a switch
86 4.7.4. [44]Use 'long' or 'short' Instead of 'int'
87 4.7.5. [45]Don't mix size_t and other types
88 4.7.6. [46]Declare each variable and struct on its own
91 4.7.7. [47]Use malloc/zalloc sparingly
92 4.7.8. [48]The Programmer Who Uses 'malloc' is Responsible
95 4.7.9. [49]Add loaders to the `file_list' structure and in
98 4.7.10. [50]"Uncertain" new code and/or changes to exitinst
101 4.8. [51]Addendum: Template for files and function comment
104 5. [52]Version Control Guidelines
105 6. [53]Testing Guidelines
107 6.1. [54]Testplan for releases
108 6.2. [55]Test reports
110 7. [56]Contact the developers
111 8. [57]Copyright and History
117 _________________________________________________________________
119 2. Quickstart to Privoxy Development
121 You'll need an account on Sourceforge to support our development. Mail
122 you ID to the list and wait until a project manager has added you. For
123 the time beeing (read, this section is under construction), please
124 note the following guidelines for changing stuff in the code. If it is
126 1. A bugfix / clean-up / cosmetic thing: shoot
127 2. A new feature that can be turned off: shoot
128 3. A clear improvement w/o side effects on other parts of the code:
130 4. A matter of taste: ask the list
131 5. A major redesign of some part of the code: ask the list
132 _________________________________________________________________
134 3. Documentation Guidelines
136 All docs are in SGML format and located in the doc/source directory.
138 How do you update the webserver (i.e. the pages on sourceforge)?
140 1. Run make dok (which uses the documents in doc/source to update all
141 text files in doc/text and to update all web documents in
143 2. Run make webserver which copies all files from doc/webserver to
144 the sourceforge webserver via scp.
145 _________________________________________________________________
151 This set of standards is designed to make our lives easier. It is
152 developed with the simple goal of helping us keep the "new and
153 improved Privoxy" consistent and reliable. Thus making maintenance
154 easier and increasing chances of success of the project.
156 And that of course comes back to us as individuals. If we can increase
157 our development and product efficiencies then we can solve more of the
158 request for changes/improvements and in general feel good about
160 _________________________________________________________________
164 4.2.1. Comment, Comment, Comment
168 Comment as much as possible without commenting the obvious. For
169 example do not comment "aVariable is equal to bVariable". Instead
170 explain why aVariable should be equal to the bVariable. Just because a
171 person can read code does not mean they will understand why or what is
172 being done. A reader may spend a lot more time figuring out what is
173 going on when a simple comment or explanation would have prevented the
174 extra research. Please help your brother IJB'ers out!
176 The comments will also help justify the intent of the code. If the
177 comment describes something different than what the code is doing then
178 maybe a programming error is occurring.
181 /* if page size greater than 1k ... */
182 if ( PageLength() > 1024 )
184 ... "block" the page up ...
187 /* if page size is small, send it in blocks */
188 if ( PageLength() > 1024 )
190 ... "block" the page up ...
193 This demonstrates 2 cases of "what not to do". The first is a
194 "syntax comment". The second is a comment that does not fit what
195 is actually being done.
196 _________________________________________________________________
198 4.2.2. Use blocks for comments
202 Comments can help or they can clutter. They help when they are
203 differentiated from the code they describe. One line comments do not
204 offer effective separation between the comment and the code. Block
205 identifiers do, by surrounding the code with a clear, definable
209 /*********************************************************************
210 * This will stand out clearly in your code!
211 *********************************************************************/
212 if ( thisVariable == thatVariable )
214 DoSomethingVeryImportant();
218 /* unfortunately, this may not */
219 if ( thisVariable == thatVariable )
221 DoSomethingVeryImportant();
225 if ( thisVariable == thatVariable ) /* this may not either */
227 DoSomethingVeryImportant();
232 If you are trying to add a small logic comment and do not wish to
233 "disrubt" the flow of the code, feel free to use a 1 line comment
234 which is NOT on the same line as the code.
235 _________________________________________________________________
237 4.2.3. Keep Comments on their own line
241 It goes back to the question of readability. If the comment is on the
242 same line as the code it will be harder to read than the comment that
245 There are three exceptions to this rule, which should be violated
246 freely and often: during the definition of variables, at the end of
247 closing braces, when used to comment parameters.
250 /*********************************************************************
251 * This will stand out clearly in your code,
252 * But the second example won't.
253 *********************************************************************/
254 if ( thisVariable == thatVariable )
256 DoSomethingVeryImportant();
259 if ( thisVariable == thatVariable ) /*can you see me?*/
261 DoSomethingVeryImportant(); /*not easily*/
265 /*********************************************************************
266 * But, the encouraged exceptions:
267 *********************************************************************/
268 int urls_read = 0; /* # of urls read + rejected */
269 int urls_rejected = 0; /* # of urls rejected */
273 DoSomethingVeryImportant();
277 short DoSomethingVeryImportant(
278 short firstparam, /* represents something */
279 short nextparam /* represents something else */ )
283 } /* -END- DoSomethingVeryImportant */
284 _________________________________________________________________
286 4.2.4. Comment each logical step
290 Logical steps should be commented to help others follow the intent of
291 the written code and comments will make the code more readable.
293 If you have 25 lines of code without a comment, you should probably go
294 back into it to see where you forgot to put one.
296 Most "for", "while", "do", etc... loops _probably_ need a comment.
297 After all, these are usually major logic containers.
298 _________________________________________________________________
300 4.2.5. Comment All Functions Thoroughly
304 A reader of the code should be able to look at the comments just prior
305 to the beginning of a function and discern the reason for its
306 existence and the consequences of using it. The reader should not have
307 to read through the code to determine if a given function is safe for
308 a desired use. The proper information thoroughly presented at the
309 introduction of a function not only saves time for subsequent
310 maintenance or debugging, it more importantly aids in code reuse by
311 allowing a user to determine the safety and applicability of any
312 function for the problem at hand. As a result of such benefits, all
313 functions should contain the information presented in the addendum
314 section of this document.
315 _________________________________________________________________
317 4.2.6. Comment at the end of braces if the content is more than one screen
322 Each closing brace should be followed on the same line by a comment
323 that describes the origination of the brace if the original brace is
324 off of the screen, or otherwise far away from the closing brace. This
325 will simplify the debugging, maintenance, and readability of the code.
327 As a suggestion , use the following flags to make the comment and its
330 use following a closing brace: } /* -END- if() or while () or etc...
336 DoSomethingVeryImportant();
337 ...some long list of commands...
338 } /* -END- if x is 1 */
344 DoSomethingVeryImportant();
345 ...some long list of commands...
346 } /* -END- if ( 1 == X ) */
347 _________________________________________________________________
349 4.3. Naming Conventions
351 4.3.1. Variable Names
355 Use all lowercase, and seperate words via an underscore ('_'). Do not
356 start an identifier with an underscore. (ANSI C reserves these for use
357 by the compiler and system headers.) Do not use identifiers which are
358 reserved in ANSI C++. (E.g. template, class, true, false, ...). This
359 is in case we ever decide to port Privoxy to C++.
362 int ms_iis5_hack = 0;
366 int msiis5hack = 0; int msIis5Hack = 0;
367 _________________________________________________________________
369 4.3.2. Function Names
373 Use all lowercase, and seperate words via an underscore ('_'). Do not
374 start an identifier with an underscore. (ANSI C reserves these for use
375 by the compiler and system headers.) Do not use identifiers which are
376 reserved in ANSI C++. (E.g. template, class, true, false, ...). This
377 is in case we ever decide to port Privoxy to C++.
380 int load_some_file( struct client_state *csp )
384 int loadsomefile( struct client_state *csp )
385 int loadSomeFile( struct client_state *csp )
386 _________________________________________________________________
388 4.3.3. Header file prototypes
392 Use a descriptive parameter name in the function prototype in header
393 files. Use the same parameter name in the header file that you use in
397 (.h) extern int load_aclfile( struct client_state *csp );
398 (.c) int load_aclfile( struct client_state *csp )
401 (.h) extern int load_aclfile( struct client_state * ); or
402 (.h) extern int load_aclfile();
403 (.c) int load_aclfile( struct client_state *csp )
404 _________________________________________________________________
406 4.3.4. Enumerations, and #defines
410 Use all capital letters, with underscores between words. Do not start
411 an identifier with an underscore. (ANSI C reserves these for use by
412 the compiler and system headers.)
415 (enumeration) : enum Boolean { FALSE, TRUE };
416 (#define) : #define DEFAULT_SIZE 100;
418 Note: We have a standard naming scheme for #defines that toggle a
419 feature in the preprocessor: FEATURE_>, where > is a short (preferably
420 1 or 2 word) description.
423 #define FEATURE_FORCE 1
426 #define FORCE_PREFIX blah
427 #endif /* def FEATURE_FORCE */
428 _________________________________________________________________
434 Spell common words out entirely (do not remove vowels).
436 Use only widely-known domain acronyms and abbreviations. Capitalize
437 all letters of an acronym.
439 Use underscore (_) to separate adjacent acronyms and abbreviations.
440 Never terminate a name with an underscore.
443 #define USE_IMAGE_LIST 1
447 #define USE_IMG_LST 1 or
448 #define _USE_IMAGE_LIST 1 or
449 #define USE_IMAGE_LIST_ 1 or
450 #define use_image_list 1 or
451 #define UseImageList 1
452 _________________________________________________________________
456 4.4.1. Put braces on a line by themselves.
460 The brace needs to be on a line all by itself, not at the end of the
461 statement. Curly braces should line up with the construct that they're
462 associated with. This practice makes it easier to identify the opening
463 and closing braces for a block.
473 if ( this == that ) { ... }
477 if ( this == that ) { ... }
479 Note: In the special case that the if-statement is inside a loop, and
480 it is trivial, i.e. it tests for a condidtion that is obvious from the
481 purpose of the block, one-liners as above may optically preserve the
482 loop structure and make it easier to read.
484 Status: developer-discrection.
487 while ( more lines are read )
489 /* Please document what is/is not a comment line here */
490 if ( it's a comment ) continue;
492 do_something( line );
494 _________________________________________________________________
496 4.4.2. ALL control statements should have a block
500 Using braces to make a block will make your code more readable and
501 less prone to error. All control statements should have a block
513 if ( this == that ) DoSomething(); DoSomethingElse();
517 if ( this == that ) DoSomething();
519 Note: The first example in "Instead of" will execute in a manner other
520 than that which the developer desired (per indentation). Using code
521 braces would have prevented this "feature". The "explanation" and
522 "exception" from the point above also applies.
523 _________________________________________________________________
525 4.4.3. Do not belabor/blow-up boolean expressions
528 structure->flag = ( condition );
532 if ( condition ) { structure->flag = 1; } else { structure->flag = 0;
535 Note: The former is readable and consice. The later is wordy and
536 inefficient. Please assume that any developer new to the project has
537 at least a "good" knowledge of C/C++. (Hope I do not offend by that
539 _________________________________________________________________
541 4.4.4. Use white space freely because it is free
545 Make it readable. The notable exception to using white space freely is
546 listed in the next guideline.
551 int anotherValue = 0;
552 int thisVariable = 0;
554 if ( thisVariable == thatVariable )
556 firstValue = oldValue + ( ( someValue - anotherValue ) - whatever )
557 _________________________________________________________________
559 4.4.5. Don't use white space around structure operators
563 - structure pointer operator ( "->" ) - member operator ( "." ) -
564 functions and parentheses
566 It is a general coding practice to put pointers, references, and
567 function parentheses next to names. With spaces, the connection
568 between the object and variable/function name is not as clear.
575 Instead of: aStruct -> aMember; aStruct . aMember; FunctionName ();
576 _________________________________________________________________
578 4.4.6. Make the last brace of a function stand out
586 } /* -END- function1 */
591 } /* -END- function2 */
595 int function1( ... ) { ...code... return( retCode ); } int function2(
598 Note: Use 1 blank line before the closing brace and 2 lines
599 afterwards. This makes the end of function standout to the most casual
600 viewer. Although function comments help seperate functions, this is
601 still a good coding practice. In fact, I follow these rules when using
602 blocks in "for", "while", "do" loops, and long if {} statements too.
603 After all whitespace is free!
605 Status: developer-discrection on the number of blank lines. Enforced
606 is the end of function comments.
607 _________________________________________________________________
609 4.4.7. Use 3 character indentions
613 If some use 8 character TABs and some use 3 character TABs, the code
614 can look *very* ragged. So use 3 character indentions only. If you
615 like to use TABs, pass your code through a filter such as "expand -t3"
616 before checking in your code.
619 static const char * const url_code_map[256] =
629 return( ALWAYS_TRUE );
633 return( HOW_DID_YOU_GET_HERE );
636 return( NEVER_GETS_HERE );
639 _________________________________________________________________
643 4.5.1. Initialize all variables
647 Do not assume that the variables declared will not be used until after
648 they have been assigned a value somewhere else in the code. Remove the
649 chance of accidentally using an unassigned variable.
656 Note: It is much easier to debug a SIGSEGV if the message says you are
657 trying to access memory address 00000000 and not 129FA012; or
658 arrayPtr[20] causes a SIGSEV vs. arrayPtr[0].
660 Status: developer-discrection if and only if the variable is assigned
661 a value "shortly after" declaration.
662 _________________________________________________________________
666 4.6.1. Name functions that return a boolean as a question.
670 Value should be phrased as a question that would logically be answered
671 as a true or false statement
677 _________________________________________________________________
679 4.6.2. Always specify a return type for a function.
683 The default return for a function is an int. To avoid ambiguity,
684 create a return for a function when the return has a purpose, and
685 create a void return type if the function does not need to return
687 _________________________________________________________________
689 4.6.3. Minimize function calls when iterating by using variables
693 It is easy to write the following code, and a clear argument can be
694 made that the code is easy to understand:
697 for ( size_t cnt = 0; cnt < blockListLength(); cnt ++ )
702 Note: Unfortunately, this makes a function call for each and every
703 iteration. This increases the overhead in the program, because the
704 compiler has to look up the function each time, call it, and return a
705 value. Depending on what occurs in the blockListLength() call, it
706 might even be creating and destroying structures with each iteration,
707 even though in each case it is comparing "cnt" to the same value, over
708 and over. Remember too - even a call to blockListLength() is a
709 function call, with the same overhead.
711 Instead of using a function call during the iterations, assign the
712 value to a variable, and evaluate using the variable.
715 size_t len = blockListLength();
717 for ( size_t cnt = 0; cnt < len; cnt ++ )
722 Exceptions: if the value of blockListLength() *may* change or could
723 *potentially* change, then you must code the function call in the
725 _________________________________________________________________
727 4.6.4. Pass and Return by Const Reference
731 This allows a developer to define a const pointer and call your
732 function. If your function does not have the const keyword, we may not
733 be able to use your function. Consider strcmp, if it were defined as:
734 extern int strcmp( char *s1, char *s2 );
736 I could then not use it to compare argv's in main: int main( int argc,
737 const char *argv[] ) { strcmp( argv[0], "privoxy" ); }
739 Both these pointers are *const*! If the c runtime library maintainers
740 do it, we should too.
741 _________________________________________________________________
743 4.6.5. Pass and Return by Value
747 Most structures cannot fit onto a normal stack entry (i.e. they are
748 not 4 bytes or less). Aka, a function declaration like: int
749 load_aclfile( struct client_state csp )
751 would not work. So, to be consistent, we should declare all prototypes
752 with "pass by value": int load_aclfile( struct client_state *csp )
753 _________________________________________________________________
755 4.6.6. Names of include files
759 Your include statements should contain the file name without a path.
760 The path should be listed in the Makefile, using -I as processor
761 directive to search the indicated paths. An exception to this would be
762 for some proprietary software that utilizes a partial path to
763 distinguish their header files from system or other header files.
766 #include <iostream.h> /* This is not a local include */
767 #include "config.h" /* This IS a local include */
771 /* This is not a local include, but requires a path element. */
772 #include <sys/fileName.h>
774 Note: Please! do not add "-I." to the Makefile without a _very_ good
775 reason. This duplicates the #include "file.h" behaviour.
776 _________________________________________________________________
778 4.6.7. Provide multiple inclusion protection
782 Prevents compiler and linker errors resulting from redefinition of
785 Wrap each header file with the following syntax to prevent multiple
786 inclusions of the file. Of course, replace PROJECT_H with your file
787 name, with "." Changed to "_", and make it uppercase.
790 #ifndef PROJECT_H_INCLUDED
791 #define PROJECT_H_INCLUDED
793 #endif /* ndef PROJECT_H_INCLUDED */
794 _________________________________________________________________
796 4.6.8. Use `extern "C"` when appropriate
800 If our headers are included from C++, they must declare our functions
801 as `extern "C"`. This has no cost in C, but increases the potential
802 re-usability of our code.
808 #endif /* def __cplusplus */
810 ... function definitions here ...
814 #endif /* def __cplusplus */
815 _________________________________________________________________
817 4.6.9. Where Possible, Use Forward Struct Declaration Instead of Includes
821 Useful in headers that include pointers to other struct's.
822 Modifications to excess header files may cause needless compiles.
825 /*********************************************************************
826 * We're avoiding an include statement here!
827 *********************************************************************/
829 extern file_list *xyz;
831 Note: If you declare "file_list xyz;" (without the pointer), then
832 including the proper header file is necessary. If you only want to
833 prototype a pointer, however, the header file is unneccessary.
835 Status: Use with discrection.
836 _________________________________________________________________
838 4.7. General Coding Practices
840 4.7.1. Turn on warnings
844 Compiler warnings are meant to help you find bugs. You should turn on
845 as many as possible. With GCC, the switch is "-Wall". Try and fix as
846 many warnings as possible.
847 _________________________________________________________________
849 4.7.2. Provide a default case for all switch statements
853 What you think is guaranteed is never really guaranteed. The value
854 that you don't think you need to check is the one that someday will be
855 passed. So, to protect yourself from the unknown, always have a
856 default step in a switch statement.
859 switch( hash_string( cmd ) )
861 case hash_actions_file :
871 ... anomly code goes here ...
872 continue; / break; / exit( 1 ); / etc ...
874 } /* end switch( hash_string( cmd ) ) */
876 Note: If you already have a default condition, you are obviously
877 exempt from this point. Of note, most of the WIN32 code calls
878 `DefWindowProc' after the switch statement. This API call *should* be
879 included in a default statement.
881 Another Note: This is not so much a readability issue as a robust
882 programming issue. The "anomly code goes here" may be no more than a
883 print to the STDERR stream (as in load_config). Or it may really be an
886 Status: Programmer discretion is advised.
887 _________________________________________________________________
889 4.7.3. Try to avoid falling through cases in a switch statement.
893 In general, you will want to have a 'break' statement within each
894 'case' of a switch statement. This allows for the code to be more
895 readable and understandable, and furthermore can prevent unwanted
896 surprises if someone else later gets creative and moves the code
899 The language allows you to plan the fall through from one case
900 statement to another simply by omitting the break statement within the
901 case statement. This feature does have benefits, but should only be
902 used in rare cases. In general, use a break statement for each case
905 If you choose to allow fall through, you should comment both the fact
906 of the fall through and reason why you felt it was necessary.
907 _________________________________________________________________
909 4.7.4. Use 'long' or 'short' Instead of 'int'
913 On 32-bit platforms, int usually has the range of long. On 16-bit
914 platforms, int has the range of short.
916 Status: open-to-debate. In the case of most FSF projects (including
917 X/GNU-Emacs), there are typedefs to int4, int8, int16, (or equivalence
918 ... I forget the exact typedefs now). Should we add these to IJB now
919 that we have a "configure" script?
920 _________________________________________________________________
922 4.7.5. Don't mix size_t and other types
926 The type of size_t varies across platforms. Do not make assumptions
927 about whether it is signed or unsigned, or about how long it is. Do
928 not compare a size_t against another variable of a different type (or
929 even against a constant) without casting one of the values. Try to
930 avoid using size_t if you can.
931 _________________________________________________________________
933 4.7.6. Declare each variable and struct on its own line.
937 It can be tempting to declare a series of variables all on one line.
949 Explanation: - there is more room for comments on the individual
950 variables - easier to add new variables without messing up the
951 original ones - when searching on a variable to find its type, there
952 is less clutter to "visually" eliminate
954 Exceptions: when you want to declare a bunch of loop variables or
955 other trivial variables; feel free to declare them on 1 line. You
956 should, although, provide a good comment on their functions.
958 Status: developer-discrection.
959 _________________________________________________________________
961 4.7.7. Use malloc/zalloc sparingly
965 Create a local stuct (on the stack) if the variable will live and die
966 within the context of one function call.
968 Only "malloc" a struct (on the heap) if the variable's life will
969 extend beyond the context of one function call.
972 If a function creates a struct and stores a pointer to it in a
973 list, then it should definately be allocated via `malloc'.
974 _________________________________________________________________
976 4.7.8. The Programmer Who Uses 'malloc' is Responsible for Ensuring 'free'
980 If you have to "malloc" an instance, you are responsible for insuring
981 that the instance is `free'd, even if the deallocation event falls
982 within some other programmer's code. You are also responsible for
983 ensuring that deletion is timely (i.e. not too soon, not too late).
984 This is known as "low-coupling" and is a "good thing (tm)". You may
985 need to offer a free/unload/destuctor type function to accomodate
989 int load_re_filterfile( struct client_state *csp ) { ... }
990 static void unload_re_filterfile( void *f ) { ... }
994 The developer cannot be expected to provide `free'ing functions for C
995 run-time library functions ... such as `strdup'.
997 Status: developer-discrection. The "main" use of this standard is for
998 allocating and freeing data structures (complex or nested).
999 _________________________________________________________________
1001 4.7.9. Add loaders to the `file_list' structure and in order
1005 I have ordered all of the "blocker" file code to be in alpha order. It
1006 is easier to add/read new blockers when you expect a certain order.
1008 Note: It may appear that the alpha order is broken in places by POPUP
1009 tests coming before PCRS tests. But since POPUPs can also be referred
1010 to as KILLPOPUPs, it is clear that it should come first.
1011 _________________________________________________________________
1013 4.7.10. "Uncertain" new code and/or changes to exitinst code, use FIXME
1017 If you have enough confidence in new code or confidence in your
1018 changes, but are not *quite* sure of the reprocussions, add this:
1020 /* FIXME: this code has a logic error on platform XYZ, * attempthing
1021 to fix */ #ifdef PLATFORM ...changed code here... #endif
1025 /* FIXME: I think the original author really meant this... */
1026 ...changed code here...
1030 /* FIXME: new code that *may* break something else... */ ...new code
1033 Note: If you make it clear that this may or may not be a "good thing
1034 (tm)", it will be easier to identify and include in the project (or
1035 conversly exclude from the project).
1036 _________________________________________________________________
1038 4.8. Addendum: Template for files and function comment blocks:
1040 Example for file comments:
1041 const char FILENAME_rcs[] = "$Id: developer-manual.sgml,v 1.10 2002/03/24 12:33
1043 /*********************************************************************
1047 * Purpose : (Fill me in with a good description!)
1049 * Copyright : Written by and Copyright (C) 2001 the SourceForge
1050 * Privoxy team. http://www.privoxy.org/
1052 * Based on the Internet Junkbuster originally written
1053 * by and Copyright (C) 1997 Anonymous Coders and
1054 * Junkbusters Corporation. http://www.junkbusters.com
1056 * This program is free software; you can redistribute it
1057 * and/or modify it under the terms of the GNU General
1058 * Public License as published by the Free Software
1059 * Foundation; either version 2 of the License, or (at
1060 * your option) any later version.
1062 * This program is distributed in the hope that it will
1063 * be useful, but WITHOUT ANY WARRANTY; without even the
1064 * implied warranty of MERCHANTABILITY or FITNESS FOR A
1065 * PARTICULAR PURPOSE. See the GNU General Public
1066 * License for more details.
1068 * The GNU General Public License should be included with
1069 * this file. If not, you can view it at
1070 * http://www.gnu.org/copyleft/gpl.html
1071 * or write to the Free Software Foundation, Inc., 59
1072 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1077 *********************************************************************/
1082 ...necessary include files for us to do our work...
1084 const char FILENAME_h_rcs[] = FILENAME_H_VERSION;
1086 Note: This declares the rcs variables that should be added to the
1087 "show-proxy-args" page. If this is a brand new creation by you, you
1088 are free to change the "Copyright" section to represent the rights you
1091 Note: The formfeed character that is present right after the comment
1092 flower box is handy for (X|GNU)Emacs users to skip the verbige and get
1093 to the heart of the code (via `forward-page' and `backward-page').
1094 Please include it if you can.
1096 Example for file header comments:
1099 #define FILENAME_H_VERSION "$Id: developer-manual.sgml,v 1.10 2002/03/24 12:33:
1101 /*********************************************************************
1105 * Purpose : (Fill me in with a good description!)
1107 * Copyright : Written by and Copyright (C) 2001 the SourceForge
1108 * Privoxy team. http://www.privoxy.org/
1110 * Based on the Internet Junkbuster originally written
1111 * by and Copyright (C) 1997 Anonymous Coders and
1112 * Junkbusters Corporation. http://www.junkbusters.com
1114 * This program is free software; you can redistribute it
1115 * and/or modify it under the terms of the GNU General
1116 * Public License as published by the Free Software
1117 * Foundation; either version 2 of the License, or (at
1118 * your option) any later version.
1120 * This program is distributed in the hope that it will
1121 * be useful, but WITHOUT ANY WARRANTY; without even the
1122 * implied warranty of MERCHANTABILITY or FITNESS FOR A
1123 * PARTICULAR PURPOSE. See the GNU General Public
1124 * License for more details.
1126 * The GNU General Public License should be included with
1127 * this file. If not, you can view it at
1128 * http://www.gnu.org/copyleft/gpl.html
1129 * or write to the Free Software Foundation, Inc., 59
1130 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1135 *********************************************************************/
1138 #include "project.h"
1144 ... function headers here ...
1147 /* Revision control strings from this header and associated .c file */
1148 extern const char FILENAME_rcs[];
1149 extern const char FILENAME_h_rcs[];
1156 #endif /* ndef _FILENAME_H */
1164 Example for function comments:
1165 /*********************************************************************
1167 * Function : FUNCTION_NAME
1169 * Description : (Fill me in with a good description!)
1172 * 1 : param1 = pointer to an important thing
1173 * 2 : x = pointer to something else
1175 * Returns : 0 => Ok, everything else is an error.
1177 *********************************************************************/
1178 int FUNCTION_NAME( void *param1, const char *x )
1185 Note: If we all follow this practice, we should be able to parse our
1186 code to create a "self-documenting" web page.
1187 _________________________________________________________________
1189 5. Version Control Guidelines
1191 To be filled. note on cvs comments. don't comment what you did,
1192 comment why you did it.
1193 _________________________________________________________________
1195 6. Testing Guidelines
1198 _________________________________________________________________
1200 6.1. Testplan for releases
1202 Explain release numbers. major, minor. developer releases. etc.
1204 1. Remove any existing rpm with rpm -e
1205 2. Remove any file that was left over. This includes (but is not
1210 + /etc/init.d/privoxy
1212 3. Install the rpm. Any error messages?
1213 4. start,stop,status Privoxy with the specific script (e.g.
1214 /etc/rc.d/init/privoxy stop). Reboot your machine. Does autostart
1216 5. Start browsing. Does Privoxy work? Logfile written?
1217 6. Remove the rpm. Any error messages? All files removed?
1218 _________________________________________________________________
1222 Please submit test reports only with the [59]test form at sourceforge.
1225 * Select category: the distribution you test on.
1226 * Select group: the version of Privoxy that we are about to release.
1227 * Fill the Summary and Detailed Description with something
1228 intelligent (keep it short and precise).
1230 Do not mail to the mailinglist (we cannot keep track on issues there).
1231 _________________________________________________________________
1233 7. Contact the developers
1235 Please see the user manual for information on how to contact the
1237 _________________________________________________________________
1239 8. Copyright and History
1241 Please see the user manual for information on Copyright and History.
1242 _________________________________________________________________
1246 Please see the user manual for information on references.
1250 1. http://www.privoxy.org/developer-manual/
1251 2. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#INTRODUCTION
1252 3. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#QUICKSTART
1253 4. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#DOCUMENTATION
1254 5. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#CODING
1255 6. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S1
1256 7. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S2
1257 8. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S3
1258 9. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S4
1259 10. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S5
1260 11. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S6
1261 12. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S7
1262 13. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S8
1263 14. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S9
1264 15. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S10
1265 16. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S11
1266 17. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S12
1267 18. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S13
1268 19. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S14
1269 20. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S15
1270 21. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S16
1271 22. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S17
1272 23. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S18
1273 24. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S19
1274 25. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S20
1275 26. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S21
1276 27. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S22
1277 28. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S23
1278 29. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S24
1279 30. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S25
1280 31. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S26
1281 32. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S27
1282 33. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S28
1283 34. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S29
1284 35. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S30
1285 36. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S31
1286 37. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S32
1287 38. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S33
1288 39. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S34
1289 40. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S35
1290 41. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S36
1291 42. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S37
1292 43. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S38
1293 44. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S39
1294 45. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S40
1295 46. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S41
1296 47. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S42
1297 48. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S43
1298 49. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S44
1299 50. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S45
1300 51. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S46
1301 52. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#CVS
1302 53. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#TESTING
1303 54. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#TESTING-PLAN
1304 55. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#TESTING-REPORT
1305 56. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#CONTACT
1306 57. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#COPYRIGHT
1307 58. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#SEEALSO
1308 59. http://sourceforge.net/tracker/?func=add&group_id=11118&atid=395005