[BACK]Return to CodeStyle CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot

Annotation of OpenXM_contrib/gnuplot/CodeStyle, Revision 1.1.1.2

1.1.1.2 ! maekawa     1: $Id: CodeStyle,v 1.5 1998/11/20 22:20:20 lhecking Exp $
1.1       maekawa     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>