Is there any way to "undo" the effect of #line in C? - c

I am generating C code based on information provided by another file (an XML file). Certain chunks of C are included in this XML file and should be included verbatim in my generated C file. I wish to use the #line directive, so that if these chunks contain an error, the user will see the line number in the XML file that the chunk came from. For example, I wish to generate code like:
int main() {
#line 35 "file.xml"
....
#line
}
I wish to somehow "close" the #line section, I mean I think if there is an error e.g. with the closing } and that is generated by my program, the user should not see "error on line 36 of file.xml", that will be meaningless to them and confuse them.
For example, I could imagine a #line directive on its own (as in my example) would do something like that. But it doesn't work, and there is no such mention of any such facility in the gcc docs on #line.
Is there any such facility I'm missing? Or am I just asking for something that doesn't exist? How would you go about such a problem?

You need to issue another #line directive "resetting" to the line and filename of your original file.

Related

Support for compiling ASN1 file to C with CONTAINING keyword

I'm using ESNACC for compiling multiple ASN source files to C code. For ease of understanding, I will explain the scenario here as succintly as possible:-
FileA.asn1 contains the following:-
FileA DEFINITIONS ::=
BEGIN
A ::= SEQUENCE
{
AContent [0] OCTET STRING (CONTAINING FileB.B)
}
END
FileB.asn1 contains the following:-
FileB DEFINITIONS ::=
BEGIN
B ::= SEQUENCE
{
BElem1 [0] INTEGER,
BElem2 [1] INTEGER
}
END
I used ESNACC to compile both files in one command. Upon analysing the C source files generated, I observed that the AContent field will be decoded as a constructed OCTET STRING (the data being received in the application guarantees that the field will be specified as constructed) with its contents being filled into a simple string. This means that FileB does not come into the picture at all. I was hoping that AContent would be further decoded with a structure of FileB being filled, so that I can easily access the elements within. This does not seem to be the case.
I'm fairly new with ASN1, so please let me know if my understanding is wrong in any way.
Is ESNACC not capable of generating code for supporting CONTAINING keyword properly?
Are there other compilers that are able to do this?
Can this be done by using ESNACC in any way?
If this cannot be done using ESNACC, and I don't want to use any other compiler, how would I access the contents within AContent at runtime easily?
I am not sure of the capabilities of ESNACC, but there are many other compilers that support the CONTAINING keyword. An excellent list of compilers can be found at https://www.itu.int/en/ITU-T/asn1/Pages/Tools.aspx which is part of the ITU-T ASN.1 Project.
Heimdal's ASN.1 compiler (lib/asn1/) has support for the funky Information Object System syntax extensions that allow you to declare things like what all goes into Certificate Extensions (for example), and the generated code will decode everything recursively in one go.

C extra # lines after preprocessing part [duplicate]

I was inspecting the preprocessed output generated by GCC, and I see a lot of these in the .i file that I generated using the -save-temps flag:
# 8 "/usr/include/i386-linux-gnu/gnu/stubs.h" 2 3 4
What do the numbers before and after the absolute path of stubs.h mean? It seems to be some kind of debugging information that is inserted by the preprocessor and allows the compiler to issue error messages referring to this information. These lines do not affect the program itself, but what specifically is each number for?
Based on the documentation the number before the filename is the line number. The numbers after the file name are a flag and mean the following:
1 indicates the start of a new file.
2 indicates returning to a file (after having included another file).
3 indicates that the following text comes from a system header file, so certain warnings should be suppressed.
4 indicates that the following text should be treated as being wrapped in an implicit extern "C" block.

What does the preprocessor do with "# <number> <filename>"?

I've just encountered a C file which contains both preprocessor directives and lines that look like this:
# 9 "filename"
I have never seen such lines before. What do they mean? I'm guessing these are preprocessor directives, but what does the preprocessor do with them?
Also, for some of the lines the string doesn't even represent an existing filename...
I believe it's another way of using the #line preprocessor directive.
For example you could write:
// you could write #line 7 "filename" or
// # 7 "filename" or
// # 7 or
#line 7
int main(void)
{
printf("%d\n", __LINE__);
And all of them would give you (in this case) 10 on stdout.
And a note about the "filename" part it's optional and unverified (that's why it can be anything, even a file that doesn't exist). Its use is explained in the link I provided -
If you specify a file name, the compiler views the next line as part of the specified file. If you do not specify a file name, the compiler views the next line as part of the current source file.

how to find source file name from executable?

IN LINUX:
Not sure if it is possible. I have 100 source file, and 100 respective executable files.
Now, given the executable file, is it possible to determine, respective source file.
I guess you can give this a try.
readelf -s a.out | grep FILE
I think you can add some grep and sed magic to the above command and get the source file name.
No, since your assumption, that a single binary comes from exactly one source file, is very false.
Most real applications consist of hundreds, if not thousands, of individual source files that are all compiled separately, with the results liked together to form the binary.
If you have non-stripped binaries, or (even better) binaries compiled with debugging information present, then there might (or will, for the case of debugging info) be information left in the file to allow you to figure out the names of the source files, but in general you won't have such binaries unless you build them yourself.
If source filenames are present in an executable, you can find them with:
strings executable | grep '\.c'
But filenames may or may not be present in the executable and they may or may not represent the source filenames.
Change .c to whatever extension you assume the program has been written in.
Your question only makes sense if we presume that it is a given fact that every single one of these 100 executables comes from a single source file, and that you have all those source files and are capable of compiling them all.
What you can do is to declare within each source file a string that looks like "HERE!HERE!>>>" + __FILE__ and then write a utility which searches for "HERE!HERE!>>>" inside the executable and parses the string which follows it. __FILE__ is a preprocessor directive which expands to the full pathname of the source file being compiled.
This kind of help falls in the 'close the barn door after the horse has run away' kind of thing, but it might help future posters.
This is an old problem. UNIX and Linux support the what command which was invented by Mark Rochkind (if I remember correctly), for his version of SCCS. Handles exactly this type of problem. It is only 100% reliable for one source file -> one exectuable (or object file ) kind of thing. There are other more important uses.
char unique_id[] = "#(#)identification information";
The #(#) is called a "what string" and does not occur as a by-product of compiling source into an executable image. Use what from the command line. Inside code use maybe something like this (assumes you get only one file name as an answer, therefore choose your what strings carefully):
char *foo(char *whoami, size_t len_whoami)
{
char tmp[80]={0x0};
FILE *cmd;
sprintf(tmp, "/usr/bin/grep -F -l '%s' /path/to/*.c", unique_id);
cmd=popen(tmp, "r");
fgets(whoami, len_whoami, cmd);
pclose(cmd);
return whoami;
}
will return the source code file name with the same what string from which your executable was built. In other words, exactly what you asked, except I'm sure you never heard of what strings, so they do not exist in your current code base.

#line keyword in C

I am trying to understand some code and I've come across a keyword that I've never seen before. I tried to google it, but haven't found anything regarding it as well.
char *valtext;
#line 1 "Values.l"
#define INITIAL 0
#line 2 "Values.l"
int reserve(char *s);
#line 388 "lex.val.c"
I've included the entire block hoping that perhaps someone can help me understand this chunk of code. I can't find any files on my system named "Values.l" and this chunk of code is located in the "lex.val.c" file.
Thanks in advance.
A #line directive sets the compiler's setting for the current file name and line number. This affects the __FILE__ and __LINE__ symbols, the output generated by a failing assert(), and diagnostic messages (errors and warnings). It's typically used by the preprocessor so that error and warning messages can refer to the original source code, not to the output of the preprocessor (which is typically discarded by the time you see any messages).
It's also used by other tools that generate C source code, such as lex/flex and yacc/bison, so that error messages can refer to the input file rather than the (temporary) generated C code.
The definitive reference is the C standard (pdf), section 6.10.4.
A line of the form
#line number
sets the current line number. A line of the form
#line number "file-name"
sets both the line number and the file name. You can also generate one of these two forms via macro expansion; for example:
#define LINE 42
#define FILE "foo.c"
#line LINE FILE
The #line directive is for the use of preprocessors, so that the original line number of the source can be communicated to the C compiler. It makes it so that error messages from the compiler properly refer to line numbers the user will understand.
For example, line 12 of your mycode.c may go through a preprocessor, and now be line 183 of mycode.tmp.cc. If the C compiler finds an error on that line, you don't want to be told the error is on line 183 of mycode.tmp.cc. So the C compiler needs to be given "original coordinates" of each line. The #line directive does this, telling the compiler the current line number and filename to use in error messages.
The line directive:
http://msdn.microsoft.com/en-US/library/b5w2czay%28v=VS.80%29.aspx
That code has gone through the pre-processor and as such is marked up by one stage of a compiler, intended to be consumed by another stage of the same compiler. The features that it uses aren't intended for your use.
The files that it references may be temporary files created by the compiler as it runs.
This is done so that the line number changes.
This is done in order to show the line numbers of the Lex input file, for example, in error messages and warnings. Because Lex generates C code, without #line directives compile errors and warnings wouldn't be of any value.

Resources