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