clang-format won't attach brace if there is a newline - c++

I got a problem regarding clang-format:
What I want to enforce is that braces at the start of blocks are always attached to the function head / control sequence ...
This means that instead of
int f()
{
return 1;
}
or
if(o < 1)
{
return -1;
}
clang-format should always attach the opening brace like this:
int f() {
return 1;
}
and
if(o < 1) {
return -1;
}
While this works for the first case (no newline between function head and brace), it does not work if there is a newline between the function head / if etc.
I did not find any option for clang-format that enforces this.
The option closest to what I am looking for is BreakBeforeBraces: Attach, but this did not format the second case properly either. Playing around with this option as well as the options underneath BraceWrapping did not solve the issue as well.
Is there a way to configure clang-format to join lines such as the opening brackets always end up at the end of the last line of code before them?
I played around with online configurators like https://clangformat.com/ or http://cf.monofraps.net/ but could not find an option set that would serve my needs.
I am currently using clang-format version 3.8 .

You could use:
MaxEmptyLinesToKeep: 0
This would cause the empty lines to be deleted, and then the braces would get formatted the way you request.
However, I expect this is not really a good solution for you, because it will delete all empty lines, not just the empty lines before a brace.
Other than this, I don't think this is possible with clang-format 6.0.0. I don't think it has been added in newer versions either - nothing in the documentation seems to relate to this.

Related

Eclipse / CDT auto-indent on new line only incorrect for structs?

Using new Eclipse and CDT versions built into STM32CubeIDE. I have the built in formatter options adjusted and use clang-format as my main beautifier. Everywhere I can see in the Window >> Preferences menus I have indent turned to 2 spaces-only.
Next line indent works correctly with everything but structs which the indentation seems to be doubled.
It doesn't seem to be indenting 2 units twice, because pressing tab moves me 4 spaces while inside a struct block. Clang-Format with CTRL + SHIFT + F does fix the incorrect formatting, but I'd rather a proper solution.
Either it's a bug, or somewhere this is yet another setting for "4 space indent but only while inside a struct block"?
See examples:
typedef struct
{
//New lines created inside the block start here, indented at 4 and not 2
//I get here if I press tab from the start column
//This is where it should intent to, manually pressed spaced twice
} some_new_t;
void foo()
{
//Correct
}
if (something)
{
//Correct
}
while(1)
{
//Correct
}
#ifdef TEST
//Doesn't indent, that's fine
#endif
EDIT: Applies to unions as well
Figured it out. This was not a 2 spaces vs 4 spaces issue, rather double indent when you only wanted one.
For some reason CDT has a lot more references to C++ and still Java than C and this was labeled under something misleading.
Under Window, Preferences, C/C++, Code Style, Formatter >> Edit >> Indentation >> Indent there are two options that can be checked.
'public', 'protected', 'private' within class body
and
Declarations relative to 'public' 'private'
You can check ONLY ONE of these for C structures and unions to indent at your chosen width. For whatever non-C reason, each one counts as including one indent width.

recursive_directory_iterator's skip_permission_denied option appears to be ignored on macOS?

Using C++20 and std::filesystem::recursive_directory_iterator on macOS, this code:
for (auto& f : recursive_directory_iterator(getenv("HOME"), directory_options::skip_permission_denied)) {
// dummy
}
Which should, according to my understanding of the documentation, skip directories which it does not have permission to recurse into, encounters an error upon trying to recurse into ~/Library/Application Support/MobileSync/.
However:
in recursive_directory_iterator::operator++(): attempting recursion into "/Users/t/Library/Application Support/MobileSync": Operation not permitted
I assume this means that there is some permission / security feature in place that the iterator will not skip over even if skip_permission_denied is present - what might this be, and how would I cleanly make the iterator skip over directories that cause it to break regardless of permissions?
I could manually disable_recursion_pending() when encountering known directories like MobileSync or .Trash that cause this problem, but that would be a messy solution compared to being able to detect in advance when a directory will cause this issue.
I'm afraid there is no easy way around it, as the iterator is "closed" on error so a post-error disable_recursion_pending will not help. I opened an issue for libcxx (https://github.com/llvm/llvm-project/issues/48870) and libstdc++ (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99533) that got worked on, but the libcxx one was not fixed yet, and even then it would have to make it into macOS as on macOS the standard library is part of the system.
One admittedly ugly but possible non-hardcoded workaround would be to blacklist dynamically and retry e.g. somewhere along the lines of:
// ugly workaround to iterate the home dir on macOS with std::filesystem:
std::set<fs::path> blacklist;
while(true) {
fs::path lastPath;
try {
for(auto rdi = fs::recursive_directory_iterator(getenv("HOME"), fs::directory_options::skip_permission_denied);
rdi != fs::recursive_directory_iterator();
++rdi) {
auto& de = *rdi;
lastPath = de.path();
if(blacklist.count(de.path())) {
rdi.disable_recursion_pending();
}
else {
// collect info you need here
// ...
}
++rdi;
}
}
catch (fs::filesystem_error& fe) {
if(!blacklist.insert(lastPath).second) {
// exception on same path, double error, something went really wrong
break;
}
else {
// we blacklisted a new entry, reset your collected info here,
// we need to restart
// ...
continue;
}
}
// we are through and managed to get all info
// ...
break;
}
Of course this is a lot of code working around something that should be a single line and only needed on macOS, so if one uses this at all, it should be wrapped away.
One subtle thing to be aware of is that a range-based-for uses the fs::begin(fs::recursive_directory_iterator) function that creates an "invisible" copy, and makes it impossible to call disable_recursion_pending() on the correct instance. This is the reason why a regular for-loop is used.
Another ugly part of that workaround is that besides the standards suggestions neither path1() nor path2() of the exception deliver the offending path and as parsing the exception text is a bad idea, the paths are remembered in the otherwise useless lastPath variable.
All in all it works, but this is nothing I would actually use, as the tree needs to be scanned multiple times (on my notebooks "Application Support" it takes six rescans until it gets through and four times the runtime of an implementation that works without this hack), so I would see this more as an experiment if it is possible to generically iterate the home on macOS with std::filesystem.
So, sadly, until those issues are fixed, std::filesystem::recursive_directory_iterator is not that great on macOS, and I continue to use my drop-in filesystem replacement on that platform, that honors skip_permission_denied for EPERM and EACCES (but is utf-8 only).

Space after 'if', 'while', 'catch' etc.. with clang-format

Cannot figure out that option adds the space after if, while, catch, etc...
Currently my .clang-format file produce this:
while(true)
{
if(flushedCount == count)
{
break;
}
}
The clang-format configuration option controlling space after if, while, catch and other control statements is called SpaceBeforeParens.
SpaceBeforeParens: ControlStatements
From clang-format 8 documentation:
SpaceBeforeParens (SpaceBeforeParensOptions)
Defines in which cases to put a space before opening parentheses.
Possible values:
[...]
SBPO_ControlStatements (in configuration: ControlStatements) Put a space before opening parentheses only after control statement keywords (for/if/while...).
[...]

Opening code written in emacs on Xcode appears badly indented

This is my first post on stack overflow, so please forgive me for any mistakes.
I learned c++ with Xcode and recently started working with a group that uses Emacs. This group has a huge code in c++ and so I did a CMake interface to generate a project in Xcode. What happened is that the code appears badly indented in Xcode. For instance, these lines in emacs:
if ( argc > 4 ) {
std::string argument( argv[arg_index++] );
// NOTE: file_name should NOT be "aboveCrack" or "belowCrack"
if ( argument == "aboveCrack" ) {
surf_to_draw = CrackMn3DGraphDX2::EAboveSurface;
}
else if ( argument == "belowCrack" ) {
surf_to_draw = CrackMn3DGraphDX2::EBelowSurface;
}
else {
// argument 4 is comp. crack surface output name
got_file_name = true;
postCompSurface_file_name = argument;
}
}
if ( !got_file_name && argc > 5 ) {
got_file_name = true;
postCompSurface_file_name = argv[arg_index++];
if ( argc > 6 ) {
// get comp. crack surface output style
postCompSurface_style = argv[arg_index++];
}
}
Look like this in Xcode:
if ( argc > 4 ) {
std::string argument( argv[arg_index++] );
// NOTE: file_name should NOT be "aboveCrack" or "belowCrack"
if ( argument == "aboveCrack" ) {
surf_to_draw = CrackMn3DGraphDX2::EAboveSurface;
}
else if ( argument == "belowCrack" ) {
surf_to_draw = CrackMn3DGraphDX2::EBelowSurface;
}
else {
// argument 4 is comp. crack surface output name
got_file_name = true;
postCompSurface_file_name = argument;
}
}
if ( !got_file_name && argc > 5 ) {
got_file_name = true;
postCompSurface_file_name = argv[arg_index++];
if ( argc > 6 ) {
// get comp. crack surface output style
postCompSurface_style = argv[arg_index++];
}
}
Which is impossible to program with.
I searched and apparently it has something to do with the tabs in Emacs. Based on this, one fix I could find was to open each file in Emacs and do C-x h (mark all) followed by M-x untabify. This transforms the tabs in spaces and everything looks good in Xcode.
The problems with this idea are that it requires to change the files one by one and it won't stop this from happening again in the future.
Therefore, my question is: is there a way to open the Emacs indented files in Xcode preserving the indentation?
Many thanks!
Nathan Shauer
The first setting that you need to put in your .emacs is: (setq-default indent-tabs-mode nil). This will make sure emacs uses spaces instead of tabs for indentation.
Also, I created a tiny function:
(defun rag/untabify-buffer ()
;; get rid of all the tabs in a buffer
(interactive)
(untabify (point-min) (point-max))
nil)
Add this to before-save-hook and this will make sure all the files will be untabified when you make a change and save a file. Once you've untabified all files, you can remove the hook
No. While it is possible to use emacs to make these changes or even a number of other tools which can automate such changes, it won't really fix your problem as you will likely have to do it every time you check out the code from version control. Depending on the version control system used, it is also possible that doing such formatting changes will result in the code appearing to be modified, which will result in larger checkins and make other useful tools less useful because more will appear to have been changed than was actually changed. This will likely frustrate other project members.
There are two basic approaches, but one depends on the version control solution being used by the project. The first solution is to get the project to agree on a coding standard which specifies either that normal spaces must be used for indentation or that tabs are to be used. The problems you are seeing are primarily due to a mix. Emacs is able to handle this sort of mixed formatting quite well, but other editors, like Xcode are not so smart.
The other approach, which can work quite well because it doesn't rely on everyone following the standard is to configure the version control system to translate tabs as part of the checkin process into spaces. How this is done depends on the version control system being used.
Essentially, this is a problem which needs to be addressed at the project or version control level. Anything you do will only need to be repeated every time you do a fresh pull from version control for any files which have been modified. Fix it at the repository level and the issue will go away.

How to put a conditional breakpoint to test if a CString variable is empty

So I have this simple code snippet:
CString str;
..................
if ( str.IsEmpty() )
str = spRelease->GetID();
I want to put a conditional breakpoint on the last line to test if str is empty.
I tried this first:
str == ""
But I get this:
Error overloaded operator not found
Then this:
str.isEmpty() == 0
And get this:
Symbol isEMpty() not found
Any idee how this could be done ? Any workaround ?
Thanks.
Why don't you just put a normal breakpoint on the last line? You already know str is empty. If you want to double check whether your string is empty, I would use an ASSERT instead.
If you really have to check your string, you have to check m_pszData in your CString, so your condition looks like this:
str.m_pszData[0] == '\0'
In Visual Studio 6 you have the operation IsEmpty(), note that the first 'I' is uppercase. You also have the Compare() operation. Which version of VS are you using?
One pattern that I've seen for things like this is to add a bit of code like this:
if (some_condition) {
int breakpoint=rand();
}
This generates a warning about breakpoint being initialized but not used so it is easy to remember to take it back out. This also allows you test any condition you want, including invoking functions or anything else, without having to worry about restructions of the debugger. This also avoids the limit on the number of conditional breakpoints you can have that some debuggers have.
The obvious downsides are that you can't add one during a debug session, recompiling, remembering to take them out, etc.