Task: Implement Caller.c for CactusTest/TestFpointerNULL thorn

thorn_name: CactusTest/TestFpointerNULL
src_filename: Caller.c
interface: # Interface definition for thorn TestFpointerNULL
# $Header$

implements: TestFpointerNULL

private:

REAL array_group TYPE=ARRAY DIM=2 SIZE=5,10
{
  array
} "CCTK_REAL test array"

INT scalar_group TYPE=SCALAR
{
  scalar
} "CCTK_INT test scalar"

schedule: # Schedule definitions for thorn TestFpointerNULL
# $Header$

STORAGE: scalar_group array_group

SCHEDULE TestFpointerNULL_Caller AT INITIAL
{
  LANG:    C
} "Test passing a NULL pointer from a C function into Fortran routine"

param: # Parameter definitions for thorn TestFpointerNULL
# $Header$

context: make.code.defn:
```
# Main make.code.defn file for thorn PassNULLtoFortran
# $Header$

# Source files in this directory
SRCS = Caller.c Callee.F77

```

Callee.F77:
```
c @@
c @file       Callee.c
c  @date      Thu 13 June 2002
c  @author    Thomas Radke
c  @desc
c             Fortran interface of the TestFpointerNULL thorn.
c  @enddesc
c  @version   $Id$
c@@

#include "cctk.h"


c  @@
c  @routine    TestFpointerNULL_Callee
c  @author     Thomas Radke
c  @date       Thu 13 June 2002
c  @desc
c              Fortran routine which gets passed a scalar and a 2D array
c              which will be set to a value != 0.
c              In addition, a dummy scalar and array are passed in as NULL
c              pointers by the C caller.
c              These variables should not be touched by this routine.
c  @enddesc
c
c  @var        null_scalar
c  @vdesc      invalid reference to a scalar variable
c  @vtype      CCTK_INT
c  @vio        in
c  @endvar
c  @var        scalar
c  @vdesc      valid reference to a scalar variable
c  @vtype      CCTK_INT
c  @vio        inout
c  @endvar
c  @var        null_array
c  @vdesc      invalid reference to an array variable
c  @vtype      CCTK_REAL
c  @vio        in
c  @endvar
c  @var        array
c  @vdesc      valid reference to an array variable
c  @vtype      CCTK_REAL
c  @vio        inout
c  @endvar
c  @var        lsh
c  @vdesc      dimensions of the array variables
c  @vtype      int *
c  @vio        in
c  @endvar
c@@
      subroutine TestFpointerNULL_Callee (null_scalar, scalar,
     &                                    null_array, array, lsh)

      implicit none

      integer lsh(2)
      CCTK_INT null_scalar, scalar
      CCTK_REAL null_array(lsh(1), lsh(2)), array(lsh(1), lsh(2))

      integer i, j


c     set the variables to some value != 0

      scalar = 42

      do j = 1, lsh(2)
        do i = 1, lsh(1)
   
          array(i, j) = 42

        end do
      end do

c     Uncomment the following lines to make the program crash.
c     null_scalar = 42
c     null_array  = 42

      end

```


combined_doc_context: ## README (README):
```
Cactus Code Thorn TestFpointerNULL
Author(s)    : Thomas Radke
Maintainer(s): Cactus team
Licence      : LGPL
--------------------------------------------------------------------------

1. Purpose

This thorn tests whether a Fortran routine accepts a NULL pointer reference
as a function argument when called from a C function. The code should not crash
as long as the NULL pointer argument isn't dereferenced.

Currently this mechanism is used by the Cactus scheduler bindings C functions
which pass unallocated grid variables as NULL pointers to a scheduled Fortran
routine. Cactus makes the assumption here that those NULL pointers are legal
function arguments.

Once we find out that this basic assumption is no longer true we have a problem.
So always run this thorn's testsuite on a new platform / with a new fortran
compiler !

```



Reference answer:
src_code: /*@@
  @file       Caller.c
   @date      Thu 13 June 2002
   @author    Thomas Radke
   @desc
              C interface of the TestFpointerNULL thorn.
   @enddesc
   @version   $Id$
 @@*/

#include <stdio.h>
#include <string.h>

#include "cctk.h"
#include "cctk_FortranString.h"

/* the rcsid and the macro to use it */
static const char *rcsid = "$Header$";
CCTK_FILEVERSION(CactusTest_TestFpointerNULL_Caller_c)


/********************************************************************
 ********************    External Routines   ************************
 ********************************************************************/
void TestFpointerNULL_Caller (cGH *GH);
void CCTK_FCALL CCTK_FNAME (TestFpointerNULL_Callee)
                           (CCTK_INT *null_scalar, CCTK_INT *scalar,
                            CCTK_REAL *null_array, CCTK_REAL *array,
                            const int *lsh);


 /*@@
   @routine    TestFpointerNULL_Caller
   @author     Thomas Radke
   @date       Thu 13 June 2002
   @desc
               C function which initializes a scalar and a 2D array to zero
               and passes them on to a Fortran routine for modification.
               In addition, a dummy scalar and array are passed as NULL
               pointers. These should not be touched by the Fortran routine.
   @enddesc
   @calls      TestFpointerNULL_Callee

   @var        GH
   @vdesc      Pointer to CCTK GH
   @vtype      const cGH *
   @vio        in
   @endvar
@@*/
void TestFpointerNULL_Caller (cGH *GH)
{
  CCTK_INT *scalar;
  CCTK_REAL *array;
  int lsh[2];


  /* get the grid variables' pointers */
  scalar = (CCTK_INT *) CCTK_VarDataPtr (GH, 0, "TestFpointerNULL::scalar");
  array = (CCTK_REAL *) CCTK_VarDataPtr (GH, 0, "TestFpointerNULL::array");
  CCTK_GrouplshVI (GH, 2, lsh, CCTK_VarIndex ("TestFpointerNULL::array"));

  /* initialize the grid variables */
  *scalar = 0;
  memset (array, 0, lsh[0] * lsh[1] * sizeof (CCTK_REAL));

  /* call the Fortran routine */
  CCTK_FNAME (TestFpointerNULL_Callee) (NULL, scalar, NULL, array, lsh);
}