mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 13:38:26 +00:00
update style guideline to reflect current practice
It now mentions clang-format, doesn't parenthesize return values, and no longer calls for backward compatibility in public function names.
This commit is contained in:
parent
d71869d6a7
commit
9f7314eaa4
566
doc/dev/style.md
566
doc/dev/style.md
@ -31,6 +31,15 @@ all supported platforms that don't support all of the C11 features.
|
||||
Given a reasonable set of things to warn about (e.g. -W -Wall for gcc), the goal
|
||||
is to compile with no warnings.
|
||||
|
||||
#### Automatic style enforcement
|
||||
|
||||
All code merged into BIND 9 is checked first with the most recent
|
||||
stable version of clang-format, using the settings defined in the files
|
||||
.clang-format and .clang-format.headers at the top of the source tree.
|
||||
It can reformat code as needed to follow most of the style guidelines
|
||||
described below, except in cases where human judgment is required,
|
||||
such as choice of variable names.
|
||||
|
||||
#### Copyright Notices
|
||||
|
||||
The license described in the ``COPYING`` file applies to the BIND 9 source as a
|
||||
@ -65,29 +74,29 @@ Use tabs for indentation. Spaces before statements are only allowed when
|
||||
needed to line up a continued expression. In the following example, spaces
|
||||
used for indentation are indicated with `"_"`:
|
||||
|
||||
if (i == 0) {
|
||||
printf("this is going to be %s very long %s statement\\n",
|
||||
_______"a", "printf");
|
||||
}
|
||||
if (i == 0) {
|
||||
printf("this is going to be %s very long %s statement\\n",
|
||||
_______"a", "printf");
|
||||
}
|
||||
|
||||
Text editors should be configured with tab-stop set to 8 characters, and
|
||||
tabs should not be expanded to into spaces. The following `vim` settings
|
||||
conform well to BIND 9 C style:
|
||||
|
||||
set showmatch
|
||||
set showmode
|
||||
set autoindent
|
||||
set expandtab
|
||||
set showmatch
|
||||
set showmode
|
||||
set autoindent
|
||||
set expandtab
|
||||
|
||||
filetype plugin on
|
||||
let c_syntax_for_h = 1
|
||||
autocmd FileType c,cc,cpp set cindent
|
||||
autocmd FileType c,cc,cpp set cino=(0:0l1
|
||||
autocmd FileType c,cc,cpp set fo=rotcq
|
||||
autocmd FileType c,cc,cpp set noexpandtab ts=8
|
||||
autocmd FileType python set ts=4 sw=4
|
||||
filetype plugin on
|
||||
let c_syntax_for_h = 1
|
||||
autocmd FileType c,cc,cpp set cindent
|
||||
autocmd FileType c,cc,cpp set cino=(0:0l1
|
||||
autocmd FileType c,cc,cpp set fo=rotcq
|
||||
autocmd FileType c,cc,cpp set noexpandtab ts=8
|
||||
autocmd FileType python set ts=4 sw=4
|
||||
|
||||
filetype indent on
|
||||
filetype indent on
|
||||
|
||||
#### Vertical Whitespace
|
||||
|
||||
@ -103,10 +112,10 @@ indentation rules to make them fit. Since C11 is assumed, the best way to
|
||||
deal with strings that extend past column 80 is to break them into two or
|
||||
more sections separated from each other by a newline and indentation:
|
||||
|
||||
puts("This string got very far to the "
|
||||
"right and wrapped. ANSI "
|
||||
"catenation rules will turn this "
|
||||
"into one long string.");
|
||||
puts("This string got very far to the "
|
||||
"right and wrapped. ANSI "
|
||||
"catenation rules will turn this "
|
||||
"into one long string.");
|
||||
|
||||
The rule for string formatting can be violated in cases where breaking
|
||||
the string prevents ability to lookup the string using grep. Also please
|
||||
@ -133,19 +142,19 @@ and end with a period.
|
||||
|
||||
Good:
|
||||
|
||||
/*
|
||||
* Private variables.
|
||||
*/
|
||||
/*
|
||||
* Private variables.
|
||||
*/
|
||||
|
||||
static int a /* Description of 'a'. */
|
||||
static int b /* Description of 'b'. */
|
||||
static char * c /* Description of 'c'. */
|
||||
static int a /* Description of 'a'. */
|
||||
static int b /* Description of 'b'. */
|
||||
static char * c /* Description of 'c'. */
|
||||
|
||||
|
||||
The following macros should be used where appropriate:
|
||||
|
||||
FALLTHROUGH;
|
||||
UNREACHABLE();
|
||||
FALLTHROUGH;
|
||||
UNREACHABLE();
|
||||
|
||||
#### Header files
|
||||
|
||||
@ -179,63 +188,63 @@ include the file. `<isc/lang.h>` SHOULD be included for private header files
|
||||
or for public files that do not declare any functions.
|
||||
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
/*****
|
||||
***** Module Info
|
||||
*****/
|
||||
/*****
|
||||
***** Module Info
|
||||
*****/
|
||||
|
||||
/*
|
||||
* (Module name here.)
|
||||
*
|
||||
* (One line description here.)
|
||||
*
|
||||
* (Extended description and notes here.)
|
||||
*
|
||||
* MP:
|
||||
* (Information about multiprocessing considerations
|
||||
* here, e.g. locking requirements.)
|
||||
*
|
||||
* Reliability:
|
||||
* (Any reliability concerns should be mentioned here.)
|
||||
*
|
||||
* Resources:
|
||||
* (A rough guide to how resources are used by this module.)
|
||||
*
|
||||
* Security:
|
||||
* (Any security issues are discussed here.)
|
||||
*
|
||||
* Standards:
|
||||
* (Any standards relevant to the module are listed here.)
|
||||
*/
|
||||
/*
|
||||
* (Module name here.)
|
||||
*
|
||||
* (One line description here.)
|
||||
*
|
||||
* (Extended description and notes here.)
|
||||
*
|
||||
* MP:
|
||||
* (Information about multiprocessing considerations
|
||||
* here, e.g. locking requirements.)
|
||||
*
|
||||
* Reliability:
|
||||
* (Any reliability concerns should be mentioned here.)
|
||||
*
|
||||
* Resources:
|
||||
* (A rough guide to how resources are used by this module.)
|
||||
*
|
||||
* Security:
|
||||
* (Any security issues are discussed here.)
|
||||
*
|
||||
* Standards:
|
||||
* (Any standards relevant to the module are listed here.)
|
||||
*/
|
||||
|
||||
/***
|
||||
*** Imports
|
||||
***/
|
||||
/***
|
||||
*** Imports
|
||||
***/
|
||||
|
||||
/* #includes here. */
|
||||
#include <isc/lang.h>
|
||||
/* #includes here. */
|
||||
#include <isc/lang.h>
|
||||
|
||||
/***
|
||||
*** Types
|
||||
***/
|
||||
/***
|
||||
*** Types
|
||||
***/
|
||||
|
||||
/* (Type definitions here.) */
|
||||
/* (Type definitions here.) */
|
||||
|
||||
/***
|
||||
*** Functions
|
||||
***/
|
||||
ISC_LANG_BEGINDECLS
|
||||
/* (Function declarations here, with full prototypes.) */
|
||||
ISC_LANG_ENDDECLS
|
||||
/***
|
||||
*** Functions
|
||||
***/
|
||||
ISC_LANG_BEGINDECLS
|
||||
/* (Function declarations here, with full prototypes.) */
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#### Including Interfaces (.h files)
|
||||
|
||||
@ -255,10 +264,10 @@ not be used to form compound statements.
|
||||
|
||||
Bad:
|
||||
|
||||
if (i > 0) {
|
||||
printf("yes\\n"); i = 0; j = 0;
|
||||
x = 4, y *= 2;
|
||||
}
|
||||
if (i > 0) {
|
||||
printf("yes\\n"); i = 0; j = 0;
|
||||
x = 4, y *= 2;
|
||||
}
|
||||
|
||||
#### Functions
|
||||
|
||||
@ -266,20 +275,18 @@ The use of ANSI C function prototypes is required.
|
||||
|
||||
The return type of the function should be listed on a line by itself when
|
||||
specifying the implementation of the function. The opening curly brace
|
||||
should occur on the same line as the argument list, unless the argument
|
||||
list is more than one line long:
|
||||
should occur on the same line as the argument list:
|
||||
|
||||
static void
|
||||
func1(int i) {
|
||||
/* whatever */
|
||||
}
|
||||
static void
|
||||
func1(int i) {
|
||||
/* whatever */
|
||||
}
|
||||
|
||||
int
|
||||
func2(int first_argument, int next_argument,
|
||||
int last_argument)
|
||||
{
|
||||
/* whatever */
|
||||
}
|
||||
int
|
||||
func2(int first_argument, int next_argument,
|
||||
int last_argument) {
|
||||
/* whatever */
|
||||
}
|
||||
|
||||
To suppress compiler warnings, unused function arguments must be
|
||||
declared within the function via the `UNUSED()` macro.
|
||||
@ -312,28 +319,28 @@ this.
|
||||
|
||||
Good:
|
||||
|
||||
static void
|
||||
f(int i) {
|
||||
if (i > 0) {
|
||||
printf("yes\\n");
|
||||
i = 0;
|
||||
} else {
|
||||
printf("no\\n");
|
||||
}
|
||||
static void
|
||||
f(int i) {
|
||||
if (i > 0) {
|
||||
printf("yes\\n");
|
||||
i = 0;
|
||||
} else {
|
||||
printf("no\\n");
|
||||
}
|
||||
}
|
||||
|
||||
Bad:
|
||||
|
||||
void f(int i)
|
||||
{
|
||||
if(i<0){i=0;printf("was negative\\n");}
|
||||
if (i == 0)
|
||||
printf("no\\n");
|
||||
if (i > 0)
|
||||
{
|
||||
printf("yes\\n");
|
||||
i = 0;
|
||||
}}
|
||||
void f(int i)
|
||||
{
|
||||
if(i<0){i=0;printf("was negative\\n");}
|
||||
if (i == 0)
|
||||
printf("no\\n");
|
||||
if (i > 0)
|
||||
{
|
||||
printf("yes\\n");
|
||||
i = 0;
|
||||
}}
|
||||
|
||||
#### Spaces
|
||||
|
||||
@ -341,7 +348,7 @@ Bad:
|
||||
* DO put a space after `,`.
|
||||
* DO put a space after `;` in a `for` statement.
|
||||
* DO put spaces after C reserved words such as `if`, `for`, `while`, and `do`.
|
||||
* DO put a space after `return`, and parenthesize the return value.
|
||||
* DO put a space between `return` and the return value, if any.
|
||||
* Do NOT put a space between a variable or function name and `(` or `[`.
|
||||
* Do NOT put a space after the `sizeof` operator name, and DO parenthesize its argument: `malloc(4 * sizeof(long))`.
|
||||
* Do NOT put a space immediately after a `(` or immediately before a `)`, unless it improves readability. The same goes for `[` and `]`.
|
||||
@ -369,29 +376,29 @@ avoided.
|
||||
|
||||
Good:
|
||||
|
||||
os_result_t result;
|
||||
os_descriptor_t s;
|
||||
os_result_t result;
|
||||
os_descriptor_t s;
|
||||
|
||||
result = os_socket_create(AF_INET, SOCK_STREAM, 0, &s);
|
||||
if (result != OS_R_SUCCESS) {
|
||||
/* Do something about the error. */
|
||||
return;
|
||||
}
|
||||
result = os_socket_create(AF_INET, SOCK_STREAM, 0, &s);
|
||||
if (result != OS_R_SUCCESS) {
|
||||
/* Do something about the error. */
|
||||
return;
|
||||
}
|
||||
|
||||
Not so good:
|
||||
|
||||
int s;
|
||||
int s;
|
||||
|
||||
/*
|
||||
* Obviously using interfaces like socket() (below) is allowed
|
||||
* since otherwise you couldn't call operating system routines; the
|
||||
* point is not to write more interfaces like them.
|
||||
*/
|
||||
s = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s < 0) {
|
||||
/* Do something about the error using errno. */
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Obviously using interfaces like socket() (below) is allowed
|
||||
* since otherwise you couldn't call operating system routines; the
|
||||
* point is not to write more interfaces like them.
|
||||
*/
|
||||
s = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s < 0) {
|
||||
/* Do something about the error using errno. */
|
||||
return;
|
||||
}
|
||||
|
||||
#### Integral Types
|
||||
|
||||
@ -430,29 +437,29 @@ Bit testing should be as follows:
|
||||
|
||||
Good:
|
||||
|
||||
/* Test if flag set. */
|
||||
if ((flags & FOO) != 0) {
|
||||
/* Test if flag set. */
|
||||
if ((flags & FOO) != 0) {
|
||||
|
||||
}
|
||||
/* Test if flag clear. */
|
||||
if ((flags & BAR) == 0) {
|
||||
}
|
||||
/* Test if flag clear. */
|
||||
if ((flags & BAR) == 0) {
|
||||
|
||||
}
|
||||
/* Test if both flags set. */
|
||||
if ((flags & (FOO|BAR)) == (FOO|BAR)) {
|
||||
}
|
||||
/* Test if both flags set. */
|
||||
if ((flags & (FOO|BAR)) == (FOO|BAR)) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Bad:
|
||||
|
||||
/* Test if flag set. */
|
||||
if (flags & FOO) {
|
||||
/* Test if flag set. */
|
||||
if (flags & FOO) {
|
||||
|
||||
}
|
||||
/* Test if flag clear. */
|
||||
if (! (flags & BAR)) {
|
||||
}
|
||||
/* Test if flag clear. */
|
||||
if (! (flags & BAR)) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#### Testing for Zero or Non-zero
|
||||
|
||||
@ -461,23 +468,23 @@ variables.
|
||||
|
||||
Good:
|
||||
|
||||
int i = 10;
|
||||
int i = 10;
|
||||
|
||||
/* ... */
|
||||
/* ... */
|
||||
|
||||
if (i != 0) {
|
||||
/* Do something. */
|
||||
}
|
||||
if (i != 0) {
|
||||
/* Do something. */
|
||||
}
|
||||
|
||||
Bad:
|
||||
|
||||
int i = 10;
|
||||
int i = 10;
|
||||
|
||||
/* ... */
|
||||
/* ... */
|
||||
|
||||
if (i) {
|
||||
/* Do something. */
|
||||
}
|
||||
if (i) {
|
||||
/* Do something. */
|
||||
}
|
||||
|
||||
#### Null Pointer
|
||||
|
||||
@ -488,23 +495,23 @@ comparison; do not treat a pointer variable as if it were a boolean.
|
||||
|
||||
Good:
|
||||
|
||||
char *c = NULL;
|
||||
char *c = NULL;
|
||||
|
||||
/* ... */
|
||||
/* ... */
|
||||
|
||||
if (c != NULL) {
|
||||
/* Do something. */
|
||||
}
|
||||
if (c != NULL) {
|
||||
/* Do something. */
|
||||
}
|
||||
|
||||
Bad:
|
||||
|
||||
char *c = NULL;
|
||||
char *c = NULL;
|
||||
|
||||
/* ... */
|
||||
/* ... */
|
||||
|
||||
if (c) {
|
||||
/* Do something. */
|
||||
}
|
||||
if (c) {
|
||||
/* Do something. */
|
||||
}
|
||||
|
||||
#### The Ternary Operator
|
||||
|
||||
@ -522,22 +529,22 @@ permissible, and never when returning result codes.
|
||||
|
||||
Good:
|
||||
|
||||
printf("%c is%s a number.\\n", c, isdigit(c) ? "" : " NOT");
|
||||
l = (l1 < l2) ? l1 : l2;
|
||||
s = (a_very_long_variable < an_even_longer_variable)
|
||||
? "true"
|
||||
: "false";
|
||||
if (gp.length + (go < 16384 ? 2 : 3) >= name->length) {
|
||||
/* whatever */
|
||||
}
|
||||
printf("%c is%s a number.\\n", c, isdigit(c) ? "" : " NOT");
|
||||
l = (l1 < l2) ? l1 : l2;
|
||||
s = (a_very_long_variable < an_even_longer_variable)
|
||||
? "true"
|
||||
: "false";
|
||||
if (gp.length + (go < 16384 ? 2 : 3) >= name->length) {
|
||||
/* whatever */
|
||||
}
|
||||
|
||||
Okay:
|
||||
|
||||
return ((length1 < length2) ? -1 : 1);
|
||||
return (length1 < length2) ? -1 : 1;
|
||||
|
||||
Bad:
|
||||
|
||||
return (success ? ISC_R_SUCCESS : ISC_R_FAILURE);
|
||||
return success ? ISC_R_SUCCESS : ISC_R_FAILURE;
|
||||
|
||||
#### Assignment in Parameters
|
||||
|
||||
@ -547,11 +554,11 @@ operators.
|
||||
|
||||
Bad:
|
||||
|
||||
isc_mem_get(mctx, size = 20);
|
||||
isc_mem_get(mctx, size = 20);
|
||||
|
||||
Okay:
|
||||
|
||||
fputc(c++, stdout);
|
||||
fputc(c++, stdout);
|
||||
|
||||
#### Invalidating Pointers
|
||||
|
||||
@ -561,12 +568,12 @@ structure which is itself going to be freed immediately.
|
||||
|
||||
Good:
|
||||
|
||||
char *text;
|
||||
char *text;
|
||||
|
||||
/* text is initialized here. */
|
||||
/* text is initialized here. */
|
||||
|
||||
isc_mem_free(mctx, text);
|
||||
text = NULL;
|
||||
isc_mem_free(mctx, text);
|
||||
text = NULL;
|
||||
|
||||
#### Variable Scopes
|
||||
|
||||
@ -574,44 +581,44 @@ Always use minimal scopes for the variables, e.g. use block scope instead of
|
||||
local scope whenever possible.
|
||||
|
||||
Bad:
|
||||
void
|
||||
foo() {
|
||||
size_t i;
|
||||
[...];
|
||||
for (i = 0; i < 10; i++);
|
||||
[...]
|
||||
}
|
||||
void
|
||||
foo() {
|
||||
size_t i;
|
||||
[...];
|
||||
for (i = 0; i < 10; i++);
|
||||
[...]
|
||||
}
|
||||
|
||||
Good:
|
||||
void
|
||||
foo() {
|
||||
[...];
|
||||
for (size_t i = 0; i < 10; i++);
|
||||
[...]
|
||||
}
|
||||
void
|
||||
foo() {
|
||||
[...];
|
||||
for (size_t i = 0; i < 10; i++);
|
||||
[...]
|
||||
}
|
||||
|
||||
Bad:
|
||||
void
|
||||
foo() {
|
||||
size_t j = 0;
|
||||
[...] /* j not used here */
|
||||
if (true) {
|
||||
while (j < 10) ++j;
|
||||
}
|
||||
[...] /* j not used here */
|
||||
return (0);
|
||||
}
|
||||
void
|
||||
foo() {
|
||||
size_t j = 0;
|
||||
[...] /* j not used here */
|
||||
if (true) {
|
||||
while (j < 10) ++j;
|
||||
}
|
||||
[...] /* j not used here */
|
||||
return 0;
|
||||
}
|
||||
|
||||
Good:
|
||||
void
|
||||
foo() {
|
||||
[...]
|
||||
if (true) {
|
||||
size_t j = 0;
|
||||
while (j < 10) ++j;
|
||||
}
|
||||
[...]
|
||||
}
|
||||
void
|
||||
foo() {
|
||||
[...]
|
||||
if (true) {
|
||||
size_t j = 0;
|
||||
while (j < 10) ++j;
|
||||
}
|
||||
[...]
|
||||
}
|
||||
|
||||
Integrating cppcheck with editor of your choice (f.e. flycheck with emacs) could
|
||||
be a great help in identifying places where variable scopes can be reduced.
|
||||
@ -621,59 +628,59 @@ be a great help in identifying places where variable scopes can be reduced.
|
||||
Static initializers should be used instead of memset.
|
||||
|
||||
Good:
|
||||
char array[10] = { 0 };
|
||||
char array[10] = { 0 };
|
||||
|
||||
Bad:
|
||||
char array[10];
|
||||
memset(array, 0, sizeof(array));
|
||||
char array[10];
|
||||
memset(array, 0, sizeof(array));
|
||||
|
||||
Designated initializers should be used to initialize structures.
|
||||
|
||||
Good:
|
||||
struct example {
|
||||
int foo;
|
||||
int bar;
|
||||
int baz;
|
||||
};
|
||||
struct example {
|
||||
int foo;
|
||||
int bar;
|
||||
int baz;
|
||||
};
|
||||
|
||||
struct example x = { .foo = -1 };
|
||||
struct example x = { .foo = -1 };
|
||||
|
||||
Bad:
|
||||
struct example {
|
||||
int foo;
|
||||
int bar;
|
||||
int baz;
|
||||
};
|
||||
struct example {
|
||||
int foo;
|
||||
int bar;
|
||||
int baz;
|
||||
};
|
||||
|
||||
struct example x;
|
||||
struct example x;
|
||||
|
||||
x.foo = -1;
|
||||
x.bar = 0;
|
||||
x.baz = 0;
|
||||
x.foo = -1;
|
||||
x.bar = 0;
|
||||
x.baz = 0;
|
||||
|
||||
Good:
|
||||
struct example {
|
||||
int foo;
|
||||
int bar;
|
||||
int baz;
|
||||
};
|
||||
struct example {
|
||||
int foo;
|
||||
int bar;
|
||||
int baz;
|
||||
};
|
||||
|
||||
struct example *x = isc_mem_get(mctx, sizeof(*x));
|
||||
struct example *x = isc_mem_get(mctx, sizeof(*x));
|
||||
|
||||
*x = (struct example){ .foo = -1 };
|
||||
*x = (struct example){ .foo = -1 };
|
||||
|
||||
Bad:
|
||||
struct example {
|
||||
int foo;
|
||||
int bar;
|
||||
int baz;
|
||||
};
|
||||
struct example {
|
||||
int foo;
|
||||
int bar;
|
||||
int baz;
|
||||
};
|
||||
|
||||
struct example *x = isc_mem_get(mctx, sizeof(*x));
|
||||
struct example *x = isc_mem_get(mctx, sizeof(*x));
|
||||
|
||||
x->foo = -1;
|
||||
x->bar = 0;
|
||||
x->baz = 0;
|
||||
x->foo = -1;
|
||||
x->bar = 0;
|
||||
x->baz = 0;
|
||||
|
||||
#### Const
|
||||
|
||||
@ -696,18 +703,18 @@ All public interfaces to functions, macros, typedefs, and variables
|
||||
provided by the library, should use names of the form
|
||||
`{library}_{module}_{what}`, such as:
|
||||
|
||||
isc_buffer_t /* typedef */
|
||||
dns_name_setbuffer(name, buffer) /* function */
|
||||
ISC_LIST_HEAD(list) /* macro */
|
||||
isc_commandline_argument /* variable */
|
||||
isc_buffer_t /* typedef */
|
||||
dns_name_setbuffer(name, buffer) /* function */
|
||||
ISC_LIST_HEAD(list) /* macro */
|
||||
isc_commandline_argument /* variable */
|
||||
|
||||
Structures which are `typedef`'d generally have the name of the typedef
|
||||
sans the final `_t`:
|
||||
|
||||
typedef struct dns_rbtnode dns_rbtnode_t;
|
||||
struct dns_rbtnode {
|
||||
/* ... members ... */
|
||||
}
|
||||
typedef struct dns_rbtnode dns_rbtnode_t;
|
||||
struct dns_rbtnode {
|
||||
/* ... members ... */
|
||||
}
|
||||
|
||||
In some cases, structures are specific to a single C file and are
|
||||
opaque outside that file. In these cases, the `typedef` occurs in the
|
||||
@ -727,35 +734,16 @@ separating natural word elements, as demonstrated in
|
||||
`isc_commandline_argument` and `dns_name_setbuffer` above. The `{module}`
|
||||
part is usually the same as the basename of the source file, but sometimes
|
||||
other `{module}` interfaces appear within one file, such as `dns_label_*`
|
||||
interfaces in `lib/dns/name.c`. However, in the public libraries the file
|
||||
name must be the same as some module interface provided by the file; e.g.,
|
||||
`dns_rbt_*` interfaces would not be declared in a file named redblack.c (in
|
||||
lieu of any other `dns_redblack_*` interfaces in the file).
|
||||
interfaces in `lib/dns/name.c`. But generally, the file name must be
|
||||
the same as some module interface provided by the file; e.g., `dns_rbt_*`
|
||||
interfaces would not be declared in a file named redblack.c (in lieu of any
|
||||
other `dns_redblack_*` interfaces in the file).
|
||||
|
||||
The one notable exception to this naming rule is the interfaces provided by
|
||||
`<isc/util.h>`. There's a large caveat associated with the public
|
||||
description of this file that it is hazardous to use because it pollutes
|
||||
the general namespace.
|
||||
|
||||
When the signature of a public function needs to change, the old function
|
||||
name should be retained for backward compatibility, if at all possible.
|
||||
For example, when `dns_zone_setfile()` needed to include a file format
|
||||
parameter, it was changed to `dns_zone_setfile2()`; the original function
|
||||
name became a wrapper for the new function, calling it with the default
|
||||
value of the format parameter:
|
||||
|
||||
isc_result_t
|
||||
dns_zone_setfile(dns_zone_t *zone, const char *file) {
|
||||
return (dns_zone_setfile2(zone, file, dns_masterformat_text);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_zone_setfile2(dns_zone_t *zone, const char *file,
|
||||
dns_masterformat_t format)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
#### <a name="private_namespace"></a>Shared Private Interfaces
|
||||
|
||||
When a module provides an interface for internal use by other modules in
|
||||
@ -834,7 +822,7 @@ lame".
|
||||
When the variable text forms a separate phrase, such as when it separated
|
||||
from the rest of the message by a colon, it can be left unquoted:
|
||||
|
||||
isc_log_write(... "open: %s: %s", filename, isc_result_totext(result));
|
||||
isc_log_write(... "open: %s: %s", filename, isc_result_totext(result));
|
||||
|
||||
File names (`__FILE__`), line numbers (`__LINE__`), function names,
|
||||
memory addresses, and other references to program internals may be used
|
||||
@ -856,14 +844,14 @@ There are also a few other requirements:
|
||||
* The `__init__()` method should always be the first one declared in a
|
||||
class definition, like so:
|
||||
|
||||
class Foo:
|
||||
# constructor definition here
|
||||
def __init__(self):
|
||||
...
|
||||
# other functions may follow
|
||||
def bar(self):
|
||||
...
|
||||
Close all file and socket objects
|
||||
class Foo:
|
||||
# constructor definition here
|
||||
def __init__(self):
|
||||
...
|
||||
# other functions may follow
|
||||
def bar(self):
|
||||
...
|
||||
Close all file and socket objects
|
||||
|
||||
* All Python standard library objects that have an underlying file
|
||||
descriptor (fd) should be closed explicitly using the `.close()` method.
|
||||
@ -871,8 +859,8 @@ There are also a few other requirements:
|
||||
* In cases where a file is opened and closed in a single block, it
|
||||
is often preferable to use the `with` statement:
|
||||
|
||||
with open('filename') as f:
|
||||
do_something_with(f)
|
||||
with open('filename') as f:
|
||||
do_something_with(f)
|
||||
|
||||
### <a name="plstyle"></a>Perl
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user