                  SPSS for Windows - User Code
                          Release 6.0


Release 6.0 of SPSS for Windows supports User Code written in
either FORTRAN or C.  The User Code manual for SPSS for the IBM
RS/6000 provides an overview of the User Code facility and is, in
general, applicable to SPSS for Windows.  This document deals
with the specifics of SPSS for Windows and is intended as a
supplement for Chapter 16 and Appendixes A and B of the User Code
manual.  The machine-readable materials which support the User
Code facility are included in the SPSS for Windows distribution
materials.  This document generally assumes the use of Microsoft
language translators and utilities.  However, users with some
familiarity with the Windows environment can probably use other
vendors' products to produce User Code programs.


    Creating a Module for Your User Code Program (Chapter 16)

User Code programs have been successfully linked using versions
5.15 and 5.31 of the Microsoft link utility.  Version 5.15 works
with object files produced by version 5.1 of the Microsoft
FORTRAN compiler, version 6.0 of the Microsoft C compiler, and
the associated run time libraries.  Version 5.31 is required when
using version 7 of the Microsoft C compiler or the associated run
time libraries.  The specifics for compiling FORTRAN and C User
Code programs are covered in subsequent sections of this
document.  This section is concerned with linking the results of
those compilations.

Under Windows, each User Code program occupies its own Dynamic
Link Library (DLL).  A DLL is a separately linked executable file
which can be loaded and called by another executable file at
execution time.  While DLL's are intended to be shareable, those
for use with SPSS for Windows need not be sharable since
simultaneous SPSS for Windows sessions are not permitted.  The
root name of a DLL ("myproc" in c:\spsswin\myproc.dll) is the
name by which the User Code program is invoked on the SPSS
USERPROC or USERGET command.  The name is, of course, case
insensitive.  At execution time, the search path for a User Code
DLL is somewhat different from that used for other SPSS for
Windows DLL's.  In addition to the directory from which SPSS for
Windows (spsswin.exe) was loaded, the working directory and all
directories specified by the PATH environment variable are
searched.  The effect is that locally written User Code DLL's
need not reside with the rest of SPSS for Windows.

Basically, the process is to link the object (.obj) files
resulting from compilation with spssuser.lib plus the C and/or
FORTRAN run time libraries.  Spssuser.lib contains import
definitions for all the subroutines/functions in the User Code
API, e.g. for UPINIT and UREAD.  It also contains the object code
for USSTUB (the entry point of all User Code DLL's) and stubs for
USRGET and USRPGM.  The language specific run time libraries must
be those intended for Windows DLL's.  Building the proper run
time libraries is a subject covered in the documentation provided
with the compilers.

In order to link a DLL, a module definition (.def) file is
required.  We have found the following module definition commands
produce the desired effect:

  LIBRARY - tells the linker that a DLL rather than an EXE is to
    be produced.
  EXETYPE WINDOWS 3.0 - specifies the target system and makes it
    unnecessary to run the resource compiler on the resulting
    DLL.
  STUB 'WINSTUB.EXE' - specifies the code to be executed if an
    attempt is made to run the file in the wrong environment.
    Winstub.exe is provided with the Microsoft FORTRAN compiler
    and with the Windows Software Development Kit.
  CODE MOVEABLE DISCARDABLE - defines the attributes of the code
    segments.  Specifying PRELOAD may be desirable when
    debugging with CodeView.
  DATA MOVEABLE SINGLE - defines the attributes of the data
    segments.
  HEAPSIZE 0x0100 - defines the size of the local heap.  As User
    Code DLL's are large model, not much use is made of the
    local heap.
  EXPORTS WEP - specifies the DLL termination routine.
  EXPORTS USSTUB - specifies the DLL entry point.

When linking User Code DLL's, the following link switches have
been found to be useful:

  /b - cuts screen output down to the essentials.
  /co - to include information for debugging with CodeView.
  /m - produces a link map.  This is necessary for running
    mapsym.
  /nod - inhibits searching default run time libraries.
  /noe - necessary due to the presence of USRPGM and USRGET in
    spssuser.lib.
  /packc:4096 - avoids multiple code segments for small
    subprograms.
  /packd:4096 - avoids multiple small data segments.

Regarding a link map, we have found it useful to produce maps for
all DLL's and to process these maps with mapsym, a utility which
is provided with the Windows 3.1 Software Development Kit.  The
output of mapsym is a file with an extension of .sym.  If this
file is present at execution time, Dr Watson (a utility provided
with Windows 3.1) will include symbolic information in the log
produced when a UAE occurs.  That symbolic information can be
useful for debugging.

If you intend to debug a User Code program with CodeView, there
are some compatibility considerations regarding the language
translators and the versions of CodeView.  CodeView version 3.07
seems to work for DLL's produced by version 5.15 of Link and can
handle both C and FORTRAN source.  CodeView version 4.01 is
required for DLL's produced by version 5.31 of Link but has some
problems dealing with FORTRAN source.  The net effect is that you
are better off using version 6 of C, version 5.15 of Link, and
version 3.07 of CodeView if you have a mixed language User Code
DLL.


             FORTRAN User Code Summary (Appendix A)

FORTRAN User Code programs have been successfully built using
version 5.1 of the Microsoft FORTRAN compiler and associated run
time libraries.

Perhaps the most important Windows specific considerations for
FORTRAN User Code programs involve the addressing model.  The
recommended model for all User Code programs is the "huge" model.
In actuality, the "large" model can be used as long as the User
Code program recognizes that the SPSS workspace and the
observation vector (as provided to the USRPGM and USRGET
subroutines) can span data segments.  That is, these two vectors
must be declared with the huge attribute wherever they are used.
A second consideration is that, in a Windows DLL, the stack and
data segments will be different, i.e. SS and DS are not equal.
Specifying to the compiler that these segments are different is
accomplished via a parameter of the addressing model switch as in
-AHw or -ALw.

The distributed User Code machine-readable materials include
fabricat.for and fabricat.mak.  These are the FORTRAN source and
an nmake script for the USERGET example in Appendix A of the
manual.  The nmake script, in particular, can be used as a guide
to building FORTRAN User Code DLL's.

The User Code commons are distributed as cmnset.for, cmnusr.for,
and cmnpar.for.  It is intended that these files be included in
FORTRAN source files via the include statement.

Usercode.fi is a file which is specific to the Windows
implementation of User Code.  This file contains FORTRAN
interface statements defining all the subroutines which can be
called by FORTRAN User Code programs.  This file can be included
at the beginning of each User Code compilation unit so that the
compiler can check each call to one of these subroutines for a
proper argument list.

Usercode.fd is identical to usercode.f as described in the User
Code manual.  It contains possibly useful parameter statements
for the SPSS format codes and the two arguments to the UERROR
subroutine.  That is, it permits F formats to be specified as
FMCF rather than 5 when calling UOUTCV.  The file must be
included in each subprogram which references one of the
parameters.

When compiling FORTRAN user code, the following switches have
been found to be useful:

  -c - specifies compilation without linking.  Linking is
    generally done with a specific link command.
  -AHw - specifies the huge addressing model and different stack
    and data segments.
  -FPi - generates code for execution with either a coprocessor
    or the emulator library.  -FPi87 can be specified if it is
    known that the User Code program will only be used on
    machines with coprocessors.
  -Gew2 - generates entry point code with the Windows prolog and
    with stack checking.
  -Gt1025 - places all static data items of less than 1025 bytes
    in the local data segment.
  -nologo - eliminates the copyright message when the compiler
    is invoked.
  -Zl - eliminates the specification of a default run time
    library in the object files.  Use -Zil to include CodeView
    information.
  -4Ya - puts all local variables on the stack.  There will be
    16K bytes available on the stack when a User Code program is
    invoked, and specifying this option cuts down on the size of
    the local data segment.

The appropriate run time library for use with FORTRAN object
files will depend on the local environment.  If the FORTRAN run
time libraries were installed without "C compatibility", only the
DLL resident FORTRAN run time library is required.  This is
normally named ldllfew.lib or ldllf7w.lib.  If "C compatibility"
was specified when the libaries were installed, the run time
libraries specified to the linker will depend on whether version
6 or version 7 of the C compiler has been installed.  If version
6 of C has been installed, the libraries should be specified as:

    ldllfew ldllcew libw

If version 7 of C has been installed, the libraries should be
specified as:

    ldllcew oldnames ldllfew libw

The C run time libraries are supplied with the Windows 3.0 SDK or
with version 7 of the C compiler.


                C User Code Summary - Appendix B

C User Code programs have been successfully created using
versions 6 and 7 of the Microsoft C compiler and the Windows 3.0
and 3.1 Software Development Kits.

The primary considerations for writing C User Code programs have
to do with the addressing model and the entry point attributes
which are compatible with FORTRAN calling conventions.  Regarding
the addressing model, the use of the "huge" model is recommended,
although the "large" model can be used as long as the source code
is cognizant that the SPSS workspace and the observation vector
can span segment boundaries.  In addition, as in all Windows
DLL's, the stack and data segments will be different, i.e. ss is
not equal to ds.  These addressing considerations are accounted
for at compile time by using either the -AHw or -ALw switches.

In order to masquerade as FORTRAN entry points, the User Code
Usrset, Usrpgm, and Usrget functions must have the _far and
_fortran attributes and must address all scalar parameters
indirectly.  The _far attribute is implicit in the large and huge
addressing models.  The _fortran attribute, which is equivalent
to _pascal, deals with the case sensitivity and decoration of the
function name and the order in which the parameters appear.
Suffice it to say that the User Code manual is correct regarding
Windows User Code and that the use of the SUBROUTINE macro for
function declarations is appropriate.

The distributed User Code materials include uprmeans.c and
uprmeans.mak.  These comprise the source and nmake script for the
example C language USERPROC in Appendix B of the manual.  The
nmake script assumes the use of version 7 of C, but should be
useful as a template when using version 6 of C.

The User Code commons are distributed as cmnset.h, cmnusr.h, and
cmnpar.h.  These are suitable for inclusion in C source files via
the #include directive.  As documented in the User Code manual,
variables residing in commons are referenced via pointers as in:

    CmnSet->mxnewv = 25L;

Usercode.h is as documented in the User Code manual.  This header
file is a prerequisite for the commons header files as it defines
the SPSS data types.  It also provides function prototypes for
all the User Code subroutines and symbolic names for the SPSS
formats and Uerror arguments.

As an addition to the User Code API as described in the manual,
the Windows implementation includes replacements for the C run
time memory allocation routines - malloc, free, halloc, and
realloc.  The use of the replacement routines has two advantages.
First, the replacement routines perform suballocation of memory
segments to reduce the number of calls to the Windows API
function GlobalAlloc when relatively small amounts of memory are
required.  Second, all the memory acquired by a User Code DLL is
automatically freed when the User Code program is terminated.
The definitions of the replacement functions are as follows:

void _huge* _far Uhalloc(      /* Allocates huge memory block */
    long num,                  /* Number of elements */
    size_t size);              /* Element length in bytes */

void _far* _far Umalloc(       /* Allocate memory blocks */
    size_t size);              /* Types to allocate */

void _far* _far Urealloc(      /* Reallocate memory blocks */
    void _far* memblock,       /* Pointer to existing block */
    size_t size);              /* New size in bytes */

void _far Ufree(               /* Deallocate a memory block */
    void _far* memblock);      /* Pointer to existing block */

The use of these replacements for malloc, free, etc., is not
required but is recommended.

When compiling C User Code, the following switches have been
found to be useful:
  -c - specifies compilation without linking.  Linking is
    generally done with a specific link command.
  -AHw - specifies the huge addressing model and different stack
    and data segments.
  -FPi - generates code for execution with either a coprocessor
    or the emulator library.  -FPi87 can be specified if it is
    known that the User Code program will only be used on
    machines with coprocessors.
  -Gew2 - generates entry point code with the Windows prolog and
    with stack checking.
  -nologo - eliminates the copyright message when the compiler
    is invoked.
  -W3 - specifies how nitpicking the warning messages should be.
  -Zlp - eliminates the specification of a default run time
    library in the object files and the packing of structures.
    Use -Zilp to include CodeView information.
  -D_WINDOWS - selects Windows compatible definitions in the C
    header files.
  -D_WINDLL - selects DLL compatible definitions in the C header
    files.

When linking C object files, the appropriate run time library is
ldllcew.lib (or ldllc7w.lib) plus libw.lib.  These libraries are
provided as part of the Windows 3.0 SDK and version 7 of the C
compiler.  If linking a mixed FORTRAN and C User Code program,
the specification of the run time libaries will depend on whether
version 6 or version 7 of the C compiler is used.  For version 6,
specify:

    ldllfew ldllcew libw

For version 7, specify:

    ldllcew oldnames ldllfew libw

If version 6 of the C compiler is used, there are additional
considerations regarding the DLL initialization and termination
routines.  These subjects are covered in the Windows 3.0 SDK
documentation.  Suffice it to say that you will probably have to
provide the following functions unless you are linking with the
FORTRAN run time library:  WEP, LibEntry, and LibMain.


                   Machine Readable Materials

The following machine files are distributed with Version 6.0 of
SPSS for Windows:

    cmnpar.for - FORTRAN version of cmnpar
    cmnpar.h - C version of cmnpar
    cmnset.for - FORTRAN version of cmnset
    cmnset.h - C version of cmnset
    cmnusr.for - FORTRAN version of cmnusr
    cmnusr.h - C version of cmnusr
    fabricat.for - example FORTRAN USERGET
    fabricat.mak - nmake script to build fabricat.dll
    spssuser.lib - import definitions for User Code API
    uprmeans.c - example C USERPROC
    uprmeans.mak - nmake script to build uprmeans.dll
    usercode.fd - useful FORTRAN parameter statements
    usercode.fi - FORTRAN definition of User Code API
    usercode.h - C definition of User Code API
    userdemo.sps - SPSS commands to run fabricat and uprmeans


Microsoft and CodeView are registered trademarks, and Windows is
a trademark of Microsoft Corporation.

RS/6000 is a registered trademark of International Business
Machines Corporation.

SPSS is a registered trademark of SPSS Inc.
