Annotation of embedaddon/curl/docs/CODE_STYLE.md, revision 1.1.1.1

1.1       misho       1: # curl C code style
                      2: 
                      3: Source code that has a common style is easier to read than code that uses
                      4: different styles in different places. It helps making the code feel like one
                      5: single code base. Easy-to-read is a very important property of code and helps
                      6: making it easier to review when new things are added and it helps debugging
                      7: code when developers are trying to figure out why things go wrong. A unified
                      8: style is more important than individual contributors having their own personal
                      9: tastes satisfied.
                     10: 
                     11: Our C code has a few style rules. Most of them are verified and upheld by the
                     12: `lib/checksrc.pl` script. Invoked with `make checksrc` or even by default by
                     13: the build system when built after `./configure --enable-debug` has been used.
                     14: 
                     15: It is normally not a problem for anyone to follow the guidelines, as you just
                     16: need to copy the style already used in the source code and there are no
                     17: particularly unusual rules in our set of rules.
                     18: 
                     19: We also work hard on writing code that are warning-free on all the major
                     20: platforms and in general on as many platforms as possible. Code that obviously
                     21: will cause warnings will not be accepted as-is.
                     22: 
                     23: ## Naming
                     24: 
                     25: Try using a non-confusing naming scheme for your new functions and variable
                     26: names. It doesn't necessarily have to mean that you should use the same as in
                     27: other places of the code, just that the names should be logical,
                     28: understandable and be named according to what they're used for. File-local
                     29: functions should be made static. We like lower case names.
                     30: 
                     31: See the [INTERNALS](INTERNALS.md) document on how we name non-exported
                     32: library-global symbols.
                     33: 
                     34: ## Indenting
                     35: 
                     36: We use only spaces for indentation, never TABs. We use two spaces for each new
                     37: open brace.
                     38: 
                     39:     if(something_is_true) {
                     40:       while(second_statement == fine) {
                     41:         moo();
                     42:       }
                     43:     }
                     44: 
                     45: ## Comments
                     46: 
                     47: Since we write C89 code, **//** comments are not allowed. They weren't
                     48: introduced in the C standard until C99. We use only **/* comments */**.
                     49: 
                     50:     /* this is a comment */
                     51: 
                     52: ## Long lines
                     53: 
                     54: Source code in curl may never be wider than 79 columns and there are two
                     55: reasons for maintaining this even in the modern era of very large and high
                     56: resolution screens:
                     57: 
                     58: 1. Narrower columns are easier to read than very wide ones. There's a reason
                     59:    newspapers have used columns for decades or centuries.
                     60: 
                     61: 2. Narrower columns allow developers to easier show multiple pieces of code
                     62:    next to each other in different windows. I often have two or three source
                     63:    code windows next to each other on the same screen - as well as multiple
                     64:    terminal and debugging windows.
                     65: 
                     66: ## Braces
                     67: 
                     68: In if/while/do/for expressions, we write the open brace on the same line as
                     69: the keyword and we then set the closing brace on the same indentation level as
                     70: the initial keyword. Like this:
                     71: 
                     72:     if(age < 40) {
                     73:       /* clearly a youngster */
                     74:     }
                     75: 
                     76: You may omit the braces if they would contain only a one-line statement:
                     77: 
                     78:     if(!x)
                     79:       continue;
                     80: 
                     81: For functions the opening brace should be on a separate line:
                     82: 
                     83:     int main(int argc, char **argv)
                     84:     {
                     85:       return 1;
                     86:     }
                     87: 
                     88: ## 'else' on the following line
                     89: 
                     90: When adding an **else** clause to a conditional expression using braces, we
                     91: add it on a new line after the closing brace. Like this:
                     92: 
                     93:     if(age < 40) {
                     94:       /* clearly a youngster */
                     95:     }
                     96:     else {
                     97:       /* probably grumpy */
                     98:     }
                     99: 
                    100: ## No space before parentheses
                    101: 
                    102: When writing expressions using if/while/do/for, there shall be no space
                    103: between the keyword and the open parenthesis. Like this:
                    104: 
                    105:     while(1) {
                    106:       /* loop forever */
                    107:     }
                    108: 
                    109: ## Use boolean conditions
                    110: 
                    111: Rather than test a conditional value such as a bool against TRUE or FALSE, a
                    112: pointer against NULL or != NULL and an int against zero or not zero in
                    113: if/while conditions we prefer:
                    114: 
                    115:     result = do_something();
                    116:     if(!result) {
                    117:       /* something went wrong */
                    118:       return result;
                    119:     }
                    120: 
                    121: ## No assignments in conditions
                    122: 
                    123: To increase readability and reduce complexity of conditionals, we avoid
                    124: assigning variables within if/while conditions. We frown upon this style:
                    125: 
                    126:     if((ptr = malloc(100)) == NULL)
                    127:       return NULL;
                    128: 
                    129: and instead we encourage the above version to be spelled out more clearly:
                    130: 
                    131:     ptr = malloc(100);
                    132:     if(!ptr)
                    133:       return NULL;
                    134: 
                    135: ## New block on a new line
                    136: 
                    137: We never write multiple statements on the same source line, even for very
                    138: short if() conditions.
                    139: 
                    140:     if(a)
                    141:       return TRUE;
                    142:     else if(b)
                    143:       return FALSE;
                    144: 
                    145: and NEVER:
                    146: 
                    147:     if(a) return TRUE;
                    148:     else if(b) return FALSE;
                    149: 
                    150: ## Space around operators
                    151: 
                    152: Please use spaces on both sides of operators in C expressions.  Postfix **(),
                    153: [], ->, ., ++, --** and Unary **+, - !, ~, &** operators excluded they should
                    154: have no space.
                    155: 
                    156: Examples:
                    157: 
                    158:     bla = func();
                    159:     who = name[0];
                    160:     age += 1;
                    161:     true = !false;
                    162:     size += -2 + 3 * (a + b);
                    163:     ptr->member = a++;
                    164:     struct.field = b--;
                    165:     ptr = &address;
                    166:     contents = *pointer;
                    167:     complement = ~bits;
                    168:     empty = (!*string) ? TRUE : FALSE;
                    169: 
                    170: ## No parentheses for return values
                    171: 
                    172: We use the 'return' statement without extra parentheses around the value:
                    173: 
                    174:     int works(void)
                    175:     {
                    176:       return TRUE;
                    177:     }
                    178: 
                    179: ## Parentheses for sizeof arguments
                    180: 
                    181: When using the sizeof operator in code, we prefer it to be written with
                    182: parentheses around its argument:
                    183: 
                    184:     int size = sizeof(int);
                    185: 
                    186: ## Column alignment
                    187: 
                    188: Some statements cannot be completed on a single line because the line would be
                    189: too long, the statement too hard to read, or due to other style guidelines
                    190: above. In such a case the statement will span multiple lines.
                    191: 
                    192: If a continuation line is part of an expression or sub-expression then you
                    193: should align on the appropriate column so that it's easy to tell what part of
                    194: the statement it is. Operators should not start continuation lines. In other
                    195: cases follow the 2-space indent guideline. Here are some examples from
                    196: libcurl:
                    197: 
                    198:     if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
                    199:        (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
                    200:        (handle->set.httpreq == HTTPREQ_GET ||
                    201:         handle->set.httpreq == HTTPREQ_HEAD))
                    202:       /* didn't ask for HTTP/1.0 and a GET or HEAD */
                    203:       return TRUE;
                    204: 
                    205: If no parenthesis, use the default indent:
                    206: 
                    207:     data->set.http_disable_hostname_check_before_authentication =
                    208:       (0 != va_arg(param, long)) ? TRUE : FALSE;
                    209: 
                    210: Function invoke with an open parenthesis:
                    211: 
                    212:     if(option) {
                    213:       result = parse_login_details(option, strlen(option),
                    214:                                    (userp ? &user : NULL),
                    215:                                    (passwdp ? &passwd : NULL),
                    216:                                    NULL);
                    217:     }
                    218: 
                    219: Align with the "current open" parenthesis:
                    220: 
                    221:     DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing "
                    222:                  "server response left\n",
                    223:                  (int)clipamount));
                    224: 
                    225: ## Platform dependent code
                    226: 
                    227: Use **#ifdef HAVE_FEATURE** to do conditional code. We avoid checking for
                    228: particular operating systems or hardware in the #ifdef lines. The HAVE_FEATURE
                    229: shall be generated by the configure script for unix-like systems and they are
                    230: hard-coded in the `config-[system].h` files for the others.
                    231: 
                    232: We also encourage use of macros/functions that possibly are empty or defined
                    233: to constants when libcurl is built without that feature, to make the code
                    234: seamless. Like this example where the **magic()** function works differently
                    235: depending on a build-time conditional:
                    236: 
                    237:     #ifdef HAVE_MAGIC
                    238:     void magic(int a)
                    239:     {
                    240:       return a + 2;
                    241:     }
                    242:     #else
                    243:     #define magic(x) 1
                    244:     #endif
                    245: 
                    246:     int content = magic(3);

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>