Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fortran substitute subroutine name using macro

Tags:

macros

fortran

I am writing a module that allows users to log information. I want to provide an interface that logs a string message, which can be called as

call m_log(msg)

So in file m_logger.f90, I will have

module m_logger
..
  subroutine m_log(msg)
  ..
end module 

In file main.f90, a user will have

program main
use m_logger

call m_log(msg)
end program 

Now how can I substitute call m_log(msg) with call m_log(msg, __FILE__, __LINE__) ?

Because of this substitution, a different subroutine subroutine m_log(msg, filename, linenum) in the logger module will be called instead.

If I use a macro like #define m_log(msg) m_log(msg,__FILE__,__LINE__) , it will have to be added to every user file that uses the logger.

Also, I do not want to enforce the user to pass __FILE__ and __LINE__ explicitly.

Is there a way I can do this? Or are there any other alternatives altogether?

Thanks in advance

Edit: I had a discussion on comp.lang.fortran. Adding a link for reference. here

like image 710
jitihsk Avatar asked May 14 '26 22:05

jitihsk


2 Answers

In this case you would have to use the same approach C uses. Define the macro you proposed

 #define log(msg) m_log(msg,__FILE__,__LINE__)

in a separate file (possibly with other useful macros) and include it using #include "file.inc" (standard Fortran include won't suffice).

If the macro has a different name, than the subroutine it actually calls, you can ensure that the user has to use the include and cannot forget it.

like image 99
Vladimir F Героям слава Avatar answered May 18 '26 09:05

Vladimir F Героям слава


If you don't want to force __file__ and __line__ explicitly, then you can use the optional flag, such that your subroutine looks like:

subroutine m_log(msg, filename, linenum)
   character(len=*) :: msg
   character(len=*), optional :: filename
   integer, optional :: linenum
   if(present(filename)) then
      <something with filename>
   endif
   if(present(linenum)) then
      <something with linenume>
   endif
   <normal stuff with msg>
end subroutine

The intrinsic function present returns a true value if filename or linenum have any values attached to it, returning false otherwise.

like image 35
Kyle Kanos Avatar answered May 18 '26 10:05

Kyle Kanos



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!