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