Files correlati : utilma verione di curl git-svn-id: svn://10.65.10.50/branches/R_10_00@24159 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			239 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			239 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
# 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](INTERNALS.md) 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.
 | 
						|
 | 
						|
    if(something_is_true) {
 | 
						|
      while(second_statement == fine) {
 | 
						|
        moo();
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
## 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 79 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.
 | 
						|
 | 
						|
## Braces
 | 
						|
 | 
						|
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 */
 | 
						|
    }
 | 
						|
 | 
						|
You may omit the braces if they would contain only a one-line statement:
 | 
						|
 | 
						|
    if(!x)
 | 
						|
      continue;
 | 
						|
 | 
						|
For functions the opening brace should be on a separate line:
 | 
						|
 | 
						|
    int main(int argc, char **argv)
 | 
						|
    {
 | 
						|
      return 1;
 | 
						|
    }
 | 
						|
 | 
						|
## '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 grumpy */
 | 
						|
    }
 | 
						|
 | 
						|
## 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 */
 | 
						|
    }
 | 
						|
 | 
						|
## Use boolean conditions
 | 
						|
 | 
						|
Rather than test a conditional value such as a bool against TRUE or FALSE, a
 | 
						|
pointer against NULL or != NULL and an int against zero or not zero in
 | 
						|
if/while conditions we prefer:
 | 
						|
 | 
						|
    result = do_something();
 | 
						|
    if(!result) {
 | 
						|
      /* something went wrong */
 | 
						|
      return result;
 | 
						|
    }
 | 
						|
 | 
						|
## 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)
 | 
						|
      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;
 | 
						|
 | 
						|
## Space around operators
 | 
						|
 | 
						|
Please use spaces on both sides of operators in C expressions.  Postfix `(),
 | 
						|
[], ->, ., ++, --` and Unary `+, - !, ~, &` operators excluded they should
 | 
						|
have no space.
 | 
						|
 | 
						|
Examples:
 | 
						|
 | 
						|
    bla = func();
 | 
						|
    who = name[0];
 | 
						|
    age += 1;
 | 
						|
    true = !false;
 | 
						|
    size += -2 + 3 * (a + b);
 | 
						|
    ptr->member = a++;
 | 
						|
    struct.field = b--;
 | 
						|
    ptr = &address;
 | 
						|
    contents = *pointer;
 | 
						|
    complement = ~bits;
 | 
						|
    empty = (!*string) ? TRUE : FALSE;
 | 
						|
 | 
						|
## Column alignment
 | 
						|
 | 
						|
Some statements cannot be completed on a single line because the line would
 | 
						|
be too long, the statement too hard to read, or due to other style guidelines
 | 
						|
above. In such a case the statement will span multiple lines.
 | 
						|
 | 
						|
If a continuation line is part of an expression or sub-expression then you
 | 
						|
should align on the appropriate column so that it's easy to tell what part of
 | 
						|
the statement it is. Operators should not start continuation lines. In other
 | 
						|
cases follow the 2-space indent guideline. Here are some examples from libcurl:
 | 
						|
 | 
						|
~~~c
 | 
						|
    if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
 | 
						|
       (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
 | 
						|
       (handle->set.httpreq == HTTPREQ_GET ||
 | 
						|
        handle->set.httpreq == HTTPREQ_HEAD))
 | 
						|
      /* didn't ask for HTTP/1.0 and a GET or HEAD */
 | 
						|
      return TRUE;
 | 
						|
~~~
 | 
						|
 | 
						|
~~~c
 | 
						|
  case CURLOPT_KEEP_SENDING_ON_ERROR:
 | 
						|
    data->set.http_keep_sending_on_error = (0 != va_arg(param, long)) ?
 | 
						|
                                           TRUE : FALSE;
 | 
						|
    break;
 | 
						|
~~~
 | 
						|
 | 
						|
~~~c
 | 
						|
    data->set.http_disable_hostname_check_before_authentication =
 | 
						|
      (0 != va_arg(param, long)) ? TRUE : FALSE;
 | 
						|
~~~
 | 
						|
 | 
						|
~~~c
 | 
						|
  if(option) {
 | 
						|
    result = parse_login_details(option, strlen(option),
 | 
						|
                                 (userp ? &user : NULL),
 | 
						|
                                 (passwdp ? &passwd : NULL),
 | 
						|
                                 NULL);
 | 
						|
  }
 | 
						|
~~~
 | 
						|
 | 
						|
~~~c
 | 
						|
        DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing "
 | 
						|
                     "server response left\n",
 | 
						|
                     (int)clipamount));
 | 
						|
~~~
 | 
						|
 | 
						|
## 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);
 |