<div dir="ltr">Thanks!<div><br></div><div>Here's a (not minimal) reduction of the first issue; it looks like the other issues are basically the same thing:</div><div><br></div><div><font face="courier new, monospace">$ cat fmt.c<br>void cdataSectionTok()<br>{<br>  switch (1) {<br>#define LEAD_CASE(n) \<br>  case BT_LEAD ## n: \<br>    break<br>  LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)<br>#undef LEAD_CASE<br>  default:<br>    break;<br>  }<br>}<br><br>$ out/gn/bin/clang-format fmt.c<br>void cdataSectionTok() {<br>  switch (1) {<br>#define LEAD_CASE(n)                                                           \<br>  case BT_LEAD##n:                                                             \<br>    break<br>    LEAD_CASE(2)<br>    LEAD_CASE(3) LEAD_CASE(4)<br>#undef LEAD_CASE<br>        default : break;<br>  }<br>}</font></div><div><br></div><div>As you can see by the weird "default : break" at the end, clang-format gets confused about the whole switch statement. It looks like the macros confuse it. Just adding semicolons after it is sufficient to unconfuse it:</div><div><br><font face="courier new, monospace">$ cat fmt.c<br>void cdataSectionTok()<br>{<br>  switch (1) {<br>#define LEAD_CASE(n) \<br>  case BT_LEAD ## n: \<br>    break<br>  LEAD_CASE(2); LEAD_CASE(3); LEAD_CASE(4);<br>#undef LEAD_CASE<br>  default:<br>    break;<br>  }<br>}<br><br>$ out/gn/bin/clang-format fmt.c<br>void cdataSectionTok() {<br>  switch (1) {<br>#define LEAD_CASE(n)                                                           \<br>  case BT_LEAD##n:                                                             \<br>    break<br>    LEAD_CASE(2);<br>    LEAD_CASE(3);<br>    LEAD_CASE(4);<br>#undef LEAD_CASE<br>  default:<br>    break;<br>  }<br>}</font><br></div><div><br></div><div>If you're able to change expat's source, this might be a good approach.</div><div><br></div><div>Else, you can explicitly tell clang-format the name of macros that should be handled as statements in your .clang-format file like so:</div><div><br></div><div>StatementMacros: ['LEAD_CASE']<br></div><div><br></div><div>That helps with LEAD_CASE. (clang-format should still converge within one round, but it's going to converge to something bad without either of the two things I suggest, so it wouldn't help you much).</div><div><br></div><div>Like Raphaël's mail says, XCS is slightly different because it's not a statement. clang-format has special logic for formatting sequences of string literals, and that doesn't fire if each literal is surrounded by a macro.</div><div><br></div><div>You can fix this by doing `XCS("foo" "bar")` (with a linebreak in between foo and bar) instead of `XCS("foo") XCS("bar")`. Semantically they do the same thing as far as I can tell, but clang-format does much better with the first form. Having done this transformation locally, this is arguably easier to read for humans too.</div><div><br></div><div>There isn't a .clang-format setting for this case as far as I know.</div><div><br></div><div>(Again, clang-format should reach a fixed point in one hop, but again the one hop gives you pretty bad formatting so fixing that bug wouldn't help you all that much.)</div><div><br></div><div>With these two changes, clang-format does reach an end state in one step, and its output (for the two cases I looked at) looks good too.</div><div><br></div><div>Hope this helps!</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jul 26, 2019 at 5:03 PM Sebastian Pipping <<a href="mailto:sebastian@pipping.org">sebastian@pipping.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Nico,<br>
<br>
<br>
that's great to hear.  I have attached a script to reproduce the issue<br>
from public code of libexpat 2.2.7 as well as the second iteration diff<br>
I get from clang-format version 10.0.0<br>
(/var/tmp/portage/sys-devel/clang-10.0.0.9999/work/x/y/clang-10.0.0.9999<br>
c0048be7ff340ebba3092e95d82147bc9928b909) of Gentoo.<br>
<br>
Best<br>
<br>
<br>
<br>
Sebastian<br>
<br>
<br>
On 26.07.19 22:07, Nico Weber wrote:<br>
> clang-cl is supposed to reach a fixpoint in one iteration. If it<br>
> doesn't, that's a bug. If you can, please post a reduced repro case :)<br>
> <br>
> On Thu, Jul 25, 2019 at 5:38 PM Sebastian Pipping via cfe-dev<br>
> <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a> <mailto:<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>>> wrote:<br>
> <br>
>     Hi!<br>
> <br>
> <br>
>     I'm trying to integrate clang-format version 9 with CI in a way that the<br>
>     CI run only passes if applying clang-format yields the exact same<br>
>     code, i.e. "git diff --exit-code" returns 0.  The idea is that every<br>
>     pull request would only pass if clang-format<br>
> <br>
>     When trying to put that approach to action with libexpat [1]<br>
>     I noticed that multiple runs to clang-format do not seem to produce the<br>
>     same code, at least not with the two version of Clang 9 that I tested<br>
>     [2], and at least not with libexpat code.<br>
> <br>
>     I wonder if that's a known problem, if it's fixed in later versions<br>
>     of clang-format, if you are aware of workarounds, or if I just need<br>
>     to say goodbye to combining clang-format and CI for stable style<br>
>     checking.<br>
> <br>
>     Thanks in advance!<br>
> <br>
>     Best<br>
> <br>
> <br>
> <br>
>     Sebastian<br>
> <br>
> <br>
>     [1] <a href="https://github.com/libexpat/libexpat/pull/293" rel="noreferrer" target="_blank">https://github.com/libexpat/libexpat/pull/293</a><br>
>     [2] 9.0.0.9999 commit 28c954cf961a846789a972a8ed179b7108244ae7<br>
>     _______________________________________________<br>
>     cfe-dev mailing list<br>
>     <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a> <mailto:<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>><br>
>     <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
> <br>
<br>
</blockquote></div>