2 Privoxy Developer Manual
6 $Id: developer-manual.sgml,v 1.9 2002/03/24 11:01:05 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://ijbswa.sourceforge.net/developer-manual/. Please see the
20 Contact section in the user-manual if you want to contact the
22 _________________________________________________________________
26 2. [3]Quickstart to Privoxy Development
27 3. [4]Documentation Guidelines
28 4. [5]Coding Guidelines
31 4.2. [7]Using Comments
33 4.2.1. [8]Comment, Comment, Comment
34 4.2.2. [9]Use blocks for comments
35 4.2.3. [10]Keep Comments on their own line
36 4.2.4. [11]Comment each logical step
37 4.2.5. [12]Comment All Functions Thoroughly
38 4.2.6. [13]Comment at the end of braces if the content is
39 more than one screen length
41 4.3. [14]Naming Conventions
43 4.3.1. [15]Variable Names
44 4.3.2. [16]Function Names
45 4.3.3. [17]Header file prototypes
46 4.3.4. [18]Enumerations, and #defines
51 4.4.1. [21]Put braces on a line by themselves.
52 4.4.2. [22]ALL control statements should have a block
53 4.4.3. [23]Do not belabor/blow-up boolean expressions
54 4.4.4. [24]Use white space freely because it is free
55 4.4.5. [25]Don't use white space around structure operators
56 4.4.6. [26]Make the last brace of a function stand out
57 4.4.7. [27]Use 3 character indentions
61 4.5.1. [29]Initialize all variables
65 4.6.1. [31]Name functions that return a boolean as a
68 4.6.2. [32]Always specify a return type for a function.
69 4.6.3. [33]Minimize function calls when iterating by using
72 4.6.4. [34]Pass and Return by Const Reference
73 4.6.5. [35]Pass and Return by Value
74 4.6.6. [36]Names of include files
75 4.6.7. [37]Provide multiple inclusion protection
76 4.6.8. [38]Use `extern "C"` when appropriate
77 4.6.9. [39]Where Possible, Use Forward Struct Declaration
80 4.7. [40]General Coding Practices
82 4.7.1. [41]Turn on warnings
83 4.7.2. [42]Provide a default case for all switch statements
84 4.7.3. [43]Try to avoid falling through cases in a switch
87 4.7.4. [44]Use 'long' or 'short' Instead of 'int'
88 4.7.5. [45]Don't mix size_t and other types
89 4.7.6. [46]Declare each variable and struct on its own
92 4.7.7. [47]Use malloc/zalloc sparingly
93 4.7.8. [48]The Programmer Who Uses 'malloc' is Responsible
96 4.7.9. [49]Add loaders to the `file_list' structure and in
99 4.7.10. [50]"Uncertain" new code and/or changes to exitinst
102 4.8. [51]Addendum: Template for files and function comment
105 5. [52]Version Control Guidelines
106 6. [53]Testing Guidelines
108 6.1. [54]Testplan for releases
109 6.2. [55]Test reports
111 7. [56]Contact the developers
112 8. [57]Copyright and History
118 _________________________________________________________________
120 2. Quickstart to Privoxy Development
122 You'll need an account on Sourceforge to support our development. Mail
123 you ID to the list and wait until a project manager has added you. For
124 the time beeing (read, this section is under construction), please
125 note the following guidelines for changing stuff in the code. If it is
127 1. A bugfix / clean-up / cosmetic thing: shoot
128 2. A new feature that can be turned off: shoot
129 3. A clear improvement w/o side effects on other parts of the code:
131 4. A matter of taste: ask the list
132 5. A major redesign of some part of the code: ask the list
133 _________________________________________________________________
135 3. Documentation Guidelines
137 All docs are in SGML format and located in the doc/source directory.
139 How do you update the webserver (i.e. the pages on sourceforge)?
141 1. Run make dok (which uses the documents in doc/source to update all
142 text files in doc/text and to update all web documents in
144 2. Run make webserver which copies all files from doc/webserver to
145 the sourceforge webserver via scp.
146 _________________________________________________________________
152 This set of standards is designed to make our lives easier. It is
153 developed with the simple goal of helping us keep the "new and
154 improved Privoxy" consistent and reliable. Thus making maintenance
155 easier and increasing chances of success of the project.
157 And that of course comes back to us as individuals. If we can increase
158 our development and product efficiencies then we can solve more of the
159 request for changes/improvements and in general feel good about
161 _________________________________________________________________
165 4.2.1. Comment, Comment, Comment
169 Comment as much as possible without commenting the obvious. For
170 example do not comment "aVariable is equal to bVariable". Instead
171 explain why aVariable should be equal to the bVariable. Just because a
172 person can read code does not mean they will understand why or what is
173 being done. A reader may spend a lot more time figuring out what is
174 going on when a simple comment or explanation would have prevented the
175 extra research. Please help your brother IJB'ers out!
177 The comments will also help justify the intent of the code. If the
178 comment describes something different than what the code is doing then
179 maybe a programming error is occurring.
182 /* if page size greater than 1k ... */
183 if ( PageLength() > 1024 )
185 ... "block" the page up ...
188 /* if page size is small, send it in blocks */
189 if ( PageLength() > 1024 )
191 ... "block" the page up ...
194 This demonstrates 2 cases of "what not to do". The first is a
195 "syntax comment". The second is a comment that does not fit what
196 is actually being done.
197 _________________________________________________________________
199 4.2.2. Use blocks for comments
203 Comments can help or they can clutter. They help when they are
204 differentiated from the code they describe. One line comments do not
205 offer effective separation between the comment and the code. Block
206 identifiers do, by surrounding the code with a clear, definable
210 /*********************************************************************
211 * This will stand out clearly in your code!
212 *********************************************************************/
213 if ( thisVariable == thatVariable )
215 DoSomethingVeryImportant();
219 /* unfortunately, this may not */
220 if ( thisVariable == thatVariable )
222 DoSomethingVeryImportant();
226 if ( thisVariable == thatVariable ) /* this may not either */
228 DoSomethingVeryImportant();
233 If you are trying to add a small logic comment and do not wish to
234 "disrubt" the flow of the code, feel free to use a 1 line comment
235 which is NOT on the same line as the code.
236 _________________________________________________________________
238 4.2.3. Keep Comments on their own line
242 It goes back to the question of readability. If the comment is on the
243 same line as the code it will be harder to read than the comment that
246 There are three exceptions to this rule, which should be violated
247 freely and often: during the definition of variables, at the end of
248 closing braces, when used to comment parameters.
251 /*********************************************************************
252 * This will stand out clearly in your code,
253 * But the second example won't.
254 *********************************************************************/
255 if ( thisVariable == thatVariable )
257 DoSomethingVeryImportant();
260 if ( thisVariable == thatVariable ) /*can you see me?*/
262 DoSomethingVeryImportant(); /*not easily*/
266 /*********************************************************************
267 * But, the encouraged exceptions:
268 *********************************************************************/
269 int urls_read = 0; /* # of urls read + rejected */
270 int urls_rejected = 0; /* # of urls rejected */
274 DoSomethingVeryImportant();
278 short DoSomethingVeryImportant(
279 short firstparam, /* represents something */
280 short nextparam /* represents something else */ )
284 } /* -END- DoSomethingVeryImportant */
285 _________________________________________________________________
287 4.2.4. Comment each logical step
291 Logical steps should be commented to help others follow the intent of
292 the written code and comments will make the code more readable.
294 If you have 25 lines of code without a comment, you should probably go
295 back into it to see where you forgot to put one.
297 Most "for", "while", "do", etc... loops _probably_ need a comment.
298 After all, these are usually major logic containers.
299 _________________________________________________________________
301 4.2.5. Comment All Functions Thoroughly
305 A reader of the code should be able to look at the comments just prior
306 to the beginning of a function and discern the reason for its
307 existence and the consequences of using it. The reader should not have
308 to read through the code to determine if a given function is safe for
309 a desired use. The proper information thoroughly presented at the
310 introduction of a function not only saves time for subsequent
311 maintenance or debugging, it more importantly aids in code reuse by
312 allowing a user to determine the safety and applicability of any
313 function for the problem at hand. As a result of such benefits, all
314 functions should contain the information presented in the addendum
315 section of this document.
316 _________________________________________________________________
318 4.2.6. Comment at the end of braces if the content is more than one screen
323 Each closing brace should be followed on the same line by a comment
324 that describes the origination of the brace if the original brace is
325 off of the screen, or otherwise far away from the closing brace. This
326 will simplify the debugging, maintenance, and readability of the code.
328 As a suggestion , use the following flags to make the comment and its
331 use following a closing brace: } /* -END- if() or while () or etc...
337 DoSomethingVeryImportant();
338 ...some long list of commands...
339 } /* -END- if x is 1 */
345 DoSomethingVeryImportant();
346 ...some long list of commands...
347 } /* -END- if ( 1 == X ) */
348 _________________________________________________________________
350 4.3. Naming Conventions
352 4.3.1. Variable Names
356 Use all lowercase, and seperate words via an underscore ('_'). Do not
357 start an identifier with an underscore. (ANSI C reserves these for use
358 by the compiler and system headers.) Do not use identifiers which are
359 reserved in ANSI C++. (E.g. template, class, true, false, ...). This
360 is in case we ever decide to port Privoxy to C++.
363 int ms_iis5_hack = 0;
367 int msiis5hack = 0; int msIis5Hack = 0;
368 _________________________________________________________________
370 4.3.2. Function Names
374 Use all lowercase, and seperate words via an underscore ('_'). Do not
375 start an identifier with an underscore. (ANSI C reserves these for use
376 by the compiler and system headers.) Do not use identifiers which are
377 reserved in ANSI C++. (E.g. template, class, true, false, ...). This
378 is in case we ever decide to port Privoxy to C++.
381 int load_some_file( struct client_state *csp )
385 int loadsomefile( struct client_state *csp )
386 int loadSomeFile( struct client_state *csp )
387 _________________________________________________________________
389 4.3.3. Header file prototypes
393 Use a descriptive parameter name in the function prototype in header
394 files. Use the same parameter name in the header file that you use in
398 (.h) extern int load_aclfile( struct client_state *csp );
399 (.c) int load_aclfile( struct client_state *csp )
402 (.h) extern int load_aclfile( struct client_state * ); or
403 (.h) extern int load_aclfile();
404 (.c) int load_aclfile( struct client_state *csp )
405 _________________________________________________________________
407 4.3.4. Enumerations, and #defines
411 Use all capital letters, with underscores between words. Do not start
412 an identifier with an underscore. (ANSI C reserves these for use by
413 the compiler and system headers.)
416 (enumeration) : enum Boolean { FALSE, TRUE };
417 (#define) : #define DEFAULT_SIZE 100;
419 Note: We have a standard naming scheme for #defines that toggle a
420 feature in the preprocessor: FEATURE_>, where > is a short (preferably
421 1 or 2 word) description.
424 #define FEATURE_FORCE 1
427 #define FORCE_PREFIX blah
428 #endif /* def FEATURE_FORCE */
429 _________________________________________________________________
435 Spell common words out entirely (do not remove vowels).
437 Use only widely-known domain acronyms and abbreviations. Capitalize
438 all letters of an acronym.
440 Use underscore (_) to separate adjacent acronyms and abbreviations.
441 Never terminate a name with an underscore.
444 #define USE_IMAGE_LIST 1
448 #define USE_IMG_LST 1 or
449 #define _USE_IMAGE_LIST 1 or
450 #define USE_IMAGE_LIST_ 1 or
451 #define use_image_list 1 or
452 #define UseImageList 1
453 _________________________________________________________________
457 4.4.1. Put braces on a line by themselves.
461 The brace needs to be on a line all by itself, not at the end of the
462 statement. Curly braces should line up with the construct that they're
463 associated with. This practice makes it easier to identify the opening
464 and closing braces for a block.
474 if ( this == that ) { ... }
478 if ( this == that ) { ... }
480 Note: In the special case that the if-statement is inside a loop, and
481 it is trivial, i.e. it tests for a condidtion that is obvious from the
482 purpose of the block, one-liners as above may optically preserve the
483 loop structure and make it easier to read.
485 Status: developer-discrection.
488 while ( more lines are read )
490 /* Please document what is/is not a comment line here */
491 if ( it's a comment ) continue;
493 do_something( line );
495 _________________________________________________________________
497 4.4.2. ALL control statements should have a block
501 Using braces to make a block will make your code more readable and
502 less prone to error. All control statements should have a block
514 if ( this == that ) DoSomething(); DoSomethingElse();
518 if ( this == that ) DoSomething();
520 Note: The first example in "Instead of" will execute in a manner other
521 than that which the developer desired (per indentation). Using code
522 braces would have prevented this "feature". The "explanation" and
523 "exception" from the point above also applies.
524 _________________________________________________________________
526 4.4.3. Do not belabor/blow-up boolean expressions
529 structure->flag = ( condition );
533 if ( condition ) { structure->flag = 1; } else { structure->flag = 0;
536 Note: The former is readable and consice. The later is wordy and
537 inefficient. Please assume that any developer new to the project has
538 at least a "good" knowledge of C/C++. (Hope I do not offend by that
540 _________________________________________________________________
542 4.4.4. Use white space freely because it is free
546 Make it readable. The notable exception to using white space freely is
547 listed in the next guideline.
552 int anotherValue = 0;
553 int thisVariable = 0;
555 if ( thisVariable == thatVariable )
557 firstValue = oldValue + ( ( someValue - anotherValue ) - whatever )
558 _________________________________________________________________
560 4.4.5. Don't use white space around structure operators
564 - structure pointer operator ( "->" ) - member operator ( "." ) -
565 functions and parentheses
567 It is a general coding practice to put pointers, references, and
568 function parentheses next to names. With spaces, the connection
569 between the object and variable/function name is not as clear.
576 Instead of: aStruct -> aMember; aStruct . aMember; FunctionName ();
577 _________________________________________________________________
579 4.4.6. Make the last brace of a function stand out
587 } /* -END- function1 */
592 } /* -END- function2 */
596 int function1( ... ) { ...code... return( retCode ); } int function2(
599 Note: Use 1 blank line before the closing brace and 2 lines
600 afterwards. This makes the end of function standout to the most casual
601 viewer. Although function comments help seperate functions, this is
602 still a good coding practice. In fact, I follow these rules when using
603 blocks in "for", "while", "do" loops, and long if {} statements too.
604 After all whitespace is free!
606 Status: developer-discrection on the number of blank lines. Enforced
607 is the end of function comments.
608 _________________________________________________________________
610 4.4.7. Use 3 character indentions
614 If some use 8 character TABs and some use 3 character TABs, the code
615 can look *very* ragged. So use 3 character indentions only. If you
616 like to use TABs, pass your code through a filter such as "expand -t3"
617 before checking in your code.
620 static const char * const url_code_map[256] =
630 return( ALWAYS_TRUE );
634 return( HOW_DID_YOU_GET_HERE );
637 return( NEVER_GETS_HERE );
640 _________________________________________________________________
644 4.5.1. Initialize all variables
648 Do not assume that the variables declared will not be used until after
649 they have been assigned a value somewhere else in the code. Remove the
650 chance of accidentally using an unassigned variable.
657 Note: It is much easier to debug a SIGSEGV if the message says you are
658 trying to access memory address 00000000 and not 129FA012; or
659 arrayPtr[20] causes a SIGSEV vs. arrayPtr[0].
661 Status: developer-discrection if and only if the variable is assigned
662 a value "shortly after" declaration.
663 _________________________________________________________________
667 4.6.1. Name functions that return a boolean as a question.
671 Value should be phrased as a question that would logically be answered
672 as a true or false statement
678 _________________________________________________________________
680 4.6.2. Always specify a return type for a function.
684 The default return for a function is an int. To avoid ambiguity,
685 create a return for a function when the return has a purpose, and
686 create a void return type if the function does not need to return
688 _________________________________________________________________
690 4.6.3. Minimize function calls when iterating by using variables
694 It is easy to write the following code, and a clear argument can be
695 made that the code is easy to understand:
698 for ( size_t cnt = 0; cnt < blockListLength(); cnt ++ )
703 Note: Unfortunately, this makes a function call for each and every
704 iteration. This increases the overhead in the program, because the
705 compiler has to look up the function each time, call it, and return a
706 value. Depending on what occurs in the blockListLength() call, it
707 might even be creating and destroying structures with each iteration,
708 even though in each case it is comparing "cnt" to the same value, over
709 and over. Remember too - even a call to blockListLength() is a
710 function call, with the same overhead.
712 Instead of using a function call during the iterations, assign the
713 value to a variable, and evaluate using the variable.
716 size_t len = blockListLength();
718 for ( size_t cnt = 0; cnt < len; cnt ++ )
723 Exceptions: if the value of blockListLength() *may* change or could
724 *potentially* change, then you must code the function call in the
726 _________________________________________________________________
728 4.6.4. Pass and Return by Const Reference
732 This allows a developer to define a const pointer and call your
733 function. If your function does not have the const keyword, we may not
734 be able to use your function. Consider strcmp, if it were defined as:
735 extern int strcmp( char *s1, char *s2 );
737 I could then not use it to compare argv's in main: int main( int argc,
738 const char *argv[] ) { strcmp( argv[0], "privoxy" ); }
740 Both these pointers are *const*! If the c runtime library maintainers
741 do it, we should too.
742 _________________________________________________________________
744 4.6.5. Pass and Return by Value
748 Most structures cannot fit onto a normal stack entry (i.e. they are
749 not 4 bytes or less). Aka, a function declaration like: int
750 load_aclfile( struct client_state csp )
752 would not work. So, to be consistent, we should declare all prototypes
753 with "pass by value": int load_aclfile( struct client_state *csp )
754 _________________________________________________________________
756 4.6.6. Names of include files
760 Your include statements should contain the file name without a path.
761 The path should be listed in the Makefile, using -I as processor
762 directive to search the indicated paths. An exception to this would be
763 for some proprietary software that utilizes a partial path to
764 distinguish their header files from system or other header files.
767 #include <iostream.h> /* This is not a local include */
768 #include "config.h" /* This IS a local include */
772 /* This is not a local include, but requires a path element. */
773 #include <sys/fileName.h>
775 Note: Please! do not add "-I." to the Makefile without a _very_ good
776 reason. This duplicates the #include "file.h" behaviour.
777 _________________________________________________________________
779 4.6.7. Provide multiple inclusion protection
783 Prevents compiler and linker errors resulting from redefinition of
786 Wrap each header file with the following syntax to prevent multiple
787 inclusions of the file. Of course, replace PROJECT_H with your file
788 name, with "." Changed to "_", and make it uppercase.
791 #ifndef PROJECT_H_INCLUDED
792 #define PROJECT_H_INCLUDED
794 #endif /* ndef PROJECT_H_INCLUDED */
795 _________________________________________________________________
797 4.6.8. Use `extern "C"` when appropriate
801 If our headers are included from C++, they must declare our functions
802 as `extern "C"`. This has no cost in C, but increases the potential
803 re-usability of our code.
809 #endif /* def __cplusplus */
811 ... function definitions here ...
815 #endif /* def __cplusplus */
816 _________________________________________________________________
818 4.6.9. Where Possible, Use Forward Struct Declaration Instead of Includes
822 Useful in headers that include pointers to other struct's.
823 Modifications to excess header files may cause needless compiles.
826 /*********************************************************************
827 * We're avoiding an include statement here!
828 *********************************************************************/
830 extern file_list *xyz;
832 Note: If you declare "file_list xyz;" (without the pointer), then
833 including the proper header file is necessary. If you only want to
834 prototype a pointer, however, the header file is unneccessary.
836 Status: Use with discrection.
837 _________________________________________________________________
839 4.7. General Coding Practices
841 4.7.1. Turn on warnings
845 Compiler warnings are meant to help you find bugs. You should turn on
846 as many as possible. With GCC, the switch is "-Wall". Try and fix as
847 many warnings as possible.
848 _________________________________________________________________
850 4.7.2. Provide a default case for all switch statements
854 What you think is guaranteed is never really guaranteed. The value
855 that you don't think you need to check is the one that someday will be
856 passed. So, to protect yourself from the unknown, always have a
857 default step in a switch statement.
860 switch( hash_string( cmd ) )
862 case hash_actions_file :
872 ... anomly code goes here ...
873 continue; / break; / exit( 1 ); / etc ...
875 } /* end switch( hash_string( cmd ) ) */
877 Note: If you already have a default condition, you are obviously
878 exempt from this point. Of note, most of the WIN32 code calls
879 `DefWindowProc' after the switch statement. This API call *should* be
880 included in a default statement.
882 Another Note: This is not so much a readability issue as a robust
883 programming issue. The "anomly code goes here" may be no more than a
884 print to the STDERR stream (as in load_config). Or it may really be an
887 Status: Programmer discretion is advised.
888 _________________________________________________________________
890 4.7.3. Try to avoid falling through cases in a switch statement.
894 In general, you will want to have a 'break' statement within each
895 'case' of a switch statement. This allows for the code to be more
896 readable and understandable, and furthermore can prevent unwanted
897 surprises if someone else later gets creative and moves the code
900 The language allows you to plan the fall through from one case
901 statement to another simply by omitting the break statement within the
902 case statement. This feature does have benefits, but should only be
903 used in rare cases. In general, use a break statement for each case
906 If you choose to allow fall through, you should comment both the fact
907 of the fall through and reason why you felt it was necessary.
908 _________________________________________________________________
910 4.7.4. Use 'long' or 'short' Instead of 'int'
914 On 32-bit platforms, int usually has the range of long. On 16-bit
915 platforms, int has the range of short.
917 Status: open-to-debate. In the case of most FSF projects (including
918 X/GNU-Emacs), there are typedefs to int4, int8, int16, (or equivalence
919 ... I forget the exact typedefs now). Should we add these to IJB now
920 that we have a "configure" script?
921 _________________________________________________________________
923 4.7.5. Don't mix size_t and other types
927 The type of size_t varies across platforms. Do not make assumptions
928 about whether it is signed or unsigned, or about how long it is. Do
929 not compare a size_t against another variable of a different type (or
930 even against a constant) without casting one of the values. Try to
931 avoid using size_t if you can.
932 _________________________________________________________________
934 4.7.6. Declare each variable and struct on its own line.
938 It can be tempting to declare a series of variables all on one line.
950 Explanation: - there is more room for comments on the individual
951 variables - easier to add new variables without messing up the
952 original ones - when searching on a variable to find its type, there
953 is less clutter to "visually" eliminate
955 Exceptions: when you want to declare a bunch of loop variables or
956 other trivial variables; feel free to declare them on 1 line. You
957 should, although, provide a good comment on their functions.
959 Status: developer-discrection.
960 _________________________________________________________________
962 4.7.7. Use malloc/zalloc sparingly
966 Create a local stuct (on the stack) if the variable will live and die
967 within the context of one function call.
969 Only "malloc" a struct (on the heap) if the variable's life will
970 extend beyond the context of one function call.
973 If a function creates a struct and stores a pointer to it in a
974 list, then it should definately be allocated via `malloc'.
975 _________________________________________________________________
977 4.7.8. The Programmer Who Uses 'malloc' is Responsible for Ensuring 'free'
981 If you have to "malloc" an instance, you are responsible for insuring
982 that the instance is `free'd, even if the deallocation event falls
983 within some other programmer's code. You are also responsible for
984 ensuring that deletion is timely (i.e. not too soon, not too late).
985 This is known as "low-coupling" and is a "good thing (tm)". You may
986 need to offer a free/unload/destuctor type function to accomodate
990 int load_re_filterfile( struct client_state *csp ) { ... }
991 static void unload_re_filterfile( void *f ) { ... }
995 The developer cannot be expected to provide `free'ing functions for C
996 run-time library functions ... such as `strdup'.
998 Status: developer-discrection. The "main" use of this standard is for
999 allocating and freeing data structures (complex or nested).
1000 _________________________________________________________________
1002 4.7.9. Add loaders to the `file_list' structure and in order
1006 I have ordered all of the "blocker" file code to be in alpha order. It
1007 is easier to add/read new blockers when you expect a certain order.
1009 Note: It may appear that the alpha order is broken in places by POPUP
1010 tests coming before PCRS tests. But since POPUPs can also be referred
1011 to as KILLPOPUPs, it is clear that it should come first.
1012 _________________________________________________________________
1014 4.7.10. "Uncertain" new code and/or changes to exitinst code, use FIXME
1018 If you have enough confidence in new code or confidence in your
1019 changes, but are not *quite* sure of the reprocussions, add this:
1021 /* FIXME: this code has a logic error on platform XYZ, * attempthing
1022 to fix */ #ifdef PLATFORM ...changed code here... #endif
1026 /* FIXME: I think the original author really meant this... */
1027 ...changed code here...
1031 /* FIXME: new code that *may* break something else... */ ...new code
1034 Note: If you make it clear that this may or may not be a "good thing
1035 (tm)", it will be easier to identify and include in the project (or
1036 conversly exclude from the project).
1037 _________________________________________________________________
1039 4.8. Addendum: Template for files and function comment blocks:
1041 Example for file comments:
1042 const char FILENAME_rcs[] = "$Id: developer-manual.sgml,v 1.9 2002/03/24 11:01:
1044 /*********************************************************************
1048 * Purpose : (Fill me in with a good description!)
1050 * Copyright : Written by and Copyright (C) 2001 the SourceForge
1051 * PRIVOXY team. http://ijbswa.sourceforge.net
1053 * Based on the Internet Junkbuster originally written
1054 * by and Copyright (C) 1997 Anonymous Coders and
1055 * Junkbusters Corporation. http://www.junkbusters.com
1057 * This program is free software; you can redistribute it
1058 * and/or modify it under the terms of the GNU General
1059 * Public License as published by the Free Software
1060 * Foundation; either version 2 of the License, or (at
1061 * your option) any later version.
1063 * This program is distributed in the hope that it will
1064 * be useful, but WITHOUT ANY WARRANTY; without even the
1065 * implied warranty of MERCHANTABILITY or FITNESS FOR A
1066 * PARTICULAR PURPOSE. See the GNU General Public
1067 * License for more details.
1069 * The GNU General Public License should be included with
1070 * this file. If not, you can view it at
1071 * http://www.gnu.org/copyleft/gpl.html
1072 * or write to the Free Software Foundation, Inc., 59
1073 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1078 *********************************************************************/
1083 ...necessary include files for us to do our work...
1085 const char FILENAME_h_rcs[] = FILENAME_H_VERSION;
1087 Note: This declares the rcs variables that should be added to the
1088 "show-proxy-args" page. If this is a brand new creation by you, you
1089 are free to change the "Copyright" section to represent the rights you
1092 Note: The formfeed character that is present right after the comment
1093 flower box is handy for (X|GNU)Emacs users to skip the verbige and get
1094 to the heart of the code (via `forward-page' and `backward-page').
1095 Please include it if you can.
1097 Example for file header comments:
1100 #define FILENAME_H_VERSION "$Id: developer-manual.sgml,v 1.9 2002/03/24 11:01:0
1102 /*********************************************************************
1106 * Purpose : (Fill me in with a good description!)
1108 * Copyright : Written by and Copyright (C) 2001 the SourceForge
1109 * PRIVOXY team. http://ijbswa.sourceforge.net
1111 * Based on the Internet Junkbuster originally written
1112 * by and Copyright (C) 1997 Anonymous Coders and
1113 * Junkbusters Corporation. http://www.junkbusters.com
1115 * This program is free software; you can redistribute it
1116 * and/or modify it under the terms of the GNU General
1117 * Public License as published by the Free Software
1118 * Foundation; either version 2 of the License, or (at
1119 * your option) any later version.
1121 * This program is distributed in the hope that it will
1122 * be useful, but WITHOUT ANY WARRANTY; without even the
1123 * implied warranty of MERCHANTABILITY or FITNESS FOR A
1124 * PARTICULAR PURPOSE. See the GNU General Public
1125 * License for more details.
1127 * The GNU General Public License should be included with
1128 * this file. If not, you can view it at
1129 * http://www.gnu.org/copyleft/gpl.html
1130 * or write to the Free Software Foundation, Inc., 59
1131 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1136 *********************************************************************/
1139 #include "project.h"
1145 ... function headers here ...
1148 /* Revision control strings from this header and associated .c file */
1149 extern const char FILENAME_rcs[];
1150 extern const char FILENAME_h_rcs[];
1157 #endif /* ndef _FILENAME_H */
1165 Example for function comments:
1166 /*********************************************************************
1168 * Function : FUNCTION_NAME
1170 * Description : (Fill me in with a good description!)
1173 * 1 : param1 = pointer to an important thing
1174 * 2 : x = pointer to something else
1176 * Returns : 0 => Ok, everything else is an error.
1178 *********************************************************************/
1179 int FUNCTION_NAME( void *param1, const char *x )
1186 Note: If we all follow this practice, we should be able to parse our
1187 code to create a "self-documenting" web page.
1188 _________________________________________________________________
1190 5. Version Control Guidelines
1192 To be filled. note on cvs comments. don't comment what you did,
1193 comment why you did it.
1194 _________________________________________________________________
1196 6. Testing Guidelines
1199 _________________________________________________________________
1201 6.1. Testplan for releases
1203 Explain release numbers. major, minor. developer releases. etc.
1205 1. Remove any existing rpm with rpm -e
1206 2. Remove any file that was left over. This includes (but is not
1211 + /etc/init.d/privoxy
1213 3. Install the rpm. Any error messages?
1214 4. start,stop,status Privoxy with the specific script (e.g.
1215 /etc/rc.d/init/privoxy stop). Reboot your machine. Does autostart
1217 5. Start browsing. Does Privoxy work? Logfile written?
1218 6. Remove the rpm. Any error messages? All files removed?
1219 _________________________________________________________________
1223 Please submit test reports only with the [59]test form at sourceforge.
1226 * Select category: the distribution you test on.
1227 * Select group: the version of Privoxy that we are about to release.
1228 * Fill the Summary and Detailed Description with something
1229 intelligent (keep it short and precise).
1231 Do not mail to the mailinglist (we cannot keep track on issues there).
1232 _________________________________________________________________
1234 7. Contact the developers
1236 Please see the user manual for information on how to contact the
1238 _________________________________________________________________
1240 8. Copyright and History
1242 Please see the user manual for information on Copyright and History.
1243 _________________________________________________________________
1247 Please see the user manual for information on references.
1251 1. http://ijbswa.sourceforge.net/developer-manual/
1252 2. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#INTRODUCTION
1253 3. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#QUICKSTART
1254 4. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#DOCUMENTATION
1255 5. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#CODING
1256 6. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S1
1257 7. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S2
1258 8. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S3
1259 9. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S4
1260 10. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S5
1261 11. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S6
1262 12. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S7
1263 13. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S8
1264 14. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S9
1265 15. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S10
1266 16. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S11
1267 17. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S12
1268 18. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S13
1269 19. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S14
1270 20. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S15
1271 21. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S16
1272 22. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S17
1273 23. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S18
1274 24. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S19
1275 25. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S20
1276 26. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S21
1277 27. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S22
1278 28. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S23
1279 29. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S24
1280 30. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S25
1281 31. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S26
1282 32. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S27
1283 33. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S28
1284 34. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S29
1285 35. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S30
1286 36. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S31
1287 37. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S32
1288 38. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S33
1289 39. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S34
1290 40. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S35
1291 41. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S36
1292 42. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S37
1293 43. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S38
1294 44. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S39
1295 45. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S40
1296 46. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S41
1297 47. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S42
1298 48. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S43
1299 49. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S44
1300 50. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S45
1301 51. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#S46
1302 52. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#CVS
1303 53. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#TESTING
1304 54. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#TESTING-PLAN
1305 55. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#TESTING-REPORT
1306 56. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#CONTACT
1307 57. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#COPYRIGHT
1308 58. file://localhost/home/swa/sf/current-org/doc/source/tmp.html#SEEALSO
1309 59. http://sourceforge.net/tracker/?func=add&group_id=11118&atid=395005