Keep indentation for particular preprocessor include blocks with clang-format - clang-format

We have include mechanics that protects some definitions when including external libraries, we would like to keep them as they are when formatting code, eventually ordering alphabetically the contents of the block.
e.g:
#include <ExternalIncludeBegin.h>
# include <somelib/someheader.h>
# include <somelib/anotherheader.h>
#include <ExternalIncludeEnd.h>
Right now, clang-format transforms this block in
#include <ExternalIncludeBegin.h>
#include <somelib/someheader.h>
#include <somelib/anotherheader.h>
#include <ExternalIncludeEnd.h>
but I would like to keep the original indentation, if possible without having to encapsulate everything with new code (the codebase we would like to format is pretty old and big), is there anything clang-format can do for me here ?

Take a look at "Disabling format" feature
Disabling Formatting on a Piece of Code
Clang-format understands also special comments that switch formatting in a delimited range. The code between a comment // clang-format off or /* clang-format off */ up to a comment // clang-format on or /* clang-format on */ will not be formatted. The comments themselves will be formatted (aligned) normally.
int formatted_code;
// clang-format off
void unformatted_code ;
// clang-format on
void formatted_code_again;
more details: https://clang.llvm.org/docs/ClangFormatStyleOptions.html
So, you also could use “sed” or other tool in order to inject clang-specific comments in the whole project.

Related

How to avoid formatting for XML, SQL etc. raw strings in clang-format?

I have some C++ code with embedded XML like this:
QLatin1String test()
{
return QLatin1String(R"XML(
<ui language="c++">
<widget class="Test" name="dialogbuttonbox">
<property name="text">
<string>DialogButtonBox</string>
</property>
</widget>
</ui>)XML");
}
When formatting this with
clang-format --style=WebKit test1.cpp
Then the xml will be formatted to be broken, because of the definition of RawStringFormat:
If no style has been defined in the .clang-format file for the
specific language, a predefined style given by ‘BasedOnStyle’ is used.
If ‘BasedOnStyle’ is not found, the formatting is based on llvm style.
So I tried the following within .clang-format:
RawStringFormats:
- Language: None
Delimiters: ['XML']
DisableFormat: true
Which results into the following error:
.clang-format:177:15: error: unknown enumerated scalar - Language: None
What I really want to avoid is to add comments to the source code to switch formatting off/on:
// clang-format off
// clang-format on
So my question is how to switch off formatting for XML, SQL or whatever is not supported by clang-format raw strings?
Also what about the above unknown enumerated scalar message? Does it mean that Language: None ist not allowed? So maybe I have a feature request?
I had a similar issue.
My fix was to split the XML sections into their own files.
The clang formater then doesn't touch them and your standard VS Code formater will be used.
I then needed to set the maxLineWidth to 0 which means no new lines because of column length.
.vscode/settings.json
"xml.format.maxLineWidth": 0

Clang format to recognize main include with prefixed path

I've been trying to get clang format to recognize an include with prefixed path as a main include.
Project/B/Test.cpp file has an following include block:
#include "Project/A/SomeInclude.h"
#include "Project/C/Other.h"
#include <libs/somelib.h>
#include <string>
#include "Project/Project.h"
#include "Project/B/Test.h"
I want to sort it using this rules:
IncludeCategories:
- Regex: 'Project\/Project\.h'
Priority: 0
- Regex: '".*"'
Priority: 2
- Regex: '^<.*\.(h)>'
Priority: 3
- Regex: '^<.*>'
Priority: 4
Which should result with this:
(1)
#include "Project/Project.h"
#include "Project/A/SomeInclude.h"
#include "Project/B/Test.h"
#include "Project/C/Other.h"
#include <libs/somelib.h>
#include <string>
I also want the main include to be at priority 1, which is what this line should do, provided it matches the main include:
IncludeIsMainRegex: '()$?'
Main include will always have format #include "path/to/include/from/Project/folder/name.h" This should be the end result:
(2)
#include "Project/Project.h"
#include "Project/B/Test.h"
#include "Project/A/SomeInclude.h"
#include "Project/C/Other.h"
#include <libs/somelib.h>
#include <string>
I've tried many version of IncludeIsMainRegex, and none work. The interesting thing about the one above is that the first time I run the tool, it sorts everything the way I want (2), but if I then run it again on the same file, it puts the main include in the category 2, and messes up the sort (1).
I'm guessing that the prefixed path is the problem. Short of removing the path from the main include, is there any way to make clang format to recognize the file? The documentation on the feature isn't all that clear on how the matching is done and I hope I can tell it that the file might have a path prefixed to it.
The question is quite similar to this one, however, the asker didn't provide the clang format it was using, so it's of limited help.
It seems that simple IncludeIsMainRegex: '$?' does the trick. Just make sure you place this line above IncludeCategories: to make sure that the main file doesn't get picked up before it reaches that line.

After importing a static library, some headers in the header cannot be found

My static library is an engine depending on other headers.
For example, in XXXEngine.h
#include "CommonUtil.h"
#include "DebugLogger.h"
All of these files are added when I build the static library. So I only export XXXEngine.h as the API and hide my implementations.
But the problem is that when I import that header file into another project and the .a file is already added as well, I get some errors saying that "CommonUtil.h" cannot be found. It can find XXXEngine.h, but just not the headers inside this file. But I didn't want to expose those header files.
What should I do to fix this? Thanks!
Any header files that you #include in the header files that define your
library's API become part of your library's API. If the compiler ever has to
find MyLib.h then it has to find every header that is (recursively) #include-ed
in MyLib.h.
So if you don't want to expose a particular header file and don't want your
library's users to need it, then you just can't include it in MyLib.h.
Instead of, e.g:-
MyLib.h
...
...
#include "private_header.h"
#include "public_header.h"
...
...
and
MyLib.m
#include "MyLib.h"
...
...
you need to refactor like:
MyLib.h
...
...
#include "public_header.h"
...
...
and
MyLib.m
#include "MyLib.h"
#include "private_header.h"
...
...
If your project will not compile like that, then it proves that MyLib.h
does need declarations from private_header.h, which you do not want it to expose.
In that case, rethink and refactor your code until it doesn't.

Using Clang to get AST

I would like to use Clang to get to its AST to get some information about the variables and methods in a particular source file. However, I do not want to use the LibTooling facilities. I would like to, by hand, to write to code that would call the methods to parse the .cpp and then get the tree. I can not find any resources that tell me how to do this. Can anybody help?
If your goal is to learn how to drive Clang components to work with the compilation database, configure the compiler instance, and so on, then the Clang source code is a resource. Perhaps the source for the ClangTool::buildASTs() method would be a good place to start: see Tooling.cpp in the lib/Tooling/ directory of the source tree.
If your goal is to do an analysis that LibTooling doesn't support, and you just want to get the AST with minimal fuss, then either ClangTool::buildASTs or clang::tooling::buildASTFromCode might be of service. The ClangTool approach would be better if you need the compilation database to express compiler options, include paths, and so on. buildASTFromCode is fine if you have a standalone bit of code for lightweight tests. Here's an example of the ClangTool approach:
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/CommandLine.h"
#include <memory>
#include <vector>
static llvm::cl::OptionCategory MyOpts("Ignored");
int main(int argc, const char ** argv)
{
using namespace clang;
using namespace clang::tooling;
CommonOptionsParser opt_prs(argc, argv, MyOpts);
ClangTool tool(opt_prs.getCompilations(), opt_prs.getSourcePathList());
using ast_vec_t = std::vector<std::unique_ptr<ASTUnit>>;
ast_vec_t asts;
tool.buildASTs(asts);
// now you the AST for each translation unit
...
Here's an example of buildASTFromCode:
#include "clang/Frontend/ASTUnit.h"
#include "clang/Tooling/Tooling.h"
...
std::string code = "struct A{public: int i;}; void f(A & a}{}";
std::unique_ptr<clang::ASTUnit> ast(clang::tooling::buildASTFromCode(code));
// now you have the AST for the code snippet
clang::ASTContext * pctx = &(ast->getASTContext());
clang::TranslationUnitDecl * decl = pctx->getTranslationUnitDecl();
...

lua bindings for bullet

are there any lua bindings for libbullet?
tried using swig and simply %includeing the BulletDynamicsCommon.h:
%module ybullet
%{
#include <btBulletDynamicsCommon.h>
%}
%include "%BULLET_inc_path%/btBulletDynamicsCommon.h"
but that doesn't work, as it also just includes other files, which is ignored by swig:
ybullet/helloWorld.lua:4: attempt to call field 'btDbvtBroadphase' (a nil value)
my lua file is ported from http://bulletphysics.org/mediawiki-1.5.8/index.php/Hello_World
found out a way using swig and a zsh script to automagically extract the %includes from the header files to get this: https://github.com/nonchip/YEngine/blob/master/ybullet/ybullet.i.tpl

Resources