1
DRAFT of a Coding Styleguide
2
============================
11
Each developer providing code for SGE followes the rules of this
17
Each rule in this style guide is part of one of the following categories:
20
----------- -----------
24
It is abolutely not allowed to break one of the rules being
25
part of this category.
26
Only those rules are part of the A category which have
27
a direct impact on stability or security of a software
32
Each developer has to stick to such rules. A violation
33
against one of these rules has to be discussed on
34
'dev@gridengine.sunsource.net'.
38
Rules of this group should only be violated with an
43
Rules part of this category are recomendations.
47
(M) All Grid Engine developers respect the rules defined in
48
this styleguide. All new code developed conformes to this
51
(R) The Grid Engine source code base contains a high amount of code
52
not yet conforming to the style guide.
53
Whenever existing code pieces are changed, they are made
54
conformant to the style guide.
56
(M) This styleguide will be maintained by all developers of SGE. Each
57
developer can suggest the addition/modification/removal of
58
rules in this styleguide. All modifications of this guide are
59
discussed on 'dev@gridengine.sunsource.net'.
64
Version Date Developer Changes
65
-------- ----------- -------------- ------------------------------------
67
0.1 ? E. Bablick Initial version
69
0.2 11/13/2002 J. Gabler Review. Added a cull programming rule
81
(A) No more additional static buffers are added to the source code to
82
store strings, exchange error messages, concatenate collected
84
Instead dynamic strings and the provided access functions are
85
used (dstring, libs/uti/sge_dstring.h).
89
(S) If functions return strings, make the caller pass a
90
dstring as parameter and use this string as buffer.
91
The alternative - writing to a local buffer and returning a
92
duplicate (strdup) - often leads to memory leaks.
93
As a side effect this method can show better performance, as the
94
buffer can be reused for multiple calls of a function requiring
97
(M) If memory is allocated for use in an automatic pointer variable,
98
this is done on demand (as late as possible).
99
No memory is allocated for the initialization of the variable.
100
Initializing with NULL in most cases is the better choice.
101
Thereby memory leaks can be avoided, esp. when the function
102
has multiple exit points, e.g. in error handling.
112
2.2 Programming style
113
---------------------
115
2.2.1 Naming Conventions
116
- - - - - - - - - - - - -
120
(M) All names are build up with english words.
122
(M) Names are built up of letters, digits and the underscore
125
(M) If a name consists of more than a word, all words are separated
126
by an underscore sign ('_').
128
(S) The maximum length for name is 35 characters.
130
(M) All names (of datatypes, constants, functions ...) which have
131
global character and which may not be associated to an object or
132
a whole module begin with with the prefix "sge_" or a
133
module specific prefix.
138
(M) All names (of datatypes, constants, functions ...) that can be
139
associated to an object begin with the objects name.
142
- range_parse_from_string()
144
- queue_initial_state())
146
(M) Names that can be associated to lists of objects contain the
147
phrase "_list_" in between the object name and the end part of
150
- range_list_calculate_union_set()
155
(M) Object names contain only letters and the underscore sign ('_').
159
(M) Following list shows some of the objects and their corresponding
163
----------- ---------------------------
166
ckpt Checkpointing object
168
cmplx_attr Complex Attribute object
169
ja_task Job array task object
171
pe Parallel Environment object
172
pe_task PE task object
174
range Id range object
175
schedd_conf Scheduler Configuration object
178
Preprocessor Definitions
180
(M) Names interpreted by the prepocessor contain only capital letters
181
and the underscore sign ('_').
183
(M) Names preventing the preprocessor from including header files
184
twice or multiple times begin with "__" and end with "_H".
186
#ifndef __SGE_RANGE_H
187
#define __SGE_RANGE_H
189
#endif /* __SGE_RANGE_H */
193
(M) Type definitions contain only lower case letters and the
194
underscore sign ('_').
196
(S) They end with "_t".
200
(M) Names of constants or enum values contain only capital letters
201
and the underscore sign ('_').
205
(M) Names of variables contain only letters and the underscore sign
208
(S) Global variables begin with the prefix "GLOBAL_"
210
(S) Names of global variables are expressive.
212
(R) Names of local variables are short.
220
Functions which might be interpreted as 'methods'
222
(M) Function pairs which primarily read or write an attribute
223
of an object begin with "get_" or "set_" in its
226
- var_list_get_string()
227
- var_list_set_string()
229
(M) Functions which primarily check a certain state and upon
230
the state return true or false contain the phrase
231
"is_" or "has_" in their name.
238
(M) Filenames of modules and their corresponding headerfiles
239
are be build up of lower case letters and the underscore sign
242
(S) All sourcefiles have the prefix "sge_".
244
(M) The basename of a source file and its corresponding header file
247
- sge_job.h, sge_job.c
248
- sge_queue.h, sge_queue.c
250
(M) The extension of C source and header files is ".c" and ".h"
255
(M) Functions, global variables are declared in a header file
256
whereas the implementation part is put into a source file.
257
There are following exceptions:
258
a) Test applications can be put completely into a sourcefile.
259
b) The main() function does not need a declaration.
260
c) Functions that will only be called locally in a module are
261
declared locally in the sourcefile.
263
(S) Structure of header files:
265
1) #ifdef - to prevent multiple interpretation of declararion
268
4) an ADOC header that gives an introduction
269
to the modules purpose and contents
270
5) Preprocessor definitions with ADOC comments
271
6) Enum and type definitions with ADOC comments
272
7) Declaration of global variables
273
8) Declaration of functions
276
(S) Structure of source files:
281
b) includes of Grid Engine library modules
282
c) includes local to the component (directory)
283
d) include of message catalog headers
284
e) include of headerfile for this source file
285
3) Global ADOC comments
286
4) Private preprocessor definitions with ADOC comments
287
5) Private type definitions with ADOC comments
288
6) Private enum definitions with ADOC comments
289
8) Definition of global variables with ADOC comment
290
7) Static (module global) variables with ADOC comment
291
8) Declaration of static functions with ADOC comment
292
9) Definition of functions, each function has an individual
297
(M) Each file (sourcefile, headerfile, makefile) begins
298
with a copyright comment. (find an example of a copyright
299
comment in "source/libs/gdi/version.c")
301
(M) Each "Sun Microsystems" copyright comment is
302
introduced by the comment "/*___INFO__MARK_BEGIN__*/" and
303
finished with following comment "/*___INFO__MARK_END__*/".
307
(S) Headerfiles are included in the following order:
310
2) 3rd party includes
311
3) SGE includes (Grid Engine libraries)
312
4) includes local to the component (directory)
313
5) Includes of the own module
315
For technical reasons the order might be different but then
316
the reason has to be explained explicitely with a
319
2.2.3 Programming Techniques
320
- - - - - - - - - - - - - - -
324
(S) enums are used instead of defines where possible.
326
(S) typedefs are used where possible, e.g. for enums.
327
This allows the compiler to do type checks, many errors
328
can already be found at compile time.
332
(M) CULL lists are created "on demand" (as late as possible,
333
see also the section about Memory Leaks).
334
There is a set of functions that faciliates this policy:
335
lSetElemStr, lSetSubStr, lSetElemUlong, ...
337
(S) CULL object types are defined in separate header files.
338
These header fieles are named "sge_<type>L.h".
339
Object type specific enums, typedefs and access functions are
340
declared in a module "sge_<type>.h", the corresponding function
341
definitions are in a source module "sge_<type>.c".
343
- sge_jobL.h, sge_job.h, sge_job.c
344
- sge_queueL.h, sge_queue.h, sge_queue.c
348
(R) Data types are strictly distinguished.
349
NULL is explicitly tested.
350
Conditions have the type boolean.
352
/* "traditional" C */ | /* preferred style */
354
lListElem queue; | lListElem *queue;
355
queue = ... | queue = ...
356
if(!queue) { | if(queue == NULL) {
360
if(!strcmp(a, b) { | if(strcmp(a, b) == 0) {
365
- This policy makes transitions of code to other programming
366
languages much easier.
367
Example: According to the c++ standard, NULL is not
368
necessarily defined to have the value 0.
369
- Modern programming languages like Java explicitly require
371
- It makes code more readable.
375
(M) Library functions do not do any error output to stderr (using
376
macros like ERROR or WARNING).
378
Functions in libuti can have a dstring as parameter that will be
379
used to return error messages. The dstring is the first parameter
382
Functions in all libs depending on gdilib (and gdilib itself)
383
take an answer list as parameter that can be populated by the
384
function as errors or warnings occur, or to return informational
386
For object specific functions (having a "this-pointer" as first
387
parameter, the answer list is the second parameter, else the
389
In libs/gdi/sge_answer.h functions are declared that allow for an
390
easy creation of answers.
394
(M) All messages that can be output by Grid Engine (except debug
395
messages, DPRINTF), are defined in special header files.
396
Each component (directory) has its own messages file, its name is
397
built as "msg_<component>.h", e.g. "msg_utilib.h" or
400
(S) There is one global messages file ("common/msg_common.h"), that
401
contains general error messages like "out of memory", "cannot
402
write to file" etc., that would otherwise be duplicated for each
405
(S) Each module only includes the common messages file and the one of
406
its component (directory).
408
System calls and standard C library functions
410
(S) For a high number of system calls and C library functions there
411
exist Grid Engine equivalents in libuti, that do additional error
412
checking and hide operating system specific behaviour.
413
These functions are always prefered over the original functions.
416
- Tabelle der bisherigen answer return werte
422
Zusammengesetze Befehle
425
- DENTER/DEXIT/Varaibleninitialisierung
434
Environment Variables
437
- auskommentierung von code
445
(M) Tabs are not used within source and header files.
447
(M) 3 spaces are used to indent source code.
449
(M) Lines have to be wrapped after the 79th character.
451
(R) The script "gridengine/source/scripts/format.sh" is used to
452
format the C source code automatically.
453
Automated sourcecode reformating can be disabled for short code
454
pieces with the comment "/* *INDENT-OFF* */".
455
"/* *INDENT-ON* */" reenables the format mechanism.
457
Preprocessor elements
459
Here are some examples:
462
# include <sys/some_special_header.h>
465
#define SGE_MIN_USAGE 1.0
467
#define REF_SET_TYPE(ref, cull_attr, ref_attr, value, function) \
469
if ((ref)->ja_task) { \
470
(function)((ref)->ja_task, cull_attr, (value)); \
472
(ref_attr) = (value); \
476
(M) "#" of a preprocessor tag is put in column 0 (ANSI C).
477
The keyword of the tag is indented.
479
(M) Constant names and their value are put into one line.
481
(M) Macro definitions are formatted similar to function definitions.
485
Functions have following format:
488
queue_weakclean(lListElem *qep, lList **answer,
489
u_long32 force, char *user,
490
char *host, int isoperator,
496
(M) Functions start with qualifier and return type.
498
(M) There is no space between the function name and the
501
(M) If the arguments do not fit into one line, the arguments are
502
continued in a new line under the first argument of the previous
505
(M) Functions which do not accept parameters contain the keyword
506
"void" in its declatation and definition.
508
(M) The brace in the function definition, is in column zero again.
509
Statements inside the function body are idented like statements
510
inside a compound statement.
514
Statements have following format:
516
for (i = 0; i < MAX; i++) {
530
} else if (i == -5) {
533
only_one_function_call();
539
(M) In contrast to functions, the opening left brace of a
540
compound statement is at the end of the line beginning
541
the compound statement and the closing right brace stands
544
(M) There is one space between the keyword and the open
547
(M) Braces are in the same line as the keywords.
549
(S) All blocks are enclosed in braces, even if the block only
550
consists of a single line.
552
(M) Function calls do not contain spaces between the function
553
name and the parentheses.
555
(S) The format of a function prototype is equivalent with
556
the function definition.
560
Declarartions have following format:
562
static int sge_set_ls_fds(lListElem *this_ls, fd_set *fds)
565
int ret = -1; /* return value */
566
int name[3] = { LS_out, LS_in, LS_err };
567
FILE *file = NULL; /* load sensor fd */
572
(M) Multiple variables of same type are declared in one line.
574
(M) Each pre-initialized variable has its own line.
576
(M) The asterik of a pointer declaration is part of the
579
(M) One space is put in between the type name and the asterisk of
580
a pointer declaration.
582
(M) Function parameters are commented in the functions ADOC comment.
584
(R) Local variable declarations are commented at the end of the
587
(R) Variable declarations are done as local as possible.
589
lListElem *queue; /* local in function */
591
for_each(queue, Master_Queue_List) {
592
const char *queue_name; /* local in block */
594
queue_name = lGetString(QU_qname);
600
(M) Comments are inserted in front of the code block which they
601
describe or behind the code but starting in the same line.
604
* comment for the following compound element
607
int name; /* description of name */
609
* more detailed description of
610
* the variable pattern.
614
(M) Line comments like this: /* line comment */
616
(M) Block comments look like this:
619
* block comment block comment block comment
620
* block comment block comment block comment
625
(M) Special comments are used within the sourcecode
626
to mark certain code sections.
628
SpecialComment := "/*" Initials ":" Keyword
629
[ " (" IssueNumber ")" ] ":"
632
Initials := '2 character initials, same as in Changelog' .
634
Keyword := "TODO" | "DEBUG" .
636
IssueNumber := 'Issuezilla id'
638
Text := 'Descriptional text'.
641
- during the development phase of a certain feature,
642
one might want to mark tasks still to be finished:
643
/* JG: TODO: improve error handling */
644
- during development a code section is detected, that can
645
cause problems or can be improved, but the change has
646
nothing to do with the current development and the change
647
and esp. testing is non trivial:
648
/* JG: TODO: args should be dynamically allocated */
649
- a bug or enhancement request is filed in issuezilla and
650
the corresponding code section shall be marked for later
652
/* JG: TODO (254): use function creating path */
656
(M) ADOC comments are used to describe language elements.
657
These type of comments are extracted from the sourcecode
658
using the adoc tool to generate pdf/html/GNU Info ...
660
"doc/devel/adoc.html" describes more details about ADOC tool
661
and the format of ADOC comments to be used.
663
3 Software Development
664
======================
674
use dbx and/or insure