I want to get the name of the compiled file without extension as a constant in PROGMEM. Partially the name can be cleared like this:
#define __FILENAME__ strrchr(__FILE__, '\\') + 1
Okay, it's easy. Next I need to delete the file extension, I can do this with the code:
char *dot = strrchr(__FILENAME__, '.'); *dot = '\0'
But I can't get all-in-one inside #define because of step-by-step actions sequence and an redundant variable.
Is there a pretty solution? Length of the filename is unknown.
The option of clearing the name in the program body is an extra expense of code and memory.
It is not possible to use C preprocessor to get a filename with file extension - C preprocessor has no capability of parsing strings.
Defining identifiers starting with double
__is invalid. They are reserved, you can't define such your own identifiers.Your code will fail miserably when the
__FILE__does not contain a slash or a dot.The code you presented is invalid. You can't modify
__FILE__, it is a constant. If you are using runtime, you have tomallocthe required memory or allocate the memory on stack.Potentially, you could execute a function on program startup to fix the value, or just call the function right after
main. The happy assumption here is that filename without extension will always be smaller than__FILE__, so we can overallocate memory.With GCC, there are
__attribute__((__constructor__))and__FILE_NAME__extension you might be interested in.It is impossible to get a string literal of a filename without extension in C programming language. You have to use an external program or an extension.
With the above approach and using GCC, you can just instead compute only the length of
file_weat runtime and store__FILE_NAME__in a constant static variable. You will lose 2 bytes for.c, but that is really not much.In this case, we might precompute the dot position with a constant expression, given the string is not long. The compilation time with longer strings when writing such long ternary expressions might increase.
In real life, typically, the build system is configured to precompute the value and pass it using compiler options for each file separately, like
-DFILE_WE="something".For example, the following CMake script:
Compiles a program:
With:
Or you can use a better preprocessor like
m4orjinja2orphp.