replica nfl jerseysreplica nfl jerseyssoccer jerseyreplica nfl jerseys forums.silverfrost.com :: View topic - Can a function access the name of the referencing routine?
forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Can a function access the name of the referencing routine?

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
hdalgarno



Joined: 27 Jun 2013
Posts: 8

PostPosted: Fri Jul 12, 2013 9:22 am    Post subject: Can a function access the name of the referencing routine? Reply with quote

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
View user's profile Send private message
JohnMansell



Joined: 10 May 2006
Posts: 18
Location: Darlington

PostPosted: Fri Jul 12, 2013 9:45 am    Post subject: Reply with quote

Not in standerd fortran. It lacks a COMEFROM statement Wink
You may find this amusing: http://en.wikipedia.org/wiki/COMEFROM
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1899

PostPosted: Fri Jul 12, 2013 1:42 pm    Post subject: Reply with quote

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
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2615
Location: Sydney

PostPosted: Fri Jul 12, 2013 1:45 pm    Post subject: Reply with quote

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
View user's profile Send private message
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Sat Jul 13, 2013 12:31 pm    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
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