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