Doxygen recognize parameters with linebreak - fortran

I'm trying to document my Fortran 77+90 extensions files. In general, everything works fine, except for one thing. Some of my subroutines have a little longer parameter list. Because of that, they are written with linebreak to add inline comments, as you can see below:
subroutine example (
& a, ! fist parameter
& b, ! second parameter
& c, ! third parameter
& ...
& z) ! 26th parameter
<doing some stuff here...>
end
However, when I run doxygen, it doesn’t recognize these parameter, which results in an empty parameter list inside my html document. It just says:
subroutine example ( )
Of course I can add the parameters using #param, but they don’t show up in the initial description.
Is there a hidden option/command in doxygen to get my desired output? I want something like this in my documentation:
subroutine example ( integer a
double precision b
....
integer z )
This can be created when i put all my parameters inline like this:
subroutine example (a,b,c,...,z)
<doing some stuff here...>
end
Unfortunately, the requested fixed format of Fortran doesn’t let me use this. Can someone help me with that?
EDIT: This is what happens with linebreaks in the subroutine parameterlist!
http://www.pic-upload.de/view-28502940/pic.png.html

To elaborate on albert's comment, you can document your subroutine for example like this:
!> Get a globally defined function.
subroutine aot_fun_global(L, fun, key)
type(flu_state) :: L !< Handle for the Lua script.
!> Returned handle, providing access to the function.
type(aot_fun_type), intent(out) :: fun
!> Name of the function to look up in the global scope of the Lua script.
character(len=*), intent(in) :: key
And the doxygen html for it.

Related

External files in Doxygen

I am currently working on a very big ocean model, and since I am developing a new parametrization, I want to explain it deeply in the documentation of the code. To do this, I am using Doxygen. Of course the documentation I want to provide is long, as it is necessary to explain a lot of details, and I need also a lot of formulas. I am talking about a couple of hundreds of lines of latex formatted text (including formulas) for each module (I am working in fortran90).
Since it seems bad to insert directly all this explanations in the .f90 source file, I am looking for a valid alternative. To be clear, I want something like the \input{} command in LaTex, to refer to an external file that could be possibly containing all my explanation in some suitable formatted text.
!----------------------------------------------------------------------
! A VERY BIG GENERAL CIRCULATION MODEL
!----------------------------------------------------------------------
!
! MODULE: tludyn
!
! DESCRIPTION:
!> #brief A novel parametrization of Navier stokes
!>
!> #details Here goes a long description. This parametrization needs a
!> lot of explaining, long formulas, long texts... Let's say that every
!> subroutine needs a couple of hundreds lines of latex-formatted code
!
!> \f[
!> \left( \nabla \cdot A \right)_{i}= \frac{1}{e_{1}e_{2}}
!> \left[
!> \frac{\partial}{\partial i}\left( e_{2}a_{i1} \right) +
!> \frac{\partial}{\partial j}\left( e_{1}a_{i2} \right) +
!> \right] +
!> \frac{1}{e_{3}}\left[
!> \frac{\partial}{\partial k}\left( a_{i3} \right)
!> \right]
!> \f]
!> #include tlu_dyn.md
!>
!----------------------------------------------------------------------
Potentially, I would love to put everything in a file, say flu_dyn.md and include sections of this file in different parts of my .f90 source code. If not possible I would like to just include external files as they are. The included file should appear in the html page.
How can I achieve this?
Edit 1
I am using version 1.9.2 and these are the differences with the reference config file:
PROJECT_NAME = DoxyNEMO
CREATE_SUBDIRS = YES
TAB_SIZE = 8
OPTIMIZE_FOR_FORTRAN = YES
EXTENSION_MAPPING = f=FortranFixed \
f90=FortranFree \
txt=md
EXTRACT_PRIVATE = YES
INPUT = release-4.0/src/tlu_dyn.f90 \ (source)
release-4.0/src/tlu_dyn.md (here I want to put
the long explanations)
FILE_PATTERNS = all the usual plus this: *.dox
EXAMPLE_PATH = release-4.0/src
LATEX_HEADER = doxy_header.tex
LATEX_FOOTER = doxy_footer.tex
In the file tlu_dyn.md there are the same lines from \f[ to \f].
The result looks like:
.
Edit 2
The file tlu_dyn.md, that contains my pedantic description of the code, is the result of 2 days of trials where I tried several extensions and several commands. In the first example I posted, the file contained exactly what shown in the figure, as I was trying to see if Doxygen syntax was ok. In a second trial, I tried to put two simple lines as
# Is this working? (Header)
This is plain text.
to see if a tex with markdown syntax was better.
I would like to write in this file in a simple way, so markdown is an option, pure latex would be even better (even though there is no evidence that pure latex is admitted), html or Doxygen syntax are last resorts.

Reading multiple files in fortran in a loop

I want to read in multiple files in Fortran in a loop by using the filename formatting system. Problem is the filenames have numbers that don't follow each other directly. Examples of the filenames are 4e3_2048_380_40_3e9.ksz_cl.txt, 4e3_2048_200_80_2e8.ksz_cl.txt. The 3rd, 4th and 5th numbers in the filenames form a 3x3 grid. The first number goes from 140-260, the second goes from 40-80 and the third number goes from 2e8-2e9.
I've searched for answers in threads like reading multiple files in fortran but it doesn't seem to answer my question. My code below currently print out 4e3_2048_01.ksz_cl.txt.
program readfiles
implicit none
integer :: i, N
Logical, Save :: first_time = .True.
CHARACTER(len=25) :: FN
N=3 !--arbitrary number of files
if(first_time) then
DO I=1,N
WRITE(FN,10)I
WRITE(6,*)FN
OPEN(1,FILE=FN, status='replace')
CLOSE(1)
END DO
10 FORMAT('4e3_2048_',I2.2,'.ksz_cl.txt')
endif
end program readfiles

How to automatically adjust string length in the A edit descriptor?

I'm trying to write a string filename in fortran using:
WRITE(FILENAME,'(A27,I3.3,A1,I3.3,A3)') NAME,MYPR,'_',IBL,'.nc'
where NAME is a string of variable lengths, and MYPR and IBL are integers.
I'm searching for a solution where I can dynamically write the format:
'(A27,I3.3,A1,I3.3,A3)',
where A27 will change depending on the length of NAME. I've tried 'A' alone but this caused an error. I'm not sure of what is possible here as many texts do not even cover something similar issues.
Would appreciate some ideas.
The obvious solution would be to use the format string '(A,I3.3,A1,I3.3,A3)', i.e. using just A for the name and letting the compiler choose the correct length. This is working perfectly for me.
As #agentp suggested, you might see issues due to whitespaces in the string. This might be resolved by using trim(name) to get rid of trailing whitespace, or even trim(adjustl(name)) which removes both leading and trailing whitespace. This solution is given below in subroutine print1().
The other option would be to generate the format string dynamically - after all, that is just a string as well. This is quite cumbersome, and an overkill in your situation - see print2().
module test_mod
implicit none
contains
subroutine print1(NAME,MYPR,IBL)
character(len=*),intent(in) :: NAME
integer,intent(in) :: MYPR,IBL
WRITE(*,'(A,I3.3,A1,I3.3,A3)') trim(adjustl(NAME)),MYPR,'_',IBL,'.nc'
end subroutine
subroutine print2(NAME,MYPR,IBL)
character(len=*),intent(in) :: NAME
integer,intent(in) :: MYPR,IBL
character(len=128) :: fmt
write(fmt,*) len_trim(adjustl(NAME))
fmt = '(A'//trim(adjustl(fmt))//',I3.3,A1,I3.3,A3)'
WRITE(*,fmt) trim(adjustl(NAME)),MYPR,'_',IBL,'.nc'
end subroutine
end module
program test
use test_mod
call print1(' Testfile ', 1, 2)
call print2(' Testfile ', 1, 2)
end program
Output:
./a.out
Testfile001_002.nc
Testfile001_002.nc

Write to file using an implicit do loop

I need a help about implicit do loop in Fortran.
This is my simple code:
Program Simple
Implicit none
Integer::i,j
Integer,parameter::N=2,M=3
Real,dimension(N,M)::Pot
Open(1,File='First.txt',Status='old')
Read(1,'(M(f3.1,1x))') ((Pot(i,j),j=1,M),i=1,N)
Close(1)
Open(2,File='Second.txt',Status='Unknown')
Write(2,'(M(i0,1x,i0,1x,f3.1,1x))') ((i,j,Pot(i,j),j=1,M),i=1,N)
Close(2)
Stop
End program Simple
This is the file First.txt:
1.1 1.2 1.3
2.1 2.2 2.3
When I try to execute this program I got a this message:
Unexpected element 'N' in format string
Unexpected element 'M' in format string
I want to keep the name of integer variables N and M in write statement.
Is there any way to also keep their values from declaration part?
You are using M and N in the string (as characters), not as variables. In order to use the variables you need to write their values into the format string:
character(len=128) :: fmtString
!...
write(fmtString,*) M
fmtString = '('//trim(adjustl(fmtString))//'(f3.1,1x))'
Read(1,fmtString) ((Pot(i,j),j=1,M),i=1,N)
And similarly for the write statement.
However, you can probably use list-directed input (Read(1,*)) for the input, and let Fortran figure out the exact format.
Instead of this string manipulation you can use (*(f3.1,1x)) in modern compilers, or if you have an old one just specify a very large number, e.g. (99999(f3.1,1x)). In both cases, the correct number of values will be printed. However, this will result into writing all m*n values in one single line [thanks #agentp for pointing this out].

Fortran; looping over file names with common attributes

I'm fairly new to Fortran and I am having trouble with my file names, I have a bunch of data in simuln#.res (where 1<#<20), I have multiple different directories with all the same simuln#.res names but they had different input parameters. The code looks like this:
character(len=11) :: theFileA
character(len=12) :: theFileB
character(len=:), allocatable :: fileplace
write(*,*) "the directory with the data sets, use quotations"
read(*,*) fileplace
fileLoop : do j=1,20
if (j .lt. 10) then
write(theFileA, '("simuln", I1,".res")' ) j
open(newunit= iin,file = fileplace//theFileA,status='old')
else
write(theFileB, '("simuln",I2,".res")') j
open(newunit= iin,file = fileplace//theFileB,status='old')
end if
does some stuff with the file
end do fileLoop
The code compiles with a gfortran compiler on my mac, but when I put in my path to the directory with the files, it gives the error simuln1.res does not exist (which it absolutely does, triple checked). I have tried changing the edit descriptor (and making real(j)), but I still get the same thing.
Can anyone help me?
You have fileplace of deferred length ((len=:)), but you appear to not allocate it before attempting the read.
That is, read(*,*) fileplace doesn't, under the F2003 rules of automatic allocation, allocate fileplace to the correct length and assign. That means that later on fileplace could well be being treated as a zero-length character variable ('') in the file to be opened.
To check this hypothesis, try print *, fileplace//theFileA. This could be supported by the fact that the error message refers to just the trailing part of the file's name.
If this is the case, then use a "large" variable. You say 90 characters is as long as you need, so:
character(len=90) :: fileplace ! Adjust length as desired
...
read(*,*) fileplace
...
open (newunit=iin, file=TRIM(fileplace)//theFileA, status='old')
...
Ensure you append the file's name to the trimmed directory name to avoid having spaces between the two parts.
[As a side note, you appear to not need theFileA and theFileB; just use the latter, considering that trailing blanks are ignored. And you may well want to force a trailing '/' on fileplace.]