File: README.Contributing

package info (click to toggle)
squeak-vm 1%3A4.10.2.2614-4.1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 13,284 kB
  • ctags: 15,344
  • sloc: ansic: 75,096; cs: 11,191; objc: 5,494; sh: 3,170; asm: 1,533; cpp: 449; pascal: 372; makefile: 366; awk: 103
file content (485 lines) | stat: -rw-r--r-- 14,191 bytes parent folder | download | duplicates (8)
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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
If you plan on contributing code or submitting patches to fix bugs
then PLEASE adhere to the following coding conventions.  Doing so
makes my life easier (since I *will* reformat myself any code that
doesn't conform) and makes your code much more likely to be accepted
(since any code that is difficult to read because of formatting
problems simply won't get read, and if I haven't read it then it isn't
going into my sources -- period).

Of course, if you're submitting an entire file full of stuff (and you
are therefore the original author of the file) then you can format it
any way you like (and tell the rest of us how we have to format our
code to get it included in your file. ;-)

The following guidelines are sufficiently close to the GNU Coding
Standards that you shouldn't need to change any of Emacs's C-mode
variables from their default settings.



FORMATTING CODE
---------------


Tabs stops are every TWO characters.  Regardless of what Torvalds
might say, if tab stops were meant to be 8 characters apart then
humans would have evolved wide-angle vision shortly after the
invention of the Newbury terminal.  (If your editor doesn't remind you
about the matching delimiter when a block is more than a page long
then it's time you evolved to Emacs. ;-)

Always use C-style comment delimiters.  Unix Squeak runs on lots of
platforms where GNU gcc is not the standard compiler.  Many of these
compilers choke (quite rightly) on C++ style comments.  Similarly,
always comment-out any additional explanatory text appearing after
`#else' and `#endif'.

Use `#if defined(...)' in preference to `#ifdef ...'.

Indent preprocessor commands to reflect the nesting of conditional
sections, and place a comment after any `#else' or `#endif' that isn't
utterly obvious:

	#if defined(LAZY)
	# include <sleep.h>
	# ...
	# if defined(VERY_LAZY)
	#   include <vacation.h>
	#   ...
	# endif
	# ...
	#else /* !LAZY */
	# include <schedule.h>
	#endif

Declarations and external definitions should start in column zero.
The only exception is for small conditional sections where indentation
helps to show the "scope" of the conditional code.  Hence:

	#if defined(EAT_DONUTS)
	# include <donut/supplies.h>
	  int donutCounter= 0;	/* number of donuts consumed since startup */
	#endif /* EAT_DONUTS */

But don't overdo this -- the start/end of the conditional section
should remain clearly visible while looking at indented declarations.

Always use ANSI prototypes, and put the return types of functions and
their identifiers on the same line (unless you rely on tools that
prefer function names to start in column zero, in which case you're
forgiven in advance).  Hence:

	static char *concat(char *s1, char *s2)
	{
	  ...
	}

If the arguments don't fit nicely on one line, and the function
identifier is short, split the declaration like this:

	int lotsOfArgs(int anInteger, long aLong, short aShort,
		       double aDouble, float aFloat)
        ...

If the identifier is enormous (which sometimes happens because of the
frequent association between C functions and Squeak selectors) then
put the opening parenthesis on the next line, indented by four
characters.  (That way Emacs knows how to indent the rest of the
arguments nicely.)  Like this:

	int ioDoSomethingObscureWithFarTooMuchBabbleInTheIdentifier
	    (int anInteger, long aLong, short aShort,
	     double aDouble, float aFloat)
        ...

Put spaces on either side of an arithmetic or relational operator.

One of the most common (and most difficult to debug) problems in C is
caused by writing `=' when you meant `=='.  To avoid such mistakes, it
is a great help to omit the space before an operator that side-effects
its l-value.  For example:

	if (x == 42)
	  x= 666;

	while (ptr >= base)
	  processWord(ptr-= 4);

(In my three years of writing C before adopting this convention I
spent many tens of hours tracking down `=' vs. `==' bugs.  In the
fifteen years since the instant that I adopted the above convention I
have suffered from that bug precisely ONCE.)

For similar reasons it's also a good idea to place constant values on
the left side of a comparison.  Most compilers will happily let this
this pass:

	int c= getchar();
	if (c= EOF)
	  ...

but will detect the problem if the comparison is written the other way
round:

	int c= getchar();
	if (EOF= c)
	  ...

Character constants are characters:

	void terminate(char *string, size_t len)
	{
	  string[len]= '\0';	/* NOT `string[len]= 0;' !!! */
	}

Always initialise a variable, even if you're just about to give it a
value:

	int min= 0;

	if (x < y)
	  min= x;
	else
	  min= y;
	...

Just about every compiler in existence can optimise away the
assignment.  On the hand, always assigning an initial value avoids
warning messages about possibly uninitialised variables from several
compilers when their optimisation dials are `cranked up to 11'.


Vertically align related elements in dense program sections, such as a
long series of assignments or declarations:

	int a=        42;	/* current data value */
	int counter=   0;	/* how many we've counted */
	int moreToDo=  1;	/* 1 if we've got more to count */

This applies to the _identifiers_ when indirection is present:

	int   a=         42;	/* current data value */
	int  *current=    0;	/* current data location */
	int **dataLists=  0;	/* current data list */

Don't be tempted to write `C++ style' types.  Respect also the proper
placement of whitespace in casts, which should have spaces in exactly
the same places as would the equivalent declaration.  Hence:

	/* ptr to (ptr to int) fn of ptr to ptr to int */
	typedef int *(*ppifpi)(int **);

	ppifpi myPpifpi= 0;

	int ioSetPpifpi(int sqFunctionIndex)
	{
	  myPpifpi= (int *(*)(int **))sqFunctionIndex;
	}

(Outside Squeak code too, I guarantee that you'll come up against many
more brick walls trying to use the `C++ style' "int* foo" [ugh -- it
_isn't_ the `int' that's the pointer in there!!] and suchlike than you
will if you stick to the old-fashioned, and _rational_, C syntax.)


Put a space between a keyword and a parenthesised argument.  Put
spaces after commas.  Don't put a space between a function name and
the argument list, and never put a space after an opening parenthesis
or before a closing parenthesis:

	if (x < foo(y, z))
          haha= bar[4] + 5;
	else
	  {
	    while (z)
	      {
		haha+= foo(z, z);
		--z;
	      }
	    return ++x + bar();
	  }

When you split an expression into multiple lines, split it BEFORE an
operator, not after one.  Here is the right way:

     if (fooThisIsLong && bar > win(x, y, z)
	 && remaining_condition)
       ...

Avoid having two operators of different precedence at the same level
of indentation.  For example, don't write this:

	mode= (inmode[j] == VOIDmode
	       || GET_MODE_SIZE(outmode[j]) > GET_MODE_SIZE(inmode[j])
	       ? outmode[j] : inmode[j]);

Instead, use extra parentheses so that the indentation shows the
logical nesting:

	mode= ((inmode[j] == VOIDmode
		|| (GET_MODE_SIZE(outmode[j]) > GET_MODE_SIZE(inmode[j])))
	       ? outmode[j] : inmode[j]);

Insert extra parentheses so that Emacs will indent the code properly.
For example, the following indentation looks nice if you do it by
hand, but Emacs would mess it up:

	v = rup->ru_utime.tv_sec*1000 + rup->ru_utime.tv_usec/1000
	    + rup->ru_stime.tv_sec*1000 + rup->ru_stime.tv_usec/1000;

But adding a set of parentheses solves the problem:

	v = (rup->ru_utime.tv_sec*1000 + rup->ru_utime.tv_usec/1000
	     + rup->ru_stime.tv_sec*1000 + rup->ru_stime.tv_usec/1000);

With very few exceptions, braces should always go on a line by
themselves.  Instead of this:

	if (x < y) {
	  z= x;
	} else {
	  z= y;
	}

write this:

	if (x < y)
	  {
	    z= x;
	  }
	else
	  {
	    z= y;
	  }

Never, ever, put an `else' and a brace on the same line.

Format do-while statements like this:

	do
	  {
	    a= foo(a);
	  }
	while (a > 0);

Empty `while' and `for' loops should have their trailing semicolon on
a line by itself, to make the absence of the body utterly obvious:

	for (i= 1; i < argc; processArg(i++))
	  ;

	while ('\0' != (*dst++= *src++))
	  ;

Introduce redundant braces to restrict the scope of temporaries to the
smallest possible region.  This is WRONG:

	void foo(void)
	{
	  int i;
	  /* ... lots of code ... */
	  for (i= 0; i < LIMIT; ++i)
	    {
	      ...
	    }
	  /* ... lots of code ... */
	  for (i= 0; i < LIMIT; ++i)
	    {
	      ...
	    }
	}

while this is right:

	void foo(void)
	{
	  /* ... lots of code ... */
	  {
	    int i= 0;
	    for (i= 0; i < LIMIT; ++i)
	      {
	        ...
	      }
	  }
	  /* ... lots of code ... */
	  {
	    int i= 0;
	    for (i= 0; i < LIMIT; ++i)
	      {
	        ...
	      }
	  }
	}

The above is not just to help small-brained coders (like me) remember
to delete variables when the code that uses them is removed.  It's
preferable because some compilers are hopelessly bad at live-range
splitting.  Reducing the scope of variables to the absolute minimum
encourages them to produce _much_ better code.  (You'll also be far
less tempted to use the value of an iteration variable after the end
of the loop, which is unforgivably bad programming style.)


Just like a good composer, a good programmer knows that rarefied zones
are the most effective media in which to produce contrast.  Leave lots
of vertical whitespace between logically independent program sections,
with a minimum of comment `decoration' to make them stand out.  For example:

  1 line of whitespace within function bodies to separate variable
  declarations from statements

  1 line of whitespace between groups of external declarations.

  2 lines of whitespace between function definitions.

  Begin a new "logical section" of the code with three blank lines, a
  comment explaining what the section is all about, and then three
  more blank lines before the section itself.

and so on.  Just use common sense.  In particular, when there are many
lines of declarations/definitions in a given section, the following is
much kinder on the reader:

	...


	/*** variable declarations ***/


	/* counters */

	int a= 0;
	int b= 0;

	/* pointers */

	void *start=    0;	/* initial address */
	void *position= 0;	/* current address, post-incremented */
	void *end=      0;	/* last address + 1 */


	/*** function definitions ***/


	/* accessors */

	int getA(void)
	{
	  return a;
	}

	/* predicates */

	bool atEnd(void)
	{
	  return position == end;
	}

	...

(and more effective) than the `noisy' equivalent:

	...

	/*****************************/
	/*****************************/
	/***                       ***/
	/*** variable declarations ***/
	/***                       ***/
	/*****************************/
	/*****************************/

	/****************/
	/*** counters ***/
	/****************/

	int a= 0;
	int b= 0;

	/****************************/
	/****************************/
	/***                      ***/
	/*** function definitions ***/
	/***                      ***/
	/****************************/
	/****************************/

	/*****************/
	/*** accessors ***/
	/*****************/

	int getA(void)
	{
	  return a;
	}

	/******************/
	/*** predicates ***/
	/******************/

	bool atEnd(void)
	{
	  return position == end;
	}

	...

where the details are hopelessly lost in the noisy comments, which
serve only to make the program HARDER to read.

(Besides, it looks just plain ugly.  Typographers have known for
centuries about the importance of maintaining a consistent `density'
in the characters that make up an aesthetically-pleasing and easy to
read font.  The same applies to programs.  Avoid large horizontal
blobs of asterisks and other `dense' material intended to make things
stand out -- they simply distract the reader's attention away from the
essential.  Use whitespace instead!)



One final comment: remember that a crystal clear program is a MUCH
more impressive achievement in the eyes of the vast majority of
readers compared to a program designed to show off the author's
cleverness in using obscure and obfuscating `C-isms' and cramming the
maximum possible amount of functionality in the minimum number of
source lines.  Also, the time you spend making your program visually
pleasing (and consistent) will be paid back many times over when you
eventually have to go bug hunting.



PORTABILITY
-----------


Stick to ANSI Standard C in source code.  Resist the temptation to
introduce GNU-specific extensions, even if you think your code is only
ever going to run in a GNU environment.  If you use gcc then be sure
your code compiles without warnings when `-Wall' is in effect (which
is the case for all source files in the "unix" source directory).
Ideally, your code should compile without warnings when "-pedantic" is
turned on too, but I'm not insisting on this -- yet.

ABSOLUTELY avoid GNU make-specific stuff in Makefiles.  If your
wizz-bang Squeak feature requires a GNU make-specific rule or
conditional section in a Makefile someplace then go away and rethink
your feature.  (If the entire GNU compiler suite can be built using
the tiniest imaginable subset of Makefile features, then so can
Squeak.)

Another way to avoid GNU make features in Makefiles is to run a script
from `configure' to make a `fragment' and then AC_SUBST_FILE() it into
the Makefile.in.  If you do this then please, please make sure that
the script is *strict* Bourne shell.  (If you're on a system that has
bash as its standard shell then you must ABSOLUTELY install ash [or
something similar] and exercise every path through the script with the
first line set to "#!/bin/ash", before changing it to "#!/bin/sh".)

If you normally develop on a GNU-based Linux system (or any similarly
well-documented system) then check the "CONFORMING TO" or "STANDARDS"
section of the manual page for every library function and system call
that you use.  Avoid functions that don't conform to ANSI or POSIX,
and pay particular attention to functions that are missing in either
BSD or SysV.  (These should be used with extreme caution, and only if
the necessary conditional stuff [with a suitable fallback] is
present.)