Escaping a # Symbol in a #Define MACro

Escaping a # symbol in a #define macro?

As far as I remember you cannot use another preprocessor directive in define.

How to escape a # in a macro

Using an indirection through another macro should do the trick:

#define HASH_LIT #
#define HASH() HASH_LIT

#define create_me(name) \
__asm\
mov name,HASH()0x1021\
__endasm

How to print a pound / hash via C preprocessor?

The answer is:

#define hash #
#define f(x) x
#define label(a) f(hash)a

then

label(foobar)

creates

#foobar

I found it with the help of all of you, but especially wintermute.
Thanks a lot!

(Using gcc 4.3.3)

Construct string/char escape sequence using C macro

You can do this by generating a large header file, e.g. using a little bit of Python:

for x in range(0,256):
print '#define BODGE_0x%x \\x%x' % (x,x)

And then use the output of that in C:

#include <stdio.h>

#include "bodge.h"

#define xstr(s) str(s)
#define str(s) #s
#define XCHR(x,y) (xstr(x##y))
#define CHR(x) xstr(BODGE_##x)

int main() {
return printf("%s\n", CHR(0x20));
}

Which does exactly what you asked for, gcc -E shows:

return printf("%s\n", "\x20");

It's possible (but fiddly) to do something less crude if you accept calling CHR(20) to imply hex without the 0x prefix.

The obvious solution would be to build a macro that expands to:

printf("%s", "\x" "20");

which is fairly easy to do with one level of indirection, and the obvious assumption would be that the compile time concatenation of strings would handle this. Unfortunately that solution isn't viable because of the point in translation when the escape sequence gets handle. GCC therefore gives the error:

error: \x used with no following hex digits

We can however work around that and cause the string "\x20" to be generated by using a pre-processor concatenation (##) in conjunction with the "usual" preprocessor stringification indirection:

#include <stdio.h>

#define xstr(s) str(s)
#define str(s) #s
#define XCHR(x,y) (xstr(x##y))
#define CHR(y) XCHR(\x,y)

int main() {
return printf("%s", CHR(20));
}

This does work and, gcc -E shows:

return printf("%s", ("\x20"));

which is what we'd hope to see when the macro works.


You could also do:

#define CHR(x) ((char[2]){(x), 0x0})

which has the desired effect.

Is there a way to escape a C preprocessor directive?

A slight variant of Marcelo Cantos's answer works for me on GNU cpp 4.4.3:

#define HASH(x) x

...

HASH(#)ifdef __cplusplus
class foo { };
HASH(#)endif

How should I escape a comma inside the arguments to esyscmd?

As configured in autoconf, the M4 quote characters are [ and ]. Commas inside a quote will not be interpreted as argument separators. Thus you should simply quote the command you are passing to esyscmd, by surrounding it with [ and ].

Unlike in other programming languages you may be used to, quoting doesn't make the argument a string or anything like that -- quoting is simply a way to treat some text as fixed, and not to interpret macros or special characters within that text.

The M4 manual is really the only way to learn about M4.

C Macro utilizing immediate values in embedded arm asm - armcc

The second of your referenced questions shows you how to do it:

#define hash #
#define mash(x) x
#define immediate(a) mash(hash)a
#define ISR_THREAD_MGMT(ISR_FUNC,FUNC_NAME) \
__asm void FUNC_NAME ( void ); \
__asm void FUNC_NAME ( void ) \
{ \
STMDB sp!, {r0-r3}; \
MRS r0, SPSR; \
SUB lr, lr, immediate(4); \
STMDB sp!, {r0, r10, r12, lr}; \
bl _thread_vectored_context_save; \
bl ISR_FUNC; \
b _thread_context_restore; \
}

ISR_THREAD_MGMT(abc,def)

Output:

# 1 "x.c"
# 1 "<command-line>"
# 1 "x.c"
# 17 "x.c"
__asm void def ( void ); __asm void def ( void ) { STMDB sp!, {r0-r3}; MRS r0, SPSR; SUB lr, lr, #4; STMDB sp!, {r0, r10, r12, lr}; bl _thread_vectored_context_save; bl abc; b _thread_context_restore; }

Output reformatted:

# 1 "x.c"
# 1 "<command-line>"
# 1 "x.c"
# 17 "x.c"
__asm void def ( void );
__asm void def ( void )
{
STMDB sp!, {r0-r3};
MRS r0, SPSR;
SUB lr, lr, #4;
STMDB sp!, {r0, r10, r12, lr};
bl _thread_vectored_context_save;
bl abc;
b _thread_context_restore;
}

I'm not convinced it is a good idea, but it does at least work.



Related Topics



Leave a reply



Submit