290 lines
9.0 KiB
Plaintext
290 lines
9.0 KiB
Plaintext
# NetHack 3.7 code_style.txt $NHDT-Date: 1694890786 2023/09/16 18:59:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $
|
|
# Copyright (c) 2015 by Derek S. Ray
|
|
# NetHack may be freely redistributed. See license for details.
|
|
|
|
NetHack DevTeam Coding Style
|
|
============================
|
|
|
|
NetHack is written in C, with a little bit of C++ to access platform
|
|
libraries. This coding style document is concerned primarily with the style
|
|
used for C source files. We do not have a defined style for C++ files, but C++
|
|
should be styled in keeping with C.
|
|
|
|
The code base in C files was, close to the 3.6 release, reformatted using a
|
|
version of the clang-format tool patched to support K&R-style argument
|
|
declarations. Due to some incompatibilities, the patch is not publicly
|
|
available and clang-format is not expected to be regularly used. Since then,
|
|
function declarations and definitions have been switched to ANSI.
|
|
|
|
Developers should do their best to adhere to the coding style to promote
|
|
legible, easy-to-edit code. Legibility is paramount, so in some cases, it may
|
|
be better not to fully adhere to the style guidelines.
|
|
|
|
Recipes for common text editors can be found at the end of this file.
|
|
|
|
Indentation and Spacing
|
|
-----------------------
|
|
|
|
The basic indentation is 4 spaces wide. All indentation is done using space
|
|
characters, not tabs.
|
|
|
|
Lines should be at most 78 characters wide. If a line would be longer than the
|
|
limit, the line should be wrapped and the wrapped portion should be aligned
|
|
with the parentheses or brackets containing the wrap. If there is no set of
|
|
parentheses or brackets, the line should be indented four spaces. Wrapping
|
|
should normally occur after a comma or before a binary operator, when
|
|
possible:
|
|
|
|
int index
|
|
= SomeExcessivelyLongExpression;
|
|
|
|
fcall(arg1,
|
|
arg2, (cond13
|
|
&& cond2));
|
|
|
|
Single blank lines should be used wherever convenient to improve readability.
|
|
|
|
Functions and Control Statements
|
|
--------------------------------
|
|
|
|
For a function definition, the return type, declarator, and opening brace
|
|
should each appear on a line of their own. Arguments are defined in the following
|
|
parenthesis, per ANSI. There are two general styles. One with no comments, where
|
|
arguments are added one after another, with a wrap aligning to the first argument
|
|
if there is an overflow.
|
|
|
|
void
|
|
foo(int i, char c)
|
|
{
|
|
/* function body */
|
|
}
|
|
|
|
void
|
|
long_function_name(int first_arg, struct long_name *second_arg,
|
|
int third_arg, int forth_arg)
|
|
{
|
|
/* function body */
|
|
}
|
|
|
|
Alternatively, arguments can be one per line if they are commented:
|
|
|
|
void
|
|
long_function_name(int first_arg, /* main operation */
|
|
struct long_name *second_arg, /* control details */
|
|
int third_arg, /* local conditions - if
|
|
they apply */
|
|
int forth_arg) /* remote conditions */
|
|
{
|
|
/* function body */
|
|
}
|
|
|
|
If the function takes no parameters:
|
|
|
|
int
|
|
long_function_name(void)
|
|
{
|
|
/* function body */
|
|
}
|
|
|
|
Opening braces of control statements appear on the same line as the control
|
|
statement:
|
|
|
|
if (condition) {
|
|
/* body */
|
|
}
|
|
|
|
Else statements and the while statements of do-while blocks appear on the same
|
|
line as the closing brace of the if or do statement. Otherwise, closing braces
|
|
always get a line of their own.
|
|
|
|
if (condition) {
|
|
/* body */
|
|
} else if (condition) {
|
|
do {
|
|
/* body */
|
|
} while (condition);
|
|
} else {
|
|
/* body */
|
|
}
|
|
|
|
If a control block has only a single statement, it can appear on a line of its
|
|
own, with an indent. If the statement is a null statement, then it should be
|
|
expressed as an empty set block, not with a semicolon, because many compilers
|
|
will warn if a null statement is used:
|
|
|
|
if (condition)
|
|
fcall();
|
|
|
|
if (condition) {
|
|
} else
|
|
fcall();
|
|
|
|
If multiple control blocks are being used in a row, it may be more readable to
|
|
use braces even for single statements, and they should be used if they improve
|
|
readability. The following is an example of poor usage:
|
|
|
|
if (condition) {
|
|
/* long body */
|
|
} else if (condition)
|
|
statement;
|
|
else {
|
|
/* very long body */
|
|
}
|
|
|
|
Switch statements should have the case labels unindented, and the statements
|
|
should be indented normally. The default case should occur last unless there's
|
|
a compelling reason not to, and fallthroughs should be explicitly marked as
|
|
such with a comment, to avoid Yeenoghu getting the touch of death again:
|
|
|
|
switch (condition) {
|
|
case FOO:
|
|
case BAR:
|
|
fcall();
|
|
/* fall-through */
|
|
case BAZ:
|
|
fcall();
|
|
break;
|
|
|
|
default:
|
|
statement;
|
|
}
|
|
|
|
Variables should never be declared in a condition or a for loop
|
|
initialization, and if an assignment is used as a condition, it should be
|
|
wrapped in an additional set of parentheses for clarity:
|
|
|
|
int *p;
|
|
if ((p = fcall())) {
|
|
/* body */
|
|
}
|
|
|
|
int i;
|
|
for (i = 1; i < 10; ++i) {
|
|
/* body */
|
|
}
|
|
|
|
Variable names to avoid
|
|
-----------------------
|
|
|
|
near, far Some compilers and cross-compilers that target old
|
|
processors with segmented architectures may treat
|
|
those as keywords. It is safest to just avoid them.
|
|
|
|
Spaces in Expressions
|
|
---------------------
|
|
|
|
Spaces should appear around binary operators, after commas, after a C-style
|
|
cast, and after the keyword in a control statement. They should not appear
|
|
between a function name and the opening parenthesis of a function call, nor
|
|
immediately inside a pair of parentheses:
|
|
|
|
foo(i, j, l);
|
|
if ((boolean) condition) {
|
|
/* body */
|
|
}
|
|
|
|
Casts and sizeof
|
|
----------------
|
|
|
|
Casts should separate the cast operator and its expression with a space:
|
|
'(char *) str'
|
|
'sizeof (type)' requires the parentheses. 'sizeof expression' does not;
|
|
using them is not wrong but omitting them avoids some visual clutter.
|
|
Using them without the separating space gives the false impression of a
|
|
function call or macro-with-argument(s) expansion; 'sizeof' is an operator
|
|
and the parentheses required for '(type)' are to treat it like a cast.
|
|
|
|
Comments
|
|
--------
|
|
|
|
Some block comments are undecorated, just split into reasonable width lines:
|
|
/* this is
|
|
a comment */
|
|
They usually don't include sentence punctuation.
|
|
|
|
Others are more elaborate:
|
|
/*
|
|
* This is
|
|
* another comment.
|
|
*/
|
|
This style is usually used with sentence punctuation, particularly if they
|
|
contain more than one sentence.
|
|
|
|
End-of-line comments which need to span lines
|
|
somecode(); /* this comment
|
|
* is ok */
|
|
should start every continuation line with an asterisk, otherwise clang-format
|
|
would convert them into a block comment
|
|
othercode(); /* this comment
|
|
should be avoided */
|
|
because it would be converted into
|
|
othercode();
|
|
/* this comment
|
|
should be avoided */
|
|
if another bulk reformatting ever gets performed. Similarly, multiple
|
|
comments intended to read as one
|
|
morecode(); /* start of comment */
|
|
/* more of comment */
|
|
/* end of comment */
|
|
are deprecated because they will end up losing the indentation of the
|
|
followup lines if reformatted.
|
|
|
|
Many files end with
|
|
/*filename*/
|
|
usually preceded by a blank line. This was intended as a workaround for a
|
|
comment--somewhere, possibly in Amiga or Atari code--that stated that some
|
|
compiler or other didn't always process the last line of the file. If that
|
|
last line is a comment, nothing is lost. The real issue almost certainly
|
|
was source file(s) that didn't end in newline. These days we try to force
|
|
the final newline for every file, prior to release if not always maintained
|
|
day-to-day. The name at the end can still be worthwhile when editing or
|
|
browsing multiple files.
|
|
|
|
|
|
Vim Configuration
|
|
=================
|
|
|
|
For vim, the following settings are encouraged when editing NetHack code, to
|
|
ensure that indentation is done correctly:
|
|
|
|
set shiftwidth=4
|
|
set softtabstop=4
|
|
set expandtab
|
|
set tabstop=4
|
|
set shiftround
|
|
set textwidth=78
|
|
set cindent
|
|
set filetype=c
|
|
|
|
|
|
Visual Studio Configuration
|
|
===========================
|
|
|
|
In Visual Studio under Tools->Options->Text Editor->C/C++, you can set the
|
|
following options to obtain desired behavior:
|
|
|
|
[Tabs]
|
|
Indenting: Smart
|
|
Tab size: 4
|
|
Indent size: 4
|
|
Insert Spaces
|
|
|
|
There are a number of other options under [Formatting] that should be
|
|
checked (Indentation, New Lines, Spacing, and Wrapping), but there are so
|
|
many entries that reproducing them here is impractical. Fortunately, the
|
|
options are in plain English, so walking through them with a copy of
|
|
this Guide handy and making changes as required will suffice.
|
|
|
|
Emacs Configuration
|
|
===================
|
|
|
|
There are no doubt umpteen different ways to handle this in Emacs.
|
|
Putting the following in ~/.emacs.el is one
|
|
|
|
(defun hook-c ()
|
|
(setq c-set-style "k&r")
|
|
(setq c-basic-offset 4)
|
|
(setq indent-tabs-mode nil))
|
|
(add-hook 'c-mode-common-hook 'hook-c)
|
|
|