705c33b4373df07f7ee016f06c3ed5e76218d462
[privoxy.git] / doc / STANDARDS.txt
1 @ Introduction
2
3
4 This set of standards is designed to make our lives easier. It is
5 developed with the simple goal of helping us keep the "new and
6 improved Junkbusters" consistent and reliable.  Thus making
7 maintenance easier and increasing chances of success of the
8 project.
9
10 And that of course comes back to us as individuals. If we can
11 increase our development and product efficiencies then we can
12 solve more of the request for changes/improvements and in general 
13 feel good about ourselves.  ;->
14
15
16 @ Using Comments
17
18
19 @@ Comment, Comment, Comment
20
21 @@@ Explanation:
22
23 Comment as much as possible without commenting the obvious.  For
24 example do not comment "aVariable is equal to bVariable".  Instead
25 explain why aVariable should be equal to the bVariable.  Just
26 because a person can read code does not mean they will understand
27 why or what is being done.  A reader may spend a lot more time
28 figuring out what is going on when a simple comment or explanation
29 would have prevented the extra research.  Please help your brother
30 IJB'ers out!
31
32 The comments will also help justify the intent of the code.  If the
33 comment describes something different than what the code is doing
34 then maybe a programming error is occurring.
35
36 @@@ Example:
37
38 /* if page size greater than 1k ... */
39 if ( PageLength() > 1024 )
40 {
41     ... "block" the page up ...
42 }
43
44 /* if page size is small, send it in blocks */
45 if ( PageLength() > 1024 )
46 {
47     ... "block" the page up ...
48 }
49
50 This demonstrates 2 cases of "what not to do".  The first is a
51 "syntax comment".  The second is a comment that does not fit what
52 is actually being done.
53
54
55 @@ Use blocks for comments
56
57 @@@ Explanation:
58
59 Comments can help or they can clutter.  They help when they are
60 differentiated from the code they describe.  One line comments do
61 not offer effective separation between the comment and the code.
62 Block identifiers do, by surrounding the code with a clear,
63 definable pattern.
64
65 @@@ Example:
66
67 /*********************************************************************
68  * This will stand out clearly in your code!
69  *********************************************************************/
70 if ( thisVariable == thatVariable )
71 {
72    DoSomethingVeryImportant();
73 }
74
75
76 /* unfortunately, this may not */
77 if ( thisVariable == thatVariable )
78 {
79    DoSomethingVeryImportant();
80 }
81
82
83 if ( thisVariable == thatVariable ) /* this may not either */
84 {
85    DoSomethingVeryImportant();
86 }
87
88 @@@ Exception:
89
90 If you are trying to add a small logic comment and do not wish to
91 "disrubt" the flow of the code, feel free to use a 1 line comment
92 which is NOT on the same line as the code.
93
94
95 @@ Keep Comments on their own line
96
97 @@@ Explanation:
98
99 It goes back to the question of readability.  If the comment is on
100 the same line as the code it will be harder to read than the
101 comment that is on its own line.
102
103 There are three exceptions to this rule, which should be violated
104 freely and often: during the definition of variables, at the end
105 of closing braces, when used to comment parameters.
106
107 @@@ Example:
108
109 /*********************************************************************
110  * This will stand out clearly in your code,
111  * But the second example won't.
112  *********************************************************************/
113 if ( thisVariable == thatVariable )
114 {
115    DoSomethingVeryImportant();
116 }
117
118 if ( thisVariable == thatVariable ) /*can you see me?*/
119 {
120    DoSomethingVeryImportant(); /*not easily*/
121 }
122
123
124 /*********************************************************************
125  * But, the encouraged exceptions:
126  *********************************************************************/
127 int urls_read     = 0;     /* # of urls read + rejected */
128 int urls_rejected = 0;     /* # of urls rejected */
129
130 if ( 1 == X )
131 {
132    DoSomethingVeryImportant();
133 }
134
135
136 short DoSomethingVeryImportant(
137    short firstParam,   /* represents something */
138    short nextParam     /* represents something else */ )
139 {
140    ...code here...
141
142 }   /* -END- DoSomethingVeryImportant */
143
144
145 @@ Comment each logical step
146
147 @@@ Explanation:
148
149 Logical steps should be commented to help others follow the
150 intent of the written code and comments will make the code more
151 readable.
152
153 If you have 25 lines of code without a comment, you should
154 probably go back into it to see where you forgot to put one.
155
156 Most "for", "while", "do", etc... loops _probably_ need a
157 comment.  After all, these are usually major logic containers.
158
159
160 @@ Comment All Functions Thoroughly
161
162 @@@ Explanation:
163
164 A reader of the code should be able to look at the comments just
165 prior to the beginning of a function and discern the reason for
166 its existence and the consequences of using it.  The reader
167 should not have to read through the code to determine if a given
168 function is safe for a desired use.  The proper information
169 thoroughly presented at the introduction of a function not only
170 saves time for subsequent maintenance or debugging, it more
171 importantly aids in code reuse by allowing a user to determine
172 the safety and applicability of any function for the problem at
173 hand.  As a result of such benefits, all functions should contain
174 the information presented in the addendum section of this
175 document.
176
177
178 @@ Comment at the end of braces if the content is more than one screen length
179
180 @@@ Explanation:
181
182 Each closing brace should be followed on the same line by a
183 comment that describes the origination of the brace if the
184 original brace is off of the screen, or otherwise far away from
185 the closing brace.  This will simplify the debugging, maintenance,
186 and readability of the code.
187
188 As a suggestion , use the following flags to make the comment and
189 its brace more readable:
190
191 use following a closing brace:
192    } /* -END- if() or while () or etc... */
193
194 @@@ Example:
195
196 if ( 1 == X )
197 {
198    DoSomethingVeryImportant();
199    ...some long list of commands...
200 } /* -END- if x is 1 */
201
202 or:
203
204 if ( 1 == X )
205 {
206    DoSomethingVeryImportant();
207    ...some long list of commands...
208 } /* -END- if ( 1 == X ) */
209
210
211 @ Naming Conventions
212
213
214 @@ Variable Names
215
216 @@@ Explanation:
217
218 Use all lowercase, and seperate words via an underscore ('_').
219 Do not start an identifier with an underscore.  (ANSI C
220 reserves these for use by the compiler and system headers.)
221 Do not use identifiers which are reserved in ANSI C++.
222 (E.g. template, class, true, false, ...).  This is in case
223 we ever decide to port JunkBuster to C++.
224
225 @@@ Example:
226
227 int ms_iis5_hack = 0;
228
229 @@@ Instead of:
230
231 int msiis5hack = 0;
232 int msIis5Hack = 0;
233
234
235 @@ Function Names
236
237 @@@ Explanation:
238
239 Use all lowercase, and seperate words via an underscore ('_').
240 Do not start an identifier with an underscore.  (ANSI C
241 reserves these for use by the compiler and system headers.)
242 Do not use identifiers which are reserved in ANSI C++.
243 (E.g. template, class, true, false, ...).  This is in case
244 we ever decide to port JunkBuster to C++.
245
246 @@@ Example:
247
248 int load_some_file( struct client_state *csp )
249
250 @@@ Instead of:
251
252 int loadsomefile( struct client_state *csp )
253 int loadSomeFile( struct client_state *csp )
254
255
256 @@ Header file prototypes
257
258 @@@ Explanation:
259
260 Use a descriptive parameter name in the function prototype in
261 header files.  Use the same parameter name in the header file
262 that you use in the c file.
263
264 @@@ Example:
265
266 (.h) extern int load_aclfile( struct client_state *csp );
267 (.c) int load_aclfile( struct client_state *csp )
268
269 @@@ Instead of:
270 (.h) extern int load_aclfile( struct client_state * );   or
271 (.h) extern int load_aclfile();
272 (.c) int load_aclfile( struct client_state *csp )
273
274
275 @@  Enumerations, and #defines
276
277 @@@ Explanation:
278
279 Use all capital letters, with underscores between words.
280 Do not start an identifier with an underscore.  (ANSI C
281 reserves these for use by the compiler and system headers.)
282
283 @@@ Example:
284
285 (enumeration) : enum Boolean { FALSE, TRUE };
286 (#define) : #define DEFAULT_SIZE 100;
287
288 @@@ Note: We have a standard naming scheme for #defines that
289 toggle a feature in the preprocessor: FEATURE_xxx, where 
290 xxx is a short (preferably 1 or 2 word) description.
291
292 @@@ Example:
293
294 #define FEATURE_FORCE 1
295
296 #ifdef FEATURE_FORCE
297 #define FORCE_PREFIX blah
298 #endif /* def FEATURE_FORCE */
299
300
301 @@ Constants
302
303 @@@ Explanation:
304
305 Spell common words out entirely (do not remove vowels).
306
307 Use only widely-known domain acronyms and abbreviations.  Capitalize
308 all letters of an acronym.
309
310 Use underscore (_) to separate adjacent acronyms and
311 abbreviations.  Never terminate a name with an underscore.
312
313 @@@ Example:
314
315 #define USE_IMAGE_LIST 1
316
317 @@@ Instead of:
318
319 #define USE_IMG_LST 1       or
320 #define _USE_IMAGE_LIST 1   or
321 #define USE_IMAGE_LIST_ 1   or
322 #define use_image_list  1   or
323 #define UseImageList    1
324
325
326 @ Using Space
327
328
329 @@ Put braces on a line by themselves.
330
331 @@@ Explanation:
332
333 The brace needs to be on a line all by itself, not at the end of
334 the statement.  Curly braces should line up with the construct
335 that they're associated with.  This practice makes it easier to
336 identify the opening and closing braces for a block.
337
338 @@@ Example:
339
340 if ( this == that )
341 {
342    ...
343 }
344
345 @@@ Instead of:
346
347 if ( this == that ) {
348    ...
349 }
350
351 or
352
353 if ( this == that ) { ...  }
354
355 @@@ Note: In the special case that the if-statement is inside a loop,
356 and it is trivial, i.e. it tests for a condidtion that is obvious
357 from the purpose of the block, one-liners as above may optically
358 preserve the loop structure and make it easier to read.
359
360 @@@ Status: developer-discrection.
361
362 @@@ Example exception:
363
364 while ( more lines are read )
365 {
366    /* Please document what is/is not a comment line here */
367    if ( it's a comment ) continue;
368
369    do_something( line );
370 }
371
372
373 @@ ALL control statements should have a block
374
375 @@@ Explanation:
376
377 Using braces to make a block will make your code more readable
378 and less prone to error.  All control statements should have a
379 block defined.
380
381 @@@ Example:
382
383 if ( this == that )
384 {
385    DoSomething();
386    DoSomethingElse();
387 }
388
389 @@@ Instead of:
390
391 if ( this == that )
392    DoSomething();
393    DoSomethingElse();
394
395 or
396
397 if ( this == that ) DoSomething();
398
399 @@@ Note: The first example in "Instead of" will execute in a manner
400 other than that which the developer desired (per indentation).  Using
401 code braces would have prevented this "feature".  The "explanation"
402 and "exception" from the point above also applies.
403
404
405 @@ Do not belabor/blow-up boolean expressions
406
407 @@@ Example:
408
409 structure->flag = ( condition );
410
411 @@@ Instead of:
412
413 if ( condition )
414 {
415    structure->flag = 1;
416 }
417 else
418 {
419    structure->flag = 0;
420 }
421
422 @@@ Note: The former is readable and consice.  The later is wordy and
423 inefficient.  Please assume that any developer new to the project has
424 at least a "good" knowledge of C/C++.  (Hope I do not offend by that
425 last comment ... 8-)
426
427
428 @@ Use white space freely because it is free
429
430 @@@ Explanation:
431
432 Make it readable.  The notable exception to using white space
433 freely is listed in the next guideline.
434
435 @@@ Example:
436
437 int firstValue   = 0;
438 int someValue    = 0;
439 int anotherValue = 0;
440 int thisVariable = 0;
441
442 if ( thisVariable == thatVariable )
443
444 firstValue = oldValue + ( ( someValue - anotherValue ) - whatever )
445
446
447 @@ Don't use white space around structure operators
448
449 @@@ Explanation:
450
451 - structure pointer operator ( "->" ) 
452 - member operator ( "." )
453 - functions and parentheses
454
455 It is a general coding practice to put pointers, references, and
456 function parentheses next to names.  With spaces, the connection
457 between the object and variable/function name is not as clear.
458
459 @@@ Example:
460
461 aStruct->aMember;
462 aStruct.aMember;
463 FunctionName();
464
465 @@@ Instead of:
466 aStruct -> aMember;
467 aStruct .  aMember;
468 FunctionName ();
469
470
471 @@ Make the last brace of a function stand out
472
473 @@@ Example:
474
475 int function1( ... )
476 {
477    ...code...
478    return( retCode );
479
480 }   /* -END- function1 */
481
482
483 int function2( ... )
484 {
485 }   /* -END- function2 */
486
487
488 @@@ Instead of:
489
490 int function1( ... )
491 {
492    ...code...
493    return( retCode );
494 }
495 int function2( ... )
496 {
497 }
498
499 @@@ Note: Use 1 blank line before the closing brace and 2 lines
500 afterwards.  This makes the end of function standout to the most
501 casual viewer.  Although function comments help seperate functions,
502 this is still a good coding practice.  In fact, I follow these rules
503 when using blocks in "for", "while", "do" loops, and long if {}
504 statements too.  After all whitespace is free!
505
506 @@@ Status: developer-discrection on the number of blank lines.
507 Enforced is the end of function comments.
508
509
510 @@ Use 3 character indentions
511
512 @@@ Explanation:
513
514 If some use 8 character TABs and some use 3 character TABs, the code
515 can look *very* ragged.  So use 3 character indentions only.  If you
516 like to use TABs, pass your code through a filter such as "expand -t3"
517 before checking in your code.
518
519 @@@ Example:
520
521 static const char * const url_code_map[256] =
522 {
523    NULL, ...
524 };
525
526
527 int function1( ... )
528 {
529    if ( 1 )
530    {
531       return( ALWAYS_TRUE );
532    }
533    else
534    {
535       return( HOW_DID_YOU_GET_HERE );
536    }
537
538    return( NEVER_GETS_HERE );
539
540 }
541
542
543 @ Initializing
544
545
546 @@ Initialize all variables
547
548 @@@ Explanation:
549
550 Do not assume that the variables declared will not be used until
551 after they have been assigned a value somewhere else in the
552 code.  Remove the chance of accidentally using an unassigned
553 variable.
554
555 @@@ Example:
556
557 short anShort = 0;
558 float aFloat  = 0;
559 struct *ptr = NULL;
560
561 @@@ Note: It is much easier to debug a SIGSEGV if the message says
562 you are trying to access memory address 00000000 and not
563 129FA012; or arrayPtr[20] causes a SIGSEV vs. arrayPtr[0].
564
565 @@@ Status: developer-discrection if and only if the variable is
566 assigned a value "shortly after" declaration.
567
568
569 @ Functions
570
571
572 @@ Name functions that return a boolean as a question.
573
574 @@@ Explanation:
575
576 Value should be phrased as a question that would logically be
577 answered as a true or false statement
578
579 @@@ Example:
580
581 ShouldWeBlockThis();
582 ContainsAnImage();
583 IsWebPageBlank();
584
585
586 @@ Always specify a return type for a function.
587
588 @@@ Explanation:
589
590 The default return for a function is an int.  To avoid ambiguity,
591 create a return for a function when the return has a purpose, and
592 create a void return type if the function does not need to return
593 anything.
594
595
596 @@ Minimize function calls when iterating by using variables
597
598 @@@ Explanation:
599
600 It is easy to write the following code, and a clear argument can
601 be made that the code is easy to understand:
602
603 @@@ Example:
604
605 for ( size_t cnt = 0; cnt < blockListLength(); cnt ++ )
606 {
607    ....
608 }
609
610 @@@ Note: Unfortunately, this makes a function call for each and every
611 iteration.  This increases the overhead in the program, because the
612 compiler has to look up the function each time, call it, and return a
613 value.  Depending on what occurs in the blockListLength() call, it
614 might even be creating and destroying structures with each iteration,
615 even though in each case it is comparing "cnt" to the same value, over
616 and over.  Remember too - even a call to blockListLength() is a
617 function call, with the same overhead.
618
619 Instead of using a function call during the iterations, assign
620 the value to a variable, and evaluate using the variable.
621
622 @@@ Example:
623
624 size_t len = blockListLength();
625
626 for ( size_t cnt = 0; cnt < len; cnt ++ )
627 {
628    ....
629 }
630
631 @@@ Exceptions: if the value of blockListLength() *may* change or could
632 *potentially* change, then you must code the function call in the
633 for/while loop.
634
635
636 @@ Pass and Return by Const Reference
637
638 @@@ Explanation:
639
640 This allows a developer to define a const pointer and call your
641 function.  If your function does not have the const keyword, we
642 may not be able to use your function.  Consider strcmp, if it
643 were defined as:
644    extern int strcmp( char *s1, char *s2 );
645
646 I could then not use it to compare argv's in main:
647    int main( int argc, const char *argv[] )
648    {
649      strcmp( argv[0], "junkbusters" );
650    }
651
652 Both these pointers are *const*!  If the c runtime library maintainers
653 do it, we should too.
654
655
656 @@ Pass and Return by Value
657
658 @@@ Explanation:
659
660 Most structures cannot fit onto a normal stack entry (i.e. they
661 are not 4 bytes or less).  Aka, a function declaration like:
662    int load_aclfile( struct client_state csp )
663
664 would not work.  So, to be consistent, we should declare all
665 prototypes with "pass by value":
666    int load_aclfile( struct client_state *csp )
667
668
669 @@ Use #include <fileName> and #include "fileName" for locals
670
671 @@@ Explanation:
672
673 Your include statements should contain the file name without a
674 path.  The path should be listed in the Makefile, using -I as
675 processor directive to search the indicated paths.  An exception
676 to this would be for some proprietary software that utilizes a
677 partial path to distinguish their header files from system or
678 other header files.
679
680 @@@ Example:
681
682 #include <iostream.h>     /* This is not a local include */
683 #include "config.h"       /* This IS a local include */
684
685 @@@ Exception:
686
687 /* This is not a local include, but requires a path element. */
688 #include <sys/fileName.h>
689
690 @@@ Note: Please! do not add "-I." to the Makefile without a _very_
691 good reason.  This duplicates the #include "file.h" behaviour.
692
693
694 @@ Provide multiple inclusion protection
695
696 @@@ Explanation:
697
698 Prevents compiler and linker errors resulting from redefinition of
699 items.
700
701 Wrap each header file with the following syntax to prevent multiple
702 inclusions of the file.  Of course, replace PROJECT_H with
703 your file name, with "." Changed to "_", and make it uppercase.
704
705 @@@ Example:
706
707 #ifndef PROJECT_H_INCLUDED
708 #define PROJECT_H_INCLUDED
709  ...
710 #endif /* ndef PROJECT_H_INCLUDED */
711
712
713 @@ Use `extern "C"` when appropriate
714
715 @@@ Explanation:
716
717 If our headers are included from C++, they must declare our 
718 functions as `extern "C"`.  This has no cost in C, but increases
719 the potential re-usability of our code.
720
721 @@@ Example:
722
723 #ifdef __cplusplus
724 extern "C"
725 {
726 #endif /* def __cplusplus */
727
728 ... function definitions here ...
729
730 #ifdef __cplusplus
731 }
732 #endif /* def __cplusplus */
733
734
735 @@ Where Possible, Use Forward Struct Declaration Instead of Includes
736
737 @@@ Explanation:
738
739 Useful in headers that include pointers to other struct's.
740 Modifications to excess header files may cause needless compiles.
741
742 @@@ Example:
743
744 /*********************************************************************
745  * We're avoiding an include statement here!
746  *********************************************************************/
747 struct file_list;
748 extern file_list *xyz;
749
750 @@@ Note: If you declare "file_list xyz;" (without the pointer), then
751 including the proper header file is necessary.  If you only want to
752 prototype a pointer, however, the header file is unneccessary.
753
754 @@@ Status: Use with discrection.
755
756
757 @ General Coding Practices
758
759
760 @@ Turn on warnings
761
762 @@@ Explanation
763
764 Compiler warnings are meant to help you find bugs.  You should turn
765 on as many as possible.  With GCC, the switch is "-Wall".  Try and 
766 fix as many warnings as possible.
767
768
769 @@ Provide a default case for all switch statements
770
771 @@@ Explanation:
772
773 What you think is guaranteed is never really guaranteed.  The value
774 that you don't think you need to check is the one that someday will be
775 passed.  So, to protect yourself from the unknown, always have a
776 default step in a switch statement.
777
778 @@@ Example:
779
780 switch( hash_string( cmd ) )
781 {
782    case hash_actions_file :
783       ... code ...
784       break;
785
786    case hash_confdir :
787       ... code ...
788       break;
789
790    default :
791       log_error( ... );
792       ... anomly code goes here ...
793       continue; / break; / exit( 1 ); / etc ...
794
795 } /* end switch( hash_string( cmd ) ) */
796
797 @@@ Note: If you already have a default condition, you are obviously
798 exempt from this point.  Of note, most of the WIN32 code calls
799 `DefWindowProc' after the switch statement.  This API call
800 *should* be included in a default statement.
801
802 @@@ Another Note: This is not so much a readability issue as a robust
803 programming issue.  The "anomly code goes here" may be no more than a
804 print to the STDERR stream (as in load_config).  Or it may really be
805 an ABEND condition.
806
807 @@@ Status: Programmer discretion is advised.
808
809
810 @@ Try to avoid falling through cases in a switch statement.
811
812 @@@ Explanation:
813
814 In general, you will want to have a 'break' statement within each
815 'case' of a switch statement.  This allows for the code to be more
816 readable and understandable, and furthermore can prevent unwanted
817 surprises if someone else later gets creative and moves the code
818 around.
819
820 The language allows you to plan the fall through from one case
821 statement to another simply by omitting the break statement within the
822 case statement.  This feature does have benefits, but should only be
823 used in rare cases.  In general, use a break statement for each case
824 statement.
825
826 If you choose to allow fall through, you should comment both the fact
827 of the fall through and reason why you felt it was necessary.
828
829
830 @@ Use 'long' or 'short' Instead of 'int'
831
832 @@@ Explanation:
833
834 On 32-bit platforms, int usually has the range of long.  On 16-bit
835 platforms, int has the range of short.
836
837 @@@ Status: open-to-debate.  In the case of most FSF projects
838 (including X/GNU-Emacs), there are typedefs to int4, int8, int16, (or
839 equivalence ... I forget the exact typedefs now).  Should we add these
840 to IJB now that we have a "configure" script?
841
842
843 @@ Don't mix size_t and other types
844
845 @@@Explanation:
846
847 The type of size_t varies across platforms.  Do not make assumptions
848 about whether it is signed or unsigned, or about how long it is.
849 Do not compare a size_t against another variable of a different type
850 (or even against a constant) without casting one of the values.  
851 Try to avoid using size_t if you can.
852
853
854 @@ Declare each variable and struct on its own line.
855
856 @@@ Explanation:
857
858 It can be tempting to declare a series of variables all on one line.
859 Don't.
860
861 @@@ Example:
862
863 long a = 0;
864 long b = 0;
865 long c = 0;
866
867 @@@ Instead of:
868
869 long a, b, c;
870
871 @@@ Explanation:
872 - there is more room for comments on the individual variables
873 - easier to add new variables without messing up the original ones
874 - when searching on a variable to find its type, there is less
875   clutter to "visually" eliminate
876
877 @@@ Exceptions: when you want to declare a bunch of loop variables or
878 other trivial variables; feel free to declare them on 1 line.  You
879 should, although, provide a good comment on their functions.
880
881 @@@ Status: developer-discrection.
882
883
884 @@ Use malloc/zalloc sparingly
885
886 @@@ Explanation:
887
888 Create a local stuct (on the stack) if the variable will live
889 and die within the context of one function call.
890
891 Only "malloc" a struct (on the heap) if the variable's life will
892 extend beyond the context of one function call.
893
894 @@@ Example:
895
896 If a function creates a struct and stores a pointer to it in a
897 list, then it should definately be allocated via `malloc'.
898
899
900 @@ The Programmer Who Uses 'malloc' is Responsible for Ensuring 'free'
901
902 @@@ Explanation:
903
904 If you have to "malloc" an instance, you are responsible for insuring
905 that the instance is `free'd, even if the deallocation event falls
906 within some other programmer's code.  You are also responsible for
907 ensuring that deletion is timely (i.e. not too soon, not too late).
908 This is known as "low-coupling" and is a "good thing (tm)".  You may
909 need to offer a free/unload/destuctor type function to accomodate
910 this.
911
912 @@@ Example:
913
914 int load_re_filterfile( struct client_state *csp ) { ... }
915 static void unload_re_filterfile( void *f ) { ... }
916
917 @@@ Exceptions:
918
919 The developer cannot be expected to provide `free'ing functions for 
920 C run-time library functions ... such as `strdup'.
921
922 @@@ Status: developer-discrection.  The "main" use of this standard is
923 for allocating and freeing data structures (complex or nested).
924
925
926 @@ Add loaders to the `file_list' structure and in order
927
928 @@@ Explanation:
929
930 I have ordered all of the "blocker" file code to be in alpha
931 order.  It is easier to add/read new blockers when you expect a
932 certain order.
933
934 @@@ Note: It may appear that the alpha order is broken in places by
935 POPUP tests coming before PCRS tests.  But since POPUPs can also
936 be referred to as KILLPOPUPs, it is clear that it should come
937 first.
938
939
940 @@ "Uncertain" new code and/or changes to exitinst code, use FIXME
941
942 @@@ Explanation:
943
944 If you have enough confidence in new code or confidence in your
945 changes, but are not *quite* sure of the reprocussions, add this:
946
947 /* FIXME: this code has a logic error on platform XYZ,
948  * attempthing to fix
949  */
950 #ifdef PLATFORM
951    ...changed code here...
952 #endif
953
954 or:
955
956 /* FIXME: I think the original author really meant this... */
957    ...changed code here...
958
959 or:
960
961 /* FIXME: new code that *may* break something else... */
962    ...new code here...
963
964 @@@ Note: If you make it clear that this may or may not be a "good
965 thing (tm)", it will be easier to identify and include in the project
966 (or conversly exclude from the project).
967
968
969 @ Addendum: Template for files and function comment blocks:
970
971
972 @@@ Example for file comments:
973
974 const char FILENAME_rcs[] = "$Id: STANDARDS.txt,v 1.4 2001/07/13 01:27:19 iwanttokeepanon Exp $";
975 /*********************************************************************
976  *
977  * File        :  $S<!-- Break CVS Substitution -->ource$
978  *
979  * Purpose     :  (Fill me in with a good description!)
980  *
981  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
982  *                IJBSWA team.  http://ijbswa.sourceforge.net
983  *
984  *                Based on the Internet Junkbuster originally written
985  *                by and Copyright (C) 1997 Anonymous Coders and 
986  *                Junkbusters Corporation.  http://www.junkbusters.com
987  *
988  *                This program is free software; you can redistribute it 
989  *                and/or modify it under the terms of the GNU General
990  *                Public License as published by the Free Software
991  *                Foundation; either version 2 of the License, or (at
992  *                your option) any later version.
993  *
994  *                This program is distributed in the hope that it will
995  *                be useful, but WITHOUT ANY WARRANTY; without even the
996  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
997  *                PARTICULAR PURPOSE.  See the GNU General Public
998  *                License for more details.
999  *
1000  *                The GNU General Public License should be included with
1001  *                this file.  If not, you can view it at
1002  *                http://www.gnu.org/copyleft/gpl.html
1003  *                or write to the Free Software Foundation, Inc., 59
1004  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
1005  *
1006  * Revisions   :
1007  *    $L<!-- Break CVS Substitution -->og$
1008  *
1009  *********************************************************************/
1010 \f
1011
1012 #include "config.h"
1013
1014    ...necessary include files for us to do our work...
1015
1016 const char FILENAME_h_rcs[] = FILENAME_H_VERSION;
1017
1018
1019 @@@ Note: This declares the rcs variables that should be added to the
1020 "show-proxy-args" page.  If this is a brand new creation by you, you
1021 are free to change the "Copyright" section to represent the rights you
1022 wish to maintain.
1023
1024 @@@ Note: The formfeed character that is present right after the
1025 comment flower box is handy for (X|GNU)Emacs users to skip the verbige
1026 and get to the heart of the code (via `forward-page' and
1027 `backward-page').  Please include it if you can.
1028
1029 @@@ Example for file header comments:
1030
1031 #ifndef _FILENAME_H
1032 #define _FILENAME_H
1033 #define FILENAME_H_VERSION "$Id: STANDARDS.txt,v 1.4 2001/07/13 01:27:19 iwanttokeepanon Exp $"
1034 /*********************************************************************
1035  *
1036  * File        :  $S<!-- Break CVS Substitution -->ource$
1037  *
1038  * Purpose     :  (Fill me in with a good description!)
1039  *
1040  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
1041  *                IJBSWA team.  http://ijbswa.sourceforge.net
1042  *
1043  *                Based on the Internet Junkbuster originally written
1044  *                by and Copyright (C) 1997 Anonymous Coders and 
1045  *                Junkbusters Corporation.  http://www.junkbusters.com
1046  *
1047  *                This program is free software; you can redistribute it 
1048  *                and/or modify it under the terms of the GNU General
1049  *                Public License as published by the Free Software
1050  *                Foundation; either version 2 of the License, or (at
1051  *                your option) any later version.
1052  *
1053  *                This program is distributed in the hope that it will
1054  *                be useful, but WITHOUT ANY WARRANTY; without even the
1055  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
1056  *                PARTICULAR PURPOSE.  See the GNU General Public
1057  *                License for more details.
1058  *
1059  *                The GNU General Public License should be included with
1060  *                this file.  If not, you can view it at
1061  *                http://www.gnu.org/copyleft/gpl.html
1062  *                or write to the Free Software Foundation, Inc., 59
1063  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
1064  *
1065  * Revisions   :
1066  *    $L<!-- Break CVS Substitution -->og$
1067  *
1068  *********************************************************************/
1069 \f
1070
1071 #include "project.h"
1072
1073 #ifdef __cplusplus
1074 extern "C" {
1075 #endif
1076
1077    ... function headers here ...
1078
1079
1080 /* Revision control strings from this header and associated .c file */
1081 extern const char FILENAME_rcs[];
1082 extern const char FILENAME_h_rcs[];
1083
1084
1085 #ifdef __cplusplus
1086 } /* extern "C" */
1087 #endif
1088
1089 #endif /* ndef _FILENAME_H */
1090
1091 /*
1092   Local Variables:
1093   tab-width: 3
1094   end:
1095 */
1096
1097
1098 @@@ Example for function comments:
1099
1100 /*********************************************************************
1101  *
1102  * Function    :  FUNCTION_NAME
1103  *
1104  * Description :  (Fill me in with a good description!)
1105  *
1106  * Parameters  :
1107  *          1  :  param1 = pointer to an important thing
1108  *          2  :  x      = pointer to something else
1109  *
1110  * Returns     :  0 => Ok, everything else is an error.
1111  *
1112  *********************************************************************/
1113 int FUNCTION_NAME( void *param1, const char *x )
1114 {
1115    ...
1116    return( 0 );
1117
1118 }
1119
1120
1121 @@@ Note: If we all follow this practice, we should be able to parse
1122 our code to create a "self-documenting" web page.
1123
1124
1125 @ Local variables for this standards file
1126
1127
1128 \f
1129 Local variables:
1130 mode: outline
1131 mode: auto-fill
1132 outline-regexp: "[@]+"
1133 tab-width: 3
1134 End: