 |
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
hdalgarno
Joined: 27 Jun 2013 Posts: 8
|
Posted: Fri Jul 12, 2013 9:22 am Post subject: Can a function access the name of the referencing routine? |
|
|
I have an external function that is used extensively throughout my model. It is held in a separate .FOR file to all the program subunits that might reference it. Under certain conditions the function will print a warning to the screen, and what I'd like to be able to do is discover which particular function reference generated the warning, or even just which program subunit contained the reference.
Is there any way that the function can access and print the name of the referencing subunit within the warning? I know that I could add a flag to the list of arguments that is set by the presence of the warning, and then test this flag immediately following every use of the function within the model, but this would be very labour intensive so I'm keen to find out if there is a more elegant solution that can simply be inserted into the function itself.
Many thanks |
|
Back to top |
|
 |
JohnMansell
Joined: 10 May 2006 Posts: 18 Location: Darlington
|
|
Back to top |
|
 |
mecej4
Joined: 31 Oct 2006 Posts: 1899
|
Posted: Fri Jul 12, 2013 1:42 pm Post subject: |
|
|
What you want is a traceback that can be initiated from your code rather than a standard Fortran "exception". Such a traceback is not implementable within Fortran, but FTN95 can be induced to give you such a traceback. Other compilers provide a function (e.g., Intel Fortran provides TRACEBACKQQ()) to do this directly, but with a compiler that does not, you need to use the cuckoo's strategy.
The following example illustrates how to do this. Let us suppose that in SUB2 you want to use y==58 as the condition to print a traceback. When the condition is met, you do something that triggers a standard Fortran traceback, such as floating division by zero. Compile and link with the /DEBUG option, and run the program.
Unfortunately, there is no recovery from the exception, so you can only do one traceback per run. To print a traceback and continue, you need a more elaborate modification of your sources.
Another method is to run in the debugger, setting conditional breakpoints at the places of interest.
Code: | program tst
integer ijk
!
ijk=29
call sub1(ijk)
stop
end program tst
!
subroutine sub1(x)
integer x
call sub2(x+x)
return
end subroutine sub1
!
subroutine sub2(y)
integer y
if(y == 58)y=nint(y/0d0)
return
end subroutine sub2 |
Last edited by mecej4 on Fri Jul 12, 2013 1:46 pm; edited 1 time in total |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Fri Jul 12, 2013 1:45 pm Post subject: |
|
|
To identify where the function was called from, you could declare a global variable ( in COMMON or a MODULE) and set it to a "location identifier value". This could be an alternative to changing the argument list of your function.
This way you could judge for yourself how carefully you would need to implement the location identifier update.
Alternatively, I do not know of a way to obtain a call trace-back, which is what you realy want.
Doing a global search of the function call should not be too hard to do. The following DOS command would help:
find /i /n "%1" *.f95 >%1.tce
John |
|
Back to top |
|
 |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Sat Jul 13, 2013 12:31 pm Post subject: |
|
|
With Silverfrost's FTN95 you can supply your own version of the RUN_TRACE@ subroutine to do what you want. You enable this using the compile option /RUNTRACE (its also in Plato's project properties).
You just need to store the last subroutine/function visited in a variable.
A simple RUN_TRACE@ would look look like:
Code: |
SUBROUTINE RUN_TRACE@(line_num, fun_name, file_name)
INTEGER(3) line_num
CHARACTER(*) fun_name, file_name
INTEGER(3), SAVE :: last_line_num
CHARACTER(len=32), SAVE :: last_fun_name
print *, 'Came from : Line, ' last_line_num, ' of routine ', last_fun_name
last_fun_name = fun_name
last_line_num = line_num
END
|
_________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|