harakit/CONTRIBUTING

397 lines
12 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Make sure to read our code of conduct in the CONDUCT file.
Copyright Information
=====================
When editing a file, create a copyright statement correlated to your
identity so that it is easier to keep track of who has touched what file.
Pseudonymous contributions are welcome (and encouraged). Place new copyright
information below existing copyright information. If there is an existing
copyright statement:
* Copyright (c) 20222023 Emma Tebibyte <emma@tebibyte.media>
you would add your name below it like this:
* Copyright (c) 20222023 Emma Tebibyte <emma@tebibyte.media>
* Copyright (c) 20XX Your Name <your e-mail address or website>
Only list years in which you modified the source file. For example:
* Copyright (c) 20202021, 2023 Your Name <your-address@example.com>
This header shows that “Your Name” worked on this source file in 2020, 2021, and
2023. Please use the en dash (“–”, U+2013) to separate consecutive years in the
copyright notice.
If you are contributing a new file, please prepend the following license header
text to it, replacing the proper text on the copyright line:
/*
* Copyright (c) 20XX Your Name <your-address@example.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
When including code provided under an AGPLv3-compatible license, please modify
the license notice. The following example contains an Expat (MIT) license
notice:
/*
* Copyright (c) 20XX Your Name <your-address@example.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*
* This file incorporates work covered by the following copyright and permission
* notice:
*
* MIT License
*
* Copyright (c) <year> <copyright holders>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
Style
=====
“Everyone knows that debugging is twice as hard as writing a program in the
first place. So if youre as clever as you can be when you write it, how
will you ever debug it?”
Brian Kernighan, The Elements of Programming Style
The following guidelines are conducive to clear and readable code that is
consistent with the style of the rest of the Bonsai Computer System.
Use:
0. A single line for control flow statements short enough to be easily
understood at a glance:
if !(argc < 0) { usage(program_name); }
This applies to C switch statements and cases and Rust match statements, as
well:
switch (value) { /* aligning stuff to make it easier to read is fine */
case possibility: variable = foo; break;
default: variable = NULL; break;
}
1. Switch cases in C and match arms in Rust should start another level of
indentation:
switch (value) {
case possibility:
statement;
break;
default:
statement;
break;
}
match result {
Ok(n) => variable = n,
Err(e) => error = e,
}
2. Braces in control flow where their inclusion is left optional in C:
if (condition) { statement; }
3. Empty lines between different kinds of statements:
int t;
assert(io->bufuse > 0);
assert(io->bufuse <= io->bs);
if ((t = write(io->fd, io->buf, io->bufuse)) < 0) {
io->error = errno;
t = 0;
} else if (t > 0) {
memmove(io->buf, &(io->buf)[t], (io->bufuse -= t));
}
io->bytes += t;
io->prec += (t > 0 && io->bufuse > 0);
io->rec += (t > 0 && io->bufuse == 0);
return io;
4. Compiler options that yield the most useful warnings, such as -Wpedantic in
a lot of C compilers. Fix the warnings, too [0].
5. One more level of indentation and one argument per line when a function
call or statement header is too long to fit on one line:
let usage = format!(
"Usage: {} [-d delimiter] index command [args...]",
argv[0],
);
6. One more level of indentation than the keyword that initiated a multi-line
block.
if (condition) {
statement;
statement;
}
7. The return value of all non-void functions, or explicitly ignore them (like
casting to void in C) [0]:
if ((a = malloc(sizeof char)) == NULL) { /* handle this error */
(void)fprintf(stderr, "oh noes!"); /* explicitly ignore this one */
return EX_OSERR; /* ...because the program is exiting anyway */
}
8. The smallest possible scope for data [0].
9. Comments noting all the symbols and macros used from a C header file, next
to its include macro:
#include <unistd.h> /* close(2), getopt(3), lseek(2), read(2), write(2),
(space-aligned) * optarg, optind, STDIN_FILENO, STDOUT_FILENO */
10. Spaces in control flow statements, after the keyword and before the
opening brace:
for (i = 2; i < argc; ++i) {
11. In Rust, a trailing comma on all arguments or fields that are on their own
lines:
return Err(EvaluationError {
message: format!("{}: Invalid token", i),
code: EX_DATAERR,
})
12. In Rust, place extern statements after use statements that include standard
library crates. Group like statements:
use std::fs::Path;
extern crate strerror;
extern crate sysexits;
use strerror::StrError;
use sysexits::{ EX_OSERR, EX_USAGE };
13. If text is on the same line as a brace, spaces after an opening brace and
before a closing one:
use sysexits::{ EX_DATAERR, EX_IOERR, EX_UNAVAILABLE, EX_USAGE };
14. Alphabetic sorting, where applicable:
use std::io::{ BufWriter, Read, Write, stderr, stdin, stdout }
15. In Rust, use the to_owned() method on string types (str, OsStr, CStr, etc.)
and the to_string() method on other types.
Avoid:
16. Unbounded loops [0].
17. Function pointers [0].
18. Heap memory allocation [0].
19. Using too much nested logic (within reason).
20. Too many levels of dereferences [0]:
/* do not do this */
for (size_t i = 0; i < sizeof a / sizeof *a; ++i) {
if (a[i].id == MATCH) { a[i].val = 0; }
}
/* do this */
for (struct MadeUp *s = &a[0]; *s != NULL; s = &s[1]) {
if (s->id == MATCH) { s->val = 0; }
}
21. Using C preprocessor macros; the fewer, the better [0].
22. The exit(3p) and std::process::exit() functions; returning from the main
function skips a system call.
Do not use:
23. More than the length of one printed page for a function [0].
24. Recursion, as its complex and can unexpectedly overflow the stack [0].
25. Any functionality not in the POSIX C specification and language features not
in C99.
26. Do-while loops, as theyre unique to C and confusing for casual programmers.
27. Labels and goto statements; use sensible flow control [0].
28. Pointer arithmetic, as it tends to be confusing and unnecessary; use
index-reference patterns like &p[1] instead of p + 1. &p[n] is the address at
p + sizeof p * n, not p + n, like pointer arithmetic suggests.
29. C struct bitfields in unions, to access certain bits of bigger data types,
as its poorly defined in the C standards; use bit arithmetic.
30. C trigraphs.
31. Inclusions in C header files, to prevent multiple file inclusions.
32. C preprocessor variables to prevent multiple inclusions of the same file,
such as:
#ifdef _FILE
#define _FILE
/* file body */
#endif /* ifdef _FILE */
Instead, take the time to ensure other files arent including any files twice.
33. The gets(3p) function from <stdio.h>, as its impossible to prevent buffer
overflows when it's used; use fgets(3p) from <stdio.h>.
34. The scanf(3p) function from <stdio.h> [1].
35. Any functionality not described in the latest POSIX make(1) specification.
36. Macros which panic on failure in Rust (such as the print!() and println!()
macros). Use a function and handle any errors. However, do use the eprintln!()
macro for error messages. Handling an error for writing an error message is
redundant.
37. A -h option for help text. Instead, print usage information when any
erroneous option is specified. See the Usage Text section below.
38. Lines which exceed 80 columns in width when using four-column indentation
steps. This helps contributors with smaller screens, those using side-by-side
editor windows or panes, and those who have no text wrapping in their editor or
terminal.
Usage Text
==========
This section is adapted from the NetBSD style guide [2].
When programs are invoked incorrectly and in the synopsis of manual pages, uasge
text should be provided to the user. The following is the format used by this
project for this purpose:
All optional arguments are to be placed in square brackets (U+005B, U+005D).
Mutually exclusive arguments can be separated by a vertical line (U+007C).
Groups of arguments should be specified in alphabetical order in most cases. The
order of arguments and an example of these rules follows:
0. Options with no option arguments.
1. Options with option arguments. Arguments should be specified inside the same
square brackets as the options.
3. Non-option arguments.
"usage: f [-aDde] [-b b_arg] [-m m_arg] req1 req2 [opt1 [opt2]]\n"
"usage: f [-a | -b] [-c [-de] [-n number]]\n"
Committing
==========
When contributing to Bonsai, please sign your commit with a PGP key and create
the commit with an identity which can be easily contacted.
If committing a new utility, please include tests and documentation (see
tests/ and docs/) for the new tool.
Format commit messages following these guidelines:
$ git commit -m 'tool(1): add feature x'
If committing a new library or header file:
$ git commit -m 'library(3): fix overflow'
$ git commit -m 'header.h(3): add header.h(3)'
If committing a new manual page:
$ git commit -m 'tool.1: add author details'
If modifying some other file or directory:
$ git commit -m 'README: clarify'
$ git commit -m 'tests/posix: fix bug #47'
For multiple of these:
$ git commit -m 'Makefile, tool(1): add tool(1)'
$ git commit -m 'tool(1): add tool(1); library(3), library.3: add library(3)'
$ git commit -m 'tool(1): fix #42 & add feature x'
Commit messages should be written in the present tense.
References
==========
[0] <https://web.eecs.umich.edu/~imarkov/10rules.pdf>
[1] <http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html>
[2] <http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/share/misc/style>
--
Copyright © 20232024 Emma Tebibyte <emma@tebibyte.media>
Copyright © 2024 DTB <trinity@trinity.moe>
Copyright © Wikipedia contributors
This work is licensed under CC BY-SA 4.0. To view a copy of this license, visit
<http://creativecommons.org/licenses/by-sa/4.0/>.