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