Annotation of embedaddon/curl/docs/CODE_STYLE.md, revision 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>