[{"id":474,"web_url":"https://patchwork.libcamera.org/comment/474/","msgid":"<81764c90-00df-655a-630a-e04177a024a1@ideasonboard.com>","date":"2019-01-22T10:31:36","subject":"Re: [libcamera-devel] [PATCH v2 2/2] utils: checkstyle: Add support\n\tfor clang-format","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Hi Laurent,\n\nOn 21/01/2019 18:01, Laurent Pinchart wrote:\n> clang-format produces better results than astyle as it can better match\n> the libcamera coding style. Default to clang-format over astyle, fall\n> back to astyle if clang-format isn't found, and add a --formatter\n> command line option to select a formatter manually.\n\n\nAll I can find is a minor spelling error below:\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>  Documentation/coding-style.rst | 25 ++++++++----\n>  utils/checkstyle.py            | 70 +++++++++++++++++++++++++---------\n>  2 files changed, 71 insertions(+), 24 deletions(-)\n> \n> diff --git a/Documentation/coding-style.rst b/Documentation/coding-style.rst\n> index 30a1455d8c65..02cdc1677bf1 100644\n> --- a/Documentation/coding-style.rst\n> +++ b/Documentation/coding-style.rst\n> @@ -170,8 +170,11 @@ These rules match the `object ownership rules from the Chromium C++ Style Guide`\n>  Tools\n>  -----\n>  \n> -The 'astyle' code formatting tool can be used to reformat source files with the\n> -libcamera coding style, defined by the following arguments.\n> +The 'clang-format' code formatting tool can be used to reformat source files\n> +with the libcamera coding style, defined in the .clang-format file at the root\n> +of the source tree.\n> +\n> +Alternatively the 'astyle' tool can also be used, with the following arguments.\n>  \n>  ::\n>  \n> @@ -184,11 +187,15 @@ libcamera coding style, defined by the following arguments.\n>    --align-reference=name\n>    --max-code-length=120\n>  \n> -As astyle is a code formatter, it operates on full files outputs reformatted\n> -source code. While it can be used to reformat code before sending patches, it\n> -may generate unrelated changes. To avoid this, libcamera provides a\n> -'checkstyle.py' script wrapping astyle to only retain related changes. This\n> -should be used to validate modifications before submitting them for review.\n> +Use of astyle is discourage as clang-format better matches the libcamera coding\n\ns/discourage/discouraged/\n\n> +style.\n> +\n> +As both astyle and clang-format are code formatters, they operate on full files\n> +and output reformatted source code. While they can be used to reformat code\n> +before sending patches, it may generate unrelated changes. To avoid this,\n> +libcamera provides a 'checkstyle.py' script wrapping the formatting tools to\n> +only retain related changes. This should be used to validate modifications\n> +before submitting them for review.\n>  \n>  The script operates on one or multiple git commits specified on the command\n>  line. It does not modify the git tree, the index or the working directory and\n> @@ -277,4 +284,8 @@ diff that fixes the issues, on top of the corresponding commit. As the script is\n>  in early development false positive are expected. The flagged issues should be\n>  reviewed, but the diff doesn't need to be applied blindly.\n>  \n> +The checkstyle.py script uses clang-format by default if found, and otherwise\n> +falls back to astyle. The formatter can be manually selected with the\n> +'--formatter' argument.\n> +\n>  Happy hacking, libcamera awaits your patches!\n> diff --git a/utils/checkstyle.py b/utils/checkstyle.py\n> index a40d7dec879f..f3005d1fbb52 100755\n> --- a/utils/checkstyle.py\n> +++ b/utils/checkstyle.py\n> @@ -4,11 +4,11 @@\n>  #\n>  # Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>  #\n> -# checkstyle.py - A patch style checker script based on astyle\n> +# checkstyle.py - A patch style checker script based on astyle or clang-format\n>  #\n>  # TODO:\n>  #\n> -# - Support other formatting tools (clang-format, ...)\n> +# - Support other formatting tools and checkers (cppcheck, cpplint, kwstyle, ...)\n>  # - Split large hunks to minimize context noise\n>  # - Improve style issues counting\n>  #\n> @@ -33,6 +33,12 @@ astyle_options = (\n>      '--max-code-length=120'\n>  )\n>  \n> +dependencies = {\n> +    'astyle': False,\n> +    'clang-format': False,\n> +    'git': True,\n> +}\n> +\n>  source_extensions = (\n>      '.c',\n>      '.cpp',\n> @@ -192,30 +198,38 @@ def parse_diff(diff):\n>  # Code reformatting\n>  #\n>  \n> -def formatter_astyle(data):\n> +def formatter_astyle(filename, data):\n>      ret = subprocess.run(['astyle', *astyle_options],\n>                           input=data.encode('utf-8'), stdout=subprocess.PIPE)\n>      return ret.stdout.decode('utf-8')\n>  \n>  \n> -def formatter_strip_trailing_space(data):\n> +def formatter_clang_format(filename, data):\n> +    ret = subprocess.run(['clang-format', '-style=file',\n> +                          '-assume-filename=' + filename],\n> +                         input=data.encode('utf-8'), stdout=subprocess.PIPE)\n> +    return ret.stdout.decode('utf-8')\n> +\n> +\n> +def formatter_strip_trailing_space(filename, data):\n>      lines = data.split('\\n')\n>      for i in range(len(lines)):\n>          lines[i] = lines[i].rstrip() + '\\n'\n>      return ''.join(lines)\n>  \n>  \n> -formatters = [\n> -    formatter_astyle,\n> -    formatter_strip_trailing_space,\n> -]\n> +available_formatters = {\n> +    'astyle': formatter_astyle,\n> +    'clang-format': formatter_clang_format,\n> +    'strip-trailing-spaces': formatter_strip_trailing_space,\n> +}\n>  \n>  \n>  # ------------------------------------------------------------------------------\n>  # Style checking\n>  #\n>  \n> -def check_file(top_level, commit, filename):\n> +def check_file(top_level, commit, filename, formatters):\n>      # Extract the line numbers touched by the commit.\n>      diff = subprocess.run(['git', 'diff', '%s~..%s' % (commit, commit), '--',\n>                             '%s/%s' % (top_level, filename)],\n> @@ -239,7 +253,8 @@ def check_file(top_level, commit, filename):\n>  \n>      formatted = after\n>      for formatter in formatters:\n> -        formatted = formatter(formatted)\n> +        formatter = available_formatters[formatter]\n> +        formatted = formatter(filename, formatted)\n>  \n>      after = after.splitlines(True)\n>      formatted = formatted.splitlines(True)\n> @@ -261,7 +276,7 @@ def check_file(top_level, commit, filename):\n>      return len(formatted_diff)\n>  \n>  \n> -def check_style(top_level, commit):\n> +def check_style(top_level, commit, formatters):\n>      # Get the commit title and list of files.\n>      ret = subprocess.run(['git', 'show', '--pretty=oneline','--name-only', commit],\n>                           stdout=subprocess.PIPE)\n> @@ -282,7 +297,7 @@ def check_style(top_level, commit):\n>  \n>      issues = 0\n>      for f in files:\n> -        issues += check_file(top_level, commit, f)\n> +        issues += check_file(top_level, commit, f, formatters)\n>  \n>      if issues == 0:\n>          print(\"No style issue detected\")\n> @@ -330,17 +345,38 @@ def main(argv):\n>  \n>      # Parse command line arguments\n>      parser = argparse.ArgumentParser()\n> +    parser.add_argument('--formatter', '-f', type=str, choices=['astyle', 'clang-format'],\n> +                        help='Code formatter. Default to clang-format if not specified.')\n>      parser.add_argument('revision_range', type=str, default='HEAD', nargs='?',\n>                          help='Revision range (as defined by git rev-parse). Defaults to HEAD if not specified.')\n>      args = parser.parse_args(argv[1:])\n>  \n>      # Check for required dependencies.\n> -    dependencies = ('astyle', 'git')\n> +    for command, mandatory in dependencies.items():\n> +        found = shutil.which(command)\n> +        if mandatory and not found:\n> +            print(\"Executable %s not found\" % command)\n> +            return 1\n>  \n> -    for dependency in dependencies:\n> -        if not shutil.which(dependency):\n> -            print(\"Executable %s not found\" % dependency)\n> +        dependencies[command] = found\n> +\n> +    if args.formatter:\n> +        if not args.formatter in dependencies or \\\n> +           not dependencies[args.formatter]:\n> +            print(\"Formatter %s not available\" % args.formatter)\n>              return 1\n> +        formatter = args.formatter\n> +    else:\n> +        if dependencies['clang-format']:\n> +            formatter = 'clang-format'\n> +        elif dependencies['astyle']:\n> +            formatter = 'astyle'\n> +        else:\n> +            print(\"No formatter found, please install clang-format or astyle\")\n> +            return 1\n> +\n> +    # Create the list of formatters to be applied.\n> +    formatters = [formatter, 'strip-trailing-spaces']\n>  \n>      # Get the top level directory to pass absolute file names to git diff\n>      # commands, in order to support execution from subdirectories of the git\n> @@ -352,7 +388,7 @@ def main(argv):\n>      revlist = extract_revlist(args.revision_range)\n>  \n>      for commit in revlist:\n> -        check_style(top_level, commit)\n> +        check_style(top_level, commit, formatters)\n>          print('')\n>  \n>      return 0\n>","headers":{"Return-Path":"<kieran.bingham@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 10CC260C80\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 22 Jan 2019 11:31:41 +0100 (CET)","from [192.168.0.21]\n\t(cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 359CE53E;\n\tTue, 22 Jan 2019 11:31:40 +0100 (CET)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1548153100;\n\tbh=r4tVs0f4qfx1Z7h3KxPBbZOTKVMNGtunxgwdvUoj/cY=;\n\th=Reply-To:Subject:To:References:From:Date:In-Reply-To:From;\n\tb=p/nMNaertQ2uYKChOJTRARYsV5QOvzpyeWy1vYNYb+o3ynVqgPv/xxgSa8C1oyR3j\n\te9R7l18x8bnGuQ0l9N+g4moexBQu+k70udRJ9HFcfNJnCZrKvBF0TrpA+y6AUD9S5/\n\tONoDqqgh/AAj+FYolesf4jIUdYcJ+zhR88H/zll4=","Reply-To":"kieran.bingham@ideasonboard.com","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20190121180128.1261-1-laurent.pinchart@ideasonboard.com>\n\t<20190121180128.1261-2-laurent.pinchart@ideasonboard.com>","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Openpgp":"preference=signencrypt","Autocrypt":"addr=kieran.bingham@ideasonboard.com; keydata=\n\tmQINBFYE/WYBEACs1PwjMD9rgCu1hlIiUA1AXR4rv2v+BCLUq//vrX5S5bjzxKAryRf0uHat\n\tV/zwz6hiDrZuHUACDB7X8OaQcwhLaVlq6byfoBr25+hbZG7G3+5EUl9cQ7dQEdvNj6V6y/SC\n\trRanWfelwQThCHckbobWiQJfK9n7rYNcPMq9B8e9F020LFH7Kj6YmO95ewJGgLm+idg1Kb3C\n\tpotzWkXc1xmPzcQ1fvQMOfMwdS+4SNw4rY9f07Xb2K99rjMwZVDgESKIzhsDB5GY465sCsiQ\n\tcSAZRxqE49RTBq2+EQsbrQpIc8XiffAB8qexh5/QPzCmR4kJgCGeHIXBtgRj+nIkCJPZvZtf\n\tKr2EAbc6tgg6DkAEHJb+1okosV09+0+TXywYvtEop/WUOWQ+zo+Y/OBd+8Ptgt1pDRyOBzL8\n\tRXa8ZqRf0Mwg75D+dKntZeJHzPRJyrlfQokngAAs4PaFt6UfS+ypMAF37T6CeDArQC41V3ko\n\tlPn1yMsVD0p+6i3DPvA/GPIksDC4owjnzVX9kM8Zc5Cx+XoAN0w5Eqo4t6qEVbuettxx55gq\n\t8K8FieAjgjMSxngo/HST8TpFeqI5nVeq0/lqtBRQKumuIqDg+Bkr4L1V/PSB6XgQcOdhtd36\n\tOe9X9dXB8YSNt7VjOcO7BTmFn/Z8r92mSAfHXpb07YJWJosQOQARAQABtDBLaWVyYW4gQmlu\n\tZ2hhbSA8a2llcmFuLmJpbmdoYW1AaWRlYXNvbmJvYXJkLmNvbT6JAkAEEwEKACoCGwMFCwkI\n\tBwIGFQgJCgsCBBYCAwECHgECF4ACGQEFAlnDk/gFCQeA/YsACgkQoR5GchCkYf3X5w/9EaZ7\n\tcnUcT6dxjxrcmmMnfFPoQA1iQXr/MXQJBjFWfxRUWYzjvUJb2D/FpA8FY7y+vksoJP7pWDL7\n\tQTbksdwzagUEk7CU45iLWL/CZ/knYhj1I/+5LSLFmvZ/5Gf5xn2ZCsmg7C0MdW/GbJ8IjWA8\n\t/LKJSEYH8tefoiG6+9xSNp1p0Gesu3vhje/GdGX4wDsfAxx1rIYDYVoX4bDM+uBUQh7sQox/\n\tR1bS0AaVJzPNcjeC14MS226mQRUaUPc9250aj44WmDfcg44/kMsoLFEmQo2II9aOlxUDJ+x1\n\txohGbh9mgBoVawMO3RMBihcEjo/8ytW6v7xSF+xP4Oc+HOn7qebAkxhSWcRxQVaQYw3S9iZz\n\t2iA09AXAkbvPKuMSXi4uau5daXStfBnmOfalG0j+9Y6hOFjz5j0XzaoF6Pln0jisDtWltYhP\n\tX9LjFVhhLkTzPZB/xOeWGmsG4gv2V2ExbU3uAmb7t1VSD9+IO3Km4FtnYOKBWlxwEd8qOFpS\n\tjEqMXURKOiJvnw3OXe9MqG19XdeENA1KyhK5rqjpwdvPGfSn2V+SlsdJA0DFsobUScD9qXQw\n\tOvhapHe3XboK2+Rd7L+g/9Ud7ZKLQHAsMBXOVJbufA1AT+IaOt0ugMcFkAR5UbBg5+dZUYJj\n\t1QbPQcGmM3wfvuaWV5+SlJ+WeKIb8ta5Ag0EVgT9ZgEQAM4o5G/kmruIQJ3K9SYzmPishRHV\n\tDcUcvoakyXSX2mIoccmo9BHtD9MxIt+QmxOpYFNFM7YofX4lG0ld8H7FqoNVLd/+a0yru5Cx\n\tadeZBe3qr1eLns10Q90LuMo7/6zJhCW2w+HE7xgmCHejAwuNe3+7yt4QmwlSGUqdxl8cgtS1\n\tPlEK93xXDsgsJj/bw1EfSVdAUqhx8UQ3aVFxNug5OpoX9FdWJLKROUrfNeBE16RLrNrq2ROc\n\tiSFETpVjyC/oZtzRFnwD9Or7EFMi76/xrWzk+/b15RJ9WrpXGMrttHUUcYZEOoiC2lEXMSAF\n\tSSSj4vHbKDJ0vKQdEFtdgB1roqzxdIOg4rlHz5qwOTynueiBpaZI3PHDudZSMR5Fk6QjFooE\n\tXTw3sSl/km/lvUFiv9CYyHOLdygWohvDuMkV/Jpdkfq8XwFSjOle+vT/4VqERnYFDIGBxaRx\n\tkoBLfNDiiuR3lD8tnJ4A1F88K6ojOUs+jndKsOaQpDZV6iNFv8IaNIklTPvPkZsmNDhJMRHH\n\tIu60S7BpzNeQeT4yyY4dX9lC2JL/LOEpw8DGf5BNOP1KgjCvyp1/KcFxDAo89IeqljaRsCdP\n\t7WCIECWYem6pLwaw6IAL7oX+tEqIMPph/G/jwZcdS6Hkyt/esHPuHNwX4guqTbVEuRqbDzDI\n\t2DJO5FbxABEBAAGJAiUEGAEKAA8CGwwFAlnDlGsFCQeA/gIACgkQoR5GchCkYf1yYRAAq+Yo\n\tnbf9DGdK1kTAm2RTFg+w9oOp2Xjqfhds2PAhFFvrHQg1XfQR/UF/SjeUmaOmLSczM0s6XMeO\n\tVcE77UFtJ/+hLo4PRFKm5X1Pcar6g5m4xGqa+Xfzi9tRkwC29KMCoQOag1BhHChgqYaUH3yo\n\tUzaPwT/fY75iVI+yD0ih/e6j8qYvP8pvGwMQfrmN9YB0zB39YzCSdaUaNrWGD3iCBxg6lwSO\n\tLKeRhxxfiXCIYEf3vwOsP3YMx2JkD5doseXmWBGW1U0T/oJF+DVfKB6mv5UfsTzpVhJRgee7\n\t4jkjqFq4qsUGxcvF2xtRkfHFpZDbRgRlVmiWkqDkT4qMA+4q1y/dWwshSKi/uwVZNycuLsz+\n\t+OD8xPNCsMTqeUkAKfbD8xW4LCay3r/dD2ckoxRxtMD9eOAyu5wYzo/ydIPTh1QEj9SYyvp8\n\tO0g6CpxEwyHUQtF5oh15O018z3ZLztFJKR3RD42VKVsrnNDKnoY0f4U0z7eJv2NeF8xHMuiU\n\tRCIzqxX1GVYaNkKTnb/Qja8hnYnkUzY1Lc+OtwiGmXTwYsPZjjAaDX35J/RSKAoy5wGo/YFA\n\tJxB1gWThL4kOTbsqqXj9GLcyOImkW0lJGGR3o/fV91Zh63S5TKnf2YGGGzxki+ADdxVQAm+Q\n\tsbsRB8KNNvVXBOVNwko86rQqF9drZuw=","Organization":"Ideas on Board","Message-ID":"<81764c90-00df-655a-630a-e04177a024a1@ideasonboard.com>","Date":"Tue, 22 Jan 2019 10:31:36 +0000","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101\n\tThunderbird/60.2.1","MIME-Version":"1.0","In-Reply-To":"<20190121180128.1261-2-laurent.pinchart@ideasonboard.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-GB","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [PATCH v2 2/2] utils: checkstyle: Add support\n\tfor clang-format","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Tue, 22 Jan 2019 10:31:41 -0000"}},{"id":477,"web_url":"https://patchwork.libcamera.org/comment/477/","msgid":"<20190122112516.GI6484@bigcity.dyn.berto.se>","date":"2019-01-22T11:25:16","subject":"Re: [libcamera-devel] [PATCH v2 2/2] utils: checkstyle: Add support\n\tfor clang-format","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Laurent,\n\nThanks for your work.\n\nOn 2019-01-21 20:01:28 +0200, Laurent Pinchart wrote:\n> clang-format produces better results than astyle as it can better match\n> the libcamera coding style. Default to clang-format over astyle, fall\n> back to astyle if clang-format isn't found, and add a --formatter\n> command line option to select a formatter manually.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nWith the comment Kieran points out,\n\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n\n> ---\n>  Documentation/coding-style.rst | 25 ++++++++----\n>  utils/checkstyle.py            | 70 +++++++++++++++++++++++++---------\n>  2 files changed, 71 insertions(+), 24 deletions(-)\n> \n> diff --git a/Documentation/coding-style.rst b/Documentation/coding-style.rst\n> index 30a1455d8c65..02cdc1677bf1 100644\n> --- a/Documentation/coding-style.rst\n> +++ b/Documentation/coding-style.rst\n> @@ -170,8 +170,11 @@ These rules match the `object ownership rules from the Chromium C++ Style Guide`\n>  Tools\n>  -----\n>  \n> -The 'astyle' code formatting tool can be used to reformat source files with the\n> -libcamera coding style, defined by the following arguments.\n> +The 'clang-format' code formatting tool can be used to reformat source files\n> +with the libcamera coding style, defined in the .clang-format file at the root\n> +of the source tree.\n> +\n> +Alternatively the 'astyle' tool can also be used, with the following arguments.\n>  \n>  ::\n>  \n> @@ -184,11 +187,15 @@ libcamera coding style, defined by the following arguments.\n>    --align-reference=name\n>    --max-code-length=120\n>  \n> -As astyle is a code formatter, it operates on full files outputs reformatted\n> -source code. While it can be used to reformat code before sending patches, it\n> -may generate unrelated changes. To avoid this, libcamera provides a\n> -'checkstyle.py' script wrapping astyle to only retain related changes. This\n> -should be used to validate modifications before submitting them for review.\n> +Use of astyle is discourage as clang-format better matches the libcamera coding\n> +style.\n> +\n> +As both astyle and clang-format are code formatters, they operate on full files\n> +and output reformatted source code. While they can be used to reformat code\n> +before sending patches, it may generate unrelated changes. To avoid this,\n> +libcamera provides a 'checkstyle.py' script wrapping the formatting tools to\n> +only retain related changes. This should be used to validate modifications\n> +before submitting them for review.\n>  \n>  The script operates on one or multiple git commits specified on the command\n>  line. It does not modify the git tree, the index or the working directory and\n> @@ -277,4 +284,8 @@ diff that fixes the issues, on top of the corresponding commit. As the script is\n>  in early development false positive are expected. The flagged issues should be\n>  reviewed, but the diff doesn't need to be applied blindly.\n>  \n> +The checkstyle.py script uses clang-format by default if found, and otherwise\n> +falls back to astyle. The formatter can be manually selected with the\n> +'--formatter' argument.\n> +\n>  Happy hacking, libcamera awaits your patches!\n> diff --git a/utils/checkstyle.py b/utils/checkstyle.py\n> index a40d7dec879f..f3005d1fbb52 100755\n> --- a/utils/checkstyle.py\n> +++ b/utils/checkstyle.py\n> @@ -4,11 +4,11 @@\n>  #\n>  # Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>  #\n> -# checkstyle.py - A patch style checker script based on astyle\n> +# checkstyle.py - A patch style checker script based on astyle or clang-format\n>  #\n>  # TODO:\n>  #\n> -# - Support other formatting tools (clang-format, ...)\n> +# - Support other formatting tools and checkers (cppcheck, cpplint, kwstyle, ...)\n>  # - Split large hunks to minimize context noise\n>  # - Improve style issues counting\n>  #\n> @@ -33,6 +33,12 @@ astyle_options = (\n>      '--max-code-length=120'\n>  )\n>  \n> +dependencies = {\n> +    'astyle': False,\n> +    'clang-format': False,\n> +    'git': True,\n> +}\n> +\n>  source_extensions = (\n>      '.c',\n>      '.cpp',\n> @@ -192,30 +198,38 @@ def parse_diff(diff):\n>  # Code reformatting\n>  #\n>  \n> -def formatter_astyle(data):\n> +def formatter_astyle(filename, data):\n>      ret = subprocess.run(['astyle', *astyle_options],\n>                           input=data.encode('utf-8'), stdout=subprocess.PIPE)\n>      return ret.stdout.decode('utf-8')\n>  \n>  \n> -def formatter_strip_trailing_space(data):\n> +def formatter_clang_format(filename, data):\n> +    ret = subprocess.run(['clang-format', '-style=file',\n> +                          '-assume-filename=' + filename],\n> +                         input=data.encode('utf-8'), stdout=subprocess.PIPE)\n> +    return ret.stdout.decode('utf-8')\n> +\n> +\n> +def formatter_strip_trailing_space(filename, data):\n>      lines = data.split('\\n')\n>      for i in range(len(lines)):\n>          lines[i] = lines[i].rstrip() + '\\n'\n>      return ''.join(lines)\n>  \n>  \n> -formatters = [\n> -    formatter_astyle,\n> -    formatter_strip_trailing_space,\n> -]\n> +available_formatters = {\n> +    'astyle': formatter_astyle,\n> +    'clang-format': formatter_clang_format,\n> +    'strip-trailing-spaces': formatter_strip_trailing_space,\n> +}\n>  \n>  \n>  # ------------------------------------------------------------------------------\n>  # Style checking\n>  #\n>  \n> -def check_file(top_level, commit, filename):\n> +def check_file(top_level, commit, filename, formatters):\n>      # Extract the line numbers touched by the commit.\n>      diff = subprocess.run(['git', 'diff', '%s~..%s' % (commit, commit), '--',\n>                             '%s/%s' % (top_level, filename)],\n> @@ -239,7 +253,8 @@ def check_file(top_level, commit, filename):\n>  \n>      formatted = after\n>      for formatter in formatters:\n> -        formatted = formatter(formatted)\n> +        formatter = available_formatters[formatter]\n> +        formatted = formatter(filename, formatted)\n>  \n>      after = after.splitlines(True)\n>      formatted = formatted.splitlines(True)\n> @@ -261,7 +276,7 @@ def check_file(top_level, commit, filename):\n>      return len(formatted_diff)\n>  \n>  \n> -def check_style(top_level, commit):\n> +def check_style(top_level, commit, formatters):\n>      # Get the commit title and list of files.\n>      ret = subprocess.run(['git', 'show', '--pretty=oneline','--name-only', commit],\n>                           stdout=subprocess.PIPE)\n> @@ -282,7 +297,7 @@ def check_style(top_level, commit):\n>  \n>      issues = 0\n>      for f in files:\n> -        issues += check_file(top_level, commit, f)\n> +        issues += check_file(top_level, commit, f, formatters)\n>  \n>      if issues == 0:\n>          print(\"No style issue detected\")\n> @@ -330,17 +345,38 @@ def main(argv):\n>  \n>      # Parse command line arguments\n>      parser = argparse.ArgumentParser()\n> +    parser.add_argument('--formatter', '-f', type=str, choices=['astyle', 'clang-format'],\n> +                        help='Code formatter. Default to clang-format if not specified.')\n>      parser.add_argument('revision_range', type=str, default='HEAD', nargs='?',\n>                          help='Revision range (as defined by git rev-parse). Defaults to HEAD if not specified.')\n>      args = parser.parse_args(argv[1:])\n>  \n>      # Check for required dependencies.\n> -    dependencies = ('astyle', 'git')\n> +    for command, mandatory in dependencies.items():\n> +        found = shutil.which(command)\n> +        if mandatory and not found:\n> +            print(\"Executable %s not found\" % command)\n> +            return 1\n>  \n> -    for dependency in dependencies:\n> -        if not shutil.which(dependency):\n> -            print(\"Executable %s not found\" % dependency)\n> +        dependencies[command] = found\n> +\n> +    if args.formatter:\n> +        if not args.formatter in dependencies or \\\n> +           not dependencies[args.formatter]:\n> +            print(\"Formatter %s not available\" % args.formatter)\n>              return 1\n> +        formatter = args.formatter\n> +    else:\n> +        if dependencies['clang-format']:\n> +            formatter = 'clang-format'\n> +        elif dependencies['astyle']:\n> +            formatter = 'astyle'\n> +        else:\n> +            print(\"No formatter found, please install clang-format or astyle\")\n> +            return 1\n> +\n> +    # Create the list of formatters to be applied.\n> +    formatters = [formatter, 'strip-trailing-spaces']\n>  \n>      # Get the top level directory to pass absolute file names to git diff\n>      # commands, in order to support execution from subdirectories of the git\n> @@ -352,7 +388,7 @@ def main(argv):\n>      revlist = extract_revlist(args.revision_range)\n>  \n>      for commit in revlist:\n> -        check_style(top_level, commit)\n> +        check_style(top_level, commit, formatters)\n>          print('')\n>  \n>      return 0\n> -- \n> Regards,\n> \n> Laurent Pinchart\n> \n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","headers":{"Return-Path":"<niklas.soderlund@ragnatech.se>","Received":["from mail-lf1-x143.google.com (mail-lf1-x143.google.com\n\t[IPv6:2a00:1450:4864:20::143])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 02F3060B21\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 22 Jan 2019 12:25:19 +0100 (CET)","by mail-lf1-x143.google.com with SMTP id a8so17794673lfk.5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 22 Jan 2019 03:25:18 -0800 (PST)","from localhost (89-233-230-99.cust.bredband2.com. [89.233.230.99])\n\tby smtp.gmail.com with ESMTPSA id\n\tj25-v6sm2862249lji.77.2019.01.22.03.25.17\n\t(version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);\n\tTue, 22 Jan 2019 03:25:17 -0800 (PST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to\n\t:user-agent; bh=+FvN7vwtb1GKtK6V5c4S8192Mh5vPsYBvdKEoigvgtk=;\n\tb=WOpuYhNUFsSDk6419qCA2eu44iBjvJ4d9YnHujYeMK7D+V55Lgxzk42u2CLArcl+6Q\n\tAwqnayB6oL7LWiyUYWXIxSKh2PFiZmrjqi3s0e3fc1Aze2cfTRdUiH+ZH8vdk+43wcJn\n\tjPcMlz2tEz6iANOnJozfVBqhgbRxDDxX5LLzsevRnvQsspx258vRaiOSVhlc7sG4VMgf\n\td+4i3/LRNy+gY1b440uvx9sXth4swVMyZJr0Eqog6Jv456sn3Y0S+MsXRYTKAJREW36u\n\tKXWNiIkKYXTzuSyRsNiv90dd2t8KNQrPXyIyARZm5nrfRxKYmWKUZQGdWSfZNxGY1jJD\n\tzHkQ==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to:user-agent;\n\tbh=+FvN7vwtb1GKtK6V5c4S8192Mh5vPsYBvdKEoigvgtk=;\n\tb=j0z4OyprISgK6EpG/Jukzf8LOIhyO+Dixvq2JrTUPqAKFwnnSS6szJUBq3wTaRoNzg\n\tR7v4XoBUFRWyd4C71iQJegD0tqQb1e+5RS4IJgHJJ8oC9HilM3sEkv8hpdyIPIp74wJH\n\tv7Q2yMRYb6dAQg8LwcLKobayqSoFNl8z3JGNXIk9rHmDkMcfq+U79b8qbi8NcxCuRhYZ\n\tOOgKfPIxLldGfumuu7IvFXd3amG2syRpLtu549DFw1jhhSId2IEFeMt9QRvRrKrC+q1X\n\tSUefCzqIRvIpitYAduxc16GNTFdDfrDPAqdlt6M0sXm/pUi/3AqfpvBw92hoyN8RzPsb\n\t2kXQ==","X-Gm-Message-State":"AJcUukfnpqpNuZ6H8U9PtfB0N1DLZxuGGILGxqF5+FdK4efslwfAIYr7\n\tWPyTRcQ1STZFp+spcde7aVzk/+UgDYQ=","X-Google-Smtp-Source":"ALg8bN4295J1VX7epNIDtC2VFrkMc8gFtA+Kh2fqB/7v5z9LnBOVqOJw3wVHiwE3w5uIESla+DuurA==","X-Received":"by 2002:a19:980f:: with SMTP id\n\ta15mr21613219lfe.103.1548156317906; \n\tTue, 22 Jan 2019 03:25:17 -0800 (PST)","Date":"Tue, 22 Jan 2019 12:25:16 +0100","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20190122112516.GI6484@bigcity.dyn.berto.se>","References":"<20190121180128.1261-1-laurent.pinchart@ideasonboard.com>\n\t<20190121180128.1261-2-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=iso-8859-1","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20190121180128.1261-2-laurent.pinchart@ideasonboard.com>","User-Agent":"Mutt/1.10.1 (2018-07-13)","Subject":"Re: [libcamera-devel] [PATCH v2 2/2] utils: checkstyle: Add support\n\tfor clang-format","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Tue, 22 Jan 2019 11:25:19 -0000"}}]