Discussion:
[TECH]: Macro expansion - pre-processor directives - predefined constants __FILE __
Justin Richards
2017-12-01 11:46:09 UTC
Permalink
I have a re-usable source file that is used in many projects that is used
to generate some information about the environment that it was built in.

I use existing predefined or generated constants (not sure what to call
them) like

__DATE__

__TIME__

__FILE__

All is good until I tried to use __FILE__. As per the description __FILE__
returns the path and file name of the file that actually contains the
__FILE__ directive. Not what I want.

I want the actual file name of the parent source file as it is more
meaningful.

Thinking I was on to a solution I did this

#define __PROJECT_PATH_FN__ __FILE__

then use __PROJECT_PATH_FN__ in the in re-usable source file but the
pre-processor does what it does and replaces _PROJECT_PATH_FN__ with
__FILE__.

I was hoping it (the pre-compiler) would expand __FILE__ when it first
encounters it but sadly no.

I have a solution but it requires the target processor to do some of the
work like this

const char __PROJECT_PATH_FN__[] = __FILE__;

Then I can use __PROJECT_PATH_FN__ where needed and it expands out to the
PATH and FILENAME of the parent source file.

I assume "const char" allocates program space to store the string.

This is OK, but if anyone knows a better way i would be curious how I go
about it.

I tried understanding #pragma, thinking this may help but I dont understand
it purpose.

Any thoughts?

Cheers Justin
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
Isaac M. Bavaresco
2017-12-01 12:02:11 UTC
Permalink
Hi Justin,

The C pre-processor is a little confusing sometimes.

It needs some experimenting, but you could try some tricks.


a) Double expansion, that is, create a macro that calls another macro,
and in this second macro use the __FILE__:

#define    __MY_FILE_INTERNAL__    __FILE__

#define   __MY_FILE__                         __MY_FILE_INTERNAL__


b) Stringification operator:


#define    __MY_FILE_INTERNAL__(arg)    #arg

#define   __MY_FILE__                         __MY_FILE_INTERNAL__(__FILE__)


or perhaps:

#define    __MY_FILE_INTERNAL__(arg)    arg

#define   __MY_FILE__                        
__MY_FILE_INTERNAL__(#__FILE__)


or some other combination may work.


Cheers,

Isaac
Post by Justin Richards
I have a re-usable source file that is used in many projects that is used
to generate some information about the environment that it was built in.
I use existing predefined or generated constants (not sure what to call
them) like
__DATE__
__TIME__
__FILE__
All is good until I tried to use __FILE__. As per the description __FILE__
returns the path and file name of the file that actually contains the
__FILE__ directive. Not what I want.
I want the actual file name of the parent source file as it is more
meaningful.
Thinking I was on to a solution I did this
#define __PROJECT_PATH_FN__ __FILE__
then use __PROJECT_PATH_FN__ in the in re-usable source file but the
pre-processor does what it does and replaces _PROJECT_PATH_FN__ with
__FILE__.
I was hoping it (the pre-compiler) would expand __FILE__ when it first
encounters it but sadly no.
I have a solution but it requires the target processor to do some of the
work like this
const char __PROJECT_PATH_FN__[] = __FILE__;
Then I can use __PROJECT_PATH_FN__ where needed and it expands out to the
PATH and FILENAME of the parent source file.
I assume "const char" allocates program space to store the string.
This is OK, but if anyone knows a better way i would be curious how I go
about it.
I tried understanding #pragma, thinking this may help but I dont understand
it purpose.
Any thoughts?
Cheers Justin
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailm
Justin Richards
2017-12-01 12:30:38 UTC
Permalink
Thanks Isaac,

I will experiment as suggested.

I did find something like below (modified for my purposes) on a forum but
produced the same result. i.e it expands to give the path of the included
file

Parent File:-
#define STRINGIFY(x) #x
#define EXPAND(x) STRINGIFY(x)
#define BUILD __FILE__

Included File:-
String message = EXPAND(BUILD);
Post by Isaac M. Bavaresco
Hi Justin,
The C pre-processor is a little confusing sometimes.
It needs some experimenting, but you could try some tricks.
a) Double expansion, that is, create a macro that calls another macro,
#define __MY_FILE_INTERNAL__ __FILE__
#define __MY_FILE__ __MY_FILE_INTERNAL__
#define __MY_FILE_INTERNAL__(arg) #arg
#define __MY_FILE__
__MY_FILE_INTERNAL__(__FILE__)
#define __MY_FILE_INTERNAL__(arg) arg
#define __MY_FILE__
__MY_FILE_INTERNAL__(#__FILE__)
or some other combination may work.
Cheers,
Isaac
Post by Justin Richards
I have a re-usable source file that is used in many projects that is used
to generate some information about the environment that it was built in.
I use existing predefined or generated constants (not sure what to call
them) like
__DATE__
__TIME__
__FILE__
All is good until I tried to use __FILE__. As per the description
__FILE__
Post by Justin Richards
returns the path and file name of the file that actually contains the
__FILE__ directive. Not what I want.
I want the actual file name of the parent source file as it is more
meaningful.
Thinking I was on to a solution I did this
#define __PROJECT_PATH_FN__ __FILE__
then use __PROJECT_PATH_FN__ in the in re-usable source file but the
pre-processor does what it does and replaces _PROJECT_PATH_FN__ with
__FILE__.
I was hoping it (the pre-compiler) would expand __FILE__ when it first
encounters it but sadly no.
I have a solution but it requires the target processor to do some of the
work like this
const char __PROJECT_PATH_FN__[] = __FILE__;
Then I can use __PROJECT_PATH_FN__ where needed and it expands out to the
PATH and FILENAME of the parent source file.
I assume "const char" allocates program space to store the string.
This is OK, but if anyone knows a better way i would be curious how I go
about it.
I tried understanding #pragma, thinking this may help but I dont
understand
Post by Justin Richards
it purpose.
Any thoughts?
Cheers Justin
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
p***@roadrunner.com
2017-12-01 13:11:28 UTC
Permalink
At the top of source file "foo.c", before including "bar.h", put the
definition

#define MAIN_FILE "foo.c"

Then in "bar.h", just use MAIN_FILE to get the name.

- - Bob Ammerman
RAm Systems

-----Original Message-----
From: piclist-***@mit.edu [mailto:piclist-***@mit.edu] On Behalf Of
Justin Richards
Sent: Friday, December 1, 2017 6:46 AM
To: Microcontroller discussion list - Public. <***@mit.edu>
Subject: [TECH]: Macro expansion - pre-processor directives - predefined
constants __FILE __

I have a re-usable source file that is used in many projects that is used to
generate some information about the environment that it was built in.

I use existing predefined or generated constants (not sure what to call
them) like

__DATE__

__TIME__

__FILE__

All is good until I tried to use __FILE__. As per the description __FILE__
returns the path and file name of the file that actually contains the
__FILE__ directive. Not what I want.

I want the actual file name of the parent source file as it is more
meaningful.

Thinking I was on to a solution I did this

#define __PROJECT_PATH_FN__ __FILE__

then use __PROJECT_PATH_FN__ in the in re-usable source file but the
pre-processor does what it does and replaces _PROJECT_PATH_FN__ with
__FILE__.

I was hoping it (the pre-compiler) would expand __FILE__ when it first
encounters it but sadly no.

I have a solution but it requires the target processor to do some of the
work like this

const char __PROJECT_PATH_FN__[] = __FILE__;

Then I can use __PROJECT_PATH_FN__ where needed and it expands out to the
PATH and FILENAME of the parent source file.

I assume "const char" allocates program space to store the string.

This is OK, but if anyone knows a better way i would be curious how I go
about it.

I tried understanding #pragma, thinking this may help but I dont understand
it purpose.

Any thoughts?

Cheers Justin
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive View/change
your membership options at http://mailman.mit.edu/mailman/listinfo/piclist
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
Justin Richards
2017-12-01 14:02:34 UTC
Permalink
Hi Bob,

thanks for the hint, but doesn't automatically give me all the metadata.

I was using it to help me with versioning.

The problem I have is I move from place to place doing development. I am
making lots of significant changes to code as I am developing. I should
probably get a versioning system under control.

I was copying the entire SDE, but that is time consuming. I was using an
external drive but that also presents problems and I am not always able
(allowed) to take it with me.

Cloud is out as I dont always have access to the internet and is slow.

I am basically putting together a tool box of projects that work, then I
can later use for the final project.

Most of the target devices have web servers. When accessing the root page
it provides me with some hints of where and when I last complied that
version. i.e Time, Date,Path, Filename etc.

I try to make the name of top source file meaningful, that with the actual
path quickly reveals where I developed what and tells me instantly which
version that was.

As mentioned, I have a solution that supports my haphazard, less than ideal
approach to development, just looking for a way to lighten the demand on
the target processor, a more elegant solution.

Cheers Justin
Post by p***@roadrunner.com
At the top of source file "foo.c", before including "bar.h", put the
definition
#define MAIN_FILE "foo.c"
Then in "bar.h", just use MAIN_FILE to get the name.
- - Bob Ammerman
RAm Systems
-----Original Message-----
Justin Richards
Sent: Friday, December 1, 2017 6:46 AM
Subject: [TECH]: Macro expansion - pre-processor directives - predefined
constants __FILE __
I have a re-usable source file that is used in many projects that is used to
generate some information about the environment that it was built in.
I use existing predefined or generated constants (not sure what to call
them) like
__DATE__
__TIME__
__FILE__
All is good until I tried to use __FILE__. As per the description __FILE__
returns the path and file name of the file that actually contains the
__FILE__ directive. Not what I want.
I want the actual file name of the parent source file as it is more
meaningful.
Thinking I was on to a solution I did this
#define __PROJECT_PATH_FN__ __FILE__
then use __PROJECT_PATH_FN__ in the in re-usable source file but the
pre-processor does what it does and replaces _PROJECT_PATH_FN__ with
__FILE__.
I was hoping it (the pre-compiler) would expand __FILE__ when it first
encounters it but sadly no.
I have a solution but it requires the target processor to do some of the
work like this
const char __PROJECT_PATH_FN__[] = __FILE__;
Then I can use __PROJECT_PATH_FN__ where needed and it expands out to the
PATH and FILENAME of the parent source file.
I assume "const char" allocates program space to store the string.
This is OK, but if anyone knows a better way i would be curious how I go
about it.
I tried understanding #pragma, thinking this may help but I dont understand
it purpose.
Any thoughts?
Cheers Justin
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive View/change
your membership options at http://mailman.mit.edu/mailman/listinfo/piclist
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
t***@cowshed.us
2017-12-04 16:08:30 UTC
Permalink
I have done this, it's easy but it takes some effort....

Add some extra parameters to your functions to pass the required data
in, and rename the function (I like to add an underscore), if your old
function "doFoo" takes an integer, bar, it'll now look like this...

void _doFoo(int bar, char *calledFile, char *calledDate, char
*calledTime);

Then define a macro for the rest of your code

#define doFoo(__bar) _doFoo(__bar, __FILE__, __DATE__, __TIME__)

now everytime you "doFoo" it will pass in where it was called from and
you can use "calledFile" etc to report that information instead of where
"doFoo" actually is.

As this is all preprocessor stuff, there is no significant runtime
performance impact. However stack usage will increase due to the extra
parameters and the text segment size may increase depending on how the
literals are stored.
Post by Justin Richards
Hi Bob,
thanks for the hint, but doesn't automatically give me all the
metadata.
I was using it to help me with versioning.
The problem I have is I move from place to place doing development. I am
making lots of significant changes to code as I am developing. I should
probably get a versioning system under control.
I was copying the entire SDE, but that is time consuming. I was using an
external drive but that also presents problems and I am not always able
(allowed) to take it with me.
Cloud is out as I dont always have access to the internet and is slow.
I am basically putting together a tool box of projects that work, then I
can later use for the final project.
Most of the target devices have web servers. When accessing the root page
it provides me with some hints of where and when I last complied that
version. i.e Time, Date,Path, Filename etc.
I try to make the name of top source file meaningful, that with the actual
path quickly reveals where I developed what and tells me instantly which
version that was.
As mentioned, I have a solution that supports my haphazard, less than ideal
approach to development, just looking for a way to lighten the demand on
the target processor, a more elegant solution.
Cheers Justin
Post by p***@roadrunner.com
At the top of source file "foo.c", before including "bar.h", put the
definition
#define MAIN_FILE "foo.c"
Then in "bar.h", just use MAIN_FILE to get the name.
- - Bob Ammerman
RAm Systems
-----Original Message-----
Behalf
Of
Justin Richards
Sent: Friday, December 1, 2017 6:46 AM
Subject: [TECH]: Macro expansion - pre-processor directives -
predefined
constants __FILE __
I have a re-usable source file that is used in many projects that is used
to
generate some information about the environment that it was built in.
I use existing predefined or generated constants (not sure what to call
them) like
__DATE__
__TIME__
__FILE__
All is good until I tried to use __FILE__. As per the description __FILE__
returns the path and file name of the file that actually contains the
__FILE__ directive. Not what I want.
I want the actual file name of the parent source file as it is more
meaningful.
Thinking I was on to a solution I did this
#define __PROJECT_PATH_FN__ __FILE__
then use __PROJECT_PATH_FN__ in the in re-usable source file but the
pre-processor does what it does and replaces _PROJECT_PATH_FN__ with
__FILE__.
I was hoping it (the pre-compiler) would expand __FILE__ when it first
encounters it but sadly no.
I have a solution but it requires the target processor to do some of the
work like this
const char __PROJECT_PATH_FN__[] = __FILE__;
Then I can use __PROJECT_PATH_FN__ where needed and it expands out to the
PATH and FILENAME of the parent source file.
I assume "const char" allocates program space to store the string.
This is OK, but if anyone knows a better way i would be curious how I go
about it.
I tried understanding #pragma, thinking this may help but I dont understand
it purpose.
Any thoughts?
Cheers Justin
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive View/change
your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
Loading...