Skip to content

Commit

Permalink
Merge pull request #370 from olebole/fix-f2c
Browse files Browse the repository at this point in the history
Fix problems with using f2c.e/f77.sh on plain Fortran files
  • Loading branch information
olebole authored Feb 3, 2024
2 parents 3e3a8f9 + a7edfdf commit 264ce41
Show file tree
Hide file tree
Showing 30 changed files with 4,106 additions and 1,004 deletions.
2 changes: 1 addition & 1 deletion test/images.imcoords.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ Test options: `decimals=7`
```
cl> hpctran lng=50.12 lat=-33.45
2298092 50.12 -33.45000000000001
```
```

## imcctran - Transform image header from one celestial wcs to another

Expand Down
2 changes: 1 addition & 1 deletion test/images.imfilter.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ cl> gradient dev$pix pix.odeg 180
cl> imstat pix.odeg fields="image,npix,stddev,min,max"
# IMAGE NPIX STDDEV MIN MAX
pix.odeg 262144 42.85 -6983. 6529.
```
```

## laplace - Laplacian filter a list of 1 or 2-D images

Expand Down
24 changes: 24 additions & 0 deletions test/programming.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,30 @@ Should be zero: 0
Should be zero: 0.
```

## Plain FORTRAN files

The xc compiler should be able to compile plain FORTRAN files (with
FORTRAN I/O) as well. The f2c compiler used in 2.17, 2.17.1, 2.18
cannot compile this. See [discussion
#369](https://github.com/orgs/iraf-community/discussions/369).

File: `test_io.f`
```
PROGRAM TESTIO
OPEN (11, FILE='testio.dat')
WRITE (11, *) 'Hello world'
CLOSE (11)
END
```

```
cl> softools
cl> xc -h test_io.f
cl> !./test_io.e
cl> type testio.dat
Hello world
```

## Loop optimization

This is a test for [#60](https://iraf-community.github.io/iraf-v216/issues/60).
Expand Down
2 changes: 1 addition & 1 deletion test/run_tests
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ run_tests () {
filename='' # File name to read in
options='' # Test options
lineno=0 # line counter
cat "$FILE" | while read -r line ; do
cat "$FILE" | while IFS= read -r line ; do
lineno=$(( lineno + 1 ))
if [ "$in_code" = 1 ] ; then
if echo "$line" | grep -q '^```$' ; then
Expand Down
21 changes: 11 additions & 10 deletions unix/boot/spp/xc.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,10 @@
#define IRAFLIB5 "liblapack.a"
#define IRAFLIB6 "libfftpack.a"

char *fortlib[] = { "-lf2c", /* 0 (host progs) */
"-lf2c", /* 1 */
"-lm", /* 2 */
"-lcurl", /* 3 */
"-lexpat", /* 4 */
char *fortlib[] = { "-lf2c", /* 0 */
"-lm", /* 1 */
"-lcurl", /* 2 */
"-lexpat", /* 3 */
#if (defined (__linux__) || defined (__gnu_hurd__))
"-lpthread", /* 5 */
#else
Expand Down Expand Up @@ -618,6 +617,8 @@ passflag: mkobject = YES;

#ifdef __i386__
arglist[nargs++] = "-m32";
#elif (__SIZEOF_LONG__ == 8 && __SIZEOF_POINTER__ == 8) /* ILP64 */
arglist[nargs++] = "-i8";
#endif

if (optimize) {
Expand Down Expand Up @@ -661,6 +662,8 @@ passflag: mkobject = YES;

#ifdef __i386__
arglist[nargs++] = "-m32";
#elif (__SIZEOF_LONG__ == 8 && __SIZEOF_POINTER__ == 8) /* ILP64 */
arglist[nargs++] = "-i8";
#endif

if (optimize) {
Expand Down Expand Up @@ -807,11 +810,9 @@ passflag: mkobject = YES;

/* Libraries to link against.
*/
if (hostprog) {
arglist[nargs++] = mkfname (fortlib[0]);
} else
if (!hostprog) {
arglist[nargs++] = mkfname (LIBMAIN);

}
if (voslibs) {
if (usesharelib) {
arglist[nargs++] = mkfname (SHARELIB);
Expand All @@ -833,6 +834,7 @@ passflag: mkobject = YES;
/* The remaining system libraries depend upon which version of
* the SunOS compiler we are using.
*/
addflags (fortlib[0], arglist, &nargs);
addflags (fortlib[1], arglist, &nargs);
addflags (fortlib[2], arglist, &nargs);
addflags (fortlib[3], arglist, &nargs);
Expand All @@ -841,7 +843,6 @@ passflag: mkobject = YES;
addflags (fortlib[6], arglist, &nargs);
addflags (fortlib[7], arglist, &nargs);
addflags (fortlib[8], arglist, &nargs);
addflags (fortlib[9], arglist, &nargs);
arglist[nargs] = NULL;

if (debug)
Expand Down
190 changes: 52 additions & 138 deletions unix/f2c/libf2c/uninit.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "arith.h"

#define TYSHORT 2
Expand Down Expand Up @@ -58,15 +57,6 @@ static unsigned Long rnan = RNAN,

double _0 = 0.;

void unsupported_error()
{
fprintf(stderr,"Runtime Error: Your Architecture is not supported by the"
" -trapuv option of f2c\n");
exit(-1);
}



void
#ifdef KR_headers
_uninit_f2c(x, type, len) void *x; int type; long len;
Expand Down Expand Up @@ -188,8 +178,7 @@ ieee0(Void)
}
#endif /* MSpc */

/* What follows is for SGI IRIX only */
#if defined(__mips) && defined(__sgi) /* must link with -lfpe */
#ifdef __mips /* must link with -lfpe */
#define IEEE0_done
/* code from Eric Grosse */
#include <stdlib.h>
Expand Down Expand Up @@ -240,155 +229,80 @@ ieee0(Void)
_EN_UNDERFL|_EN_OVERFL|_EN_DIVZERO|_EN_INVALID,
ieeeuserhand,_ABORT_ON_ERROR,ieeeuserhand2);
}
#endif /* IRIX mips */

/*
* The following is the preferred method but depends upon a GLIBC extension only
* to be found in GLIBC 2.2 or later. It is a GNU extension, not included in the
* C99 extensions which allow the FP status register to be examined in a platform
* independent way. It should be used if at all possible -- AFRB
*/


#if (defined(__GLIBC__)&& ( __GLIBC__>=2) && (__GLIBC_MINOR__>=2) )
#define _GNU_SOURCE 1
#define IEEE0_done
#include <fenv.h>
static void
ieee0(Void)

{
/* Clear all exception flags */
if (fedisableexcept(FE_ALL_EXCEPT)==-1)
unsupported_error();
if (feenableexcept(FE_DIVBYZERO|FE_INVALID|FE_OVERFLOW)==-1)
unsupported_error();
}

#endif /* Glibc control */
#endif /* mips */

/* Many linux cases will be treated through GLIBC. Note that modern
* linux runs on many non-i86 plaforms and as a result the following code
* must be processor dependent rather than simply OS specific */

#if (defined(__linux__)&&(!defined(IEEE0_done)))
#ifdef __linux__
#define IEEE0_done
#include <fpu_control.h>

#include "fpu_control.h"

#ifdef __alpha__
#ifndef USE_setfpucw
#define __setfpucw(x) __fpu_control = (x)
#endif
#endif

/* Not all versions of libc define _FPU_SETCW;
* * some only provide the __setfpucw() function.
* */
#ifndef _FPU_SETCW
#define _FPU_SETCW(cw) __setfpucw(cw)
#endif

/* The exact set of flags we want to set in the FPU control word
* depends on the architecture.
* Note also that whether an exception is enabled or disabled when
* the _FPU_MASK_nn bit is set is architecture dependent!
* Enabled-when-set: M68k, ARM, MIPS, PowerPC
* Disabled-when-set: x86, Alpha
* The state we are after is:
* exceptions on division by zero, overflow and invalid operation.
*/


#ifdef __alpha__
#ifndef USE_setfpucw
#define __setfpucw(x) __fpu_control = (x)
#endif
#endif


#ifndef _FPU_SETCW
#undef Can_use__setfpucw
#define Can_use__setfpucw
#endif

#undef RQD_FPU_MASK
#undef RQD_FPU_CLEAR_MASK

static void
ieee0(Void)
{
#if (defined(__mc68000__) || defined(__mc68020__) || defined(mc68020) || defined (__mc68k__))
/* Reported 20010705 by Alan Bain <[email protected]> */
/* Note that IEEE 754 IOP (illegal operation) */
/* = Signaling NAN (SNAN) + operation error (OPERR). */
#define RQD_FPU_STATE (_FPU_IEEE + _FPU_DOUBLE + _FPU_MASK_OPERR + \
_FPU_MASK_DZ + _FPU_MASK_SNAN+_FPU_MASK_OVFL)
#define RQD_FPU_MASK (_FPU_MASK_OPERR+_FPU_MASK_DZ+_FPU_MASK_SNAN+_FPU_MASK_OVFL)
#ifdef Can_use__setfpucw
__setfpucw(_FPU_IEEE + _FPU_DOUBLE + _FPU_MASK_OPERR + _FPU_MASK_DZ + _FPU_MASK_SNAN+_FPU_MASK_OVFL);
#else
__fpu_control = _FPU_IEEE + _FPU_DOUBLE + _FPU_MASK_OPERR + _FPU_MASK_DZ + _FPU_MASK_SNAN+_FPU_MASK_OVFL;
_FPU_SETCW(__fpu_control);
#endif

#elif (defined(__powerpc__)||defined(_ARCH_PPC)||defined(_ARCH_PWR)) /* !__mc68k__ */
/* The following is NOT a mistake -- the author of the fpu_control.h
* for the PPC has erroneously defined IEEE mode to turn on exceptions
* other than Inexact! Start from default then and turn on only the ones
* which we want*/

/* I have changed _FPU_MASK_UM here to _FPU_MASK_ZM, because that is
* in line with all the other architectures specified here. -- AFRB
*/
#define RQD_FPU_STATE (_FPU_DEFAULT +_FPU_MASK_OM+_FPU_MASK_IM+_FPU_MASK_ZM)
#define RQD_FPU_MASK (_FPU_MASK_OM+_FPU_MASK_IM+_FPU_MASK_ZM)

#elif (defined(__arm__))
/* On ARM too, IEEE implies all exceptions enabled.
* -- Peter Maydell <[email protected]>
* Unfortunately some version of ARMlinux don't include any
* flags in the fpu_control.h file
*/
#define RQD_FPU_STATE (_FPU_DEFAULT +_FPU_MASK_OM+_FPU_MASK_IM+_FPU_MASK_ZM)
#define RQD_FPU_MASK (_FPU_MASK_OM+_FPU_MASK_IM+_FPU_MASK_ZM)

#elif (defined(__mips__))
/* And same again for MIPS; _FPU_IEEE => exceptions seems a common meme.
* * MIPS uses different MASK constant names, no idea why -- PMM
* */
#define RQD_FPU_STATE (_FPU_DEFAULT +_FPU_MASK_O+_FPU_MASK_V+_FPU_MASK_Z)
#define RQD_FPU_MASK (_FPU_MASK_O+_FPU_MASK_V+_FPU_MASK_Z)

#elif (defined(__sparc__))
#define RQD_FPU_STATE (_FPU_DEFAULT +_FPU_DOUBLE+_FPU_MASK_OM+_FPU_MASK_IM+_FPU_MASK_ZM)
#define RQD_FPU_MASK (_FPU_MASK_OM+_FPU_MASK_IM+_FPU_MASK_ZM)

#elif (defined(__i386__) || defined(__alpha__))
/* This case is for Intel, and also Alpha, because the Alpha header
* purposely emulates x86 flags and meanings for compatibility with
* stupid programs.
* We used to try this case for anything defining _FPU_IEEE, but I think
* that that's a bad idea because it isn't really likely to work.
* Instead for unknown architectures we just won't allow -trapuv to work.
* Trying this case was just getting us
* (a) compile errors on archs which didn't know all these constants
* (b) silent wrong behaviour on archs (like SPARC) which do know all
* constants but have different semantics for them
*/
#define RQD_FPU_STATE (_FPU_IEEE - _FPU_EXTENDED + _FPU_DOUBLE - _FPU_MASK_IM - _FPU_MASK_ZM - _FPU_MASK_OM)
#define RQD_FPU_CLEAR_MASK (_FPU_MASK_IM + _FPU_MASK_ZM + _FPU_MASK_OM)
#endif
/* Reported 20011109 by Alan Bain <[email protected]> */

static void ieee0(Void)
{
#ifdef RQD_FPU_STATE

#ifndef UNINIT_F2C_PRECISION_53 /* 20051004 */
__fpu_control = RQD_FPU_STATE;
_FPU_SETCW(__fpu_control);
#else
#ifdef Can_use__setfpucw

/* The following is NOT a mistake -- the author of the fpu_control.h
for the PPC has erroneously defined IEEE mode to turn on exceptions
other than Inexact! Start from default then and turn on only the ones
which we want*/

__setfpucw(_FPU_DEFAULT + _FPU_MASK_IM+_FPU_MASK_OM+_FPU_MASK_UM);

#else /* PPC && !Can_use__setfpucw */

__fpu_control = _FPU_DEFAULT +_FPU_MASK_OM+_FPU_MASK_IM+_FPU_MASK_UM;
_FPU_SETCW(__fpu_control);

#endif /*Can_use__setfpucw*/

#else /* !(mc68000||powerpc) */

#ifdef _FPU_IEEE
#ifndef _FPU_EXTENDED /* e.g., ARM processor under Linux */
#define _FPU_EXTENDED 0
#endif
#ifndef _FPU_DOUBLE
#define _FPU_DOUBLE 0
#endif
#ifdef Can_use__setfpucw /* pre-1997 (?) Linux */
__setfpucw(_FPU_IEEE - _FPU_MASK_IM - _FPU_MASK_ZM - _FPU_MASK_OM);
#else
#ifdef UNINIT_F2C_PRECISION_53 /* 20051004 */
/* unmask invalid, etc., and change rounding precision to double */
__fpu_control = _FPU_IEEE - _FPU_EXTENDED + _FPU_DOUBLE - _FPU_MASK_IM - _FPU_MASK_ZM - _FPU_MASK_OM;
_FPU_SETCW(__fpu_control);
#else
/* unmask invalid, etc., and keep current rounding precision */
fpu_control_t cw;
_FPU_GETCW(cw);
#ifdef RQD_FPU_CLEAR_MASK
cw &= ~ RQD_FPU_CLEAR_MASK;
#else
cw |= RQD_FPU_MASK;
#endif
cw &= ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM);
_FPU_SETCW(cw);
#endif
#endif

#else /* !_FPU_IEEE */

Expand All @@ -400,11 +314,11 @@ static void ieee0(Void)
fflush(stderr);

#endif /* _FPU_IEEE */
#endif /* __mc68k__ */
}
#endif /* __linux__ */

/* Specific to OSF/1 */
#if (defined(__alpha)&&defined(__osf__))
#ifdef __alpha
#ifndef IEEE0_done
#define IEEE0_done
#include <machine/fpu.h>
Expand All @@ -414,7 +328,7 @@ ieee0(Void)
ieee_set_fp_control(IEEE_TRAP_ENABLE_INV);
}
#endif /*IEEE0_done*/
#endif /*__alpha OSF/1*/
#endif /*__alpha*/

#ifdef __hpux
#define IEEE0_done
Expand Down
Loading

0 comments on commit 264ce41

Please sign in to comment.