Reset C / C ++ preprocessor #line physical file / line

I have a code generator that is going to take some code written by the user and paste it into a larger generated file. I want the main compiler to provide good diagnostics in the presence of defects in the user code, but I also do not want the defects in the generated code to be incorrectly assigned to the source when they should not be.

I intend to issue the #line lineNum "sourceFile" directives at the beginning of each piece of user-written code. However, I cannot find the #line directive documentation that mentions the __LINE__ and __FILE__ "reset" __LINE__ back to the actual line in the generated file after I leave the code provided by the user. An ideal solution would be similar to the C # preprocessor directive #line default .

Do I just need to keep track of how many lines I wrote, and manually reset that I myself? Or is there a better way, some kind of reset directive or control value that I can pass to #line to erase the connection with the user code?

It seems that this was before , although there is no firm answer. To distinguish this from this, I will additionally ask if the lack of response has changed from C ++ 11.

+4
source share
5 answers

The technique I used earlier is that my code generator outputs # on its own in the line when it wants to reset the line directives, and then use a simple awk script to post the file process and change them to correct the line directives:

 #!/bin/awk -f /^#$/ { printf "#line %d \"%s\"\n", NR+1, FILENAME; next; } { print; } 
+5
source

Yes, you need to keep track of the number of lines you output, and you need to know the name of the file you output to. Remember that the specified line number is the line number of the next line. So, if you wrote 12 lines, you need to output #line 14 "filename" , as the #line directive will go to line 13, and so the next line will be 14.

There is no difference between the #line preprocessor #line in C and C++ .

0
source

Suppose the input to the user.code code generator contains the following:

 int foo () { return error1 (); } int bar () { return error2 (); } 

Suppose you want to increase this so that it looks basically like this:

 int foo () { return error1 (); } int generated_foo () { return generated_error1 (); } int bar () { return error2 (); } int generated_bar () { return generated_error2 (); } 

Except that you do not want this. You want to add #line directives to the generated code so that compiler messages indicate whether errors / warnings are user code or auto-generated code. The #line directive indicates the source of the next line of code (not the line containing the #line directive).

 #line 1 "user.code" int foo () { return error1 (); } #line 7 "generated_code.cpp" // NOTE: This is line #6 of generated_code.cpp int generated_foo () { return generated_error1 (); } #line 5 "user.code" int bar () { return error2 (); } #line 17 "generated_code.cpp" // NOTE: This is line #16 of generated_code.cpp int generated_bar () { return generated_error2 (); } 
0
source

@Novelocrat,

I already asked this question here , and no solid answers were posted, but I realized that if line directives are inserted into automatically generated code that points to user code, then this makes the automatically generated code hard to carry . You must save the automatically generated and user code in places where the compiler can find them for error messages. I thought it’s better to just insert the file name and line numbers of the user code into the generated code. Good text editors deal with a few keystrokes to jump to a line in a file by placing the cursor in the file name.

For example: in vim, placing the cursor in the file name, and pressing gf will lead you to the file, and :42 will lead you to line 42 (say), which had an error.

Just post this bit here so that someone else answering the same questions might also consider this alternative.

0
source

Have you tried giving you __LINE__ and __FILE__ ? I believe that they are taken from your #line directives (what will be the point, if not?).

(A quick test with gcc-4.7.2 and clang-3.1 confirms my hunch).

-1
source

All Articles