xref: /curl/docs/CHECKSRC.md (revision 86d33001)
1<!--
2Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
3
4SPDX-License-Identifier: curl
5-->
6
7# checksrc
8
9This is the tool we use within the curl project to scan C source code and
10check that it adheres to our [Source Code Style guide](CODE_STYLE.md).
11
12## Usage
13
14    checksrc.pl [options] [file1] [file2] ...
15
16## Command line options
17
18`-W[file]` skip that file and exclude it from being checked. Helpful
19when, for example, one of the files is generated.
20
21`-D[dir]` directory name to prepend to filenames when accessing them.
22
23`-h` shows the help output, that also lists all recognized warnings
24
25## What does `checksrc` warn for?
26
27`checksrc` does not check and verify the code against the entire style guide.
28The script is an effort to detect the most common mistakes and syntax mistakes
29that contributors make before they get accustomed to our code style. Heck,
30many of us regulars do the mistakes too and this script helps us keep the code
31in shape.
32
33    checksrc.pl -h
34
35Lists how to use the script and it lists all existing warnings it has and
36problems it detects. At the time of this writing, the existing `checksrc`
37warnings are:
38
39- `ASSIGNWITHINCONDITION`: Assignment within a conditional expression. The
40  code style mandates the assignment to be done outside of it.
41
42- `ASTERISKNOSPACE`: A pointer was declared like `char* name` instead of the
43   more appropriate `char *name` style. The asterisk should sit next to the
44   name.
45
46- `ASTERISKSPACE`: A pointer was declared like `char * name` instead of the
47   more appropriate `char *name` style. The asterisk should sit right next to
48   the name without a space in between.
49
50- `BADCOMMAND`: There is a bad `checksrc` instruction in the code. See the
51   **Ignore certain warnings** section below for details.
52
53- `BANNEDFUNC`: A banned function was used. The functions sprintf, vsprintf,
54   strcat, strncat, gets are **never** allowed in curl source code.
55
56- `BRACEELSE`: '} else' on the same line. The else is supposed to be on the
57   following line.
58
59- `BRACEPOS`: wrong position for an open brace (`{`).
60
61- `BRACEWHILE`: more than once space between end brace and while keyword
62
63- `COMMANOSPACE`: a comma without following space
64
65- `COPYRIGHT`: the file is missing a copyright statement
66
67- `CPPCOMMENTS`: `//` comment detected, that is not C89 compliant
68
69- `DOBRACE`: only use one space after do before open brace
70
71- `EMPTYLINEBRACE`: found empty line before open brace
72
73- `EQUALSNOSPACE`: no space after `=` sign
74
75- `EQUALSNULL`: comparison with `== NULL` used in if/while. We use `!var`.
76
77- `EXCLAMATIONSPACE`: space found after exclamations mark
78
79- `FOPENMODE`: `fopen()` needs a macro for the mode string, use it
80
81- `INDENTATION`: detected a wrong start column for code. Note that this
82   warning only checks some specific places and can certainly miss many bad
83   indentations.
84
85- `LONGLINE`: A line is longer than 79 columns.
86
87- `MULTISPACE`: Multiple spaces were found where only one should be used.
88
89- `NOSPACEEQUALS`: An equals sign was found without preceding space. We prefer
90  `a = 2` and *not* `a=2`.
91
92- `NOTEQUALSZERO`: check found using `!= 0`. We use plain `if(var)`.
93
94- `ONELINECONDITION`: do not put the conditional block on the same line as `if()`
95
96- `OPENCOMMENT`: File ended with a comment (`/*`) still "open".
97
98- `PARENBRACE`: `){` was used without sufficient space in between.
99
100- `RETURNNOSPACE`: `return` was used without space between the keyword and the
101   following value.
102
103- `SEMINOSPACE`: There was no space (or newline) following a semicolon.
104
105- `SIZEOFNOPAREN`: Found use of sizeof without parentheses. We prefer
106  `sizeof(int)` style.
107
108- `SNPRINTF` - Found use of `snprintf()`. Since we use an internal replacement
109   with a different return code etc, we prefer `msnprintf()`.
110
111- `SPACEAFTERPAREN`: there was a space after open parenthesis, `( text`.
112
113- `SPACEBEFORECLOSE`: there was a space before a close parenthesis, `text )`.
114
115- `SPACEBEFORECOMMA`: there was a space before a comma, `one , two`.
116
117- `SPACEBEFOREPAREN`: there was a space before an open parenthesis, `if (`,
118   where one was not expected
119
120- `SPACESEMICOLON`: there was a space before semicolon, ` ;`.
121
122- `TABS`: TAB characters are not allowed
123
124- `TRAILINGSPACE`: Trailing whitespace on the line
125
126- `TYPEDEFSTRUCT`: we frown upon (most) typedefed structs
127
128- `UNUSEDIGNORE`: a `checksrc` inlined warning ignore was asked for but not
129   used, that is an ignore that should be removed or changed to get used.
130
131### Extended warnings
132
133Some warnings are quite computationally expensive to perform, so they are
134turned off by default. To enable these warnings, place a `.checksrc` file in
135the directory where they should be activated with commands to enable the
136warnings you are interested in. The format of the file is to enable one
137warning per line like so: `enable <EXTENDEDWARNING>`
138
139Currently these are the extended warnings which can be enabled:
140
141- `COPYRIGHTYEAR`: the current changeset has not updated the copyright year in
142   the source file
143
144- `STRERROR`: use of banned function strerror()
145
146- `STDERR`: use of banned variable `stderr`
147
148## Ignore certain warnings
149
150Due to the nature of the source code and the flaws of the `checksrc` tool,
151there is sometimes a need to ignore specific warnings. `checksrc` allows a few
152different ways to do this.
153
154### Inline ignore
155
156You can control what to ignore within a specific source file by providing
157instructions to `checksrc` in the source code itself. See examples below. The
158instruction can ask to ignore a specific warning a specific number of times or
159you ignore all of them until you mark the end of the ignored section.
160
161Inline ignores are only done for that single specific source code file.
162
163Example
164
165    /* !checksrc! disable LONGLINE all */
166
167This ignores the warning for overly long lines until it is re-enabled with:
168
169    /* !checksrc! enable LONGLINE */
170
171If the enabling is not performed before the end of the file, it is enabled
172again automatically for the next file.
173
174You can also opt to ignore just N violations so that if you have a single long
175line you just cannot shorten and is agreed to be fine anyway:
176
177    /* !checksrc! disable LONGLINE 1 */
178
179... and the warning for long lines is enabled again automatically after it has
180ignored that single warning. The number `1` can of course be changed to any
181other integer number. It can be used to make sure only the exact intended
182instances are ignored and nothing extra.
183
184### Directory wide ignore patterns
185
186This is a method we have transitioned away from. Use inline ignores as far as
187possible.
188
189Make a `checksrc.skip` file in the directory of the source code with the
190false positive, and include the full offending line into this file.
191