Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clang-format] output-replacements-xml returns non empty content for previously formatted code with function-try-block #96107

Open
Alexolut opened this issue Jun 19, 2024 · 1 comment

Comments

@Alexolut
Copy link

Consider following C++ code with function-try-block:

void TestFunc(const std::string &data) try {
  do_something();
  do_something_more();
} catch (const std::exception &ex) {
  log_error(ex);
}

Given .clang-format:

---
Language:        Cpp
KeepEmptyLinesAtTheStartOfBlocks: false
SeparateDefinitionBlocks: Always
...

I found that after applying code formatting to this source file, e.g.

clang-format --style=file -i file.cpp

The following call

clang-format --style=file --output-replacements-xml file.cpp

returns non-empty diff:

<?xml version='1.0'?>
<replacements xml:space='preserve' incomplete_format='false'>
<replacement offset='125' length='4'>&#13;&#10;  </replacement>
</replacements>

As far as I understand there should be no replacement offset section in result if I did formatting before with the same settings.

Investigation of that issue started here. I use clang-format 18.1.7 on Windows.

@2bndy5
Copy link

2bndy5 commented Jun 19, 2024

Given the file.cpp and clang-format config, I was able to reproduce this using

  • v18.1.8 on Ubuntu (actually using WSL on Windows).
  • v18.1.7 on Windows

Note

Contrary to steps described in OP, I did not need to first format the file.cpp before generating the XML replacements.

<?xml version='1.0'?>
<replacements xml:space='preserve' incomplete_format='false'>
<replacement offset='125' length='4'>&#13;&#10;  </replacement>
</replacements>

which (when the replacement is applied) translates to a useless diff:

 void TestFunc(const std::string &data) try {
   do_something();
   do_something_more();
-} catch (const std::exception &ex) {
-  log_error(ex);
+} catch (const std::exception &ex) {
+  log_error(ex);
 }
Proof using python

from pathlib import Path
import xml.etree.ElementTree as ET
xml = "<?xml version='1.0'?><replacements xml:space='preserve' incomplete_format='false'><replacement offset='125' length='4'>&#13;&#10;  </replacement></replacements>"
tree = ET.fromstring(xml)
offset = int(tree[0].attrib["offset"])
length = int(tree[0].attrib["length"])
replacement = tree[0].text
f = Path("file.cpp")
src = f.read_bytes()[offset : offset + length].decode(encoding="utf-8")
assert src == replacement

This doesn't seem specific to line endings as I was able to reproduce this behavior with either LF or CRLF (on both Windows and Ubuntu).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants