/usr/bin/gnuplot symlinks packageing problems were fixed gor gnuplot-x11
[gnuplot] / CodeStyle
1 $Id: CodeStyle,v 1.9 2001/02/01 17:56:04 broeker Exp $
2
3 The following things have be observed when writing new code for gnuplot:
4 (this file is currently under construction)  Some of the following is
5 just personal bug-bears, so dont take any offense if something I
6 moan about is something you think is good style...
7
8 These rules were originally written up by David Denholm, and I keep
9 updating them as I go along. -Lars
10
11
12 MISSING FUNCTIONS, AND FUNCTIONS TO BE AVOIDED
13 ----------------------------------------------
14 The following functions may not be used, since they are not present on all
15 systems (though the substitute functions might be defined to exactly these
16 functions)
17
18 function        use instead
19
20 bcopy           memcpy
21 bzero           memset
22 index           strchr
23 rindex          strrchr
24 strncasecmp     strnicmp
25
26
27
28   The number of macros for conditional compilation is getting a little
29 extreme!  I (personally) think it's better to make the conditionally-compiled
30 code 'feature-based' rather than 'compiler-based'. I think this is particularly
31 true for the many DOS compilers. The sort of thing I am thinking of is,
32 for example, whether to disable hidden3d stuff, or whether to store
33 data points as float rather than double to save space. Rather than having
34 a long list of compilers or OS's which use one or the other, add macros
35 such as SMALLMEMORY or NOHIDDENSTUFF and define these in the makefiles.
36  Perhaps a sensible guideline for choice of such macros is to arrange
37 things so that the smallest number of ports are affected. For example,
38 if we only compiled the hidden stuff if HIDDENSTUFF was defined, most
39 makefiles would have to be updated. But if instead it is being disabled
40 for a few machines, only those makefiles have to explicitly define
41 NOHIDDENSTUFF.
42
43   Perhaps a good guideline would be that gnuplot should build cleanly
44 with most available features if no macros are defined on an ANSI C compiler
45 on a 'typical' (POSIX, say) unix machine.
46
47   For example, I myself have broken this rule by requiring the macro
48 HAVE_LOCALE in order to support setlocale() - this feature is available
49 with ANSI compilers, and so setlocale() calls should be enabled by default,
50 and disabled only if NO_LOCALE is defined at compile time. Does this
51 sound reasonable?  For example, there was some code in fit.c that would
52 prefer to use tempnam() if it is available, but falls back to ANSI fn
53 tmpnam() if necessary. The way it was done, tempnam() was the default,
54 and there was a list of those systems that had to use tmpnam().
55 But the trouble was that a new one had to be added to the list every
56 few weeks as new machines were discovered. The current scheme is
57 that tmpnam() is used unless feature HAVE_TEMPNAM is enabled.
58
59
60
61 On a related note... if one particular machine does doesn't provide
62 a standard-ish function, but the same functionality can be
63 acheived, it would be preferable to implement the standardish
64 function in a os-specific source file, so that the core code can
65 simply invoke the function without any conditionals, and the OS-specific
66 files provide the missing functions. For example, in fit.c (at the
67 time of writing) where a temporary file is needed, there is some
68 inline code for DOS, OS2, AMIGA, etc to create temporary files,
69 otherwise tempnam() is used. I think I'd rather have tempnam()
70 implemented as a function in dos.c for example, then the fit code
71 would not need to have any conditional code other than HAVE_TEMPNAM
72
73
74
75 Also, think generic where possible... I once noticed that popen()
76 had been implemented for atari or similar using temporary files
77 and system() call. It seems to me that this could easily be done
78 as a generic solution, so that DOS ports, for example, could also
79 benefit.
80
81
82
83
84 FUNCTION PROTOTYPES
85 -------------------
86
87 Function prototypes are mandatory, even for local functions that are
88 declared before use. This is necessary for a clean compile on
89 some machines.  gcc -Wstrict-prototypes  is recommended.
90 However, to make the code compilable on pre-ANSI style compilers,
91 prototypes have to be enclosed in a special macro, e.g.
92
93 int strcmp __PROTO((char *s, char *t)); /* note the double ()'s */
94
95 Probably from gnuplot release 3.7.1 on, I will require that
96 all function declarations and definitions are in ANSI style.
97 I see absolutely no point at all in ignoring the benefits of
98 ANSI compilers, almost ten years after this language became
99 an ISO standard.
100
101 int
102 strcmp(char *s, char *t)
103 {
104   ...
105 }
106
107 On platforms which use the included configure script, the ansi2knr
108 tool in the src subdirectory is invoked transparently if the compiler
109 doesn't support prototypes (Ultrix, SunOS 4.x). Other platforms may
110 require explicit rules or additional makefiles for non-ANSI/ANSI
111 compilation. The man page for ansi2knr is included. Note that for
112 ansi2knr to work, the function return type must be on a separate line,
113 or, to quote from the ansi2knr manual, "ansi2knr recognizes functions
114 by seeing a non-keyword  identifier at the left margin, followed by a
115 left parenthesis, with a right parenthesis as the last character on
116 the line."
117
118
119
120 While compilers do not require that explicit declarations be
121 given for integer arguments, we do !
122
123
124 While ANSI compilers can use prototypes for implicit typecasts, k&r
125 compilers do not have this information. Avoid relying on implicit
126 conversions of function parameters.  gcc -Wconversion helps with this.
127 There are many signed/unsigned warnings, but look out for other
128 ones which may be more serious, in particular integer to float and
129 vice versa. Placing casts is necessary in this case for correct
130 code on non-ansi compilers.
131
132 [we will definitely give up k&r support in the near future, but
133  since existing code seems to work with k&r, we're sticking
134  with it for the time being.
135 ]
136
137
138
139
140 INTEGER SIZE
141 ------------
142
143 Large integer constant expression have to be explicitly cast to long, even
144 if the result is assigned to a long variable.
145
146 long t=60*60*24;
147 results in a overflow on 16 bit compilers, even though the result fits into
148 the long variable.
149
150 Correct: long t=60l*60l*24l;
151
152
153
154 Similarly, though not particularly important, ANSI and k&r compilers
155 treat integer constants > MAX_INT differently. If you mean an
156 unsigned integer constant, say so.
157
158
159
160
161 Please avoid duplicating large sections of code - make the effort
162 to make a function or macro out of the common code.
163
164
165 min(a,b), max(a,b), MIN(a,b), MAX(a,b) are all predefined by some
166 compilers. I am now using GPMIN() and GPMAX()  [wot a pain !]
167
168
169 Avoid putting directories into #includes - eg  #include "term/file.h"
170 is to be avoided. Instead, #include "file.h"  and use -Iterm on the
171 compile line.
172
173
174 coordval is typedef-ed to either double or float - it is almost always
175 double, but please take care not to mix coordval's with doubles.
176
177
178 An important rule unknown to many, it seems: *never* pass a 'char' to
179 any of the <ctype.h> functions, as-is. Don't cast it to (int), either
180 --- that would happen automatically, anyway. You *must* cast to
181 (unsigned char), instead. Otherwise, there'll quite likely be crashes
182 with 8-bit characters on systems where 'char' is signed.
183
184
185 LAYOUT AND INDENTATION
186 ----------------------
187
188  The code layout is getting into a bit of a mess, due to mixed
189 conventions. IMHO the only useful style is one tab stop per
190 indent. This way, anyone can set their editor to display
191 with their preferred spacing. More importantly, one has to
192 delete only one tab to outdent once more : this makes it so much
193 easier to ensure alignment even if the opening brace is
194 off the top of the screen.
195   Much of the code seems to assume tab=8, and uses 4 spaces,
196 then one tab, then tab+4, then 2tab, ...  On an entirely
197 personal note, this breaks my folding editor :-(
198
199  I think vi does this by default. If using vi, please try
200 putting   set ts=4  into your ~/.exrc file.
201
202
203   Unfortunately, gnu indent does not seem to recognise this
204 as a layout style. If it did, I'd have run all sources
205 through it long ago. [GNU indent -kr -cp0 -l132 -lps -br -psl
206 is what I use. Very little manual editing is necessary after
207 running this, mostly for long (> 80 cols) lines. Anyway,
208 I don't care which indentation style _you_ use, I'm running
209 all code through indent and be done with it. -Lars]
210
211
212
213 Please use lots of vertical whitespace between unrelated
214 blocks of code in functions. And it should not be need to
215 be said, but I'll say it anyway... please put in lots of
216 comments describing blocks of code. Many people maintain and
217 contribute to this code.
218
219
220   The functions in plot?d.c and graph*.c are sometimes very long.
221 This isn't really a problem, since there's a lot of semi-independent
222 things to be done in sequence. However, I do object to the
223 practise of having all variables declared at the top of
224 such functions. Please keep the scope of temporary variables
225 as local as possible, particularly in these long functions.
226 The main reason is for ease of maintenance : many people
227 make modifications to small parts of code without fully
228 understanding in exacting detail the surrounding code.
229
230
231 In case you were wondering, lines of the form /*{{{  comment */ 
232 and /*}}}*/  are markers left by my folding editor when I am forced
233 to fold up particularly long functions when trying to understand the
234 logic. I tend to leave these markers in when I finally figure it out,
235 though perhaps I should not.
236
237
238 Source code is intended to be read and maintained by humans. As such,
239 readability is prefered over elegance. Please separate all operators
240 from operands with a space, ie. instead of x+=3, use x += 3. The former
241 is not only less readable, it may also break older compilers! This rule
242 should also be followed for simple assignments, ie. in for (;;) loops.
243 Unary operators should be writen as usual, ie i++.
244
245
246 No C++ style comments (//).
247 No trailing comments on #ifdef/#ifndef lines.
248 No #error and #warning directives.
249
250 [more to come]