Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id 69D3A431FBC for ; Wed, 13 Jan 2010 05:40:53 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: 0.046 X-Spam-Level: X-Spam-Status: No, score=0.046 tagged_above=-999 required=5 tests=[AWL=-0.574, BAYES_50=0.001, RCVD_IN_SORBS_WEB=0.619] autolearn=no Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6Gn52KVE5+IO for ; Wed, 13 Jan 2010 05:40:52 -0800 (PST) Received: from mail-bw0-f224.google.com (mail-bw0-f224.google.com [209.85.218.224]) by olra.theworths.org (Postfix) with ESMTP id 5B57B431FAE for ; Wed, 13 Jan 2010 05:40:52 -0800 (PST) Received: by bwz24 with SMTP id 24so15214459bwz.30 for ; Wed, 13 Jan 2010 05:40:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:sender:from:to:subject:date :message-id:x-mailer:organization; bh=rtPfbUZNu2K1RvXWAn89qEvCJAiYRaQrzc2HJAY3Kgw=; b=Q1p/WzyXpqW6hSCUUbA4RhE4HtV8l6au2hmPbtU07JXhtN0IpOpwhkOQ16rosLAEGR UCcggM1+Lk2x7atnGE5ZFAUqFthiA85vY4q9vD2EXrX8QYyOPuG+UdTlFxIiw05flKHf BFUDkpi//qP07Cez9rPGNXw+yBueMlRF1XrZU= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:from:to:subject:date:message-id:x-mailer:organization; b=fEvuFDF4WDHNnGZArhIP4ZPnN/QM9WQeoMtywvtScCtgzOtO3gA+GDN2N7PjDCymup NTiI43utgLmiiqlaL67N111ySJrs1Y1Op9KWggsVNOt7N/205qZIi+gdBySwc1yhqAmm NR05v43IvuW3zXeBtC3pMbqIcPvqDJj/mo12Q= Received: by 10.204.27.16 with SMTP id g16mr2569252bkc.97.1263390051237; Wed, 13 Jan 2010 05:40:51 -0800 (PST) Received: from harikalardiyari ([78.179.54.193]) by mx.google.com with ESMTPS id 14sm3618297bwz.1.2010.01.13.05.40.49 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 13 Jan 2010 05:40:50 -0800 (PST) Sender: Ali Polatel From: Ali Polatel To: notmuch@notmuchmail.org Date: Wed, 13 Jan 2010 15:40:42 +0200 Message-Id: <24296f98dcf960342b02d2e1bbb303fd0ad4fa67.1263389936.git.alip@exherbo.org> X-Mailer: git-send-email 1.6.6 Organization: Pink Floyd Subject: [notmuch] [PATCH] Import CODING_STYLE from cairo X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Jan 2010 13:40:53 -0000 A good way to let new contributors know how to contribute :) --- CODING_STYLE | 291 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 291 insertions(+), 0 deletions(-) create mode 100644 CODING_STYLE diff --git a/CODING_STYLE b/CODING_STYLE new file mode 100644 index 0000000..95ceac0 --- /dev/null +++ b/CODING_STYLE @@ -0,0 +1,291 @@ +Cairo coding style. + +This document is intended to be a short description of the preferred +coding style for the cairo source code. Good style requires good +taste, which means this can't all be reduced to automated rules, and +there are exceptions. + +We want the code to be easy to understand and maintain, and consistent +style plays an important part in that, even if some of the specific +details seem trivial. If nothing else, this document gives a place to +put consistent answers for issues that would otherwise be arbitrary. + +Most of the guidelines here are demonstrated by examples, (which means +this document is quicker to read than it might appear given its +length). Most of the examples are positive examples that you should +imitate. The few negative examples are clearly marked with a comment +of /* Yuck! */. Please don't submit code to cairo that looks like any +of these. + +Indentation +----------- +Each new level is indented 4 more spaces than the previous level: + + if (condition) + do_something (); + +This may be achieved with space characters or a combination of tab +characters and space characters. It may not be achieved with tab +characters exclusively (see below). + +Tab characters +-------------- +The tab character must always be interpreted according to its +traditional meaning: + + Advance to the next column which is a multiple of 8. + +With this definition, even levels of indentation can be achieved with +a sequence of tab characters, while odd levels of indentation may +begin with a sequence of tab character but must end with 4 space +characters. + +Some programmers have been misled by certain text editors into +thinking that 4-space indentation can be achieved with tab characters +exclusively by changing the meaning of tab character to be "advance to +the next column which is a multiple of 4". Code formatted in this way, +making an assumption of a fictitious 4-character-tab will not be +accepted into cairo. + +The rationale here is that tabs are used in the code for lining things +up other than indentation, (see the Whitespace section below), and +changing the interpretation of tab from its traditional meaning will +break this alignment. + +Braces +------ +Most of the code in cairo uses bracing in the style of K&R: + + if (condition) { + do_this (); + do_that (); + } else { + do_the_other (); + } + +but some of the code uses an alternate style: + + if (condition) + { + do_this (); + do_that (); + } + else + { + do_the_other (); + } + +and that seems just fine. We won't lay down any strict rule on this +point, (though there should be some local consistency). If you came +here hoping to find some guidance, then use the first form above. + +If all of the substatements of an if statement are single statements, +the optional braces should not usually appear: + + if (condition) + do_this (); + else + do_that (); + +But the braces are mandatory when mixing single statement and compound +statements in the various clauses. For example, do not do this: + + if (condition) { + do_this (); + do_that (); + } else /* Yuck! */ + do_the_other (); + +And of course, there are exceptions for when the code just looks +better with the braces: + + if (condition) { + /* Note that we have to be careful here. */ + do_something_dangerous (with_care); + } + + if (condition && + other_condition && + yet_another) + { + do_something (); + } + +And note that this last example also shows a situation in which the +opening brace really needs to be on its own line. The following looks awful: + + if (condition && + other_condition && + yet_another) { /* Yuck! */ + do_something (); + } + +As we said above, legible code that is easy to understand and maintain +is the goal, not adherence to strict rules. + +Whitespace +---------- +Separate logically distinct chunks with a single newline. This +obviously applies between functions, but also applies within a +function or block and can even be used to good effect within a +structure definition: + + struct _cairo_gstate { + cairo_operator_t op; + + double tolerance; + + /* stroke style */ + double line_width; + cairo_line_cap_t line_cap; + cairo_line_join_t line_join; + double miter_limit; + + cairo_fill_rule_t fill_rule; + + double *dash; + int num_dashes; + double dash_offset; + + ... + } + +Use a single space before a left parenthesis, except where the +standard will not allow it, (eg. when defining a parameterized macro). + +Don't eliminate newlines just because things would still fit on one +line. This breaks the expected visual structure of the code making it +much harder to read and understand: + + if (condition) foo (); else bar (); /* Yuck! */ + +Do eliminate trailing whitespace (space or tab characters) on any +line. Also, avoid putting initial or final blank lines into any file, +and never use multiple blank lines instead of a single blank line. + +Do enable the default git pre-commit hook that detect trailing +whitespace for you and help you to avoid corrupting cairo's tree with +it. Do that as follows: + + chmod a+x .git/hooks/pre-commit + +You might also find the git-stripspace utility helpful which acts as a +filter to remove trailing whitespace as well as initial, final, and +duplicate blank lines. + +As a special case of the bracing and whitespace guidelines, function +definitions should always take the following form: + + void + my_function (argument) + { + do_my_things (); + } + +And function prototypes should similarly have the return type (and +associated specifiers and qualifiers) on a line above the function, so +that the function name is flush left. + +Break up long lines (> ~80 characters) and use whitespace to align +things nicely. For example the arguments in a long list to a function +call should all be aligned with each other: + + align_function_arguments (argument_the_first, + argument_the_second, + argument_the_third); + +And as a special rule, in a function prototype, (as well as in the +definition), whitespace should be inserted between the parameter types +and names so that the names are aligned: + + void + align_parameter_names_in_prototypes (const char *char_star_arg, + int int_arg, + double *double_star_arg, + double double_arg); + +Note that parameters with a * prefix are aligned one character to the +left so that the actual names are aligned. + +Managing nested blocks +---------------------- +Long blocks that are deeply nested make the code very hard to +read. Fortunately such blocks often indicate logically distinct chunks +of functionality that are begging to be split into their own +functions. Please listen to the blocks when they beg. + +In other cases, gratuitous nesting comes about because the primary +functionality gets buried in a nested block rather than living at the +primary level where it belongs. Consider the following: + + foo = malloc (sizeof (foo_t)); + if (foo) { /* Yuck! */ + ... + /* lots of code to initialize foo */ + ... + return SUCCESS; + } + return FAILURE; + +This kind of gratuitous nesting can be avoided by following a pattern +of handling exceptional cases early and returning: + + foo = malloc (sizeof (foo_t)); + if (foo == NULL) + return FAILURE; + + ... + /* lots of code to initialize foo */ + ... + return SUCCESS; + +The return statement is often the best thing to use in a pattern like +this. If it's not available due to additional nesting above which +require some cleanup after the current block, then consider splitting +the current block into a new function before using goto. + +Memory allocation +----------------- + +Because much of cairo's data consists of dynamically allocated arrays, +it's very easy to introduce integer overflow issues whenever malloc() +is called. Use the _cairo_malloc2(), _cairo_malloc3(), and +_cairo_malloc2_add1 macros to avoid these cases; these macros check +for overflow and will return NULL in that case. + + malloc (n * size) => _cairo_malloc_ab (n, size) + e.g. malloc (num_elts * sizeof(some_type)) => + _cairo_malloc2 (num_elts, sizeof(some_type)) + + malloc (a * b * size) => _cairo_malloc_abc (a, b, size) + e.g. malloc (width * height * 4) => + _cairo_malloc3 (width, height, 4) + + malloc (n * size + k) => _cairo_malloc_ab_plus_c (n, size, k) + e.g. malloc (num * sizeof(entry) + sizeof(header)) => + _cairo_malloc2k (num, sizeof(entry), sizeof(header)) + +In general, be wary of performing any arithmetic operations in an +argument to malloc. You should explicitly check for integer overflow +yourself in any more complex situations. + +Mode lines +---------- + +So given the rules above, what is the best way to simplify one's life as +a code monkey? Get your editor to do most of the tedious work of +beautifying your code! + +As a reward for reading this far, here are some mode lines for the more +popular editors: +/* + * vim:sw=4:sts=4:ts=8:tw=78:fo=tcroq:cindent:cino=\:0,(0 + * vim:isk=a-z,A-Z,48-57,_,.,-,> + */ + + +TODO +---- + +Write rules for common editors to use this style. Also cleanup/unify +the modelines in the source files. -- 1.6.6