Generating EXECUTE_COMMAND_LINE commands in Fortran

We needed to generate Fortran code to find all of the file names and all of the include directories required by a program. What we have uses the fpt front-end iteratively to find the missing INCLUDE files, the missing MODULES and the missing sub-programs. It iterates because every time you add a file it may have new INCLUDE and USE dependencies or reference new subroutines and functions. The Fortran generates commands like:

‘find …/modified_source/ -iname “foo$bar.inc” > FPTCOM_GREP.FSP && echo “%end” >> FPTCOM_GREP.FSP’

to find a file named foo$bar.inc, and worse still:

'HERE=$PWD && cd …/original_source && grep -ir “foo$bar” | grep -Ei “\sfoo$bar(\s|$)” | grep -Ei “.f.{0,2}:\s*module\s” > $HERE/FPTCOM_GREP.FSP

to find a module named foo$bar (Yes, I know that the is non-standard, but they still do it, and note that the is escaped in the first grep but mustn’t be in grep -E - what fun!). The code to find a subroutine or function is similar.

Note also that the output from the shell commands is written to a file which is then opened and read by the Fortran code. Is there a better way?

Now this works under Linux. My question is how do we do it under Windows?

By “under WIndows” you mean without WSL or Cygwin, etc?

Depends on so many things. If you use the Intel compilers look at the -gen-dep option; on Unix/Linux commands like ar, nm, can be useful but on any system if you put a wrapper around your compiler command that records and inspects the files it compiles or something similiar in your build rules (this is actually relatively easy with make(1), for example) and do a complete rebuild you will get a list of files.

which compiler(s) are you using?

You could adopt the solution in Fortran stdlib. It relies on C system routines, but they have been tested on all three major platforms.
An alternative would be to try and open the files as you find the file names in the actual source files.

@urbanjost - yes, by ‘under windows’ I mean with native windows tools. We have developed a Fortran analysis and restructuring tool with many users, and some of them will want to use native Windows.

We are using ifort, gfortran and vms, and for some debugging cases, SunStudio and CVF. Let me explain what we are doing:

We have two current projects (though there will always be more). One is a migration of a power distribution code from VMS to Linux. There are about 4,000 files. The original code builds under VMS, with the VMS compiler, and makes heavy use of libraries. There are perhaps a hundred programs, communicating through shared COMMON blocks. Most of the code is an extended FORTRAN 77 style, but there are sections written in Fortran 95 or later. We can process the entire code in one pass, but it would sometimes be useful to process individual programs separately. We therefore wrote a handler which can find all of the modules, subroutines and functions, and all of the include files required for a specific program. This handler works under Linux and uses EXECUTE_COMMAND_LINE to launch find and grep commands to search for the required files.

The second project is an environmental code with about 20,000 files in 2,300 directories. However it doesn’t use all of them. Happily this is modern Fortran. Again, we can analyse the whole thing, but there are duplicately named sub-programs and modules and sorting them all out is difficult. The tool we have should do this under Linux (though we still have a little work to do for this one). One of the users definitely uses Windows. Hence the original question.

Three details:
i. I would prefer not to have to open 17,000 files under Fortran to chase the dependencies. @Arjen, I am not sure how stdlib would help - please can you explain?
ii. Most of the objects linked are linked from libraries. Watching to see what the compiler compiles won’t help us.
iii. We could find the include file names from the include statements in the code (in fact, that is what fpt does) but this won’t help with functions and subroutines. We have to search the code for them. Hence the rather extravagent grep commands in my original post.

There are, by the way, at least a couple of death-traps in the analysis. A function can be passed to another routine as a sub-program actual argument. That routine may invoke it using the formal argument name. A simple analysis won’t find this. For this reason we use the fpt front-end to search for sub-programs. There are also several different ways to reference an include file:
INCLUDE ‘foobar.inc’ ! Standard and sensible
#include “foobar.inc” ! Very common
INCLUDE foobar.inc ! No string delimiters - legacy
INCLUDE ‘(foobar)’ ! Where the compiler adds the extension and removes the brackets.

So: is there a native Windows equivalent to find and grep, or another, and perhaps better way to solve the problem?

I would look at dir and findstr.

GitHub - urbanjost/M_match: subset of Regular Expressions implemented in Fortran lets you do simple grep-like searches from Fortran, but only using basic regular expressions; I see findstr,find,dir WIndows commands listed; if you use PowerShell there are more modern options described in the powershell. There are several wrappers for common regular expression libraries available for both MSWindows and LInux; and stdlib routines being referred to allow you to obtain directory listings and descend the file systems; which there are several variants of. There are POSIX-like Fortran interfaces for Linux/Unix (I have some myself) but I am not familiar with MSWindows equivalents (but they may exist) outside of ones that require other packages like CygWIn.
Using the method you currently describe and not depending on the MSWindows platform being much other than a vanilla system, it sounds like (as mentioned) you want to look at findstr and dir, and possibly any STAT/FSTAT extensions most Fortran compilers have. Note that fpm(1) has code in it to find files that might be useful as a starting point.

I may have misunderstood the question, but it looks like you are searching for files with a certain content. I thought the stdlib had a module for returning a list of files. But right now I cannot find it.

To me this looks more like a job for a scripting language than Fortran executing find and grep. Any decent language will be available on many platforms but my personal choice would be tcl.
If you’re particularly wedded to executing commands from Fortran you could on Windows use their Powershell equivalents and just have a conditional #ifdef compilation. E.g.
https://stackoverflow.com/questions/15199321/powershell-equivalent-to-grep-f

I agree that a scripting language would be useful, but I need the front-end of fpt (which is written in Fortran) to identify the different forms of include statements (many of which are non-standard) and to distinguish between subroutine and function headers in the sub-programs and in interface blocks. I am therefore looking at calls from Fortran.

Thank you @Beliavsky and @urbanjost. We do not usually use Windows in-house, and I had not realised how powerful dir and findstr are. More importantly, I didn’t realise that stdlib has file and directory handling facilities. It would be far better to make calls directly from Fortran than to use execute_command_line. I will enjoy exploring this!