File: style_guide.txt

package info (click to toggle)
gridengine 8.1.9%2Bdfsg-13.1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 57,140 kB
  • sloc: ansic: 432,689; java: 87,068; cpp: 31,958; sh: 29,445; jsp: 7,757; perl: 6,336; xml: 5,828; makefile: 4,704; csh: 3,934; ruby: 2,221; tcl: 1,676; lisp: 669; yacc: 519; python: 503; lex: 361; javascript: 200
file content (676 lines) | stat: -rw-r--r-- 24,778 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
DRAFT of a Coding Styleguide
============================


1 Introduction
==============

   1.1 Target group
   ----------------

      Each developer providing code for SGE followes the rules of this 
      styleguide.

   1.2 Conventions
   ---------------

      Each rule in this style guide is part of one of the following categories:

      Category    Description
      ----------- -----------

      A           ABSOLUTE MUST

                  It is abolutely not allowed to break one of the rules being
                  part of this category. 
                  Only those rules are part of the A category which have
                  a direct impact on stability or security of a software
                  component.

      M           MUST

                  Each developer has to stick to such rules. A violation
                  against one of these rules has to be discussed on
                  'dev@gridengineorg.

      S           SHOULD

                  Rules of this group should only be violated with an
                  important reason.

      R           RECOMMENTATION

                  Rules part of this category are recomendations.

   1.3 Usage
   ---------
      (M)   All Grid Engine developers respect the rules defined in
            this styleguide. All new code developed conformes to this 
            styleguide.

      (R)   The Grid Engine source code base contains a high amount of code
            not yet conforming to the style guide.
            Whenever existing code pieces are changed, they are made
            conformant to the style guide.

      (M)   This styleguide will be maintained by all developers of SGE. Each
            developer can suggest the addition/modification/removal of
            rules in this styleguide. All modifications of this guide are
            discussed on 'dev@gridengine.org'.

   1.4 Version
   -----------
      
      Version  Date        Developer      Changes
      -------- ----------- -------------- ------------------------------------
      
      0.1      ?           E. Bablick     Initial version
                           J. Gabler
      0.2      11/13/2002  J. Gabler      Review. Added a cull programming rule 
                                          suggested by A. Haas.
                                          

2 C language
============

   2.1 Security
   ------------

      Buffer Overflow

         (A)   No more additional static buffers are added to the source code to
               store strings, exchange error messages, concatenate collected
               information, etc.
               Instead dynamic strings and the provided access functions are 
               used (dstring, libs/uti/sge_dstring.h).

      Memory Leaks

         (S)   If functions return strings, make the caller pass a
               dstring as parameter and use this string as buffer.
               The alternative - writing to a local buffer and returning a 
               duplicate (strdup) - often leads to memory leaks.
               As a side effect this method can show better performance, as the
               buffer can be reused for multiple calls of a function requiring 
               a buffer.
               
         (M)   If memory is allocated for use in an automatic pointer variable,
               this is done on demand (as late as possible).
               No memory is allocated for the initialization of the variable.
               Initializing with NULL in most cases is the better choice.
               Thereby memory leaks can be avoided, esp. when the function
               has multiple exit points, e.g. in error handling.
               

#if TODO
      Untrusted data

         ...
#endif
      

   2.2 Programming style
   ---------------------
      
      2.2.1 Naming Conventions
      - - - - - - - - - - - - - 

         General

         (M)   All names are build up with english words.
         
         (M)   Names are built up of letters, digits and the underscore 
               sign ('_').

         (M)   If a name consists of more than a word, all words are separated
               by an underscore sign ('_').

         (S)   The maximum length for name is 35 characters.

         (M)   All names (of datatypes, constants, functions ...) which have
               global character and which may not be associated to an object or
               a whole module begin with with the prefix "sge_" or a 
               module specific prefix.
               Examples: 
                  - cull_pack_descr() 
                  - sge_peopen()

         (M)   All names (of datatypes, constants, functions ...) that can be
               associated to an object begin with the objects name.
               Examples:
                  - job_search_task()
                  - range_parse_from_string()
                  - range_is_empty()
                  - queue_initial_state())

         (M)   Names that can be associated to lists of objects contain the 
               phrase "_list_" in between the object name and the end part of 
               the name.
               Examples:
                  - range_list_calculate_union_set()
                  - job_list_add_job()

         Object names

         (M)   Object names contain only letters and the underscore sign ('_').

         (S)   They are short.

         (M)   Following list shows some of the objects and their corresponding
               names within SGE.

               Prefix         Object
               -----------    ---------------------------
               answer         Answer object
               cal            Calendar object
               ckpt           Checkpointing object
               cmplx          Complex object
               cmplx_attr     Complex Attribute object
               ja_task        Job array task object 
               job            Job object
               pe             Parallel Environment object
               pe_task        PE task object
               queue          Queue object
               range          Id range object
               schedd_conf    Scheduler Configuration object
               var            Variable object

         Preprocessor Definitions
         
         (M)   Names interpreted by the prepocessor contain only capital letters
               and the underscore sign ('_'). 

         (M)   Names preventing the preprocessor from including header files
               twice or multiple times begin with "__" and  end with "_H".
               Example:
                  #ifndef __SGE_RANGE_H
                  #define __SGE_RANGE_H
                  ...
                  #endif /* __SGE_RANGE_H */

         Datatypes

         (M)   Type definitions contain only lower case letters and the 
               underscore sign ('_'). 

         (S)   They end with "_t".

         Constants/Enums

         (M)   Names of constants or enum values contain only capital letters 
               and the underscore sign ('_').

         Variables

         (M)   Names of variables contain only letters and the underscore sign 
               ('_').

         (S)   Global variables begin with the prefix "GLOBAL_"

         (S)   Names of global variables are expressive.

         (R)   Names of local variables are short.

#if TODO
         Functions

         ...
#endif

         Functions which might be interpreted as 'methods'

         (M)   Function pairs which primarily read or write an attribute
               of an object begin with "get_" or "set_" in its
               main name.
               Examples:
                  - var_list_get_string()
                  - var_list_set_string()

         (M)   Functions which primarily check a certain state and upon
               the state return true or false contain the phrase
               "is_" or "has_" in their name.
               Examples:
                  - job_is_array()
                  - job_has_tasks()
      
         Modules

         (M)   Filenames of modules and their corresponding headerfiles
               are be build up of lower case letters and the underscore sign 
               ('_').

         (S)   All sourcefiles have the prefix "sge_".

         (M)   The basename of a source file and its corresponding header file
               are equivalent.
               Examples:
                  - sge_job.h, sge_job.c
                  - sge_queue.h, sge_queue.c

         (M)   The extension of C source and header files is ".c" and ".h"

      2.2.2 Module Design
      - - - - - - - - - -

         (M)   Functions, global variables are declared in a header file 
               whereas the implementation part is put into a source file. 
               There are following exceptions:
                  a) Test applications can be put completely into a sourcefile.
                  b) The main() function does not need a declaration. 
                  c) Functions that will only be called locally in a module are
                     declared locally in the sourcefile.

         (S)   Structure of header files:

                  1) #ifdef - to prevent multiple interpretation of declararion
                  2) Copyright Comment
                  3) Inludes
                  4) an ADOC header that gives an introduction
                     to the modules purpose and contents
                  5) Preprocessor definitions with ADOC comments
                  6) Enum and type definitions with ADOC comments
                  7) Declaration of global variables
                  8) Declaration of functions
                  9) #endif (see 1)

         (S)   Structure of source files:

                  1) Copyright Comment
                  2) Inludes
                     a) System includes
                     b) includes of Grid Engine library modules
                     c) includes local to the component (directory)
                     d) include of message catalog headers
                     e) include of headerfile for this source file
                  3) Global ADOC comments
                  4) Private preprocessor definitions with ADOC comments
                  5) Private type definitions with ADOC comments
                  6) Private enum definitions with ADOC comments 
                  8) Definition of global variables with ADOC comment
                  7) Static (module global) variables with ADOC comment
                  8) Declaration of static functions with ADOC comment
                  9) Definition of functions, each function has an individual
                     ADOC comment
               
         Copyright Comment
      
         (M)   Each file (sourcefile, headerfile, makefile) begins
               with a copyright comment. (find an example of a copyright 
               comment in "source/libs/gdi/version.c")

         (M)   Each "Sun Microsystems" copyright comment is
               introduced by the comment "/*___INFO__MARK_BEGIN__*/" and 
               finished with following comment "/*___INFO__MARK_END__*/".

         Includes

         (S)   Headerfiles are included in the following order:

               1) System inludes
               2) 3rd party includes
               3) SGE includes (Grid Engine libraries)
               4) includes local to the component (directory)
               5) Includes of the own module

               For technical reasons the order might be different but then
               the reason has to be explained explicitely with a
               "special comment"

      2.2.3 Programming Techniques
      - - - - - - - - - - - - - - -

         Constants

         (S)   enums are used instead of defines where possible.

         (S)   typedefs are used where possible, e.g. for enums.
               This allows the compiler to do type checks, many errors
               can already be found at compile time.

         CULL objects

         (M)   CULL lists are created "on demand" (as late as possible, 
               see also the section about Memory Leaks).
               There is a set of functions that faciliates this policy:
               lSetElemStr, lSetSubStr, lSetElemUlong, ...
         
         (S)   CULL object types are defined in separate header files.
               These header fieles are named "sge_<type>L.h".
               Object type specific enums, typedefs and access functions are 
               declared in a module "sge_<type>.h", the corresponding function 
               definitions are in a source module "sge_<type>.c".
               Examples:
                  - sge_jobL.h, sge_job.h, sge_job.c
                  - sge_queueL.h, sge_queue.h, sge_queue.c

         Data types

         (R)   Data types are strictly distinguished.
               NULL is explicitly tested.
               Conditions have the type boolean.
               Examples:
                  /* "traditional" C */   |  /* preferred style */
                                          |
                  lListElem queue;        |  lListElem *queue;
                  queue = ...             |  queue = ...
                  if(!queue) {            |  if(queue == NULL) {
                     ...                  |     ...
                  }                       |  }
                                          |
                  if(!strcmp(a, b) {      |  if(strcmp(a, b) == 0) {
                     ...                  |     ...
                  }                       |  }
                                          |
               Reasons:
                  - This policy makes transitions of code to other programming 
                    languages much easier. 
                    Example: According to the c++ standard, NULL is not 
                    necessarily defined to have the value 0.
                  - Modern programming languages like Java explicitly require
                    this coding style.
                  - It makes code more readable.

         Error handling

         (M)   Library functions do not do any error output to stderr (using 
               macros like ERROR or WARNING).
               
               Functions in libuti can have a dstring as parameter that will be 
               used to return error messages. The dstring is the first parameter
               of a function.

               Functions in all libs depending on gdilib (and gdilib itself) 
               take an answer list as parameter that can be populated by the 
               function as errors or warnings occur, or to return informational 
               messages.
               For object specific functions (having a "this-pointer" as first 
               parameter, the answer list is the second parameter, else the 
               first one).
               In libs/gdi/sge_answer.h functions are declared that allow for an
               easy creation of answers.

         I18N

         (M)   All messages that can be output by Grid Engine (except debug 
               messages, DPRINTF), are defined in special header files.
               Each component (directory) has its own messages file, its name is
               built as "msg_<component>.h", e.g. "msg_utilib.h" or 
               "msg_qmaster.h".

         (S)   There is one global messages file ("common/msg_common.h"), that 
               contains general error messages like "out of memory", "cannot 
               write to file" etc., that would otherwise be duplicated for each 
               component.

         (S)   Each module only includes the common messages file and the one of
               its component (directory).

         System calls and standard C library functions
         
         (S)   For a high number of system calls and C library functions there 
               exist Grid Engine equivalents in libuti, that do additional error
               checking and hide operating system specific behaviour. 
               These functions are always prefered over the original functions.

#if TODO
         - Tabelle der bisherigen answer return werte

         Initialisation

         ? operator

         Zusammengesetze Befehle
   
         Debug Output
         - DENTER/DEXIT/Varaibleninitialisierung


         Static Buffers

         Thread safety
         - global variables
         - static variables 

         Environment Variables 

         Comments
         - auskommentierung von code

#endif

   2.3 Format
   ----------
      General
      
         (M)   Tabs are not used within source and header files.

         (M)   3 spaces are used to indent source code.

         (M)   Lines have to be wrapped after the 79th character.

         (R)   The script "gridengine/source/scripts/format.sh" is used to 
               format the C source code automatically. 
               Automated sourcecode reformating can be disabled for short code 
               pieces with the comment "/* *INDENT-OFF* */".  
               "/* *INDENT-ON* */" reenables the format mechanism.

      Preprocessor elements
        
         Here are some examples:
 
            #if SOLARIS64
            #  include <sys/some_special_header.h>
            #endif

            #define SGE_MIN_USAGE 1.0
      
            #define REF_SET_TYPE(ref, cull_attr, ref_attr, value, function) \
            { \
               if ((ref)->ja_task) { \
                  (function)((ref)->ja_task, cull_attr, (value)); \
               } else { \
                  (ref_attr) = (value); \
               } \
            } 

         (M)   "#" of a preprocessor tag is put in column 0 (ANSI C).
               The keyword of the tag is indented.

         (M)   Constant names and their value are put into one line.

         (M)   Macro definitions are formatted similar to function definitions.  

      Functions

         Functions have following format:

            static int 
            queue_weakclean(lListElem *qep, lList **answer, 
                            u_long32 force, char *user,
                            char *host, int isoperator, 
                            int isowner) 
            { 
               ...
            }

         (M)   Functions start with qualifier and return type. 

         (M)   There is no space between the function name and the 
               open paraentheses.

         (M)   If the arguments do not fit into one line, the arguments are 
               continued in a new line under the first argument of the previous 
               line.

         (M)   Functions which do not accept parameters contain the keyword 
               "void" in its declatation and definition.

         (M)   The brace in the function definition, is in column zero again. 
               Statements inside the function body are idented like statements 
               inside a compound statement. 

      Statements
   
         Statements have following format:

            for (i = 0; i < MAX; i++) {
               while (1) {
                  do {
                     if (i == 1) {
                        switch (i) {
                        case 1, 2:
                           ...
                           break;
                        case 3:
                           ...
                           break;
                        default:
                           ...
                        }
                     } else if (i == -5) {
                        ...
                     } else {
                        only_one_function_call();
                     }
                  } while (!found);
               }
            }

         (M)   In contrast to functions, the opening left brace of a
               compound statement is at the end of the line beginning
               the compound statement and the closing right brace stands
               alone on a line.

         (M)   There is one space between the keyword and the open
               parentheses. 

         (M)   Braces are in the same line as the keywords.

         (S)   All blocks are enclosed in braces, even if the block only 
               consists of a single line.

         (M)   Function calls do not contain spaces between the function 
               name and the parentheses. 

         (S)   The format of a function prototype is equivalent with
               the function definition.
 
      Declarations

         Declarartions have following format:

            static int sge_set_ls_fds(lListElem *this_ls, fd_set *fds)
            {
               int i, k, l;
               int ret = -1;                               /* return value */
               int name[3] = { LS_out, LS_in, LS_err };
               FILE *file = NULL;                          /* load sensor fd */
   
               first_statement();
               ...

         (M)   Multiple variables of same type are declared in one line. 

         (M)   Each pre-initialized variable has its own line. 

         (M)   The asterik of a pointer declaration is part of the 
               variable name. 

         (M)   One space is put in between the type name and the asterisk of
               a pointer declaration.

         (M)   Function parameters are commented in the functions ADOC comment.

         (R)   Local variable declarations are commented at the end of the 
               declaration. 
           
         (R)   Variable declarations are done as local as possible.
               Example:
                  lListElem *queue;                      /* local in function */

                  for_each(queue, Master_Queue_List) {
                     const char *queue_name;             /* local in block */

                     queue_name = lGetString(QU_qname);
                     ...
                  }   

      Comments

         (M)   Comments are inserted in front of the code block which they 
               describe or behind the code but starting in the same line.
               Example:
                  /* 
                   * comment for the following compound element
                   */
                  {
                     int name;      /* description of name */
                     char *pattern; /*
                                     * more detailed description of 
                                     * the variable pattern.
                                     */
                  }
         
         (M)   Line comments like this: /* line comment */

         (M)   Block comments look like this:

               /*
                * block comment block comment block comment
                * block comment block comment block comment
                */

         Special Comments
            
            (M)   Special comments are used within the sourcecode
                  to mark certain code sections. 

                  SpecialComment := "/*" Initials ":" Keyword 
                                    [ " (" IssueNumber ")" ] ":"
                                    Text "*/" .

                  Initials := '2 character initials, same as in Changelog' .
         
                  Keyword := "TODO" | "DEBUG" .

                  IssueNumber := 'Issuezilla id'

                  Text := 'Descriptional text'.

                  Examples:
                     - during the development phase of a certain feature, 
                       one might want to mark tasks still to be finished:
                           /* JG: TODO: improve error handling */
                     - during development a code section is detected, that can
                       cause problems or can be improved, but the change has 
                       nothing to do with the current development and the change
                       and esp. testing is non trivial: 
                           /* JG: TODO: args should be dynamically allocated */
                     - a bug or enhancement request is filed in issuezilla and
                       the corresponding code section shall be marked for later 
                       use:
                           /* JG: TODO (254): use function creating path */
   
         ADOC Comments 

            (M)   ADOC comments are used to describe language elements.
                  These type of comments are extracted from the sourcecode
                  using the adoc tool to generate pdf/html/GNU Info ...
                  documentation.
                  "doc/devel/adoc.html" describes more details about ADOC tool
                  and the format of ADOC comments to be used. 

3 Software Development
======================

   3.1 Process
   -----------

#if TODO
      IssueZilla
      Review
      Quality Assurance
      Test suite
      use dbx and/or insure
      ...
#endif