A GETARG - GETENV WORK-AROUND FOR
g77
ON CYGWIN (and other platforms too)
While Fortran77 on proper Linux provides a mechanism to read the
command line and the environment (subroutines GETARG and GETENV, respectively), this
option fails under CYGWIN as you may fail to locate the main.o object that is
needed.
So you may be interested in a work-around. It's an obvious one.
A wrapper shell script copies first the command line and then the
output of unix command env to a file. Then it starts the binary module.
In order to give nice names, the wrapper will have the name of the
program without a file extension, say, myprog and the binary module
will be myprog.x
The command-line-and-env container will be given a simple name, x.args.
The Fortran program needs to open and process this file. We'll have its
name hard-wired. However, the unit number is prone to conflict with the
users' choices. So the unit number needs to have a redefining option.
To keep any repetitive burden on the programmer small, the compiler
script shown below will generate the wrap-file from a template if it
does not already exist in the target directory.
So first there is getarg.f
Note that the two well-known subroutines have changed their names: get_arg and get_env
the reason being that the linker may complain about duplicate symbols.
A main program may have the following code section
character str*128 ! or whatever you anticipate as maximum
call get_arg (1,str)
call get_env ('HOME',str)
The default file unit number is 69. When GET_ARG is called for the
first time, it tries to find a unit that has not been opened yet by
sarting with 69 and incrementing with +1 as long as needed. To get
control on this mechanism,
integer close_argenv, open_argenv
character str*128 ! or whatever you anticipate as maximum
iu
= open_argenv (68) ! for example. *)
call get_arg (1,str)
iu = close_argenv ()
*) If, however, 68 is
already open, the next free unit will be used and the number returned by open_argenv.
The wrap
script:
#!/bin/sh
prm=`echo "$1" | sed
's|\([^
]*\).*|\1|'`
if [ x$prm = x-h ]; then
echo "USAGE:
wrap
[-v] program parameters"
echo
" -v option to verify
writing of parameters to file ./x.args"
echo
"OBS!
writes to file ./x.args"
exit
fi
verify=no
if [ x$prm = x-v ]; then
verify=yes
shift
fi
prog="$1"
shift
rm -f x.args
touch x.args
while [ ! x`echo $1 | sed
's|\([^
]*\).*|\1|'` = x ]; do
echo "$1"
>>
x.args
shift
done
echo "-- ENVIRONMENT >" >> x.args
env >> x.args
if [ $verify = yes ]; then
echo $prog
cat x.args
fi
$prog
exit |
The compiler script gfmb makes
a
script mymain
(mymain.w if necesary)
from a template named wrap.stub
wrap.stub looks like this:
#!/bin/csh
wrap progfile $*
exit |
Repetition:
fcmd is a script
whose home is the directory of a family of main programs that share
most of their needs (calling libraries e.g.). The script is adapted to
these needs (many times only the string collecting the libraries needs
reworking.)
fcmd calls gfmb (if environment
variable F77COMP
is
"g77"); gfmb should be in a
directory on the current search path, e.g. $HOME/bin
The relevant lines in gfmb
are
if [ ! -r ${BINP}/${fnp} ]; then
sed
's|progfile|'${BINP}/${fnp}${FNOX}'|' /home/hgs/bin/wrap.stub >
${BINP}/${fnp}
chmod u+x
${BINP}/${fnp}
echo "wrap
file written: ${BINP}/${fnp}"
fi
It might be necessary (Cygwin) to append a `.w´ to the wrap file's
name. I.e. use ${fnp}.w
instead
of ${fnp} in the
code above.
Above, FNOX
would be set to .x
by fcmd, fnp is
the short form of the main program's name (e.g. mymain), and BINP the directory where
to install ($HOME/bin
e.g.).