linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] clang-format: add configuration file
@ 2018-03-12 23:39 Miguel Ojeda
  2018-03-12 23:45 ` Joe Perches
  2018-03-13 21:00 ` Andrew Morton
  0 siblings, 2 replies; 7+ messages in thread
From: Miguel Ojeda @ 2018-03-12 23:39 UTC (permalink / raw)
  To: rdunlap, apw, joe, corbet, akpm, linux-kernel

clang-format is a tool to format C/C++/... code according to a set
of rules and heuristics. Like all tools, it is not perfect nor
covers every single case, but it is good enough to be helpful.

In particular, it is useful for quickly re-formatting blocks of code,
spotting coding style mistakes, sorting #includes, aligning variables/
comments/macro endings, reflowing text, etc. It also serves as
a teaching tool/guide for newcomers.

The tool itself has been already included in the repositories of popular
Linux distributions for a long time. The rules in this file are intended
for clang-format >= 4, which is easily available in most distributions.

This commit adds the configuration file that contains the rules that
the tool uses to know how to format the code according to the kernel
coding style. This gives us two advantages:

  * clang-format works out of the box with reasonable defaults;
    avoiding that everyone has to re-do the configuration.

  * Everyone agrees (eventually) on what is the most useful default
    configuration for most of the kernel.

Some of clang-format's features relevant for the kernel are:

  * Uses clang's tooling support behind the scenes to parse and rewrite
    the code. It is not based on ad-hoc regexps.

  * Supports reasonably well the Linux kernel coding style.

  * Fast enough to be used at the press of a key.

  * There are already integrations (either built-in or third-party)
    for many common editors used by kernel developers (e.g. vim,
    emacs, Sublime, Atom...) that allow you to format an entire file
    or, more usefully, just your selection.

  * Able to parse unified diffs -- you can, for instance, reformat
    only the lines changed by a git commit.

  * Able to reflow text comments as well.

  * Widely supported and used by hundreds of developers in highly
    complex projects and organizations (e.g. the LLVM project itself,
    Chromium, WebKit, Google, Mozilla...). Therefore, it should be
    supported for a long time.

See more information about the tool at:

    https://clang.llvm.org/docs/ClangFormat.html
    https://clang.llvm.org/docs/ClangFormatStyleOptions.html

Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Andy Whitcroft <apw@canonical.com>
Cc: Joe Perches <joe@perches.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
---
 .clang-format                          | 107 +++++++++++++++++++++++++++++++++
 .gitignore                             |   1 +
 Documentation/process/4.Coding.rst     |   6 ++
 Documentation/process/coding-style.rst |   6 ++
 4 files changed, 120 insertions(+)
 create mode 100644 .clang-format

diff --git a/.clang-format b/.clang-format
new file mode 100644
index 000000000000..de2e083be674
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,107 @@
+# Intended for clang-format >= 4
+---
+AccessModifierOffset: -4
+AlignAfterOpenBracket: DontAlign
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+#AlignEscapedNewlines: Left # Unknown to clang-format-4.0
+AlignOperands: false
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+  AfterClass: false
+  AfterControlStatement: false
+  AfterEnum: true
+  AfterFunction: true
+  AfterNamespace: true
+  AfterObjCDeclaration: false
+  AfterStruct: true
+  AfterUnion: true
+  #AfterExternBlock: true # Unknown to clang-format-5.0
+  BeforeCatch: false
+  BeforeElse: false
+  IndentBraces: false
+  #SplitEmptyFunction: true # Unknown to clang-format-4.0
+  #SplitEmptyRecord: true # Unknown to clang-format-4.0
+  #SplitEmptyNamespace: true # Unknown to clang-format-4.0
+BreakBeforeBinaryOperators: All
+BreakBeforeBraces: Custom
+#BreakBeforeInheritanceComma: false # Unknown to clang-format-4.0
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+#BreakConstructorInitializers: BeforeComma # Unknown to clang-format-4.0
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: true
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+#CompactNamespaces: false # Unknown to clang-format-4.0
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 8
+ContinuationIndentWidth: 8
+Cpp11BracedListStyle: false
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+#FixNamespaceComments: false # Unknown to clang-format-4.0
+ForEachMacros:
+#IncludeBlocks: Preserve # Unknown to clang-format-5.0
+IncludeCategories:
+  - Regex: '.*'
+    Priority: 1
+IncludeIsMainRegex: '(Test)?$'
+IndentCaseLabels: false
+#IndentPPDirectives: None # Unknown to clang-format-5.0
+IndentWidth: 8
+IndentWrappedFunctionNames: true
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: false
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: Inner
+#ObjCBinPackProtocolList: Auto # Unknown to clang-format-5.0
+ObjCBlockIndentWidth: 8
+ObjCSpaceAfterProperty: true
+ObjCSpaceBeforeProtocolList: true
+#PenaltyBreakAssignment: 2 # Unknown to clang-format-4.0
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Right
+ReflowComments: false
+SortIncludes: true
+#SortUsingDeclarations: true # Unknown to clang-format-4.0
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+#SpaceBeforeCtorInitializerColon: true # Unknown to clang-format-5.0
+#SpaceBeforeInheritanceColon: true # Unknown to clang-format-5.0
+SpaceBeforeParens: ControlStatements
+#SpaceBeforeRangeBasedForLoopColon: true # Unknown to clang-format-5.0
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInContainerLiterals: false
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Cpp03
+TabWidth: 8
+UseTab: Always
+...
+
diff --git a/.gitignore b/.gitignore
index 1be78fd8163b..ab5cbc1e85f6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -81,6 +81,7 @@ modules.builtin
 !.gitignore
 !.mailmap
 !.cocciconfig
+!.clang-format
 
 #
 # Generated include files
diff --git a/Documentation/process/4.Coding.rst b/Documentation/process/4.Coding.rst
index 26b106071364..d4bdbb17f2f5 100644
--- a/Documentation/process/4.Coding.rst
+++ b/Documentation/process/4.Coding.rst
@@ -58,6 +58,12 @@ can never be transgressed.  If there is a good reason to go against the
 style (a line which becomes far less readable if split to fit within the
 80-column limit, for example), just do it.
 
+Note that you can use the clang-format tool to help you with these rules
+and to quickly re-format parts of your code automatically. It is specially
+useful for new files/code and to spot coding style mistakes. It is also
+useful to sort #includes, to align variables or comments, to reflow text
+and other similar tasks.
+
 
 Abstraction layers
 ******************
diff --git a/Documentation/process/coding-style.rst b/Documentation/process/coding-style.rst
index a20b44a40ec4..ceac420cd9ec 100644
--- a/Documentation/process/coding-style.rst
+++ b/Documentation/process/coding-style.rst
@@ -622,6 +622,12 @@ options ``-kr -i8`` (stands for ``K&R, 8 character indents``), or use
 re-formatting you may want to take a look at the man page.  But
 remember: ``indent`` is not a fix for bad programming.
 
+Note that you can also use the clang-format tool to help you with these rules
+and to quickly re-format parts of your code automatically. It is specially
+useful for new files/code and to spot coding style mistakes. It is also
+useful to sort #includes, to align variables or comments, to reflow text
+and other similar tasks.
+
 
 10) Kconfig configuration files
 -------------------------------
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] clang-format: add configuration file
  2018-03-12 23:39 [PATCH] clang-format: add configuration file Miguel Ojeda
@ 2018-03-12 23:45 ` Joe Perches
  2018-03-13 21:00 ` Andrew Morton
  1 sibling, 0 replies; 7+ messages in thread
From: Joe Perches @ 2018-03-12 23:45 UTC (permalink / raw)
  To: Miguel Ojeda, rdunlap, apw, corbet, akpm, linux-kernel

On Tue, 2018-03-13 at 00:39 +0100, Miguel Ojeda wrote:
> clang-format is a tool to format C/C++/... code according to a set
> of rules and heuristics. Like all tools, it is not perfect nor
> covers every single case, but it is good enough to be helpful.

Yes, thanks.

It'd also be nice to remove Lindent as clang-format
is a much better tool today and indent is unmaintained
for about a decade.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] clang-format: add configuration file
  2018-03-12 23:39 [PATCH] clang-format: add configuration file Miguel Ojeda
  2018-03-12 23:45 ` Joe Perches
@ 2018-03-13 21:00 ` Andrew Morton
  2018-03-13 21:52   ` Miguel Ojeda
  1 sibling, 1 reply; 7+ messages in thread
From: Andrew Morton @ 2018-03-13 21:00 UTC (permalink / raw)
  To: Miguel Ojeda; +Cc: rdunlap, apw, joe, corbet, linux-kernel

On Tue, 13 Mar 2018 00:39:52 +0100 Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote:

> --- a/Documentation/process/4.Coding.rst
> +++ b/Documentation/process/4.Coding.rst
> @@ -58,6 +58,12 @@ can never be transgressed.  If there is a good reason to go against the
>  style (a line which becomes far less readable if split to fit within the
>  80-column limit, for example), just do it.
>  
> +Note that you can use the clang-format tool to help you with these rules
> +and to quickly re-format parts of your code automatically. It is specially
> +useful for new files/code and to spot coding style mistakes. It is also
> +useful to sort #includes, to align variables or comments, to reflow text
> +and other similar tasks.

It would be rather helpful to tell people how to invoke clang-format. 
Is it just "clang-format foo.c" or what?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] clang-format: add configuration file
  2018-03-13 21:00 ` Andrew Morton
@ 2018-03-13 21:52   ` Miguel Ojeda
  2018-03-13 22:29     ` Joe Perches
  0 siblings, 1 reply; 7+ messages in thread
From: Miguel Ojeda @ 2018-03-13 21:52 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Randy Dunlap, Robo Bot, Joe Perches, Jonathan Corbet, linux-kernel

On Tue, Mar 13, 2018 at 10:00 PM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Tue, 13 Mar 2018 00:39:52 +0100 Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote:
>
>> --- a/Documentation/process/4.Coding.rst
>> +++ b/Documentation/process/4.Coding.rst
>> @@ -58,6 +58,12 @@ can never be transgressed.  If there is a good reason to go against the
>>  style (a line which becomes far less readable if split to fit within the
>>  80-column limit, for example), just do it.
>>
>> +Note that you can use the clang-format tool to help you with these rules
>> +and to quickly re-format parts of your code automatically. It is specially
>> +useful for new files/code and to spot coding style mistakes. It is also
>> +useful to sort #includes, to align variables or comments, to reflow text
>> +and other similar tasks.
>
> It would be rather helpful to tell people how to invoke clang-format.
> Is it just "clang-format foo.c" or what?
>

Indeed! I will add more information. Here is some more we can put (I
will properly rewrite it, but you can see it as a draft and as the
answer to your question! :-)

You can call "clang-format foo.c" and it will output to the standard
output the formatted file (using the configuration file automatically
if it is any of the parents, a la git). The -i does the replacements
inline. However, for the kernel, it is best to use it with one of the
editor integrations: the issue is that clang-format does not format
everything perfectly as we want for the kernel [*], so it is best used
to either 1) format portions of files or 2) check patches.

  - For formatting portions of files, you just select inside your text
editor something and press your favorite key binding to re-format it
(clang-format has some parameters that the editor passes when invoking
it). Since it is very fast, it works very well. Integrations with vim
and emacs come with the tool; for most other popular editors, you can
usually find a plugin or similar in the manager of such editor.

  - For checking patches, since it comes with support to read unified
diffs, it is very easy to use it for patches and for commits. What you
will see is both things that could be improved because there was a
typo/mistake by the patch author, and things that you should ignore
because clang-format does not format those cases -- it is very easy to
know which are which if you use the tool a few times, specially if you
are looking at the difference with git diff.

When I was testing clang-format to come with the configuration, I was
running the tool against full files, and while there were many cases
that have to be ignored, like [*], it is also very easy to see some
mistakes in the code. If it gets popular, I am sure people will come
up with ready-to-be-used scripts/hooks and things like that, but for
the moment I thought the best was to at least have the basic
configuration in and iterate from there. At least there is *one*
person (what an audience! :-) using it currently, since if you grep
for "clang-format" you will see one staging driver with one comment in
the code to turn off the formatting in a block. I also thought that
the sooner we define how we will use it (e.g. whether we allow those
"don't-format-this" marks, the name for those marks -- it is
configurable, etc.), the best.

[*] For instance, it does not support alignment of one-line #defines
-- but it aligns multiline #defines quite well, though. So you won't
run it for full files typically, but for groups of things. Another
simple case where it is best for selections and not for full files (at
least existing files) is the sorting of #includes i.e. It is great if
you use it when selecting a bunch of them that you know will look
better if sorted, but probably you don't want to sort ALL of them
(even if it respects the grouping, which it does); expect if you are
writing a new file.

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] clang-format: add configuration file
  2018-03-13 21:52   ` Miguel Ojeda
@ 2018-03-13 22:29     ` Joe Perches
  2018-03-14  0:18       ` Miguel Ojeda
  0 siblings, 1 reply; 7+ messages in thread
From: Joe Perches @ 2018-03-13 22:29 UTC (permalink / raw)
  To: Miguel Ojeda, Andrew Morton
  Cc: Randy Dunlap, Robo Bot, Jonathan Corbet, linux-kernel

On Tue, 2018-03-13 at 22:52 +0100, Miguel Ojeda wrote:
> On Tue, Mar 13, 2018 at 10:00 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
> > On Tue, 13 Mar 2018 00:39:52 +0100 Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote:
> > > --- a/Documentation/process/4.Coding.rst
> > > +++ b/Documentation/process/4.Coding.rst
> > > @@ -58,6 +58,12 @@ can never be transgressed.  If there is a good reason to go against the
> > >  style (a line which becomes far less readable if split to fit within the
> > >  80-column limit, for example), just do it.
> > > 
> > > +Note that you can use the clang-format tool to help you with these rules
> > > +and to quickly re-format parts of your code automatically. It is specially
> > > +useful for new files/code and to spot coding style mistakes. It is also
> > > +useful to sort #includes, to align variables or comments, to reflow text
> > > +and other similar tasks.
> > 
> > It would be rather helpful to tell people how to invoke clang-format.

clang-format has its drawbacks but at least it is
likely to be improved more in the future.

That is a lot better than Lindent/indent.

Some not kernel-style compliant oddities:

o placements of braces for definitions is like:
static const struct pci_device_id e100_id_table[]
       = { INTEL_8255X_ETHERNET_DEVICE(0x1029, 0),
o alignment of block #defines
o alignment of function arguments
o logical tests continuations moved to BOL not EOL
o misalignment of per-line comments
o location of struct/union/enum braces

etc...

After applying Miguel's patch, try it with something like:

$ git ls-files -- "drivers/net/ethernet/intel/*.[ch]" | \
  while read file ; do clang-format -i $file ; done

and look at the diff (I used clang-format-5.0.0-3)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] clang-format: add configuration file
  2018-03-13 22:29     ` Joe Perches
@ 2018-03-14  0:18       ` Miguel Ojeda
  2018-03-14  0:56         ` Miguel Ojeda
  0 siblings, 1 reply; 7+ messages in thread
From: Miguel Ojeda @ 2018-03-14  0:18 UTC (permalink / raw)
  To: Joe Perches
  Cc: Andrew Morton, Randy Dunlap, Robo Bot, Jonathan Corbet, linux-kernel

On Tue, Mar 13, 2018 at 11:29 PM, Joe Perches <joe@perches.com> wrote:
> On Tue, 2018-03-13 at 22:52 +0100, Miguel Ojeda wrote:
>> On Tue, Mar 13, 2018 at 10:00 PM, Andrew Morton <akpm@linux-foundation.org> wrote:
>> > On Tue, 13 Mar 2018 00:39:52 +0100 Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote:
>> > > --- a/Documentation/process/4.Coding.rst
>> > > +++ b/Documentation/process/4.Coding.rst
>> > > @@ -58,6 +58,12 @@ can never be transgressed.  If there is a good reason to go against the
>> > >  style (a line which becomes far less readable if split to fit within the
>> > >  80-column limit, for example), just do it.
>> > >
>> > > +Note that you can use the clang-format tool to help you with these rules
>> > > +and to quickly re-format parts of your code automatically. It is specially
>> > > +useful for new files/code and to spot coding style mistakes. It is also
>> > > +useful to sort #includes, to align variables or comments, to reflow text
>> > > +and other similar tasks.
>> >
>> > It would be rather helpful to tell people how to invoke clang-format.
>
> clang-format has its drawbacks but at least it is
> likely to be improved more in the future.
>
> That is a lot better than Lindent/indent.
>
> Some not kernel-style compliant oddities:
>
> o placements of braces for definitions is like:
> static const struct pci_device_id e100_id_table[]
>        = { INTEL_8255X_ETHERNET_DEVICE(0x1029, 0),
> o alignment of block #defines

You mean a series of one-line #defines (i.e. the body) or a multiline
#define (i.e. the backspaces)? For the former, indeed, it is what I
saw. It seems that clang-format treats it one by one, and it honors
the column width limitation (so if it does not fit in one line, it
will move it to the next). However, if it fits, it will leave it in
the same line without aligning the bodies of the other #defines.

> o alignment of function arguments

For function signatures in general, I am unsure what options to
apply... I have seen in many places the "indent until the ( in the
previous line", then again, I have seen the "1 tab indentation" style
as well. I have also seen the GNU style (I mean leaving the return
type and other specifiers in the previous line) is also present when
it does not fit in one line. The coding style guide says:

"Statements longer than 80 columns will be broken into sensible chunks, unless
exceeding 80 columns significantly increases readability and does not hide
information. Descendants are always substantially shorter than the parent and
are placed substantially to the right. The same applies to function headers
with a long argument list. However, never break user-visible strings such as
printk messages, because that breaks the ability to grep for them.
"

> o logical tests continuations moved to BOL not EOL

Changed for v2. It does not seem to say anything in the coding style
guide, but you are completely right, it is the prevalent style.

> o misalignment of per-line comments
> o location of struct/union/enum braces

Oops -- fixed.

>
> etc...
>
> After applying Miguel's patch, try it with something like:
>
> $ git ls-files -- "drivers/net/ethernet/intel/*.[ch]" | \
>   while read file ; do clang-format -i $file ; done
>
> and look at the diff (I used clang-format-5.0.0-3)

Thanks a lot for the list/review! It was very useful.

Since we seem to agree on having this, I will send a v2 after I try a
few experiments to try to reduce more the produced diffs, explain
things better in Documentation/, add more comments in the config file
and send a v2.

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] clang-format: add configuration file
  2018-03-14  0:18       ` Miguel Ojeda
@ 2018-03-14  0:56         ` Miguel Ojeda
  0 siblings, 0 replies; 7+ messages in thread
From: Miguel Ojeda @ 2018-03-14  0:56 UTC (permalink / raw)
  To: Joe Perches
  Cc: Andrew Morton, Randy Dunlap, Robo Bot, Jonathan Corbet, linux-kernel

On Wed, Mar 14, 2018 at 1:18 AM, Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>
> Since we seem to agree on having this, I will send a v2 after I try a
> few experiments to try to reduce more the produced diffs, explain
> things better in Documentation/, add more comments in the config file
> and send a v2.

Alright, time for a fun fact: roughly 11 hours after I sent the first
message, Microsoft announces they are going to support clang-format in
Visual Studio 15.7:

  https://blogs.msdn.microsoft.com/vcblog/2018/03/13/clangformat-support-in-visual-studio-2017-15-7-preview-1/

Talk about coincidences... :-)

On related news, Google also announced that they are compiling Chrome
with clang on Windows a week or so ago...

Cheers,
Miguel

[*] Their timestamp: <time class="entry-date published"
datetime="2018-03-13T11:13:51+00:00">March 13, 2018</time>

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2018-03-14  0:56 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-12 23:39 [PATCH] clang-format: add configuration file Miguel Ojeda
2018-03-12 23:45 ` Joe Perches
2018-03-13 21:00 ` Andrew Morton
2018-03-13 21:52   ` Miguel Ojeda
2018-03-13 22:29     ` Joe Perches
2018-03-14  0:18       ` Miguel Ojeda
2018-03-14  0:56         ` Miguel Ojeda

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).