Annotation of OpenXM_contrib/gnuplot/CodeStyle, Revision 1.1
1.1 ! maekawa 1: $Id: CodeStyle,v 1.9 1996/12/19 19:12:28 drd 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:
! 9:
! 10: MISSING FUNCTIONS, AND FUNCTIONS TO BE AVOIDED
! 11: ----------------------------------------------
! 12: The following functions may not be used, since they are not present on all
! 13: systems (though the substitute functions might be defined to exactly these
! 14: functions)
! 15:
! 16: function use instead
! 17:
! 18: bcopy memcpy
! 19: bzero memset
! 20: index strchr
! 21: rindex strrchr
! 22: strncasecmp strnicmp
! 23:
! 24:
! 25:
! 26: The number of macros for conditional compilation is getting a little
! 27: extreme! I (personally) think it's better to make the conditionally-compiled
! 28: code 'feature-based' rather than 'compiler-based'. I think this is particularly
! 29: true for the many DOS compilers. The sort of thing I am thinking of is,
! 30: for example, whether to disable hidden3d stuff, or whether to store
! 31: data points as float rather than double to save space. Rather than having
! 32: a long list of compilers or OS's which use one or the other, add macros
! 33: such as SMALLMEMORY or NOHIDDENSTUFF and define these in the makefiles.
! 34: Perhaps a sensible guideline for choice of such macros is to arrange
! 35: things so that the smallest number of ports are affected. For example,
! 36: if we only compiled the hidden stuff if HIDDENSTUFF was defined, most
! 37: makefiles would have to be updated. But if instead it is being disabled
! 38: for a few machines, only those makefiles have to explicitly define
! 39: NOHIDDENSTUFF.
! 40:
! 41: Perhaps a good guideline would be that gnuplot should build cleanly
! 42: with most available features if no macros are defined on an ANSI C compiler
! 43: on a 'typical' (POSIX, say) unix machine.
! 44:
! 45: For example, I myself have broken this rule by requiring the macro
! 46: HAVE_LOCALE in order to support setlocale() - this feature is available
! 47: with ANSI compilers, and so setlocale() calls should be enabled by default,
! 48: and disabled only if NO_LOCALE is defined at compile time. Does this
! 49: sound reasonable? For example, there was some code in fit.c that would
! 50: prefer to use tempnam() if it is available, but falls back to ANSI fn
! 51: tmpnam() if necessary. The way it was done, tempnam() was the default,
! 52: and there was a list of those systems that had to use tmpnam().
! 53: But the trouble was that a new one had to be added to the list every
! 54: few weeks as new machines were discovered. The current scheme is
! 55: that tmpnam() is used unless feature HAVE_TEMPNAM is enabled.
! 56:
! 57:
! 58:
! 59: On a related note... if one particular machine does doesn't provide
! 60: a standard-ish function, but the same functionality can be
! 61: acheived, it would be preferable to implement the standardish
! 62: function in a os-specific source file, so that the core code can
! 63: simply invoke the function without any conditionals, and the OS-specific
! 64: files provide the missing functions. For example, in fit.c (at the
! 65: time of writing) where a temporary file is needed, there is some
! 66: inline code for DOS, OS2, AMIGA, etc to create temporary files,
! 67: otherwise tempnam() is used. I think I'd rather have tempnam()
! 68: implemented as a function in dos.c for example, then the fit code
! 69: would not need to have any conditional code other than HAVE_TEMPNAM
! 70:
! 71:
! 72:
! 73: Also, think generic where possible... I once noticed that popen()
! 74: had been implemented for atari or similar using temporary files
! 75: and system() call. It seems to me that this could easily be done
! 76: as a generic solution, so that DOS ports, for example, could also
! 77: benefit.
! 78:
! 79:
! 80:
! 81:
! 82: FUNCTION PROTOTYPES
! 83: -------------------
! 84:
! 85: Function prototypes are mandatory, even for local functions that are
! 86: declared before use. This is necessary for a clean compile on
! 87: some machines. gcc -Wstrict-prototypes is recommended.
! 88: However, to make the code compilable on pre-ANSI style compilers,
! 89: prototypes have to be enclosed in a special macro, e.g.
! 90:
! 91: int strcmp __PROTO((char *s, char *t)); /* note the double ()'s */
! 92:
! 93: Function definitions, on the other hand, must be done in
! 94: k&r style (which ANSI compilers accept).
! 95:
! 96: int strcmp(s,t)
! 97: char *s, *t;
! 98: {
! 99: ...
! 100: }
! 101:
! 102: While compilers do not require that explicit declarations be
! 103: given for integer arguments, we do !
! 104:
! 105:
! 106:
! 107: If a function has an argument which has a default promotion (char, short,
! 108: float), this could cause problems with some strict ANSI conforming compilers.
! 109: In this case an alternate function header must be used, e.g.
! 110:
! 111: #ifdef PROTOTYPES
! 112: char *foo(char s)
! 113: #else
! 114: char *foo(s)
! 115: char s;
! 116: #endif
! 117:
! 118: but since there's no benefit from using a character as parameter, may
! 119: as well use the int ie.
! 120: char *foo(s)
! 121: int s;
! 122:
! 123: gcc -Wtraditional might help with this.
! 124: [char parameters should be avoided. int can safely be used in this case.]
! 125:
! 126:
! 127:
! 128: While ANSI compilers can use prototypes for implicit typecasts, k&r
! 129: compilers do not have this information. Avoid relying on implicit
! 130: conversions of function parameters. gcc -Wconversion helps with this.
! 131: There are many signed/unsigned warnings, but look out for other
! 132: ones which may be more serious, in particular integer to float and
! 133: vice versa. Placing casts is necessary in this case for correct
! 134: code on non-ansi compilers.
! 135:
! 136: [we will definitely give up k&r support in the near future, but
! 137: since existing code seems to work with k&r, we're sticking
! 138: with it.
! 139: ]
! 140:
! 141:
! 142:
! 143:
! 144: INTEGER SIZE
! 145: ------------
! 146:
! 147: Large integer constant expression have to be explicitly cast to long, even
! 148: if the result is assigned to a long variable.
! 149:
! 150: long t=60*60*24;
! 151: results in a overflow on 16 bit compilers, even though the result fits into
! 152: the long variable.
! 153:
! 154: Correct: long t=60l*60l*24l;
! 155:
! 156:
! 157:
! 158: Similarly, though not particularly important, ANSI and k&r compilers
! 159: treat integer constants > MAX_INT differently. If you mean an
! 160: unsigned integer constant, say so.
! 161:
! 162:
! 163:
! 164:
! 165: Please avoid duplicating large sections of code - make the effort
! 166: to make a function or macro out of the common code.
! 167:
! 168:
! 169: min(a,b), max(a,b), MIN(a,b), MAX(a,b) are all predefined by some
! 170: compilers. I am now using GPMIN() and GPMAX() [wot a pain !]
! 171:
! 172:
! 173: Avoid putting directories into #includes - eg #include "term/file.h"
! 174: is to be avoided. Instead, #include "file.h" and use -Iterm on the
! 175: compile line.
! 176:
! 177:
! 178: coordval is typedef-ed to either double or float - it is almost always
! 179: double, but please take care not to mix coordval's with doubles.
! 180:
! 181:
! 182:
! 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 -l100 -lps comes
! 206: pretty close, though. I need very little manual editing after
! 207: running this, mostly for long (> 80 cols) lines. -Lars]
! 208:
! 209:
! 210:
! 211: Please use lots of vertical whitespace between unrelated
! 212: blocks of code in functions. And it should not be need to
! 213: be said, but I'll say it anyway... please put in lots of
! 214: comments describing blocks of code. Many people maintain and
! 215: contribute to this code.
! 216:
! 217:
! 218: The functions in plot?d.c and graph*.c are sometimes very long.
! 219: This isn't really a problem, since there's a lot of semi-independent
! 220: things to be done in sequence. However, I do object to the
! 221: practise of having all variables declared at the top of
! 222: such functions. Please keep the scope of temporary variables
! 223: as local as possible, particularly in these long functions.
! 224: The main reason is for ease of maintenance : many people
! 225: make modifications to small parts of code without fully
! 226: understanding in exacting detail the surrounding code.
! 227:
! 228:
! 229: In case you were wondering, lines of the form /*{{{ comment */
! 230: and /*}}}*/ are markers left by my folding editor when I am forced
! 231: to fold up particularly long functions when trying to understand the
! 232: logic. I tend to leave these markers in when I finally figure it out,
! 233: though perhaps I should not.
! 234:
! 235:
! 236: Source code is intended to be read and maintained by humans. As such,
! 237: readability is prefered over elegance. Please separate all operators
! 238: from operands with a space, ie. instead of x+=3, use x += 3. The former
! 239: is not only less readable, it may also break older compilers! This rule
! 240: should also be followed for simple assignments, ie. in for (;;) loops.
! 241: Unary operators should be writen as usual, ie i++.
! 242:
! 243:
! 244: [more to come]
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>