r189946 - Added documentation for clang-format style options.

Alexander Kornienko alexfh at google.com
Wed Sep 4 08:09:13 PDT 2013


Author: alexfh
Date: Wed Sep  4 10:09:13 2013
New Revision: 189946

URL: http://llvm.org/viewvc/llvm-project?rev=189946&view=rev
Log:
Added documentation for clang-format style options.

Summary:
The main contents is in the ClangFormatStyleOptions.rst, which can be
updated from the Format.h by the dump_format_style.py script.

Reviewers: djasper, klimek

Reviewed By: klimek

CC: cfe-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D1597

Added:
    cfe/trunk/docs/ClangFormatStyleOptions.rst
    cfe/trunk/docs/tools/dump_format_style.py
Modified:
    cfe/trunk/docs/ClangFormat.rst
    cfe/trunk/docs/index.rst

Modified: cfe/trunk/docs/ClangFormat.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangFormat.rst?rev=189946&r1=189945&r2=189946&view=diff
==============================================================================
--- cfe/trunk/docs/ClangFormat.rst (original)
+++ cfe/trunk/docs/ClangFormat.rst Wed Sep  4 10:09:13 2013
@@ -70,6 +70,20 @@ to format C/C++/Obj-C code.
     -version                 - Display the version of this program
 
 
+When the desired code formatting style is different from the available options,
+the style can be customized using the ``-style="{key: value, ...}"`` option or
+by putting your style configuration to the ``.clang-format`` file in your
+project's directory and using ``clang-format -style=file``.
+
+An easy way to create the ``.clang-format`` file is:
+
+.. code-block:: console
+
+  clang-format -style=llvm -dump-config > .clang-format
+
+Available style options are described in :doc:`ClangFormatStyleOptions`.
+
+
 Vim Integration
 ===============
 

Added: cfe/trunk/docs/ClangFormatStyleOptions.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangFormatStyleOptions.rst?rev=189946&view=auto
==============================================================================
--- cfe/trunk/docs/ClangFormatStyleOptions.rst (added)
+++ cfe/trunk/docs/ClangFormatStyleOptions.rst Wed Sep  4 10:09:13 2013
@@ -0,0 +1,375 @@
+==========================
+Clang-Format Style Options
+==========================
+
+:doc:`ClangFormatStyleOptions` describes configurable formatting style options
+supported by :doc:`LibFormat` and :doc:`ClangFormat`.
+
+When using :program:`clang-format` command line utility or
+``clang::format::reformat(...)`` functions from code, one can either use one of
+the predefined styles (LLVM, Google, Chromium, Mozilla, WebKit) or create a
+custom style by configuring specific style options.
+
+
+Configuring Style with clang-format
+===================================
+
+:program:`clang-format` supports two ways to provide custom style options:
+directly specify style configuration in the ``-style=`` command line option or
+use ``-style=file`` and put style configuration in the ``.clang-format`` file
+in the project directory.
+
+When using ``-style=file``, :program:`clang-format` for each input file will
+try to find the ``.clang-format`` file located in the closest parent directory
+of the input file. When the standard input is used, the search is started from
+the current directory.
+
+The ``.clang-format`` file uses YAML format:
+
+.. code-block:: yaml
+
+  key1: value1
+  key2: value2
+  # A comment.
+  ...
+
+An easy way to get a valid ``.clang-format`` file containing all configuration
+options of a certain predefined style is:
+
+.. code-block:: console
+
+  clang-format -style=llvm -dump-config > .clang-format
+
+When specifying configuration in the ``-style=`` option, the same configuration
+is applied for all input files. The format of the configuration is:
+
+.. code-block:: console
+
+  -style='{key1: value1, key2: value2, ...}'
+
+
+Configuring Style in Code
+=========================
+
+When using ``clang::format::reformat(...)`` functions, the format is specified
+by supplying the `clang::format::FormatStyle
+<http://clang.llvm.org/doxygen/structclang_1_1format_1_1FormatStyle.html>`_
+structure.
+
+
+Configurable Format Style Options
+=================================
+
+This section lists the supported style options. Value type is specified for
+each option. For enumeration types possible values are specified both as a C++
+enumeration member (with a prefix, e.g. LS_Auto), and as a value usable in the
+configuration (without a prefix).
+
+
+**BasedOnStyle** (``string``)
+  The style used for all options not specifically set in the configuration.
+
+  This option is supported only in the :program:`clang-format` configuration
+  (both within ``-style='{...}'`` and the ``.clang-format`` file).
+
+  Possible values:
+
+  * ``LLVM``
+    A style complying with the `LLVM coding standards
+    <http://llvm.org/docs/CodingStandards.html>`_
+  * ``Google``
+    A style complying with `Google's C++ style guide
+    <http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml>`_
+  * ``Chromium``
+    A style complying with `Chromium's style guide
+    <http://www.chromium.org/developers/coding-style>`_
+  * ``Mozilla``
+    A style complying with `Mozilla's style guide
+    <https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style>`_
+  * ``WebKit``
+    A style complying with `WebKit's style guide
+    <http://www.webkit.org/coding/coding-style.html>`_
+
+.. START_FORMAT_STYLE_OPTIONS
+
+**AccessModifierOffset** (``int``)
+  The extra indent or outdent of access modifiers, e.g. ``public:``.
+
+**AlignEscapedNewlinesLeft** (``bool``)
+  If ``true``, aligns escaped newlines as far left as possible.
+  Otherwise puts them into the right-most column.
+
+**AlignTrailingComments** (``bool``)
+  If ``true``, aligns trailing comments.
+
+**AllowAllParametersOfDeclarationOnNextLine** (``bool``)
+  Allow putting all parameters of a function declaration onto
+  the next line even if ``BinPackParameters`` is ``false``.
+
+**AllowShortIfStatementsOnASingleLine** (``bool``)
+  If ``true``, ``if (a) return;`` can be put on a single
+  line.
+
+**AllowShortLoopsOnASingleLine** (``bool``)
+  If ``true``, ``while (true) continue;`` can be put on a
+  single line.
+
+**AlwaysBreakBeforeMultilineStrings** (``bool``)
+  If ``true``, always break before multiline string literals.
+
+**AlwaysBreakTemplateDeclarations** (``bool``)
+  If ``true``, always break after the ``template<...>`` of a
+  template declaration.
+
+**BinPackParameters** (``bool``)
+  If ``false``, a function call's or function definition's parameters
+  will either all be on the same line or will have one line each.
+
+**BreakBeforeBinaryOperators** (``bool``)
+  If ``true``, binary operators will be placed after line breaks.
+
+**BreakBeforeBraces** (``BraceBreakingStyle``)
+  The brace breaking style to use.
+
+  Possible values:
+
+  * ``BS_Attach`` (in configuration: ``Attach``)
+    Always attach braces to surrounding context.
+  * ``BS_Linux`` (in configuration: ``Linux``)
+    Like ``Attach``, but break before braces on function, namespace and
+    class definitions.
+  * ``BS_Stroustrup`` (in configuration: ``Stroustrup``)
+    Like ``Attach``, but break before function definitions.
+  * ``BS_Allman`` (in configuration: ``Allman``)
+    Always break before braces.
+
+
+**BreakConstructorInitializersBeforeComma** (``bool``)
+  Always break constructor initializers before commas and align
+  the commas with the colon.
+
+**ColumnLimit** (``unsigned``)
+  The column limit.
+
+  A column limit of ``0`` means that there is no column limit. In this case,
+  clang-format will respect the input's line breaking decisions within
+  statements.
+
+**ConstructorInitializerAllOnOneLineOrOnePerLine** (``bool``)
+  If the constructor initializers don't fit on a line, put each
+  initializer on its own line.
+
+**ConstructorInitializerIndentWidth** (``unsigned``)
+  The number of characters to use for indentation of constructor
+  initializer lists.
+
+**Cpp11BracedListStyle** (``bool``)
+  If ``true``, format braced lists as best suited for C++11 braced
+  lists.
+
+  Important differences:
+  - No spaces inside the braced list.
+  - No line break before the closing brace.
+  - Indentation with the continuation indent, not with the block indent.
+
+  Fundamentally, C++11 braced lists are formatted exactly like function
+  calls would be formatted in their place. If the braced list follows a name
+  (e.g. a type or variable name), clang-format formats as if the ``{}`` were
+  the parentheses of a function call with that name. If there is no name,
+  a zero-length name is assumed.
+
+**DerivePointerBinding** (``bool``)
+  If ``true``, analyze the formatted file for the most common binding.
+
+**ExperimentalAutoDetectBinPacking** (``bool``)
+  If ``true``, clang-format detects whether function calls and
+  definitions are formatted with one parameter per line.
+
+  Each call can be bin-packed, one-per-line or inconclusive. If it is
+  inconclusive, e.g. completely on one line, but a decision needs to be
+  made, clang-format analyzes whether there are other bin-packed cases in
+  the input file and act accordingly.
+
+  NOTE: This is an experimental flag, that might go away or be renamed. Do
+  not use this in config files, etc. Use at your own risk.
+
+**IndentCaseLabels** (``bool``)
+  Indent case labels one level from the switch statement.
+
+  When ``false``, use the same indentation level as for the switch statement.
+  Switch statement body is always indented one level more than case labels.
+
+**IndentFunctionDeclarationAfterType** (``bool``)
+  If ``true``, indent when breaking function declarations which
+  are not also definitions after the type.
+
+**IndentWidth** (``unsigned``)
+  The number of characters to use for indentation.
+
+**MaxEmptyLinesToKeep** (``unsigned``)
+  The maximum number of consecutive empty lines to keep.
+
+**NamespaceIndentation** (``NamespaceIndentationKind``)
+  The indentation used for namespaces.
+
+  Possible values:
+
+  * ``NI_None`` (in configuration: ``None``)
+    Don't indent in namespaces.
+  * ``NI_Inner`` (in configuration: ``Inner``)
+    Indent only in inner namespaces (nested in other namespaces).
+  * ``NI_All`` (in configuration: ``All``)
+    Indent in all namespaces.
+
+
+**ObjCSpaceBeforeProtocolList** (``bool``)
+  Add a space in front of an Objective-C protocol list, i.e. use
+  ``Foo <Protocol>`` instead of ``Foo<Protocol>``.
+
+**PenaltyBreakComment** (``unsigned``)
+  The penalty for each line break introduced inside a comment.
+
+**PenaltyBreakFirstLessLess** (``unsigned``)
+  The penalty for breaking before the first ``<<``.
+
+**PenaltyBreakString** (``unsigned``)
+  The penalty for each line break introduced inside a string literal.
+
+**PenaltyExcessCharacter** (``unsigned``)
+  The penalty for each character outside of the column limit.
+
+**PenaltyReturnTypeOnItsOwnLine** (``unsigned``)
+  Penalty for putting the return type of a function onto its own
+  line.
+
+**PointerBindsToType** (``bool``)
+  Set whether & and * bind to the type as opposed to the variable.
+
+**SpaceAfterControlStatementKeyword** (``bool``)
+  If ``true``, spaces will be inserted between 'for'/'if'/'while'/...
+  and '('.
+
+**SpaceInEmptyParentheses** (``bool``)
+  If ``false``, spaces may be inserted into '()'.
+
+**SpacesBeforeTrailingComments** (``unsigned``)
+  The number of spaces to before trailing line comments.
+
+**SpacesInCStyleCastParentheses** (``bool``)
+  If ``false``, spaces may be inserted into C style casts.
+
+**SpacesInParentheses** (``bool``)
+  If ``true``, spaces will be inserted after every '(' and before
+  every ')'.
+
+**Standard** (``LanguageStandard``)
+  Format compatible with this standard, e.g. use
+  ``A<A<int> >`` instead of ``A<A<int>>`` for LS_Cpp03.
+
+  Possible values:
+
+  * ``LS_Cpp03`` (in configuration: ``Cpp03``)
+    Use C++03-compatible syntax.
+  * ``LS_Cpp11`` (in configuration: ``Cpp11``)
+    Use features of C++11 (e.g. ``A<A<int>>`` instead of
+    ``A<A<int> >``).
+  * ``LS_Auto`` (in configuration: ``Auto``)
+    Automatic detection based on the input.
+
+
+**UseTab** (``bool``)
+  If ``true``, ``IndentWidth`` consecutive spaces will be replaced
+  with tab characters.
+
+.. END_FORMAT_STYLE_OPTIONS
+
+Examples
+========
+
+A style similar to the `Linux Kernel style
+<https://www.kernel.org/doc/Documentation/CodingStyle>`_:
+
+.. code-block:: yaml
+
+  BasedOnStyle: LLVM
+  IndentWidth: 8
+  UseTab: true
+  BreakBeforeBraces: Linux
+  AllowShortIfStatementsOnASingleLine: false
+  IndentCaseLabels: false
+
+The result is (imagine that tabs are used for indentation here):
+
+.. code-block:: c++
+
+  void test()
+  {
+          switch (x) {
+          case 0:
+          case 1:
+                  do_something();
+                  break;
+          case 2:
+                  do_something_else();
+                  break;
+          default:
+                  break;
+          }
+          if (condition)
+                  do_something_completely_different();
+
+          if (x == y) {
+                  q();
+          } else if (x > y) {
+                  w();
+          } else {
+                  r();
+          }
+  }
+
+A style similar to the default Visual Studio formatting style:
+
+.. code-block:: yaml
+
+  UseTab: false
+  IndentWidth: 4
+  BreakBeforeBraces: Allman
+  AllowShortIfStatementsOnASingleLine: false
+  IndentCaseLabels: false
+  ColumnLimit: 0
+
+The result is:
+
+.. code-block:: c++
+
+  void test()
+  {
+      switch (suffix)
+      {
+      case 0:
+      case 1:
+          do_something();
+          break;
+      case 2:
+          do_something_else();
+          break;
+      default:
+          break;
+      }
+      if (condition)
+          do_somthing_completely_different();
+
+      if (x == y)
+      {
+          q();
+      }
+      else if (x > y)
+      {
+          w();
+      }
+      else
+      {
+          r();
+      }
+  }
+

Modified: cfe/trunk/docs/index.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/index.rst?rev=189946&r1=189945&r2=189946&view=diff
==============================================================================
--- cfe/trunk/docs/index.rst (original)
+++ cfe/trunk/docs/index.rst Wed Sep  4 10:09:13 2013
@@ -53,6 +53,7 @@ Using Clang Tools
    ClangTools
    ClangCheck
    ClangFormat
+   ClangFormatStyleOptions
 
 Design Documents
 ================

Added: cfe/trunk/docs/tools/dump_format_style.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/tools/dump_format_style.py?rev=189946&view=auto
==============================================================================
--- cfe/trunk/docs/tools/dump_format_style.py (added)
+++ cfe/trunk/docs/tools/dump_format_style.py Wed Sep  4 10:09:13 2013
@@ -0,0 +1,143 @@
+#!/usr/bin/env python
+# A tool to parse the FormatStyle struct from Format.h and update the
+# documentation in ../ClangFormatStyleOptions.rst automatically.
+# Run from the directory in which this file is located to update the docs.
+
+import collections
+import re
+import urllib2
+
+FORMAT_STYLE_FILE = '../../include/clang/Format/Format.h'
+DOC_FILE = '../ClangFormatStyleOptions.rst'
+
+
+def substitute(text, tag, contents):
+  replacement = '\n.. START_%s\n\n%s\n\n.. END_%s\n' % (tag, contents, tag)
+  pattern = r'\n\.\. START_%s\n.*\n\.\. END_%s\n' % (tag, tag)
+  return re.sub(pattern, '%s', text, flags=re.S) % replacement
+
+def doxygen2rst(text):
+  text = re.sub(r'<tt>\s*(.*?)\s*<\/tt>', r'``\1``', text)
+  text = re.sub(r'\\c ([^ ,;\.]+)', r'``\1``', text)
+  text = re.sub(r'\\\w+ ', '', text)
+  return text
+
+def indent(text, columns):
+  indent = ' ' * columns
+  s = re.sub(r'\n([^\n])', '\n' + indent + '\\1', text, flags=re.S)
+  if s.startswith('\n'):
+    return s
+  return indent + s
+
+class Option:
+  def __init__(self, name, type, comment):
+    self.name = name
+    self.type = type
+    self.comment = comment.strip()
+    self.enum = None
+
+  def __str__(self):
+    s = '**%s** (``%s``)\n%s' % (self.name, self.type,
+                                 doxygen2rst(indent(self.comment, 2)))
+    if self.enum:
+      s += indent('\n\nPossible values:\n\n%s\n' % self.enum, 2)
+    return s
+
+class Enum:
+  def __init__(self, name, comment):
+    self.name = name
+    self.comment = comment.strip()
+    self.values = []
+
+  def __str__(self):
+    return '\n'.join(map(str, self.values))
+
+class EnumValue:
+  def __init__(self, name, comment):
+    self.name = name
+    self.comment = comment.strip()
+
+  def __str__(self):
+    return '* ``%s`` (in configuration: ``%s``)\n%s' % (
+        self.name,
+        re.sub('.*_', '', self.name),
+        doxygen2rst(indent(self.comment, 2)))
+
+def clean_comment_line(line):
+  return line[3:].strip() + '\n'
+
+def read_options(header):
+  class State:
+    BeforeStruct, Finished, InStruct, InFieldComment, InEnum, \
+    InEnumMemberComment = range(6)
+  state = State.BeforeStruct
+
+  options = []
+  enums = {}
+  comment = ''
+  enum = None
+
+  for line in header:
+    line = line.strip()
+    if state == State.BeforeStruct:
+      if line == 'struct FormatStyle {':
+        state = State.InStruct
+    elif state == State.InStruct:
+      if line.startswith('///'):
+        state = State.InFieldComment
+        comment = clean_comment_line(line)
+      elif line == '};':
+        state = State.Finished
+        break
+    elif state == State.InFieldComment:
+      if line.startswith('///'):
+        comment += clean_comment_line(line)
+      elif line.startswith('enum'):
+        state = State.InEnum
+        name = re.sub(r'enum\s+(\w+)\s*\{', '\\1', line)
+        enum = Enum(name, comment)
+      elif line.endswith(';'):
+        state = State.InStruct
+        field_type, field_name = re.match(r'(\w+)\s+(\w+);', line).groups()
+        option = Option(str(field_name), str(field_type), comment)
+        options.append(option)
+      else:
+        raise Exception('Invalid format, expected comment, field or enum')
+    elif state == State.InEnum:
+      if line.startswith('///'):
+        state = State.InEnumMemberComment
+        comment = clean_comment_line(line)
+      elif line == '};':
+        state = State.InStruct
+        enums[enum.name] = enum
+      else:
+        raise Exception('Invalid format, expected enum field comment or };')
+    elif state == State.InEnumMemberComment:
+      if line.startswith('///'):
+        comment += clean_comment_line(line)
+      else:
+        state = State.InEnum
+        enum.values.append(EnumValue(line.replace(',', ''), comment))
+  if state != State.Finished:
+    raise Exception('Not finished by the end of file')
+
+  for option in options:
+    if not option.type in ['bool', 'unsigned', 'int']:
+      if enums.has_key(option.type):
+        option.enum = enums[option.type]
+      else:
+        raise Exception('Unknown type: %s' % option.type)
+  return options
+
+options = read_options(open(FORMAT_STYLE_FILE))
+
+options = sorted(options, key=lambda x: x.name)
+options_text = '\n\n'.join(map(str, options))
+
+contents = open(DOC_FILE).read()
+
+contents = substitute(contents, 'FORMAT_STYLE_OPTIONS', options_text)
+
+with open(DOC_FILE, 'w') as output:
+  output.write(contents)
+





More information about the cfe-commits mailing list