summaryrefslogtreecommitdiff
path: root/docs/CODE_STYLE.md
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2016-03-14 10:28:54 +0100
committerDaniel Stenberg <daniel@haxx.se>2016-03-14 10:28:54 +0100
commit303bf719ff810114e335e7d562b11f9fc3c3ff57 (patch)
tree364b3723e1de6cede162de9525c2367876cc2fb8 /docs/CODE_STYLE.md
parent3c6238b3eb833c88ec864e33b6bc072a3557667f (diff)
downloadcurl-303bf719ff810114e335e7d562b11f9fc3c3ff57.tar.gz
CODE_STYLE: initial version
Ripped out from CONTRIBUTE into its own document, but also extended from there.
Diffstat (limited to 'docs/CODE_STYLE.md')
-rw-r--r--docs/CODE_STYLE.md140
1 files changed, 140 insertions, 0 deletions
diff --git a/docs/CODE_STYLE.md b/docs/CODE_STYLE.md
new file mode 100644
index 000000000..bcf13b46d
--- /dev/null
+++ b/docs/CODE_STYLE.md
@@ -0,0 +1,140 @@
+# cURL C code style
+
+Source code that has a common style is easier to read than code that uses
+different styles in different places. It helps making the code feel like one
+single code base. Easy-to-read is a very important property of code and helps
+making it easier to review when new things are added and it helps debugging
+code when developers are trying to figure out why things go wrong. A unified
+style is more important than individual contributors having their own personal
+tastes satisfied.
+
+Our C code has a few style rules. Most of them are verified and upheld by the
+lib/checksrc.pl script. Invoked with `make checksrc` or even by default by the
+build system when built after `./configure --enable-debug` has been used.
+
+It is normally not a problem for anyone to follow the guidelines, as you just
+need to copy the style already used in the source code and there are no
+particularly unusual rules in our set of rules.
+
+We also work hard on writing code that are warning-free on all the major
+platforms and in general on as many platforms as possible. Code that obviously
+will cause warnings will not be accepted as-is.
+
+## Naming
+
+Try using a non-confusing naming scheme for your new functions and variable
+names. It doesn't necessarily have to mean that you should use the same as in
+other places of the code, just that the names should be logical,
+understandable and be named according to what they're used for. File-local
+functions should be made static. We like lower case names.
+
+See the INTERNALS document on how we name non-exported library-global symbols.
+
+## Indenting
+
+We use only spaces for indentation, never TABs. We use two spaces for each new
+open brace.
+
+## Comments
+
+Since we write C89 code, `//` comments are not allowed. They weren't
+introduced in the C standard until C99. We use only `/*` and `*/` comments:
+
+ /* this is a comment */
+
+## Long lines
+
+Source code in curl may never be wider than 80 columns and there are two
+reasons for maintaining this even in the modern era of very large and high
+resolution screens:
+
+1. Narrower columns are easier to read than very wide ones. There's a reason
+ newspapers have used columns for decades or centuries.
+
+2. Narrower columns allow developers to easier show multiple pieces of code
+ next to each other in different windows. I often have two or three source
+ code windows next to each other on the same screen - as well as multiple
+ terminal and debugging windows.
+
+## Open brace on the same line
+
+In if/while/do/for expressions, we write the open brace on the same line as
+the keyword and we then set the closing brace on the same indentation level as
+the initial keyword. Like this:
+
+ if(age < 40) {
+ /* clearly a youngster */
+ }
+
+## 'else' on the following line
+
+When adding an `else` clause to a conditional expression using braces, we add
+it on a new line after the closing brace. Like this:
+
+ if(age < 40) {
+ /* clearly a youngster */
+ }
+ else {
+ /* probably intelligent */
+ }
+
+## No space before parentheses
+
+When writing expressions using if/while/do/for, there shall be no space
+between the keyword and the open parenthesis. Like this:
+
+ while(1) {
+ /* loop forever */
+ }
+
+## No assignments in conditions
+
+To increase readability and reduce complexity of conditionals, we avoid
+assigning variables within if/while conditions. We frown upon this style:
+
+ if((ptr = malloc(100)) == NULL)
+ return NULL;
+
+and instead we encourage the above version to be spelled out more clearly:
+
+ ptr = malloc(100);
+ if(ptr == NULL)
+ return NULL;
+
+## New block on a new line
+
+We never write multiple statements on the same source line, even for very
+short if() conditions.
+
+ if(a)
+ return TRUE;
+ else if(b)
+ return FALSE;
+
+and NEVER:
+
+ if(a) return TRUE;
+ else if(b) return FALSE;
+
+## Platform dependent code
+
+Use `#ifdef HAVE_FEATURE` to do conditional code. We avoid checking for
+particular operating systems or hardware in the #ifdef lines. The HAVE_FEATURE
+shall be generated by the configure script for unix-like systems and they are
+hard-coded in the config-[system].h files for the others.
+
+We also encourage use of macros/functions that possibly are empty or defined
+to constants when libcurl is built without that feature, to make the code
+seamless. Like this style where the `magic()` function works differently
+depending on a build-time conditional:
+
+ #ifdef HAVE_MAGIC
+ void magic(int a)
+ {
+ return a+2;
+ }
+ #else
+ #define magic(x) 1
+ #endif
+
+ int content = magic(3);