Reputation: 35408
I am trying to spice up my testing framework for a scripting language with some nice C macros to not to have to write the same code more than once ... So, I have the code:
TEST_CASE("Variables", "[vm_variables]")
{
nap_runtime* runtime = nap_runtime_create(0);
REQUIRE(runtime != 0);
nap_bytecode_chunk* bytecode = nap_runtime_compile(runtime,
" \
int a; \
a = 2; \
"
);
REQUIRE(bytecode != 0);
int t = nap_runtime_execute(runtime, bytecode);
REQUIRE(1 == t);
REQUIRE(2 == nap_runtime_get_int(runtime, "a"));
free(runtime);
}
As it is right now it creates a runtime where it executes the code (int a; a=2;
), and this works...
And I was thinking to extract the creation parts into a macro, like the one below, in a way that I have to write only the script ... so I came up with:
#define SCRIPT_START nap_runtime* runtime = nap_runtime_create(0); \
nap_bytecode_chunk* bytecode = nap_runtime_compile(runtime, \
"
#define SCRIPT_END " \
); \
int t = nap_runtime_execute(runtime, bytecode);
TEST_CASE("Variables", "[vm_variables]")
{
SCRIPT_START \ <<------------- HERE
int a; \
a = 2; \
SCRIPT_END
REQUIRE(2 == nap_runtime_get_int(runtime, "a"));
free(runtime);
}
And in my head this works nicely, but the compiler does not like it... where the HERE is it give mes the following error:
test.cpp: error: missing terminating " character
I have changed, and modified it several rotations, still the same... What do I do wrongly?
EDIT:
After compiling with -E
here is the relevant part:
44633 {
44634 nap_runtime* runtime = nap_runtime_create(0); nap_bytecode_chunk* bytecode = nap_runtime_compile(runtime, "
44635 int a;
44636 a = 2;
44637 " ); int t = nap_runtime_execute(runtime, bytecode); REQUIRE(1 == t);
44638
so it seems the \
from the line with the SCRIPT_START
macro is being ignored ... and also the other following lines. Why?
EDIT2 Experimenting and having fun with the compiler:
Now, I put TWO backslashes:
TEST_CASE("Variables", "[vm_variables]")
{
SCRIPT_START \\ <<------------- HERE
int a; \\
a = 2; \\
SCRIPT_END
the output via -E
is:
44634 nap_runtime* runtime = nap_runtime_create(0); nap_bytecode_chunk* bytecode = nap_runtime_compile(runtime, " \
44635 int a; \
44636 a = 2; \
44637 " ); int t = nap_runtime_execute(runtime, bytecode); REQUIRE(1 == t);
and the error is almost the same:
test.cpp:19:5: error: missing terminating " character
test.cpp:19:5: error: stray ‘\’ in program
so regardless, that with two backslashes it generates "correct" code that still fails to compile :)
Upvotes: 2
Views: 1347
Reputation: 361615
You can't have an unmatched "
in a #define
macro. The contents of a macro must be tokenizable. A string literal token is not a complete token if it doesn't have both begin and end quotes.
The other answers about backslashes and such are wrong. You simply cannot have unmatched quotes in macros. See this example program, which does not compile:
$ cat test.c
#include <stdio.h>
#define BEGIN_QUOTE "
#define END_QUOTE "
int main() {
printf(BEGIN_QUOTE hello world!\n END_QUOTE);
return 0;
}
$ gcc -Wall test.c
test.c:3:21: warning: missing terminating " character [enabled by default]
test.c:4:19: warning: missing terminating " character [enabled by default]
test.c: In function ‘main’:
test.c:7:5: error: missing terminating " character
test.c:7:24: error: ‘hello’ undeclared (first use in this function)
test.c:7:24: note: each undeclared identifier is reported only once for each function it appears in
test.c:7:30: error: expected ‘)’ before ‘world’
test.c:7:30: error: stray ‘\’ in program
test.c:7:30: error: missing terminating " character
You'll have to leave the quotes outside of the macros and write them explicitly:
SCRIPT_START
" \
int a; \
a = 2; \
"
SCRIPT_END
Upvotes: 3