Concatenating two strings in macro definition (Clang) - c++

I'm working on some code that was originally made in MSVC and I'm trying to get it to compile on Clang (using Xcode). The code I've got is something like this:
#define DO_MAPPING(x,y,z)\
myMaps[map##x] = GetTex( #x##"Map" );\
myRemaps[map##x] = GetHandle( #x##"Remap" );
Currently I'm getting a build error saying that pasting formed the string "Height""Map", where I really want "HeightMap". This code works on MSVC, is there something about Clang's macro syntax that means this kind of thing needs to be written differently?

In C, "X""Y" is equivalent to "XY". However, when you write such a thing in a macro:
str1##str2
you are telling the lexer to concat the two as one token. "X""Y" is actually two tokens that are concatenated by the lexer1, while "X"##"Y" is supposed to be one token (which is not a valid token).
What you need is to simply drop the ##:
#define DO_MAPPING(x,y,z)\
myMaps[map##x] = GetTex( #x "Map" );\
myRemaps[map##x] = GetHandle( #x "Remap" );
1 Or the semantics analyzer, depending on the implementation
Typically, the regex matching a string looks like this (simplified):
"(a|\b)*"
(assume a is a list of all characters that don't need to be escaped and b is the others). Probably, for MSVC, it is defined like this:
"(a|\b)*"s*+
(s is whitespace)
This means that MSVC probably sees "X" "Y" as one token instead of two.

Just use (#x "Map") in place of #x##"Map". It should work in C++. E.g. this is perfectly valid: ("B" "Map") and evaluates to "BMap".

Note that "Height""Map" actually is the same as "HeightMap" when parsed. So you can simply use this:
#define DO_MAPPING(x,y,z)\
myMaps[map##x] = GetTex( #x "Map" );\
myRemaps[map##x] = GetHandle( #x "Remap" );

Try this instead:
#define DO_MAPPING(x,y,z)\
myMaps[map##x] = GetTex( #x "Map" );\
myRemaps[map##x] = GetHandle( #x "Remap" );
Two string litterals are automatically concatenated by the compiler.

Related

How to compare to macros in latex

I want to compare two macros \Lgiii with the one read in as #1 in a macro called fex
\def\fex(#1,#2)
ifx\Lgiii#1
do something
else
do something else
fi
However this does not seem to work and maybe someone has a quick solution to this.
In order to compare macros, you need to store the argument inside some macro; this allows you to use \ifx:
\documentclass{article}
\def\fex(#1,#2){%
\def\Lgi{#1}% Store first argument in \Lgi
\ifx\Lgiii\Lgi
do something
\else
do something else
\fi
}
\def\Lgiii{something \relax + 2}
\begin{document}
\fex(this,that)
\fex(something \relax + 2,that)
\fex(something \relax +2,that)
\end{document}

Generate identifier from macro parameter

I have macro in which i pass an argument:
#define bind(id) function[function_id::id] = std::bind(otherFunction::id, std::placeholders::_1)
In that case id expands to whatever I write into macro while using it. However I would like to add some characters to one of them, like this:
#define bind(id) function[function_id::id] = std::bind(otherFunction::add_id, std::placeholders::_1)
So that first replacement of id is original and second is with sufix add_ . When I do that second expansion with add_ won't expand, so I end up with add_id instead of add_whatever_I_wanted.
In that case I've tried to use brackets and write it like that:
#define bind(id) function[function_id::id] = std::bind(otherFunction::add_(id), std::placeholders::_1)
And it worked partially, now id is wrapped into brackets and expansion result is
add_(whatever_I_wanted)
Instead of
add_whatever_I_wanted
It's killing me as I want to use it quite often. Is there any workaround?

Pasting formed an invalid processing token '.'

I am trying to use macro for calling appropriate object based on the type.
#define DELEGATE_FUNC(FuncName, kind, paramPtr) \
if (kind == 1) { \
return PolicyObject1.##FuncName(paramPtr); \
} \
else { \
return PolicyObject2.##FuncName(paramPtr); \
} \
return 0; \
(PolicyObject1 & PolicyObject2 are two static objects.)
Now when using the macro, e.g.
DELEGATE_FUNC(ProcessPreCreate, 1, null_ptr);
It compiles fine in VS 2015, but gives error with LLVM "Pasting formed an invalid processing token '.ProcessPreCreate'"
I looked for, and found a few posts and understood it up to some level - Need double level of indirection, e.g.
Why do I need double layer of indirection for macros?
However I am unable to define those two layers of macro, can anyone help?
(Please leave aside the discussion on design aspects)
Thanks
When the compiler reads your C++ file, one of the first steps is dividing it into tokens like identifier, string literal, number, punctuation, etc. The C preprocessor works on these tokens, not on text. The ## operator glues tokens together. So, for example, if you have
#define triple(foo) foo##3
Then triple(x) will get you the identifier x3, triple(12) will get you the integer 123, and triple(.) will get you the float .3.
However, what you have is .##FuncName, where FuncName is ProcessPreCreate. This creates the single token .ProcessPreCreate, which is not a valid C++ token. If you had typed PolicyObject1.ProcessPreCreate directly instead of through a macro, it would be tokenized into three tokens: PolicyObject1, ., and ProcessPreCreate. This is what your macro needs to produce in order to give valid C++ output.
To do that, simply get rid of the ##. It is unnecessary to glue the . to the FuncName, because they are separate tokens. To check this, you can put a space between a . and a member name; it will still compile just fine. Since they are separate tokens, they should not and cannot be glued together.
delete "##".
#define DELEGATE_FUNC(FuncName, kind, paramPtr) \
if (kind == 1) { \
return PolicyObject1.FuncName(paramPtr); \
} \
else { \
return PolicyObject2.FuncName(paramPtr); \
} \
return 0; \

How do I parse weeks-in-year with boost::date_time?

I want to parse strings that consist of a 4-digit year and the week number within the year. I've followed the boost date/time IO tutorial, producing a test example like this:
std::string week_format = "%Y-W%W";
boost::date_time::date_input_facet<boost::gregorian::date, char> week_facet = boost::date_time::date_input_facet<boost::gregorian::date, char>(week_format);
std::stringstream input_ss;
input_ss.imbue(locale(input_ss.getloc(), &week_facet));
std::string input_week = "2004-W34";
input_ss.str(input_week);
boost::gregorian::date input_date;
input_ss >> input_date;
Unfortunately, input_date just prints as "2004-01-01", implying that it just parsed the year. What am I doing wrong? Is %W not available on input? (The documentation doesn't mark it as such.)
You are correct that the documentation doesn't mark it as such in the "Format Flags" section (no "!" next to it...)
http://www.boost.org/doc/libs/1_35_0/doc/html/date_time/date_time_io.html#date_time.format_flags
But that seems to be an oversight. Because in Boost's format_date_parser.hpp there is no coverage for this case in parse_date...you can look at the switch statement and see that:
http://svn.boost.org/svn/boost/trunk/boost/date_time/format_date_parser.hpp
Despite the absence of any code to do it, even the comments in the source say it handles %W and %U on parse input. What's up with that? :-/
On another note, I believe week_facet needs to be dynamically allocated in your example:
std::string week_format = "%Y-W%W";
boost::date_time::date_input_facet<boost::gregorian::date, char>* week_facet =
new boost::date_time::date_input_facet<boost::gregorian::date, char>(
week_format
);
std::stringstream input_ss;
input_ss.imbue(std::locale(input_ss.getloc(), week_facet));
(Or at least I had to do it that way to keep the example from crashing.)

Regular Expressions to find C++ elements?

I'm looking for some predefined Regexes for elements of ANSI C++.
I would like to create a program which takes a headerfile (with includes, namespaces, classes etc) as input and returns lists with the found classnames, methods, attributes etc.
Its hard to google for something like that, I always end up with tutorials of how to use Regexes in C++. Perhaps I'm just googling the wrong terms?
Perhaps someone already has found/used/created such Regexes.
This type of operation is not possible to do with a regular expression. C++ is not a regular language and hence can't be reliably parsed with a regular expression. The safest approach here is to use an actual parser here to locate C++ elements.
If 100% correctness is not a goal though then a regular expression will work because it can be crafted to catch the majority of cases within a code base. The simplest example would be the following
class\s+[a-z]\w+
However it will incorrectly match the following as a class
Forward declarations
Any string literal with text like "class foo"
Template parameters
etc ...
You might find the code for ctags handy. It will parse code and break out the symbols for use in emacs and other programs. In fact, it might just do all the work you are trying to do yourself.
You may also find something interesting in ctags or cscope as already mentioned. I also have encountered flist here
I'm writing a Python program to extract some essential class info from a large messy C++ source tree. I'm having pretty good luck with using regexes. Fortunately, nearly all the code follows a style that lets me get away with defining just a few regexes to detect class declarations, methods, etc. Most member variables have names like "itsSomething_" or "m_something". I kludge in hard-coded hackwork to catch anything not fitting the style.
class_decl_re = re.compile( r"^class +(\w+)\s*(:|\{)" )
close_decl_re = re.compile( r"^\};" )
method_decl_re = re.compile( r"(\w[ a-zA-Z_0-9\*\<\>]+) +(\w+)\(" )
var_decl1_re = re.compile( r"(\w[ a-zA-Z_0-9\*\<\>]+) +(its\w+);" )
var_decl2_re = re.compile( r"(\w[ a-zA-Z_0-9\*\<\>]+) +(m_\w+);" )
comment_pair_re = re.compile( r"/\*.*\*/" )
This is a work in progress, but I'll show this (possibly buggy) (no, almost certainly buggy) snip of code to show how the regexes are used:
# at this point, we're looking at one line from a .hpp file
# from inside a class declaration. All initial whitespace has been
# stripped. All // and /*...*/ comments have been removed.
is_static = (line[0:6]=="static")
if is_static:
line=line[6:]
is_virtual = (line[0:7]=="virtual")
if is_virtual:
line=line[7:]
# I believe "virtual static" is impossible, but if our goal
# is to detect such coding gaffes, this code can't do it.
mm = method_decl_re.match(line)
vm1 = var_decl1_re.match(line)
vm2 = var_decl2_re.match(line)
if mm:
meth_name = mm.group(2)
minfo = MethodInfo(meth_name, classinfo.name) # class to hold info about a method
minfo.rettype = mm.group(1) # return type
minfo.is_static = is_static
if is_static:
if is_virtual:
classinfo.screwed_up=True
classinfo.class_methods[meth_name] = minfo
else:
minfo.is_polymorphic = is_virtual
classinfo.obj_methods[meth_name] = minfo
elif vm1 or vm2:
if vm1: # deal with vars named "itsXxxxx..."
vm=vm1
var_name = vm.group(2)[3:]
if var_name.endswith("_"):
var_name=var_name[:-1]
else: # deal with vars named "m_Xxxxx..."
vm=vm2
var_name = vm.group(2)[2:] # remove the m_
datatype = vm.group(1)
vi = VarInfo(var_name, datatype)
vi.is_static = is_static
classinfo.vars[var_name] = vi
I hope this is easy to understand and translate to other languages, at least for a starting point for anyone crazy enough to try. Use at your own risk.