-
Notifications
You must be signed in to change notification settings - Fork 97
/
codestyl.txt
197 lines (149 loc) · 7.6 KB
/
codestyl.txt
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
/* Please note the following comments we may use everywhere
NOTE: Notes
TODO: something should be added here
FIXME: something needs to be fixed
OBSOLETE: something could be removed from here
QUESTION: I had some questions at this point but I could not get an answer
OPT: something is commented out to improve performance
As an example: */
Harbour Coding Standards
========================
(based heavily on coding standards placed in PHP)
NOTE: For the best demonstration of Harbour coding style,
please refer to real .c and .prg code inside /src
and /include. Real-life style always overrides this
doc if there are doubts.
Code Implementation
-------------------
[0] Document your code in source files and the manual. [tm]
[1] Functions that are given pointers to resources should not free them
For instance, function int mail(char *to, char *from) should NOT free
to and/or from.
Exceptions:
- The function's designated behavior is freeing that resource.
E.g. hb_xfree()
- The function is given a boolean argument, that controls whether or not
the function may free its arguments (if true - the function must free its
arguments, if false - it must not)
[2] Functions that are tightly integrated with other functions within the
same module, and rely on each other non-trivial behavior, should be
documented as such and declared 'static'. They should be avoided if
possible.
[3] Use definitions and macros whenever possible, so that constants have
meaningful names and can be easily manipulated.
Use HB_TRUE instead of 1 (in boolean context)
Use HB_FALSE instead of 0 (in boolean context)
Use NULL instead of 0 (in pointer context)
Always use 'HB_' prefix for definitions of new datatypes and macros.
Use either 'PHB_' prefix for datatypes that are pointers.
e.g.
HB_ITEM
PHB_ITEM
[4] When writing functions that deal with strings, be sure to remember
that Harbour holds the length property of each string, and that it
shouldn't be calculated with strlen(). Write your functions in a such
a way so that they'll take advantage of the length property, both
for efficiency and in order for them to be binary-safe.
Functions that change strings and obtain their new lengths while
doing so, should return that new length, so it doesn't have to be
recalculated with strlen()
[5] NEVER USE strncat(). If you're absolutely sure you know what you're doing,
check its man page again, and only then, consider using it, and even then,
try avoiding it.
[6] Use assert(). Not only does good assertion catch bugs, but it also
helps with code readability.
- Do not use assert for error handling. Use assert only for the
condition that must be always true.
- Do not use assignments in assert conditions. If you assign inside an
assert condition, you risk an elusive bug that would be very difficult
to spot in a debug build, due to the side effect of the assignment.
Function calls in assert conditions may also cause this problem, if
they modify one of their arguments or global variables.
[7] Use hb_xgrab()/hb_xalloc(), hb_xfree(), hb_xrealloc(), hb_xsize() to
manage memory allocations. These functions implement an internal
"safety-net" mechanism that ensures the deallocation of any unfreed
memory at the end of an application. They also provide useful
allocation and overflow information while running in debug mode.
Naming Conventions
------------------
[1] Function names for user-level functions defined in C code should be
enclosed with in the HB_FUNC() macro. They should be in uppercase.
The name should be prefixed with 'HB_' if this function is an
extension to functions set defined in Clipper
Abbreviations should not be used when they greatly decrease the
readability of the function name itself.
[2] Variable names must be meaningful. One letter variable names must be
avoided, except for places where the variable has no real meaning or
a trivial meaning (e.g. for (i=0; i<100; i++) ...).
[3] Variable names should use so-called Hungarian notation. Use lowercase
letters however use underscores to separate between words.
Good:
pMemoryPtr
Bad:
p_memory_ptr
[4] Static variables should be prefixed with 's_'
[5] Global variables (variables shared between modules) should be
prefixed with 'hb_<module_prefix>', e.g. hb_vm_bDebug, hb_gc_pStart
Syntax and indentation
----------------------
[1] Never use C++ style comments (i.e. // comment). Always use C-style
comments instead. Harbour is written in C, and is aimed at compiling
under any ANSI-C compliant compiler. Even though many compilers
accept C++-style comments in C code, you have to ensure that your
code would compile with other compilers as well.
[2] Do not use K&R-style. Of course, we cannot and do not want to
force anybody to use a style he or she is not used to, but,
at the very least, when you write code that goes into the core
of Harbour or one of its standard modules, please don't use the K&R
style. This applies to just about everything, starting with
indentation and comment styles and up to function declaration
syntax.
(see also http://www.catb.org/~esr/jargon/html/I/indent-style.html)
[3] Be generous with whitespace and braces. Always prefer:
if( foo )
{
bar;
}
to:
if(foo)bar;
and to:
if( foo ){
bar;
}
Keep one empty line between the variable declaration section and
the statements in a block, as well as between logical statement
groups in a block. Maintain at least one empty line between
two functions.
[4] When indenting, use three spaces. It is important to maintain
consistency in indenture so that definitions, comments, and
control structures line up correctly.
Documentation
--------------
[1] Whenever be possible document yourself functions you developed.
Usually it's hard to understand code written by other person, moreover
when it involves some obscure algorithm, system's vars or attributes
or data unavailable for the documentation writers.
This is particularly evident for low-level functions.
[2] After some time function was written, work becomes more difficult because
it's needed to read the code several times (even for the own developer).
This is evident when variables don't have useful names (and uses only
letters).
Because that, please DO NOT leave functions without documentation.
[3] If function made calls to other non-documented functions, and the
original developer are not available anymore, could be so hard and even
impossible to document it.
[4] Tracking which functions are documented and which are not, and if they
are total or partially documented are a waste of resources in time and
people.
[5] If you are the developer of the function don't worry by your narrative
skills, concentrate in what functions do, which arguments it gets,
which are its purpose and specially what information function returns.
[6] If you are the developer of the function, and you are using system's
functions or vars undocumented, please explain it as much as possible.
If you use a obscure or strange algorithm please explain what it does
and how it works.
[7] Notes, remarks and explaining enclose always between the /* */ pair,
please don't use the double bar // because it may break portability.
[8] Remember... documentation it's a much time consuming work, usually
takes more time writing the documentation of a function that writing
the function itself.