How to get clang-format to align chained method calls - c++

I've joined an existing project and I'm the first team member to use clang-format. The existing style mostly matches except for a couple of annoying differences. Here's one (the other one being here):
folly::dynamic makeRequest(const string &response) {
return folly::dynamic::object()
("log_type", "FOO")
("src_id", "42")
("dst_id", "666")
("success", true);
}
clang-format insists on formatting it like this:
folly::dynamic makeRequest(const string &token_response) {
// using longer variable names to highlight using up the whole line lenght
return folly::dynamic::object()("log_type", "FOO")(
"src_id", somethingId)("dst_id", whateverId)("success",
sucess);
}
In the former style I don't feel strongly for how continuation lines are indented, as long as we get one method invocation per line. Is that possible?

Not the best possible solution, but you can force line breaks by putting "//" after each line:
return folly::dynamic::object() //
("log_type", "FOO") //
("src_id", "42") //
("dst_id", "666") //
("success", true);

Another approach that I have used myself is to turn off clang-format for the specific block of code.
// clang-format off
return folly::dynamic::object()
("log_type", "FOO")
("src_id", "42")
("dst_id", "666")
("success", true)
;
// clang-format on
This might not be optimal if you have more complicated logic inside the chained method params (since you will want that logic to be formatted), but if you just have a tuple like this it can be cleaner than adding empty comments.
Both ways you are bypassing clang-format, but this way is cleaner (imo) and signifies your intentions more clearly to future developers.

Related

Configuring uncrustify to add braces

I'm using version of 0.66.1 of uncrustify, and am puzzled by the behavior of 'mod_full_brace_if' which I've set to 'force'. Its comment says:
Add or remove braces on single-line 'if' statement. Will not remove the braces if they contain an 'else'.
Given the line:
if (flag) val = 10;
I hoped/expected it to be transformed to
if (flag) { val = 10; }
Instead it remains unchanged.
Is this just my misunderstanding of the behavior of 'mod_full_brace_if'?
Later:
I had some time to do a little experimentation at home. I started off by creating a new format file, and modified some of the settings having to do with forcing braces to be on the same line as various keywords, as well as some settings forcing braces to surround a one-line body. I made a test file with the following contents:
void foo() {
bool flag;
int var;
if (flag) var = 10;
if (!flag)
var = 20;
}
Running uncrustify with my new config file yielded the same lack of transformation that I saw at work.
I then created another config file and only changed 'mod_full_brace_if' (to 'force'). Using it on my test file resulted in braces surrounding the bodies of the if statements. Clearly there's some weird interaction of multiple settings. I see some change-a-setting-and-test drudgery in my future.
It turns out that the problem was setting "mod_full_brace_if_chain" to "true".
The documentation says:
Make all if/elseif/else statements in a chain be braced or not. Overrides mod_full_brace_if.
If any must be braced, they are all braced. If all can be unbraced, then the braces are removed.
I didn't read the last sentence closely enough when setting the value.

How to create option aliases with boost::program_options?

I would like to be able to have the possibility to create option aliases with boost::program_options that stores their arguments under the same key/label.
The architecture of my software uses different specialized option parsers depending on the value argv[1]. However some options are shared, like my option --inputs.
inputOptions.add_options()
("--inputs",
po::value< std::vector<std::string> >()->value_name("paths"),
"List of files to edit.\n");
For compatibility with older version of the program, I would like to add to one of the sub-parsers a compatibility option --input that stores its argument(s) under "--inputs". Ideally that option should take at most one argument instead of arbitrarily many. However if you provide a solution that makes --input identical to --inputs, I guess it's fine too, as in this case positional options are sent to "--inputs" anyway.
Thank you for any help !
You can use extra_parser(see Non-conventional syntax in the docs), i.e. parser that can be used to manipulates tokens from input before they are processed further. It can be used for things like translating --run into --command=run etc.
Extra parser is a functor that has the following signature:
std::pair<std::string, std::string>(const std::string &s)
It should return option name in pair::first and (optional) option value in pair::second. Empty pair::first means that the extra parser has not parsed anything. Value (i.e. pair::second) can be empty - only option name has been parsed. If returned pair is valid then the name or name/value pair is used instead of parsing the original token via normal machinery.
First, we write aliasing function:
using OptionAliases = std::map<std::string, std::string>;
std::pair<std::string, std::string>
renameOptions(const std::string &token, const OptionAliases &aliases)
{
auto rtoken(boost::make_iterator_range(token));
// consume "--" prefix
if (!boost::algorithm::starts_with(rtoken, "--")) { return { "", "" }; }
rtoken.advance_begin(2);
// find equal sign (returns iterator range)
const auto eq(boost::algorithm::find_first(rtoken, "="));
// extract option (between "--prefix" and "="/end()) and map it to output
const auto faliases(aliases.find(std::string(rtoken.begin(), eq.begin())));
if (faliases == aliases.end()) { return { "", "" }; }
// return remapped option and (optionally) value after "="
return std::make_pair(faliases->second
, std::string(eq.end(), rtoken.end()));
}
It simply splits input token into --, name, =, value (no value if there is no = sign) and if the name is found in the provided alias mapping it returns (remapped-name, value).
Then, we create the parser itself, using lambda:
boost::program_options::ext_parser optionAlias(OptionAliases &&aliases)
{
return [aliases{std::move(aliases)}](const std::string &token)
{
return renameOptions(token, aliases);
};
}
(Needs at least C++14, for C++11 change to return [aliases](con...)
You can plug this parser into cmdline parser:
parser.extra_parser(optionAlias({{"mark.twain", "samuel.clemens"}
, {"lewis.caroll", "charles.dodgson"}}));
Now, in the example above, both --mark.twain and --samuel.clemens will point to vars["samuel.clemens"] and both --lewis.caroll and --charles.dodgson will point to vars["charles.dodgson"].
Caveats:
Works only for command line parser.
Expects allow_long style (long options with -- prefix). Can be changed in the code.
Expects long_allow_adjacent style (values allowed in one token using =). Can be changed in the code, as well.
If there is any non-option token that parses as --alias then it is translated as well since there is no context. No way to circumvent.
Example: If there's an option with name name that expects value and long_allow_next style is used, then --name=--mark.twain will be parsed as option name with value --mark.twain (as expected) while --name --mark.twain will be parsed as option name with value samuel.clemens.
Short of that, it works as expected.
Hope it helps.
Have you tried using the form po::value<...>(&variable)? The value of the option is saved directly to the variable after parsed. You can then add two options --input and --inputs pointing to the same variable. Additionally, you'd probably have to check that only one of the two options is used and, otherwise, show an error message.
I hope I've understood your question correctly.
By default boost::program_options allows the prefix of a long option to match that option. So the code you have written will already accept --input as an alias for --inputs.

SLOC in cppcheck

I want to write checker that can be added to other checkers in CppCheck. This checker must check SLOC of all member function, for example the function should contain no more than 200 significant lines of code. But in CppCheck I only found method that checks the existence of a body hasBody(), but not a count of lines.
I am a cppcheck developer. I am no expert in this topic. I think it depends on exactly what you want to count. how many lines is this:
void f() { int x=3; int y=x+2; dostuff(x+y+4); }
I would guess that you want to go through the tokens and count semicolons or something:
for (tok = functionScope->classStart; tok != functionScope->classEnd; tok = tok->next()) {
if (tok->str() == ";")
++lines;
}
I think this checker you suggest is interesting but it does not fit well in the core cppcheck tool. I would suggest that you write an addon. I will be happy to add it in our addons folder and show it in the GUI etc.
By the way.. I have thought that it would be nice to integrate (execute and read results) ohcount, cccc, or whatever in the GUI so extended statistics can be shown.

NetBeans code-template expansion; string manipulation

I'm trying to use the Code Templates feature with PHP in NetBeans (7.3), however I'm finding it rather limited. Given the following desired output:
public function addFoo(Foo $foo) {
$this->fooCollection[] = $foo;
}
I'm trying to have every instance of "foo"/"Foo" be variable; so I used a variable:
public function add${name}(${name} $$${name}) {
$this->${name}Collection[] = $$${name};
}
Of course, when expanded there isn't any regard given to the desired capitalization rules, because I can't find a way to implement that; the result being (given I populate ${name} with "Foo"):
public function addFoo(Foo $Foo) { // note the uppercase "Foo" in the argument
$this->FooCollection[] = $Foo; // and collection property names...
} // not what I had in mind
Now, I've read that NetBeans supports FreeMarker in it's templates, but that seems to be only for file-templates and not snippet-templates like these.
As far as I can tell, the FreeMarker version would look something like the following; however, it doesn't work, and ${name?capitalize} is simply seen as another variable name.
public function add${name?capitalize}(${name?capitalize} $$${name}) {
$this->${name}Collection[] = $$${name};
}
Passing "foo", allowing capitalize to fix it for type-names, second-words, etc.
Is there any way to get FreeMarker support here, or an alternative?
I'm open to any suggestions really; third-party plugins included. I just don't want to have to abandon NetBeans.
Addendum
The example given is trivial; an obvious solution for it specifically would be:
public function add${upperName}(${upperName} $$${lowerName}) {
$this->${lowerName}Collection[] = $$${lowerName};
}
Where upper/lower would be "Foo"/"foo" respectively. However, it's just an example, and I'm looking for something more robust in general (such as FreeMarker support)

How to create an emacs macro for text templates

I am new to lisp and I am having trouble figuring out how to create a macro in emacs with the following functionality: Say I am tired of writing out the pattern in c++ for a for loop:
for (int i = 0; i < N; i++) {
}
Call this macro "forloop" then I would like to do the following: when I type "M-x forloop" the macro prints out
for (int
in the buffer and waits for an input. Then I type "i" and hit return after which the macro continues and prints
for (int i = 0; i <
And again waits for input. Finally after I type "N" and hit return the macro finishes by printing the rest:
for (int i = 0; i < N; i++) {
}
After some extensive reading and testing, I was able to write simple lisp functions, create my own macros, save them and call them and so on... but I still can't quite figure out how to make a macro that does something like I have described above. Any thoughts would be much appreciated! Thanks in advance!
Macros like this could be really nice for speeding up coding in any language. I would prefer the macro to be dynamic in the way described so that you don't have to remember how many arguments it needs and in which order they go when calling it.
I use yasnippet (http://www.emacswiki.org/emacs/Yasnippet) for this, but there are a lot of other solution.
In yasnippet you type a keyword for you snippet (say for) then the yasnippet key shortcut, then you have field to fill, using tab to go from one field to the next.
Every snippet is define in is own file in some easy to learn DSL.
I don't know anything better than yasnippet for this problem.
Here's the relevant snippet:
# -*- mode: snippet -*-
#name : for (...; ...; ...) { ... }
# --
for (unsigned int ${1:i}=0; $1<${2:N}; ++$1)$0
Note that there are two arguments (zero is the exit point),
both have default values, but you can change them by just typing.
key binding for yasnippet
I highly recommend to bind yas/expand to C-o, so it
doesn't conflict with auto-complete-mode.
The default binding for this shortcut is near-useless, but it's in
a great position:
(global-set-key "\C-o" 'aya-open-line)
(defun aya-open-line ()
(interactive)
(cond ((expand-abbrev))
((yas/snippets-at-point)
(yas/next-field-or-maybe-expand-1))
(((yas/expand)))))
This way, the shortcut for expanding and moving to the next field
is the same, which makes you very quick.
Also note that expand-abbrev takes precedence: you can fill
an abbrev table for c++-mode for the stuff that you use.
Abbrevs don't take an argument, but they all live in one table,
instead of each yasnippet living in its own file, so it's
very easy to edit abbrevs.
special function to insert curly braces
I wouldn't recommend putting the braces in yasnippet,
since sometimes you need them and sometimes you don't.
I use this function instead:
(defun ins-c++-curly ()
"Insert {}."
(interactive)
(if (looking-back "\\()\\|try\\|else\\|const\\|:\\)$")
(progn
(insert " {\n\n}")
(indent-according-to-mode)
(forward-line -1)
(indent-according-to-mode))
(insert "{}")
(backward-char))
You can see similar macros in sgml-mode.el, for example html-href-anchor, which inserts an HREF anchor (obviously :-).
You will get more specific answers if you tag this as [elisp].
If you are reading this and wondering exactly how to do what I requested with yasnippit, here is my yasnippit file:
# name: fori ... { ... }
# key: fori
# --
for (int ${1:intname} = 0; ${1:$(yas-substr text "[^: ]*")} < ${2:max}; ${1:$(yas-substr text "[^: ]*")}++) {
$0
}
Note that yasnippit already has a function for "for" in c++ mode, but I did not like the way it behaved.
Conclusion, yasnippit is awesome and super easy! Thanks for the suggestion!