/*
 * PDBTST.C - test for the PDB I/O
 *
 * Source Version: 9.0
 * Software Release #92-0043
 *
 */

#include "cpyright.h"

#include "pdb.h"

#define DATFILE "nat"

#define N_DOUBLE 3
#define N_INT    5
#define N_CHAR  10
#define N_FLOAT  4

#define FLOAT_EQUAL(d1, d2)  (PD_float_equal(d1, d2, float_tolerance) == 0)
#define DOUBLE_EQUAL(d1, d2) (PD_float_equal(d1, d2, double_tolerance) == 0)

struct s_l_frame
   {float x_min;
    float x_max;
    float y_min;
    float y_max;};

typedef struct s_l_frame l_frame;

struct s_plot
   {float x_axis[N_CHAR];
    float y_axis[N_CHAR];
    int npts;
    char *label;
    l_frame view;};

typedef struct s_plot plot;

struct s_lev2
   {char **s;
    int type;};

typedef struct s_lev2 lev2;

struct s_lev1
   {int *a;
    double *b;
    lev2 *c;};

typedef struct s_lev1 lev1;

struct s_st3
   {char a;
    short b;
    char c[2];
    int d;
    char e[3];
    float f;
    char g[4];
    double h;
    char i[5];
    char *j;
    char k[6];};

typedef struct s_st3 st3;

struct s_st4
   {short a;
    char  b;};

typedef struct s_st4 st4;

struct s_st61
   {int n;
    double a[10];};

typedef struct s_st61 st61;

struct s_st62
   {int n;
    double *a;};

typedef struct s_st62 st62;

static st61
 *d61_w = NULL;

static st62
 *d62_w = NULL;

static st4
 *vr4_w,
 *vr4_r;

static st3
 vr1_w,
 vr1_r;

static lev1
 tar5_t[4],
 tar5_r[4],
 *tar_r,
 *tar_w;

static HASHTAB
 *tab4_r,
 *tab4_w;

static char
 *CHAR_S,
 *SHORT_S,
 *INT_S,
 *LONG_S,
 *FLOAT_S,
 *DOUBLE_S,
 *HASHEL_S,
 cs_w,
 cs_r,
 ca_w[N_CHAR],
 ca_r[N_CHAR],
 *cap_w[N_DOUBLE],
 *cap_r[N_DOUBLE];

static short
 ss_w,
 ss_r,
 sa_w[N_INT],
 sa_r[N_INT];

static int
 debug_mode  = FALSE,
 native_only = FALSE,
 is_w,
 is_r,
 ia_w[N_INT],
 ia_r[N_INT],
 do_r,
 do_w,
 p_w[N_INT],
 p_r[N_INT],
 len;

static float
 d61_a[10],
 d62_a[10],
 d62_s[8],
 fs_w,
 fs_r,
 fs_app_w,
 fs_app_r,
 fs_p1_r,
 fs_p2_r,
 fs_p3_r,
 fa1_r[N_FLOAT],
 fa2_w[N_FLOAT][N_DOUBLE],
 fa2_r[N_FLOAT][N_DOUBLE],
 fa2_app_w[N_FLOAT][N_DOUBLE],
 fa2_app_r[N_FLOAT][N_DOUBLE];

static double
 ds_w,
 ds_r,
 da_w[N_FLOAT],
 da_r[N_FLOAT];

static plot
 graph_w,
 graph_r;

static l_frame
 view_w,
 view_r;

/* variables for partial and member reads in test #2 */

static int
 *ap1,
 *ap2,
 aa[4];

static double
 *bp1,
 *bp2,
 ba[4];

static lev2
 *cp1,
 *cp2,
 ca[4];

static char
 **sp1,
 **sp2,
 **sp3,
 **sp4,
 *tp1,
 *tp2,
 *tp3,
 *tp4,
 *tp5,
 *tp6,
 *tp7,
 *tp8,
 ta[8];

/*--------------------------------------------------------------------------*/

/*                         GENERAL PURPOSE ROUTINES                         */

/*--------------------------------------------------------------------------*/

/* TEST_TARGET - set up the target for the data file */

static void test_target(tgt, base, n, fname, datfile)
   char *tgt, *base;
   int n;
   char *fname, *datfile;
   {if (tgt != NULL)
       {if (strcmp(tgt, "dos") == 0)
           PD_target(&INTELA_STD, &INTELA_ALIGNMENT);
        else if (strcmp(tgt, "rs6000") == 0)
           PD_target(&IEEEA_STD, &MIPS_ALIGNMENT);
        else if (strcmp(tgt, "cray") == 0)
           PD_target(&CRAY_STD, &UNICOS_ALIGNMENT);
        else if (strcmp(tgt, "vax") == 0)
           PD_target(&VAX_STD, &DEF_ALIGNMENT);
        else if (strcmp(tgt, "mips") == 0)
           PD_target(&IEEEA_STD, &MIPS_ALIGNMENT);
        else if (strcmp(tgt, "mips64") == 0)
           PD_target(&IEEED_STD, &MIPS64_ALIGNMENT);
        else if (strcmp(tgt, "alpha64") == 0)
           PD_target(&IEEEE_STD, &ALPHA64_ALIGNMENT);
        else if (strcmp(tgt, "sun3") == 0)
           PD_target(&IEEEA_STD, &M68000_ALIGNMENT);
        else if (strcmp(tgt, "sun4") == 0)
           PD_target(&IEEEA_STD, &SPARC_ALIGNMENT);
        else if (strcmp(tgt, "mac") == 0)
           PD_target(&IEEEB_STD, &M68000_ALIGNMENT);
        sprintf(fname, "%s-%s.rs%d", base, tgt, n);
        sprintf(datfile, "%s-%s.db%d", base, tgt, n);}
    else
       {sprintf(fname, "%s-nat.rs%d", base, n);
        sprintf(datfile, "%s-nat.db%d", base, n);};

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* DUMP_TEST_SYMBOL_TABLE - dump the symbol table */

static void dump_test_symbol_table(fp, tab, n)
   FILE *fp;
   HASHTAB *tab;
   int n;
   {int i;
    char **names;

    PRINT(fp, "\nTest %d Symbol table:\n", n);

    names = SC_hash_dump(tab, NULL);
    for (i = 0; i < tab->nelements; i++)
        PRINT(fp, "%s\n", names[i]);
    SFREE(names);

    PRINT(fp, "\n");

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* PD_FLOAT_EQUAL - compare two floating point numbers
 *                - which have different precision
 */

static int PD_float_equal(d1, d2, tol)
   double d1, d2, tol;
   {double del;

    if (d1 == d2)
       return(0);

    del = (d1 - d2)/(ABS(d1) + ABS(d2) + SMALL);
    if (del < -tol)
       return(-1);
    else if (tol < del)
       return(1);
    else
       return(0);}

/*--------------------------------------------------------------------------*/

/*                            TEST #1 ROUTINES                              */

/*--------------------------------------------------------------------------*/

/* PREP_TEST_1_DATA - prepare the test data */

static void prep_test_1_data()
   {int i, k;

/* set scalars */
    cs_r    = 0;
    ss_r    = 0;
    is_r    = 0;
    fs_r    = 0.0;
    fs_p1_r = 0.0;
    fs_p2_r = 0.0;
    fs_p3_r = 0.0;
    ds_r    = 0.0;

    cs_w     = 'Q';
    ss_w     = -514;
    is_w     =  10;
    fs_w     =  3.14159;
    fs_app_w = -3.14159;
    ds_w     =  exp(1.0);

/* set char array */
    for (i = 0; i < N_CHAR; i++)
        {ca_w[i] = '\0';
         ca_r[i] = '\0';};

/* set short array */
    for (i = 0; i < N_INT; i++)
        {sa_w[i] = 2 - i;
         sa_r[i] = 0;};

/* set int array */
    for (i = 0; i < N_INT; i++)
        {ia_w[i] = i - 2;
         ia_r[i] = 0;};

/* set float array */
    for (i = 0; i < N_FLOAT; i++)
        for (k = 0; k < N_DOUBLE; k++)
            {fa2_w[i][k]     = POW((double) (i+1), (double) (k+1));
             fa2_app_w[i][k] = POW((double) (k+1), (double) (i+1));
             fa2_r[i][k]     = 0.0;
             fa2_app_r[i][k] = 0.0;};

/* set double array */
    for (i = 0; i < N_FLOAT; i++)
        {da_w[i] = POW(ds_w, (double) (i+1));
         da_r[i] = 0.0;};

/* set strings */
    strcpy(ca_w, "Hi there!");
    len = strlen(ca_w) + 1;

    cap_w[0] = SC_strsavef("lev1", "char*:PREP_TEST_1_DATA:lev1");
    cap_w[1] = SC_strsavef("lev2", "char*:PREP_TEST_1_DATA:lev2");
    cap_w[2] = SC_strsavef("tar fu blat",
                             "char*:PREP_TEST_1_DATA:tarfublat");
    cap_r[0] = NULL;
    cap_r[1] = NULL;
    cap_r[2] = NULL;

/* set structures */
    for (i = 0; i < N_CHAR; i++)
        {graph_w.x_axis[i] = ((float) i)/10.0;
         graph_w.y_axis[i] = 0.5 - graph_w.x_axis[i];
         graph_r.x_axis[i] = -1000.0;
         graph_r.y_axis[i] = -1000.0;};

    view_w.x_min = 0.1;
    view_w.x_max = 1.0;
    view_w.y_min = -0.5;
    view_w.y_max =  0.5;

    view_r.x_min = -1.e-10;
    view_r.x_max = -1.e-10;
    view_r.y_min = -1.e-10;
    view_r.y_max = -1.e-10;

    graph_w.npts  = N_CHAR;
    graph_w.label = SC_strsavef("test graph",
                                "char*:PREP_TEST_1_DATA:label");
    graph_w.view  = view_w;

    graph_r.npts  = 0;
    graph_r.label = NULL;

    graph_r.view.x_min = -1.e-10;
    graph_r.view.x_max = -1.e-10;
    graph_r.view.y_min = -1.e-10;
    graph_r.view.y_max = -1.e-10;

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* CLEANUP_TEST_1 - free all known test data memory */

static void cleanup_test_1()
   {
    SFREE(cap_w[0]);
    SFREE(cap_w[1]);
    SFREE(cap_w[2]);

    SFREE(cap_r[0]);
    SFREE(cap_r[1]);
    SFREE(cap_r[2]);

    SFREE(graph_w.label);
    SFREE(graph_r.label);

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* WRITE_TEST_1_DATA - write out the data into the PDB file */

static void write_test_1_data(strm)
   PDBfile *strm;
   {long ind[6];

/* write scalars into the file */
    if (!PD_write(strm, "cs", "char",    &cs_w))
       {PRINT(STDOUT, "CS WRITE FAILED - WRITE_TEST_1_DATA\n");
        exit(1);};
    if (!PD_write(strm, "ss", "short",   &ss_w))
       {PRINT(STDOUT, "SS WRITE FAILED - WRITE_TEST_1_DATA\n");
        exit(1);};
    if (!PD_write(strm, "is", "integer", &is_w))
       {PRINT(STDOUT, "IS WRITE FAILED - WRITE_TEST_1_DATA\n");
        exit(1);};
    if (!PD_write(strm, "fs", "float",   &fs_w))
       {PRINT(STDOUT, "FS WRITE FAILED - WRITE_TEST_1_DATA\n");
        exit(1);};
    if (!PD_write(strm, "ds", "double",  &ds_w))
       {PRINT(STDOUT, "DS WRITE FAILED - WRITE_TEST_1_DATA\n");
        exit(1);};

/* write primitive arrays into the file */
    ind[0] = 0L;
    ind[1] = len - 1;
    ind[2] = 1L;
    if (!PD_write_alt(strm, "ca", "char", ca_w, 1, ind))
       {PRINT(STDOUT, "CA WRITE FAILED - WRITE_TEST_1_DATA\n");
        exit(1);};
    if (!PD_write(strm, "sa(5)", "short", sa_w))
       {PRINT(STDOUT, "SA WRITE FAILED - WRITE_TEST_1_DATA\n");
        exit(1);};
    if (!PD_write(strm, "ia(5)", "integer", ia_w))
       {PRINT(STDOUT, "IA WRITE FAILED - WRITE_TEST_1_DATA\n");
        exit(1);};

    ind[0] = 0L;
    ind[1] = N_FLOAT - 1;
    ind[2] = 1L;
    ind[3] = 0L;
    ind[4] = N_DOUBLE - 1;
    ind[5] = 1L;
    if (!PD_write_alt(strm, "fa2", "float", fa2_w, 2, ind))
       {PRINT(STDOUT, "FA2 WRITE FAILED - WRITE_TEST_1_DATA\n");
        exit(1);};

    ind[0] = 0L;
    ind[1] = N_FLOAT - 1;
    ind[2] = 1L;
    if (!PD_write_alt(strm, "da", "double", da_w, 1, ind))
       {PRINT(STDOUT, "DA WRITE FAILED - WRITE_TEST_1_DATA\n");
        exit(1);};

    ind[0] = 0L;
    ind[1] = N_DOUBLE - 1;
    ind[2] = 1L;
    if (!PD_write_alt(strm, "cap", "char *", cap_w, 1, ind))
       {PRINT(STDOUT, "CAP WRITE FAILED - WRITE_TEST_1_DATA\n");
        exit(1);};

/* write structures into the file */
    if (!PD_write(strm, "view", "l_frame", &view_w))
       {PRINT(STDOUT, "VIEW WRITE FAILED - WRITE_TEST_1_DATA\n");
        exit(1);};

    if (!PD_write(strm, "graph", "plot", &graph_w))
       {PRINT(STDOUT, "GRAPH WRITE FAILED - WRITE_TEST_1_DATA\n");
        exit(1);};

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* APPEND_TEST_1_DATA - append some test data to the file */

static void append_test_1_data(strm)
   PDBfile *strm;
   {long ind[6];

    if (!PD_write(strm,   "fs_app",  "float", &fs_app_w))
       {PRINT(STDOUT, "FS_APP WRITE FAILED - APPEND_TEST_1_DATA\n");
        exit(1);};

    ind[0] = 0L;
    ind[1] = N_FLOAT - 1;
    ind[2] = 1L;
    ind[3] = 0L;
    ind[4] = N_DOUBLE - 1;
    ind[5] = 1L;
    if (!PD_write_alt(strm, "fa2_app",   "float",   fa2_app_w, 2, ind))
       {PRINT(STDOUT, "FA2_APP WRITE FAILED - APPEND_TEST_1_DATA\n");
        exit(1);};

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* READ_TEST_1_DATA - read the test data from the file */

static int read_test_1_data(strm)
   PDBfile *strm;
   {int err;
    long ind[6];

/* read the scalar data from the file */
    err = PD_read(strm, "cs", &cs_r);
    err = PD_read(strm, "ss", &ss_r);
    err = PD_read(strm, "is", &is_r);
    err = PD_read(strm, "fs", &fs_r);
    err = PD_read(strm, "ds", &ds_r);

/* read the primitive arrays from the file */
    err = PD_read(strm, "ca",  ca_r);
    err = PD_read(strm, "sa",  sa_r);
    err = PD_read(strm, "ia",  ia_r);
    err = PD_read(strm, "fa2", fa2_r);
    err = PD_read(strm, "da",  da_r);
    err = PD_read(strm, "cap", cap_r);

/* read the entire structures from the file */
    err = PD_read(strm, "view",  &view_r);
    err = PD_read(strm, "graph", &graph_r);

/* read the appended data from the file */
    err = PD_read(strm, "fs_app",  &fs_app_r);
    err = PD_read(strm, "fa2_app", fa2_app_r);

/* partial array read */
    ind[0] = 1;
    ind[1] = 2;
    ind[2] = 1;
    ind[3] = 0;
    ind[4] = 1;
    ind[5] = 1;
    err = PD_read_alt(strm, "fa2", fa1_r, ind);

/* struct member test */
    ind[0] = 8;
    ind[1] = 8;
    ind[2] = 1;
    err = PD_read_alt(strm, "graph.x_axis",     &fs_p1_r, ind);
    err = PD_read(    strm, "graph.view.x_max", &fs_p2_r);
    err = PD_read(    strm, "view.y_max",       &fs_p3_r);

    return(err);}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* PRINT_TEST_1_DATA - print it out to STDOUT */

static void print_test_1_data(fp)
   FILE *fp;
   {int i, k;

/* print scalars */
    PRINT(fp, "short scalar:   ss = %d\n", ss_r);
    PRINT(fp, "integer scalar: is = %d\n", is_r);
    PRINT(fp, "float scalar:   fs = %14.6e\n", fs_r);
    PRINT(fp, "double scalar:  ds = %14.6e\n", ds_r);

    PRINT(fp, "\n");

/* print char array */
    PRINT(fp, "static char array:\n  ca = %s\n", ca_r);

/* print short array */
    PRINT(fp, "short array:\n");
    for (i = 0; i < N_INT; i++)
        PRINT(fp, "  sa[%d] = %d\n", i, sa_r[i]);

/* print int array */
    PRINT(fp, "integer array:\n");
    for (i = 0; i < N_INT; i++)
        PRINT(fp, "  ia[%d] = %d\n", i, ia_r[i]);

/* print float array */
    PRINT(fp, "float array:\n");
    for (i = 0; i < N_FLOAT; i++)
        for (k = 0; k < N_DOUBLE; k++)
            PRINT(fp, "  fa2[%d][%d] = %14.6e\n", i, k, fa2_r[i][k]);

/* print double array */
    PRINT(fp, "double array:\n");
    for (i = 0; i < N_FLOAT; i++)
        PRINT(fp, "  da[%d] = %14.6e\n", i, da_r[i]);

/* print character pointer array */
    PRINT(fp, "string array:\n");
    for (i = 0; i < N_DOUBLE; i++)
        PRINT(fp, "  cap[%d] = %s\n", i, cap_r[i]);

    PRINT(fp, "\n");

/* print appended scalars */
    PRINT(fp, "appended float scalar: fs_app = %14.6e\n", fs_app_r);

/* print float array */
    PRINT(fp, "appended float array:\n");
    for (i = 0; i < N_FLOAT; i++)
        for (k = 0; k < N_DOUBLE; k++)
            PRINT(fp, "  fa2_app[%d][%d] = %14.6e\n",
                    i, k, fa2_app_r[i][k]);

    PRINT(fp, "\n");

/* whole struct test */
    PRINT(fp, "struct view:\n");
    PRINT(fp, "  x-min = %14.6e\n", view_r.x_min);
    PRINT(fp, "  x-max = %14.6e\n", view_r.x_max);
    PRINT(fp, "  y-min = %14.6e\n", view_r.y_min);
    PRINT(fp, "  y-max = %14.6e\n", view_r.y_max);

    PRINT(fp, "\n");

    PRINT(fp, "struct graph:\n");
    PRINT(fp, "  #pts  = %d\n",     graph_r.npts);
    PRINT(fp, "  x-min = %14.6e\n", graph_r.view.x_min);
    PRINT(fp, "  x-max = %14.6e\n", graph_r.view.x_max);
    PRINT(fp, "  y-min = %14.6e\n", graph_r.view.y_min);
    PRINT(fp, "  y-max = %14.6e\n", graph_r.view.y_max);

    PRINT(fp, "      x values             y values\n");
    for (i = 0; i < N_CHAR; i++)
        PRINT(fp, "   %14.6e       %14.6e\n",
              graph_r.x_axis[i], graph_r.y_axis[i]);

    PRINT(fp, "\n");

/* partial read single elements */
    PRINT(fp, "\npartial read scalars:\n");
    PRINT(fp, "  graph.x_axis[8]  = %14.6e\n", fs_p1_r);
    PRINT(fp, "  graph.view.x_max = %14.6e\n", fs_p2_r);
    PRINT(fp, "  view.y_max       = %14.6e\n", fs_p3_r);

    PRINT(fp, "\n");

/* partial read arrays */
    PRINT(fp, "partial read float array:\n");
    for (i = 0; i < N_FLOAT; i++)
        PRINT(fp, "  fa2_p[%d] = %14.6e\n", i, fa1_r[i]);

    PRINT(fp, "\n");

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* COMPARE_TEST_1_DATA - compare the test data */

static int compare_test_1_data(strm, fp)
   PDBfile *strm;
   FILE *fp;
   {int i, k, err, err_tot;
    int float_nm, double_nm;
    double float_tolerance, double_tolerance;

    float_nm  = min(strm->std->float_format[2],
                    strm->host_std->float_format[2]);
    double_nm = min(strm->std->double_format[2],
                    strm->host_std->double_format[2]);

/* pad the absolute tolerance */
    float_tolerance  = POW(2.0, -((double) float_nm));
    double_tolerance = POW(2.0, -((double) double_nm));
    err_tot = TRUE;

/* compare scalars */
    err  = TRUE;
    err &= (cs_r == cs_w);
    err &= (ss_r == ss_w);
    err &= (is_r == is_w);
    err &= FLOAT_EQUAL(fs_r, fs_w);
    err &= FLOAT_EQUAL(fs_app_r, fs_app_w);
    err &= DOUBLE_EQUAL(ds_r, ds_w);

    if (err)
       PRINT(fp, "Scalars compare\n");
    else
       PRINT(fp, "Scalars differ\n");
    err_tot &= err;

/* compare char array */
    err  = TRUE;
    for (i = 0; i < N_CHAR; i++)
        err &= (ca_r[i] == ca_w[i]);

/* compare short array */
    for (i = 0; i < N_INT; i++)
        err &= (sa_r[i] == sa_w[i]);

/* compare int array */
    for (i = 0; i < N_INT; i++)
        err &= (ia_r[i] == ia_w[i]);

/* compare float array */
    for (i = 0; i < N_FLOAT; i++)
        for (k = 0; k < N_DOUBLE; k++)
            {err &= FLOAT_EQUAL(fa2_r[i][k], fa2_w[i][k]);
             err &= FLOAT_EQUAL(fa2_app_r[i][k], fa2_app_w[i][k]);}

/* compare double array */
    for (i = 0; i < N_FLOAT; i++)
        err &= DOUBLE_EQUAL(da_r[i], da_w[i]);

    if (err)
       PRINT(fp, "Arrays compare\n");
    else
       PRINT(fp, "Arrays differ\n");
    err_tot &= err;

/* compare strings */
    err  = TRUE;

    for (i = 0; i < N_DOUBLE; i++)
        err &= (strcmp(cap_r[i], cap_w[i]) == 0);

    if (err)
       PRINT(fp, "Strings compare\n");
    else
       PRINT(fp, "Strings differ\n");
    err_tot &= err;

/* compare structures */
    err  = TRUE;
    for (i = 0; i < N_CHAR; i++)
        {err &= FLOAT_EQUAL(graph_r.x_axis[i], graph_w.x_axis[i]);
         err &= FLOAT_EQUAL(graph_r.y_axis[i], graph_w.y_axis[i]);};

    err &= FLOAT_EQUAL(view_r.x_min, view_w.x_min);
    err &= FLOAT_EQUAL(view_r.x_max, view_w.x_max);
    err &= FLOAT_EQUAL(view_r.y_min, view_w.y_min);
    err &= FLOAT_EQUAL(view_r.y_max, view_w.y_max);

    err &= (graph_r.npts == graph_w.npts);
    err &= (strcmp(graph_r.label, graph_w.label) == 0);

    err &= FLOAT_EQUAL(graph_r.view.x_min, graph_w.view.x_min);
    err &= FLOAT_EQUAL(graph_r.view.x_max, graph_w.view.x_max);
    err &= FLOAT_EQUAL(graph_r.view.y_min, graph_w.view.y_min);
    err &= FLOAT_EQUAL(graph_r.view.y_max, graph_w.view.y_max);

    if (err)
       PRINT(fp, "Structs compare\n");
    else
       PRINT(fp, "Structs differ\n");
    err_tot &= err;

/* compare partial read results */
    err  = TRUE;
    err &= FLOAT_EQUAL(fs_p1_r, graph_w.x_axis[8]);
    err &= FLOAT_EQUAL(fs_p2_r, graph_w.view.x_max);
    err &= FLOAT_EQUAL(fs_p3_r, view_w.y_max);

    if (err)
       PRINT(fp, "Partial reads compare\n");
    else
       PRINT(fp, "Partial reads differ\n");
    err_tot &= err;

    return(err_tot);}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* TEST_1 - test the fundamental PDBLib functions
 *        -
 *        - read and write scalars of all primitive types
 *        - read and write structures with no indirections
 *        - append data to a file and read it back
 *        - read structure members
 *        - read parts of arrays
 *        -
 *        - tests can be targeted
 */

static int test_1(base, tgt, n)
   char *base, *tgt;
   int n;
   {PDBfile *strm;
    char datfile[MAXLINE], fname[MAXLINE];
    int err;
    FILE *fp;

/* target the file as asked */
    test_target(tgt, base, n, fname, datfile);

    fp = fopen(fname, "w");

/* create the named file */
    strm = PD_create(datfile);
    if (strm == NULL)
       {PRINT(fp, "Test couldn't create file %s\r\n", datfile);
        exit(1);};
    PRINT(fp, "File %s created\n", datfile);

    prep_test_1_data();

/* make a few defstructs */
    PD_defstr(strm, "l_frame",
              " float x_min",
              "float x_max",
              "float y_min",
              "float y_max",
              LAST);
    PD_defstr(strm, "plot",
              "float x_axis(10)",
              "float y_axis(10)",
              "integer npts", 
              "char * label",
              "l_frame view",
               LAST);

/* write the test data */
    write_test_1_data(strm);

/* close the file */
    if (!PD_close(strm))
       {PRINT(fp, "Test couldn't close file %s\r\n", datfile);
        exit(1);};
    PRINT(fp, "File %s closed\n", datfile);

/* reopen the file to append */
    strm = PD_open(datfile, "a");
    if (strm == NULL)
       {PRINT(fp, "Test couldn't open file %s to append\r\n", datfile);
        exit(1);};
    PRINT(fp, "File %s opened to append\n", datfile);

    append_test_1_data(strm);

/* close the file after append */
    if (!PD_close(strm))
       {PRINT(fp, "Test couldn't close file %s after append\r\n",
              datfile);
        exit(1);};
    PRINT(fp, "File %s closed after append\n", datfile);

/* reopen the file */
    strm = PD_open(datfile, "r");
    if (strm == NULL)
       {PRINT(fp, "Test couldn't open file %s\r\n", datfile);
        exit(1);};
    PRINT(fp, "File %s opened\n", datfile);

/* dump the symbol table */
    dump_test_symbol_table(fp, strm->symtab, 1);

/* read the data from the file */
    read_test_1_data(strm);

/* compare the original data with that read in */
    err = compare_test_1_data(strm, fp);

/* close the file */
    if (!PD_close(strm))
       {PRINT(fp, "Test couldn't close file %s\r\n", datfile);
        exit(1);};
    PRINT(fp, "File %s closed\n", datfile);

/* print it out to STDOUT */
    print_test_1_data(fp);

/* free known test data memory */
    cleanup_test_1();

    if (debug_mode)
       SC_mem_map(STDOUT, FALSE);

    fclose(fp);
    if (err)
       REMOVE(fname);

    return(err);}

/*--------------------------------------------------------------------------*/

/*                            TEST #2 ROUTINES                              */

/*--------------------------------------------------------------------------*/

/* PREP_TEST_2_DATA - prepare the test data */

static void prep_test_2_data()
   {int i, *p1, *p2;
    double *p3, *p4;

/*    do_w = -1; */

    for (i = 0; i < N_INT; i++)
        {p_w[i] = i;
         p_r[i] = 0;};

    tar_w = FMAKE_N(lev1, 2, "PREP_TEST_2_DATA:tar_w");

    p1 = tar_w[0].a = FMAKE_N(int, N_INT, "PREP_TEST_2_DATA:tar_w[0].a");
    p2 = tar_w[1].a = FMAKE_N(int, N_INT, "PREP_TEST_2_DATA:tar_w[1].a");
    for (i = 0; i < N_INT; i++)
        {p1[i] = i;
         p2[i] = i + 10;};

    p3 = tar_w[0].b = FMAKE_N(double, N_DOUBLE,
                              "PREP_TEST_2_DATA:tar_w[0].b");
    p4 = tar_w[1].b = FMAKE_N(double, N_DOUBLE,
                              "PREP_TEST_2_DATA:tar_w[1].b");
    for (i = 0; i < N_DOUBLE; i++)
        {p3[i] = exp((double) i);
         p4[i] = log(1.0 + (double) i);};

    tar_w[0].c = FMAKE_N(lev2, 2, "PREP_TEST_2_DATA:tar_w[0].c");
    tar_w[1].c = FMAKE_N(lev2, 2, "PREP_TEST_2_DATA:tar_w[0].c");

    tar_w[0].c[0].s    = FMAKE_N(char *, 2,
                                 "PREP_TEST_2_DATA:tar_w[0].c[0].s");
    tar_w[0].c[0].s[0] = SC_strsavef("Hello",
                           "char*:PREP_TEST_2_DATA:Hello");
    tar_w[0].c[0].s[1] = SC_strsavef(" ", "char*:PREP_TEST_2_DATA:blank");
    tar_w[0].c[1].s    = FMAKE_N(char *, 2,
                                 "PREP_TEST_2_DATA:tar_w[0].c[1].s");
    tar_w[0].c[1].s[0] = SC_strsavef("world",
                           "char*:PREP_TEST_2_DATA:world");
    tar_w[0].c[1].s[1] = SC_strsavef("!", "char*:PREP_TEST_2_DATA:!");

    tar_w[1].c[0].s    = FMAKE_N(char *, 2,
                                 "PREP_TEST_2_DATA:tar_w[1].c[0].s");
    tar_w[1].c[0].s[0] = SC_strsavef("Foo", "char*:PREP_TEST_2_DATA:Foo");
    tar_w[1].c[0].s[1] = SC_strsavef(" ", "char*:PREP_TEST_2_DATA:blank");
    tar_w[1].c[1].s    = FMAKE_N(char *, 2,
                                 "PREP_TEST_2_DATA:tar_w[1].c[1].s");
    tar_w[1].c[1].s[0] = SC_strsavef("Bar", "char*:PREP_TEST_2_DATA:Bar");
    tar_w[1].c[1].s[1] = SC_strsavef("!!!", "char*:PREP_TEST_2_DATA:!!!");

    tar_w[0].c[0].type = 1;
    tar_w[0].c[1].type = 2;
    tar_w[1].c[0].type = 3;
    tar_w[1].c[1].type = 4;

    tar_r = NULL;

    ap1 = NULL;
    ap2 = NULL;
    for (i = 0; i < 4; i++)
        aa[i] = 0;

    bp1 = NULL;
    bp2 = NULL;
    for (i = 0; i < 4; i++)
        ba[i] = 0.0;

    cp1 = NULL;
    cp2 = NULL;
    for (i = 0; i < 4; i++)
        {ca[i].s    = NULL;
         ca[i].type = 0;};

    sp1 = NULL;
    sp2 = NULL;
    sp3 = NULL;
    sp4 = NULL;

    tp1 = NULL;
    tp2 = NULL;
    tp3 = NULL;
    tp4 = NULL;
    tp5 = NULL;
    tp6 = NULL;
    tp7 = NULL;
    tp8 = NULL;
    for (i = 0; i < 4; i++)
        ta[i] = 0;

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* CLEANUP_TEST_2 - free all know test data memory */

static void cleanup_test_2()
   {int i;

    if (tar_w != NULL)
       {SFREE(tar_w[0].c[0].s[0]);
        SFREE(tar_w[0].c[0].s[1]);
        SFREE(tar_w[0].c[1].s[0]);
        SFREE(tar_w[0].c[1].s[1]);

        SFREE(tar_w[1].c[0].s[0]);
        SFREE(tar_w[1].c[0].s[1]);
        SFREE(tar_w[1].c[1].s[0]);
        SFREE(tar_w[1].c[1].s[1]);

        SFREE(tar_w[0].c[0].s);
        SFREE(tar_w[0].c[1].s);
        SFREE(tar_w[1].c[0].s);
        SFREE(tar_w[1].c[1].s);

        SFREE(tar_w[0].c);
        SFREE(tar_w[1].c);

        SFREE(tar_w[0].a);
        SFREE(tar_w[1].a);

        SFREE(tar_w[0].b);
        SFREE(tar_w[1].b);

        SFREE(tar_w);};

    if (tar_r != NULL)
       {SFREE(tar_r[0].c[0].s[0]);
        SFREE(tar_r[0].c[0].s[1]);
        SFREE(tar_r[0].c[1].s[0]);
        SFREE(tar_r[0].c[1].s[1]);

        SFREE(tar_r[1].c[0].s[0]);
        SFREE(tar_r[1].c[0].s[1]);
        SFREE(tar_r[1].c[1].s[0]);
        SFREE(tar_r[1].c[1].s[1]);

        SFREE(tar_r[0].c[0].s);
        SFREE(tar_r[0].c[1].s);
        SFREE(tar_r[1].c[0].s);
        SFREE(tar_r[1].c[1].s);

        SFREE(tar_r[0].c);
        SFREE(tar_r[1].c);

        SFREE(tar_r[0].a);
        SFREE(tar_r[1].a);

        SFREE(tar_r[0].b);
        SFREE(tar_r[1].b);

        SFREE(tar_r);};

    SFREE(ap1);
    SFREE(ap2);

    SFREE(bp1);
    SFREE(bp2);

    if (cp1 != NULL)
       {if (cp1[0].s != NULL)
           {SFREE(cp1[0].s[0]);
            SFREE(cp1[0].s[1]);
            SFREE(cp1[0].s);};

        if (cp1[1].s != NULL)
           {SFREE(cp1[1].s[0]);
            SFREE(cp1[1].s[1]);
            SFREE(cp1[1].s);};

        SFREE(cp1);};

    if (cp2 != NULL)
       {if (cp2[0].s != NULL)
           {SFREE(cp2[0].s[0]);
            SFREE(cp2[0].s[1]);
            SFREE(cp2[0].s);};

        if (cp2[1].s != NULL)
           {SFREE(cp2[1].s[0]);
            SFREE(cp2[1].s[1]);
            SFREE(cp2[1].s);};

        SFREE(cp2);};

    for (i = 0; i < 4; i++)
        {SFREE(ca[i].s[0]);
	 SFREE(ca[i].s[1]);
	 SFREE(ca[i].s);};

    if (sp1 != NULL)
       {SFREE(sp1[0]);
        SFREE(sp1[1]);
        SFREE(sp1);};

    if (sp2 != NULL)
       {SFREE(sp2[0]);
        SFREE(sp2[1]);
        SFREE(sp2);};

    if (sp3 != NULL)
       {SFREE(sp3[0]);
        SFREE(sp3[1]);
        SFREE(sp3);};

    if (sp4 != NULL)
       {SFREE(sp4[0]);
        SFREE(sp4[1]);
        SFREE(sp4);};

    SFREE(tp1);
    SFREE(tp2);
    SFREE(tp3);
    SFREE(tp4);
    SFREE(tp5);
    SFREE(tp6);
    SFREE(tp7);
    SFREE(tp8);

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* WRITE_TEST_2_DATA - write out the data into the PDB file */

static void write_test_2_data(strm)
   PDBfile *strm;
   {long ind[3];

    ind[0] = 1L;
    ind[1] = N_INT;
    ind[2] = 1L;
    if (!PD_write_alt(strm, "p", "integer", p_w, 1, ind))
       {PRINT(STDOUT, "P WRITE FAILED - WRITE_TEST_2_DATA\n");
        exit(1);};

    if (!PD_write(strm, "tar", "lev1 *",  &tar_w))
       {PRINT(STDOUT, "TAR WRITE FAILED - WRITE_TEST_2_DATA\n");
        exit(1);};

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* READ_TEST_2_DATA - read the test data from the file */

static int read_test_2_data(strm)
   PDBfile *strm;
   {int err;

    do_r = strm->default_offset;

    err = PD_read(strm, "tar", &tar_r);
    err = PD_read(strm, "p", p_r);

    err = PD_read(strm, "tar(0).a", &ap1);
    err = PD_read(strm, "tar(1).a", &ap2);

    err = PD_read(strm, "tar(0).a(0)", &aa[0]);
    err = PD_read(strm, "tar(0).a(1)", &aa[1]);
    err = PD_read(strm, "tar(1).a(0)", &aa[2]);
    err = PD_read(strm, "tar(1).a(1)", &aa[3]);

    err = PD_read(strm, "tar(0).b", &bp1);
    err = PD_read(strm, "tar(1).b", &bp2);

    err = PD_read(strm, "tar(0).b(0)", &ba[0]);
    err = PD_read(strm, "tar(0).b(1)", &ba[1]);
    err = PD_read(strm, "tar(1).b(0)", &ba[2]);
    err = PD_read(strm, "tar(1).b(1)", &ba[3]);

    err = PD_read(strm, "tar(0).c", &cp1);
    err = PD_read(strm, "tar(1).c", &cp2);

    err = PD_read(strm, "tar(0).c(0)", &ca[0]);
    err = PD_read(strm, "tar(0).c(1)", &ca[1]);
    err = PD_read(strm, "tar(1).c(0)", &ca[2]);
    err = PD_read(strm, "tar(1).c(1)", &ca[3]);

    err = PD_read(strm, "tar(0).c(0).s", &sp1);
    err = PD_read(strm, "tar(0).c(1).s", &sp2);
    err = PD_read(strm, "tar(1).c(0).s", &sp3);
    err = PD_read(strm, "tar(1).c(1).s", &sp4);

    err = PD_read(strm, "tar(0).c(0).s(0)", &tp1);
    err = PD_read(strm, "tar(0).c(0).s(1)", &tp2);
    err = PD_read(strm, "tar(0).c(1).s(0)", &tp3);
    err = PD_read(strm, "tar(0).c(1).s(1)", &tp4);

    err = PD_read(strm, "tar(1).c(0).s(0)", &tp5);
    err = PD_read(strm, "tar(1).c(0).s(1)", &tp6);
    err = PD_read(strm, "tar(1).c(1).s(0)", &tp7);
    err = PD_read(strm, "tar(1).c(1).s(1)", &tp8);

    err = PD_read(strm, "tar(0).c(0).s(0)(2)", &ta[0]);
    err = PD_read(strm, "tar(0).c(0).s(1)(1)", &ta[1]);
    err = PD_read(strm, "tar(0).c(1).s(0)(3)", &ta[2]);
    err = PD_read(strm, "tar(0).c(1).s(1)(2)", &ta[3]);

    err = PD_read(strm, "tar(1).c(0).s(0)(2)", &ta[4]);
    err = PD_read(strm, "tar(1).c(0).s(1)(1)", &ta[5]);
    err = PD_read(strm, "tar(1).c(1).s(0)(3)", &ta[6]);
    err = PD_read(strm, "tar(1).c(1).s(1)(2)", &ta[7]);

    return(err);}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* PRINT_TEST_2_DATA - print it out to the file */

static void print_test_2_data(fp)
   FILE *fp;
   {int i;
    int *p1, *p2;
    double *p3, *p4;

    PRINT(fp, "\n");

    p1 = tar_r[0].a;
    p2 = tar_r[1].a;
    PRINT(fp, "TAR struct member A:\n");
    PRINT(fp, "    TAR[0].A    TAR[1].A\n");
    for (i = 0; i < N_INT; i++)
        PRINT(fp, "        %d          %d\n", p1[i], p2[i]);
    PRINT(fp, "\n");

    p3 = tar_r[0].b;
    p4 = tar_r[1].b;
    PRINT(fp, "TAR struct member B:\n");
    PRINT(fp, "    TAR[0].B    TAR[1].B\n");
    for (i = 0; i < N_DOUBLE; i++)
        PRINT(fp, "    %f    %f\n", p3[i], p4[i]);
    PRINT(fp, "\n");


    PRINT(fp, "TAR struct member C:\n");
    PRINT(fp, "    TAR[0].C[0]         TAR[0].C[1]\n");
    PRINT(fp, "   S[0]    S[1]        S[0]    S[1]\n");
    PRINT(fp, "  %s      %s        %s      %s\n",
                tar_r[0].c[0].s[0], tar_r[0].c[0].s[1],
                tar_r[0].c[1].s[0], tar_r[0].c[1].s[1]);
    PRINT(fp, "\n       TYPE\n");
    PRINT(fp, "     %d       %d\n",
                tar_r[0].c[0].type, tar_r[0].c[1].type);


    PRINT(fp, "\n    TAR[1].C[0]         TAR[1].C[1]\n");
    PRINT(fp, "   S[0]    S[1]        S[0]    S[1]\n");
    PRINT(fp, "   %s     %s           %s      %s\n",
                tar_r[1].c[0].s[0], tar_r[1].c[0].s[1],
                tar_r[1].c[1].s[0], tar_r[1].c[1].s[1]);

    PRINT(fp, "       TYPE\n");
    PRINT(fp, "     %d       %d\n",
                tar_r[1].c[0].type, tar_r[1].c[1].type);

    PRINT(fp, "\n");

/* print the offset */
    PRINT(fp, "file array index offset: %d\n\n", do_r);

    PRINT(fp, "\n");

/* read the an array which has offsets */
    PRINT(fp, "array p: \n");
    for (i = 0; i < N_INT; i++)
        PRINT(fp, "  %d\n", p_r[i]);

    PRINT(fp, "\n");

/* print the partial and member read stuff */
    if (ap1 != NULL)
       {PRINT(fp, "member read    TAR[0].A    TAR[1].A\n");
        for (i = 0; i < N_INT; i++)
            PRINT(fp, "                  %d          %d\n", ap1[i], ap2[i]);
        PRINT(fp, "\n");};
        
    if (bp1 != NULL)
       {PRINT(fp, "member read    TAR[0].B    TAR[1].B\n");
        for (i = 0; i < N_DOUBLE; i++)
            PRINT(fp, "               %f    %f\n", bp1[i], bp2[i]);
        PRINT(fp, "\n");};

    if (cp1 != NULL)
       {PRINT(fp, "member read TAR[0].C:\n");
        PRINT(fp, "    TAR[0].C[0]         TAR[0].C[1]\n");
        PRINT(fp, "   S[0]    S[1]        S[0]    S[1]\n");
        PRINT(fp, "  %s      %s        %s      %s\n",
                    cp1[0].s[0], cp1[0].s[1],
                    cp1[1].s[0], cp1[1].s[1]);
        PRINT(fp, "\n       TYPE\n");
        PRINT(fp, "     %d       %d\n",
                    cp1[0].type, cp1[1].type);

        PRINT(fp, "\nmember read TAR[1].C:\n");
        PRINT(fp, "    TAR[1].C[0]         TAR[1].C[1]\n");
        PRINT(fp, "   S[0]    S[1]        S[0]    S[1]\n");
        PRINT(fp, "   %s     %s           %s      %s\n",
                    cp2[0].s[0], cp2[0].s[1],
                    cp2[1].s[0], cp2[1].s[1]);
        PRINT(fp, "\n       TYPE\n");
        PRINT(fp, "     %d       %d\n",
                    cp2[0].type, cp2[1].type);};

/*
    PRINT(fp, "member read TAR[0].C[0]:\n");
    PRINT(fp, "   S[0]    S[1]\n");
    PRINT(fp, "  %s      %s\n", ca[0].s[0], ca[0].s[1]);

    PRINT(fp, "member read TAR[0].C[1]:\n");
    PRINT(fp, "   S[0]    S[1]\n");
    PRINT(fp, "  %s      %s\n", ca[1].s[0], ca[1].s[1]);

    PRINT(fp, "member read TAR[1].C[1]:\n");
    PRINT(fp, "   S[0]    S[1]\n");
    PRINT(fp, "  %s      %s\n", ca[2].s[0], ca[2].s[1]);

    PRINT(fp, "member read TAR[1].C[1]:\n");
    PRINT(fp, "   S[0]    S[1]\n");
    PRINT(fp, "  %s      %s\n", ca[3].s[0], ca[3].s[1]);
*/
/* TAR.C.S read */

    if (sp1 != NULL)
       {PRINT(fp, "\nmember read TAR[0].C[0].S:\n");
        PRINT(fp, "   S[0]    S[1]\n");
        PRINT(fp, "  %s      %s\n", sp1[0], sp1[1]);

        PRINT(fp, "\nmember read TAR[0].C[1].S:\n");
        PRINT(fp, "   S[0]    S[1]\n");
        PRINT(fp, "  %s      %s\n", sp2[0], sp2[1]);

        PRINT(fp, "\nmember read TAR[1].C[0].S:\n");
        PRINT(fp, "   S[0]    S[1]\n");
        PRINT(fp, "  %s      %s\n", sp3[0], sp3[1]);

        PRINT(fp, "\nmember read TAR[1].C[1].S:\n");
        PRINT(fp, "   S[0]    S[1]\n");
        PRINT(fp, "  %s      %s\n", sp4[0], sp4[1]);};

/* TAR.C.S[i] read */

    if (tp1 != NULL)
       {PRINT(fp, "\nmember read TAR[0].C[0].S[0]:\n");
        PRINT(fp, "   S[0]    S[1]\n");
        PRINT(fp, "  %s      %s\n", tp1, tp1);

        PRINT(fp, "\nmember read TAR[0].C[1].S[1]:\n");
        PRINT(fp, "   S[0]    S[1]\n");
        PRINT(fp, "  %s      %s\n", tp2, tp2);

        PRINT(fp, "\nmember read TAR[0].C[1].S[0]:\n");
        PRINT(fp, "   S[0]    S[1]\n");
        PRINT(fp, "  %s      %s\n", tp3, tp3);

        PRINT(fp, "\nmember read TAR[0].C[1].S[1]:\n");
        PRINT(fp, "   S[0]    S[1]\n");
        PRINT(fp, "  %s      %s\n", tp4, tp4);

        PRINT(fp, "\nmember read TAR[1].C[0].S[0]:\n");
        PRINT(fp, "   S[0]    S[1]\n");
        PRINT(fp, "  %s      %s\n", tp5, tp5);

        PRINT(fp, "\nmember read TAR[1].C[0].S[1]:\n");
        PRINT(fp, "   S[0]    S[1]\n");
        PRINT(fp, "  %s      %s\n", tp6, tp6);

        PRINT(fp, "\nmember read TAR[1].C[1].S[0]:\n");
        PRINT(fp, "   S[0]    S[1]\n");
        PRINT(fp, "  %s      %s\n", tp7, tp7);

        PRINT(fp, "\nmember read TAR[1].C[1].S[1]:\n");
        PRINT(fp, "   S[0]    S[1]\n");
        PRINT(fp, "  %s      %s\n", tp8, tp8);

/* TAR.C.S[i][j] read */

        PRINT(fp, "\nmember read from TAR[0]:\n");
        PRINT(fp, "C[0].S[0][2]  C[0].S[1][1]  C[1].S[0][3]  C[1].S[1][2]\n");
        PRINT(fp, "     %c             %c           %c             %c\n",
                    ta[0], ta[1], ta[2], ta[3]);};

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* COMPARE_TEST_2_DATA - compare the test data */

static int compare_test_2_data(strm, fp)
   PDBfile *strm;
   FILE *fp;
   {int i, *p1w, *p2w, *p1r, *p2r;
    double *p3w, *p4w, *p3r, *p4r;
    int err, err_tot;
    int double_nm;
    double double_tolerance;

    double_nm = min(strm->std->double_format[2],
                    strm->host_std->double_format[2]);

/* pad the absolute tolerance */
    double_tolerance = POW(2.0, -((double) double_nm));
    err_tot = TRUE;

/* compare offset and array */
    err  = TRUE;
    err &= (do_r == do_w);

    for (i = 0; i < N_INT; i++)
        err &= (p_w[i] == p_r[i]);

    if (err)
       PRINT(fp, "Offset compare\n");
    else
       PRINT(fp, "Offset differ\n");
    err_tot &= err;

    err = TRUE;
    p1w = tar_w[0].a;
    p2w = tar_w[1].a;
    p1r = tar_r[0].a;
    p2r = tar_r[1].a;
    for (i = 0; i < N_INT; i++)
        {err &= (p1w[i] == p1r[i]);
         err &= (p2w[i] == p2r[i]);};

    p3w = tar_w[0].b;
    p4w = tar_w[1].b;
    p3r = tar_r[0].b;
    p4r = tar_r[1].b;
    for (i = 0; i < N_DOUBLE; i++)
        {err &= DOUBLE_EQUAL(p3w[i], p3r[i]);
         err &= DOUBLE_EQUAL(p4w[i], p4r[i]);};

    err &= (strcmp(tar_w[0].c[0].s[0], tar_r[0].c[0].s[0]) == 0);
    err &= (strcmp(tar_w[0].c[0].s[1], tar_r[0].c[0].s[1]) == 0);
    err &= (strcmp(tar_w[0].c[1].s[0], tar_r[0].c[1].s[0]) == 0);
    err &= (strcmp(tar_w[0].c[1].s[1], tar_r[0].c[1].s[1]) == 0);

    err &= (strcmp(tar_w[1].c[0].s[0], tar_r[1].c[0].s[0]) == 0);
    err &= (strcmp(tar_w[1].c[0].s[1], tar_r[1].c[0].s[1]) == 0);
    err &= (strcmp(tar_w[1].c[1].s[0], tar_r[1].c[1].s[0]) == 0);
    err &= (strcmp(tar_w[1].c[1].s[1], tar_r[1].c[1].s[1]) == 0);

    err &= (tar_w[0].c[0].type == tar_r[0].c[0].type);
    err &= (tar_w[0].c[1].type == tar_r[0].c[1].type);
    err &= (tar_w[1].c[0].type == tar_r[1].c[0].type);
    err &= (tar_w[1].c[1].type == tar_r[1].c[1].type);

    if (err)
       PRINT(fp, "Indirects compare\n");
    else
       PRINT(fp, "Indirects differ\n");
    err_tot &= err;

    PRINT(fp, "\n");

    if (err)
       PRINT(fp, "Offset compare\n");
    else
       PRINT(fp, "Offset differ\n");
    err_tot &= err;

    err = TRUE;

    if (ap1 != NULL)
       {p1w = tar_w[0].a;
        p2w = tar_w[1].a;
        for (i = 0; i < N_INT; i++)
            {err &= (p1w[i] == ap1[i]);
             err &= (p2w[i] == ap2[i]);};};

    if (bp1 != NULL)
       {p3w = tar_w[0].b;
        p4w = tar_w[1].b;
        for (i = 0; i < N_DOUBLE; i++)
            {err &= DOUBLE_EQUAL(p3w[i], bp1[i]);
             err &= DOUBLE_EQUAL(p4w[i], bp2[i]);};};

    if (cp1 != NULL)
       {err &= (strcmp(tar_w[0].c[0].s[0], cp1[0].s[0]) == 0);
        err &= (strcmp(tar_w[0].c[0].s[1], cp1[0].s[1]) == 0);
        err &= (strcmp(tar_w[0].c[1].s[0], cp1[1].s[0]) == 0);
        err &= (strcmp(tar_w[0].c[1].s[1], cp1[1].s[1]) == 0);

        err &= (strcmp(tar_w[1].c[0].s[0], cp2[0].s[0]) == 0);
        err &= (strcmp(tar_w[1].c[0].s[1], cp2[0].s[1]) == 0);
        err &= (strcmp(tar_w[1].c[1].s[0], cp2[1].s[0]) == 0);
        err &= (strcmp(tar_w[1].c[1].s[1], cp2[1].s[1]) == 0);

        err &= (tar_w[0].c[0].type == cp1[0].type);
        err &= (tar_w[0].c[1].type == cp1[1].type);
        err &= (tar_w[1].c[0].type == cp2[0].type);
        err &= (tar_w[1].c[1].type == cp2[1].type);};
/*
    err &= (strcmp(tar_w[0].c[0].s[0], ca[0].s[0]) == 0);
    err &= (strcmp(tar_w[0].c[0].s[1], ca[0].s[1]) == 0);
    err &= (strcmp(tar_w[0].c[1].s[0], ca[1].s[0]) == 0);
    err &= (strcmp(tar_w[0].c[1].s[1], ca[1].s[1]) == 0);

    err &= (strcmp(tar_w[1].c[0].s[0], ca[2].s[0]) == 0);
    err &= (strcmp(tar_w[1].c[0].s[1], ca[2].s[1]) == 0);
    err &= (strcmp(tar_w[1].c[1].s[0], ca[3].s[0]) == 0);
    err &= (strcmp(tar_w[1].c[1].s[1], ca[3].s[1]) == 0);
*/
    if (sp1 != NULL)
       {err &= (strcmp(tar_w[0].c[0].s[0], sp1[0]) == 0);
        err &= (strcmp(tar_w[0].c[0].s[1], sp1[1]) == 0);
        err &= (strcmp(tar_w[0].c[1].s[0], sp2[0]) == 0);
        err &= (strcmp(tar_w[0].c[1].s[1], sp2[1]) == 0);

        err &= (strcmp(tar_w[1].c[0].s[0], sp3[0]) == 0);
        err &= (strcmp(tar_w[1].c[0].s[1], sp3[1]) == 0);
        err &= (strcmp(tar_w[1].c[1].s[0], sp4[0]) == 0);
        err &= (strcmp(tar_w[1].c[1].s[1], sp4[1]) == 0);};

    if (tp1 != NULL)
       {err &= (strcmp(tar_w[0].c[0].s[0], tp1) == 0);
        err &= (strcmp(tar_w[0].c[0].s[1], tp2) == 0);
        err &= (strcmp(tar_w[0].c[1].s[0], tp3) == 0);
        err &= (strcmp(tar_w[0].c[1].s[1], tp4) == 0);

        err &= (strcmp(tar_w[1].c[0].s[0], tp5) == 0);
        err &= (strcmp(tar_w[1].c[0].s[1], tp6) == 0);
        err &= (strcmp(tar_w[1].c[1].s[0], tp7) == 0);
        err &= (strcmp(tar_w[1].c[1].s[1], tp8) == 0);

        err &= (tar_w[0].c[0].s[0][2] == ta[0]);
        err &= (tar_w[0].c[0].s[1][1] == ta[1]);
        err &= (tar_w[0].c[1].s[0][3] == ta[2]);
        err &= (tar_w[0].c[1].s[1][2] == ta[3]);};

    if (err)
       PRINT(fp, "Indirects compare\n");
    else
       PRINT(fp, "Indirects differ\n");
    err_tot &= err;

    PRINT(fp, "\n");

    return(err_tot);}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* TEST_2 - test the PDBLib functions handling indirections
 *        -
 *        - read and write structures with pointers
 *        - set default array base indexes
 *        - read structure members
 *        - read parts of arrays
 *        -
 *        - tests can be targeted
 */

static int test_2(base, tgt, n)
   char *base, *tgt;
   int n;
   {PDBfile *strm;
    char datfile[MAXLINE], fname[MAXLINE];
    int err;
    FILE *fp;

/* target the file is asked */
    test_target(tgt, base, n, fname, datfile);

    fp = fopen(fname, "w");

    prep_test_2_data();

/* create the named file */
    strm = PD_create(datfile);
    if (strm == NULL)
       {PRINT(fp, "Test couldn't create file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s created\n", datfile);

/* set the default offset */
    strm->default_offset = do_w;

/* make a few defstructs */
    PD_defstr(strm, "lev2",
              "char **s",
	      "integer type",
              LAST);

    PD_defstr(strm, "lev1",
              "integer *a",
	      "double *b",
	      "lev2 *c",
              LAST);

/* write the test data */
    write_test_2_data(strm);

/* close the file */
    if (!PD_close(strm))
       {PRINT(fp, "Test couldn't close file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s closed\n", datfile);

/* reopen the file */
    strm = PD_open(datfile, "r");
    if (strm == NULL)
       {PRINT(fp, "Test couldn't open file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s opened\n", datfile);

/* dump the symbol table */
    dump_test_symbol_table(fp, strm->symtab, 2);

/* read the structs */
    read_test_2_data(strm);

/* compare the original data with that read in */
    err = compare_test_2_data(strm, fp);

/* print out the results */
    print_test_2_data(fp);

/* close the file */
    if (!PD_close(strm))
       {PRINT(fp, "Test couldn't close file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s closed\n", datfile);

/* cleanup test data memory */
    cleanup_test_2();

    if (debug_mode)
       SC_mem_map(STDOUT, FALSE);

    fclose(fp);
    if (err)
       REMOVE(fname);

    return(err);}

/*--------------------------------------------------------------------------*/

/*                            TEST #3 ROUTINES                              */

/*--------------------------------------------------------------------------*/

/* PREP_TEST_3_DATA - prepare the test data */

static void prep_test_3_data()
   {vr1_w.a    = 'A';
    vr1_w.b    = -10;
    vr1_w.c[0] = 'B';
    vr1_w.c[1] = 'a';
    vr1_w.d    = 32589;
    vr1_w.e[0] = 'C';
    vr1_w.e[1] = 'a';
    vr1_w.e[2] = 'b';
    vr1_w.f    = 1.523e-19;
    vr1_w.g[0] = 'D';
    vr1_w.g[1] = 'a';
    vr1_w.g[2] = 'b';
    vr1_w.g[3] = 'c';
    vr1_w.h    = 4.2782918323832554e30;
    vr1_w.i[0] = 'E';
    vr1_w.i[1] = 'a';
    vr1_w.i[2] = 'b';
    vr1_w.i[3] = 'c';
    vr1_w.i[4] = 'd';
    vr1_w.j    = SC_strsavef("whoa there big fella!",
                     "char*:PREP_TEST_3_DATA:whoa");
    vr1_w.k[0] = 'F';
    vr1_w.k[1] = 'a';
    vr1_w.k[2] = 'b';
    vr1_w.k[3] = 'c';
    vr1_w.k[4] = 'd';
    vr1_w.k[5] = 'e';

    vr1_r.a    = '\0';
    vr1_r.b    = 0;
    vr1_r.c[0] = '\0';
    vr1_r.c[1] = '\0';
    vr1_r.d    = 0;
    vr1_r.e[0] = '\0';
    vr1_r.e[1] = '\0';
    vr1_r.e[2] = '\0';
    vr1_r.f    = 0.0;
    vr1_r.g[0] = '\0';
    vr1_r.g[1] = '\0';
    vr1_r.g[2] = '\0';
    vr1_r.g[3] = '\0';
    vr1_r.h    = 0.0;
    vr1_r.i[0] = '\0';
    vr1_r.i[1] = '\0';
    vr1_r.i[2] = '\0';
    vr1_r.i[3] = '\0';
    vr1_r.i[4] = '\0';
    vr1_r.j    = NULL;
    vr1_r.k[0] = '\0';
    vr1_r.k[1] = '\0';
    vr1_r.k[2] = '\0';
    vr1_r.k[3] = '\0';
    vr1_r.k[4] = '\0';
    vr1_r.k[5] = '\0';

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* CLEANUP_TEST_3 - free all known test data memory */

static void cleanup_test_3()
   {SFREE(vr1_w.j);
    SFREE(vr1_r.j);

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* WRITE_TEST_3_DATA - write out the data into the PDB file */

static void write_test_3_data(strm)
   PDBfile *strm;
   {if (!PD_write(strm, "vr1", "st3", &vr1_w))
       {PRINT(STDOUT, "VR1 WRITE FAILED - WRITE_TEST_3_DATA\n");
        exit(1);};

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* READ_TEST_3_DATA - read the test data from the file */

static int read_test_3_data(strm)
   PDBfile *strm;
   {int err;

    err = PD_read(strm, "vr1", &vr1_r);

    return(err);}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* PRINT_TEST_3_DATA - print it out to the file */

static void print_test_3_data(fp)
   FILE *fp;
   {PRINT(fp, "struct vr1:\n");
    PRINT(fp, "   vr1.a    = %c\n", vr1_r.a);
    PRINT(fp, "   vr1.b    = %d\n", vr1_r.b);
    PRINT(fp, "   vr1.c[0] = %c\n", vr1_r.c[0]);
    PRINT(fp, "   vr1.c[1] = %c\n", vr1_r.c[1]);
    PRINT(fp, "   vr1.d    = %d\n", vr1_r.d);
    PRINT(fp, "   vr1.e[0] = %c\n", vr1_r.e[0]);
    PRINT(fp, "   vr1.e[1] = %c\n", vr1_r.e[1]);
    PRINT(fp, "   vr1.e[2] = %c\n", vr1_r.e[2]);
    PRINT(fp, "   vr1.f    = %14.7e\n", vr1_r.f);
    PRINT(fp, "   vr1.g[0] = %c\n", vr1_r.g[0]);
    PRINT(fp, "   vr1.g[1] = %c\n", vr1_r.g[1]);
    PRINT(fp, "   vr1.g[2] = %c\n", vr1_r.g[2]);
    PRINT(fp, "   vr1.g[3] = %c\n", vr1_r.g[3]);
    PRINT(fp, "   vr1.h    = %20.13e\n", vr1_r.h);
    PRINT(fp, "   vr1.i[0] = %c\n", vr1_r.i[0]);
    PRINT(fp, "   vr1.i[1] = %c\n", vr1_r.i[1]);
    PRINT(fp, "   vr1.i[2] = %c\n", vr1_r.i[2]);
    PRINT(fp, "   vr1.i[3] = %c\n", vr1_r.i[3]);
    PRINT(fp, "   vr1.i[4] = %c\n", vr1_r.i[4]);
    PRINT(fp, "   vr1.j    = %s\n", vr1_r.j);
    PRINT(fp, "   vr1.k[0] = %c\n", vr1_r.k[0]);
    PRINT(fp, "   vr1.k[1] = %c\n", vr1_r.k[1]);
    PRINT(fp, "   vr1.k[2] = %c\n", vr1_r.k[2]);
    PRINT(fp, "   vr1.k[3] = %c\n", vr1_r.k[3]);
    PRINT(fp, "   vr1.k[4] = %c\n", vr1_r.k[4]);
    PRINT(fp, "   vr1.k[5] = %c\n", vr1_r.k[5]);

    PRINT(fp, "\n");

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* COMPARE_TEST_3_DATA - compare the test data */

static int compare_test_3_data(strm, fp)
   PDBfile *strm;
   FILE *fp;
   {int err, err_tot;
    int float_nm, double_nm;
    double float_tolerance, double_tolerance;

    float_nm  = min(strm->std->float_format[2],
                    strm->host_std->float_format[2]);
    double_nm = min(strm->std->double_format[2],
                    strm->host_std->double_format[2]);

/* pad the absolute tolerance */
    float_tolerance  = POW(2.0, -((double) float_nm));
    double_tolerance = POW(2.0, -((double) double_nm));
    err_tot = TRUE;

/* compare offset and array */
    err  = TRUE;
    err &= (vr1_w.a == vr1_r.a);
    err &= (vr1_w.b == vr1_r.b);
    err &= (vr1_w.c[0] == vr1_r.c[0]);
    err &= (vr1_w.c[1] == vr1_r.c[1]);
    err &= (vr1_w.d == vr1_r.d);
    err &= (vr1_w.e[0] == vr1_r.e[0]);
    err &= (vr1_w.e[1] == vr1_r.e[1]);
    err &= (vr1_w.e[2] == vr1_r.e[2]);
    err &= FLOAT_EQUAL(vr1_w.f, vr1_r.f);
    err &= (vr1_w.g[0] == vr1_r.g[0]);
    err &= (vr1_w.g[1] == vr1_r.g[1]);
    err &= (vr1_w.g[2] == vr1_r.g[2]);
    err &= (vr1_w.g[3] == vr1_r.g[3]);
    err &= DOUBLE_EQUAL(vr1_w.h, vr1_r.h);
    err &= (vr1_w.i[0] == vr1_r.i[0]);
    err &= (vr1_w.i[1] == vr1_r.i[1]);
    err &= (vr1_w.i[2] == vr1_r.i[2]);
    err &= (vr1_w.i[3] == vr1_r.i[3]);
    err &= (vr1_w.i[4] == vr1_r.i[4]);
    err &= (strcmp(vr1_w.j, vr1_r.j) == 0);
    err &= (vr1_w.k[0] == vr1_r.k[0]);
    err &= (vr1_w.k[1] == vr1_r.k[1]);
    err &= (vr1_w.k[2] == vr1_r.k[2]);
    err &= (vr1_w.k[3] == vr1_r.k[3]);
    err &= (vr1_w.k[4] == vr1_r.k[4]);
    err &= (vr1_w.k[5] == vr1_r.k[5]);

    if (err)
       PRINT(fp, "Alignments compare\n");
    else
       PRINT(fp, "Alignments differ\n");
    err_tot &= err;

    PRINT(fp, "\n");

    return(err_tot);}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* TEST_3 - test the PDBLib functions handling indirections
 *        - read and write structures with alignment difficulties
 *        - tests can be targeted
 */

static int test_3(base, tgt, n)
   char *base, *tgt;
   int n;
   {PDBfile *strm;
    char datfile[MAXLINE], fname[MAXLINE];
    int err;
    FILE *fp;

/* target the file is asked */
    test_target(tgt, base, n, fname, datfile);

    fp = fopen(fname, "w");

/* create the named file */
    if ((strm = PD_create(datfile)) == NULL)
       {PRINT(fp, "Test couldn't create file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s created\n", datfile);

    prep_test_3_data();

/* make a few defstructs */
    PD_defstr(strm, "st3",
              "char a",
              "short b",
              "char c[2]",
              "integer d",
              "char e[3]",
              "float f",
              "char g[4]",
              "double h",
              "char i[5]",
              "char *j",
              "char k[6]",
              LAST);

/* write the test data */
    write_test_3_data(strm);

/* close the file */
    if (!PD_close(strm))
       {PRINT(fp, "Test couldn't close file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s closed\n", datfile);

#ifdef LINUX
/* GOTCHA: Without this delay, the test fails about half the time,
 *         iff the files are being accessed across the network.
 */
    sleep(1);
#endif

/* reopen the file */
    if ((strm = PD_open(datfile, "r")) == NULL)
       {PRINT(fp, "Test couldn't open file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s opened\n", datfile);

/* dump the symbol table */
    dump_test_symbol_table(fp, strm->symtab, 3);

/* read the structs */
    read_test_3_data(strm);

/* compare the original data with that read in */
    err = compare_test_3_data(strm, fp);

/* close the file */
    if (!PD_close(strm))
       {PRINT(fp, "Test couldn't close file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s closed\n", datfile);

/* print out the results */
    print_test_3_data(fp);

/* clean up test data memory */
    cleanup_test_3();

    if (debug_mode)
       SC_mem_map(STDOUT, FALSE);

    fclose(fp);
    if (err)
       REMOVE(fname);

    return(err);}

/*--------------------------------------------------------------------------*/

/*                            TEST #4 ROUTINES                              */

/*--------------------------------------------------------------------------*/

/* PREP_TEST_4_DATA - prepare the test data */

static void prep_test_4_data()
   {char *pc;
    short *ps;
    int *pi;
    long *pl;
    float *pf;
    double *pd;
    hashel *hp;

    tab4_w = SC_make_hash_table(3, NODOC);

    CHAR_S   = SC_strsavef("char *", "char*:PREP_TEST_4_DATA:char");
    SHORT_S  = SC_strsavef("short *", "char*:PREP_TEST_4_DATA:short");
    INT_S    = SC_strsavef("integer *", "char*:PREP_TEST_4_DATA:integer");
    LONG_S   = SC_strsavef("long *", "char*:PREP_TEST_4_DATA:long");
    FLOAT_S  = SC_strsavef("float *", "char*:PREP_TEST_4_DATA:float");
    DOUBLE_S = SC_strsavef("double *", "char*:PREP_TEST_4_DATA:double");
    HASHEL_S = SC_strsavef("hashel *", "char*:PREP_TEST_4_DATA:hashel");

    pc  = FMAKE(char, "PREP_TEST_4_DATA:pc");
    *pc = 'A';   
    SC_install("pc", pc, CHAR_S, tab4_w);

    ps  = FMAKE(short, "PREP_TEST_4_DATA:ps");
    *ps = -1024;
    SC_install("ps", ps, SHORT_S, tab4_w);

    pi  = FMAKE(int, "PREP_TEST_4_DATA:pi");
    *pi = 16384;
    SC_install("pi", pi, INT_S, tab4_w);

    pl  = FMAKE(long, "PREP_TEST_4_DATA:pl");
    *pl = -1048576;
    SC_install("pl", pl, LONG_S, tab4_w);

    pf  = FMAKE(float, "PREP_TEST_4_DATA:pf");
    *pf = 3.141596;
    SC_install("pf", pf, FLOAT_S, tab4_w);

    pd  = FMAKE(double, "PREP_TEST_4_DATA:pd");
    *pd = -1.0e-30;
    hp = SC_install("pd", pd, DOUBLE_S, tab4_w);

    SC_install("ph", hp, HASHEL_S, tab4_w);

    tab4_r = NULL;

    vr4_w = FMAKE_N(st4, 3, "PREP_TEST_4_DATA:vr4_w");

    vr4_w[0].a =  2048;
    vr4_w[0].b =  'G';
    vr4_w[1].a = -2048;
    vr4_w[1].b =  'H';
    vr4_w[2].a =  4096;
    vr4_w[2].b =  'I';

    vr4_r = NULL;

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* CLEANUP_TEST_4 - free all known test data memory */

static void cleanup_test_4()
   {int i, sz;
    hashel **tb, *np, *nxt;

    sz = tab4_w->size;
    tb = tab4_w->table;
    for (i = 0; i < sz; i++)
        {for (np = tb[i]; np != NULL; np = nxt)
             {nxt = np->next;
              SFREE(np->def);
              SFREE(np->name);
              SFREE(np);};
         tb[i] = NULL;};
    SFREE(tb);
    SFREE(tab4_w);

    if (tab4_r != NULL)
       {sz = tab4_r->size;
        tb = tab4_r->table;
        for (i = 0; i < sz; i++)
            {for (np = tb[i]; np != NULL; np = nxt)
                 {nxt = np->next;
                  SFREE(np->def);
                  SFREE(np->type);
                  SFREE(np->name);
                  SFREE(np);};
             tb[i] = NULL;};
        SFREE(tb);
        SFREE(tab4_r);};

    SFREE(CHAR_S);
    SFREE(SHORT_S);
    SFREE(INT_S);
    SFREE(LONG_S);
    SFREE(FLOAT_S);
    SFREE(DOUBLE_S);
    SFREE(HASHEL_S);

    SFREE(vr4_w);
    SFREE(vr4_r);

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* WRITE_TEST_4_DATA - write out the data into the PDB file */

static void write_test_4_data(strm)
   PDBfile *strm;
   {if (!PD_write(strm, "tab4", "HASHTAB *", &tab4_w))
       {PRINT(STDOUT, "TAB4 WRITE FAILED - WRITE_TEST_4_DATA\n");
        exit(1);};
    if (!PD_write(strm, "vr4", "st4 *", &vr4_w))
       {PRINT(STDOUT, "VR4 WRITE FAILED - WRITE_TEST_4_DATA\n");
        exit(1);};

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* READ_TEST_4_DATA - read the test data from the file */

static int read_test_4_data(strm)
   PDBfile *strm;
   {int err;

    err = PD_read(strm, "tab4", &tab4_r);
    err = PD_read(strm, "vr4", &vr4_r);

    return(err);}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* PRINT_TEST_4_DATA - print it out to the file */

static void print_test_4_data(fp)
   FILE *fp;
   {char *pc, **names;
    short *ps;
    int *pi, i;
    long *pl;
    float *pf;
    double *pd;
    hashel *ph;

    names = SC_hash_dump(tab4_r, NULL);
    for (i = 0; i < tab4_r->nelements; i++)
        PRINT(fp, "%s\n", names[i]);
    SFREE(names);

    PRINT(fp, "\n");

    pc = (char *) SC_def_lookup("pc", tab4_r);
    ps = (short *) SC_def_lookup("ps", tab4_r);
    pi = (int *) SC_def_lookup("pi", tab4_r);
    pl = (long *) SC_def_lookup("pl", tab4_r);
    pf = (float *) SC_def_lookup("pf", tab4_r);
    pd = (double *) SC_def_lookup("pd", tab4_r);
    ph = (hashel *) SC_def_lookup("ph", tab4_r);

    PRINT(fp, "Table values:\n");
    PRINT(fp, "   pc = %c %s\n", *pc, CHAR_S);
    PRINT(fp, "   ps = %d %s\n", *ps, SHORT_S);
    PRINT(fp, "   pi = %d %s\n", *pi, INT_S);
    PRINT(fp, "   pl = %ld %s\n", *pl, LONG_S);
    PRINT(fp, "   pf = %f %s\n", *pf, FLOAT_S);
    PRINT(fp, "   pd = %e %s\n", *pd, DOUBLE_S);

    PRINT(fp, "\n   ph : %s %s\n\n", ph->name, ph->type);

    PRINT(fp, "VR4[0]:\n");
    PRINT(fp, "VR4[0].A = %d\n", vr4_r[0].a);
    PRINT(fp, "VR4[0].B = %c\n", vr4_r[0].b);
    PRINT(fp, "VR4[1].A = %d\n", vr4_r[1].a);
    PRINT(fp, "VR4[1].B = %c\n", vr4_r[1].b);
    PRINT(fp, "VR4[2].A = %d\n", vr4_r[2].a);
    PRINT(fp, "VR4[2].B = %c\n", vr4_r[2].b);

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* COMPARE_TEST_4_DATA - compare the test data */

static int compare_test_4_data(strm, fp)
   PDBfile *strm;
   FILE *fp;
   {int err, err_tot;
    int float_nm, double_nm;
    double float_tolerance, double_tolerance;
    char *pc_w, *pc_r;
    short *ps_w, *ps_r;
    int *pi_w, *pi_r;
    long *pl_w, *pl_r;
    float *pf_w, *pf_r;
    double *pd_w, *pd_r;
    hashel *ph_w, *ph_r;

    float_nm  = min(strm->std->float_format[2],
                    strm->host_std->float_format[2]);
    double_nm = min(strm->std->double_format[2],
                    strm->host_std->double_format[2]);

/* pad the absolute tolerance */
    float_tolerance  = POW(2.0, -((double) float_nm));
    double_tolerance = POW(2.0, -((double) double_nm));
    err_tot = TRUE;

    pc_r = (char *) SC_def_lookup("pc", tab4_r);
    ps_r = (short *) SC_def_lookup("ps", tab4_r);
    pi_r = (int *) SC_def_lookup("pi", tab4_r);
    pl_r = (long *) SC_def_lookup("pl", tab4_r);
    pf_r = (float *) SC_def_lookup("pf", tab4_r);
    pd_r = (double *) SC_def_lookup("pd", tab4_r);
    ph_r = (hashel *) SC_def_lookup("ph", tab4_r);

    pc_w = (char *) SC_def_lookup("pc", tab4_w);
    ps_w = (short *) SC_def_lookup("ps", tab4_w);
    pi_w = (int *) SC_def_lookup("pi", tab4_w);
    pl_w = (long *) SC_def_lookup("pl", tab4_w);
    pf_w = (float *) SC_def_lookup("pf", tab4_w);
    pd_w = (double *) SC_def_lookup("pd", tab4_w);
    ph_w = (hashel *) SC_def_lookup("ph", tab4_w);

/* compare offset and array */
    err  = TRUE;
    err &= (*pc_r == *pc_w);
    err &= (*ps_r == *ps_w);
    err &= (*pi_r == *pi_w);
    err &= (*pl_r == *pl_w);
    err &= FLOAT_EQUAL(*pf_r, *pf_w);
    err &= DOUBLE_EQUAL(*pd_r, *pd_w);

    if (err)
       PRINT(fp, "Hash tables compare\n");
    else
       PRINT(fp, "Hash tables differ\n");
    err_tot &= err;

/* compare hashel info */
    err  = TRUE;
    err &= (strcmp(ph_r->name, ph_w->name) == 0);
    err &= (strcmp(ph_r->type, ph_w->type) == 0);
    if (err)
       PRINT(fp, "Hashels compare\n");
    else
       PRINT(fp, "Hashels differ\n");
    err_tot &= err;

/* check the new alignments */
    err  = TRUE;
    err &= (vr4_w[0].a == vr4_r[0].a);
    err &= (vr4_w[0].b == vr4_r[0].b);
    err &= (vr4_w[1].a == vr4_r[1].a);
    err &= (vr4_w[1].b == vr4_r[1].b);
    err &= (vr4_w[2].a == vr4_r[2].a);
    err &= (vr4_w[2].b == vr4_r[2].b);

    if (err)
       PRINT(fp, "Alignments compare\n");
    else
       PRINT(fp, "Alignments differ\n");
    err_tot &= err;

    PRINT(fp, "\n");

    return(err_tot);}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* TEST_4 - test the PDBLib functions handling indirections
 *        - read and write structures with alignment difficulties
 *        - tests can be targeted
 */

static int test_4(base, tgt, n)
   char *base, *tgt;
   int n;
   {PDBfile *strm;
    char datfile[MAXLINE], fname[MAXLINE];
    int err;
    FILE *fp;

/* target the file as asked */
    test_target(tgt, base, n, fname, datfile);

    fp = fopen(fname, "w");

/* create the named file */
    strm = PD_create(datfile);
    if (strm == NULL)
       {PRINT(fp, "Test couldn't create file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s created\n", datfile);

    prep_test_4_data();

    strm->previous_file = SC_strsavef(base, "char*:TEST_4:prev");

/* make a few defstructs */
    PD_defstr(strm, "hashel",
              "char *name",
              "char *type",
              "char *def",
              "integer free",
              "hashel *next",
              LAST);

    PD_defstr(strm, "HASHTAB",
              "integer size",
              "integer nelements",
              "integer docp",
              "hashel **table",
              LAST);

    PD_defstr(strm, "st4",
              "short a",
              "char b",
              LAST);

    PD_cast(strm, "hashel", "def", "type");

/* write the test data */
    write_test_4_data(strm);

/* close the file */
    if (!PD_close(strm))
       {PRINT(fp, "Test couldn't close file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s closed\n", datfile);

/* reopen the file */
    strm = PD_open(datfile, "r");
    if (strm == NULL)
       {PRINT(fp, "Test couldn't open file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s opened\n", datfile);

/* dump the symbol table */
    dump_test_symbol_table(fp, strm->symtab, 4);

/* read the structs */
    read_test_4_data(strm);

/* compare the original data with that read in */
    err = compare_test_4_data(strm, fp);

/* print out the results */
    print_test_4_data(fp);

/* close the file */
    if (!PD_close(strm))
       {PRINT(fp, "Test couldn't close file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s closed\n", datfile);

/* clean up test data memory */
    cleanup_test_4();

    if (debug_mode)
       SC_mem_map(STDOUT, FALSE);

    fclose(fp);
    if (err)
       REMOVE(fname);

    return(err);}

/*--------------------------------------------------------------------------*/

/*                            TEST #5 ROUTINES                              */

/*--------------------------------------------------------------------------*/

/* PREP_TEST_5_DATA - prepare the test data */

static void prep_test_5_data()
   {int i, *p1, *p2;
    double *p3, *p4;

    for (i = 0; i < N_INT; i++)
        {p_w[i] = i;
         p_r[i] = 0;};

    tar_w = FMAKE_N(lev1, 2, "PREP_TEST_5_DATA:tar_w");

    p1 = tar_w[0].a = FMAKE_N(int, N_INT, "PREP_TEST_5_DATA:tar_w[0].a");
    p2 = tar_w[1].a = FMAKE_N(int, N_INT, "PREP_TEST_5_DATA:tar_w[1].a");
    for (i = 0; i < N_INT; i++)
        {p1[i] = i;
         p2[i] = i + 10;};

    p3 = tar_w[0].b = FMAKE_N(double, N_DOUBLE,
                              "PREP_TEST_5_DATA:tar_w[0].b");
    p4 = tar_w[1].b = FMAKE_N(double, N_DOUBLE,
                              "PREP_TEST_5_DATA:tar_w[1].b");
    for (i = 0; i < N_DOUBLE; i++)
        {p3[i] = exp((double) i);
         p4[i] = log(1.0 + (double) i);};

    tar_w[0].c = NULL;
    tar_w[1].c = NULL;

    memset(tar5_t, 0, 4*sizeof(lev1));
    memset(tar5_r, 0, 4*sizeof(lev1));

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* CLEANUP_TEST_5 - free all known test data memory */

static void cleanup_test_5()
   {int l;

    if (tar_w != NULL)
       {SFREE(tar_w[0].a);
        SFREE(tar_w[1].a);

        SFREE(tar_w[0].b);
        SFREE(tar_w[1].b);

        SFREE(tar_w);};

    for (l = 0; l < 4; l++)
       {SFREE(tar5_t[l].a);
        SFREE(tar5_t[l].b);

        SFREE(tar5_r[l].a);
        SFREE(tar5_r[l].b);};

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* WRITE_TEST_5_DATA - write out the data into the PDB file */

static void write_test_5_data(strm)
   PDBfile *strm;
   {

    if (!PD_write(strm, "tar(2)", "lev1", tar_w))
       {PRINT(STDOUT, "TAR WRITE FAILED - WRITE_TEST_5_DATA\n");
        exit(1);};

    if (!PD_append(strm, "tar(2:3)", tar_w))
       {PRINT(STDOUT, "TAR APPEND FAILED - WRITE_TEST_5_DATA\n");
        exit(1);};

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* READ_TEST_5_DATA - read the test data from the file */

static int read_test_5_data(strm)
   PDBfile *strm;
   {int err;

    err = PD_read(strm, "tar", tar5_t);
    err = PD_read(strm, "tar(0)", tar5_r);
    err = PD_read(strm, "tar(1)", tar5_r+1);
    err = PD_read(strm, "tar(2)", tar5_r+2);
    err = PD_read(strm, "tar(3)", tar5_r+3);

    return(err);}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* PRINT_TEST_5_DATA - print it out to the file */

static void print_test_5_data(fp)
   FILE *fp;
   {int i;
    int *p0, *p1, *p2, *p3;
    double *p4, *p5, *p6, *p7;

    PRINT(fp, "\n");

    p0 = tar5_t[0].a;
    p1 = tar5_t[1].a;
    p2 = tar5_t[2].a;
    p3 = tar5_t[3].a;
    PRINT(fp, "TAR struct member A:\n");
    PRINT(fp, "    TAR[0].A    TAR[1].A    TAR[2].A    TAR[3].A\n");
    for (i = 0; i < N_INT; i++)
        PRINT(fp, "        %d          %d        %d          %d\n",
	      p0[i], p1[i], p2[i], p3[i]);
    PRINT(fp, "\n");

    p4 = tar5_t[0].b;
    p5 = tar5_t[1].b;
    p6 = tar5_t[2].b;
    p7 = tar5_t[3].b;
    PRINT(fp, "TAR struct member B:\n");
    PRINT(fp, "    TAR[0].B    TAR[1].B    TAR[2].B    TAR[3].B\n");
    for (i = 0; i < N_DOUBLE; i++)
        PRINT(fp, "    %f    %f    %f    %f\n",
	      p4[i], p5[i], p6[i], p7[i]);
    PRINT(fp, "\n");

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* COMPARE_TEST_5_DATA - compare the test data */

static int compare_test_5_data(strm, fp)
   PDBfile *strm;
   FILE *fp;
   {int i, l, *p1w, *p2w, *p1r, *p2r;
    double *p3w, *p4w, *p3r, *p4r;
    int err, err_tot;
    int double_nm;
    double double_tolerance;

    double_nm = min(strm->std->double_format[2],
                    strm->host_std->double_format[2]);

/* pad the absolute tolerance */
    double_tolerance = POW(2.0, -((double) double_nm));
    err_tot = TRUE;

    err = TRUE;
    p1w = tar_w[0].a;
    p2w = tar_w[1].a;
    p3w = tar_w[0].b;
    p4w = tar_w[1].b;

    for (l = 0; l < 2; l++)
        {p1r = tar5_t[2*l].a;
	 p2r = tar5_t[2*l+1].a;
	 for (i = 0; i < N_INT; i++)
	     {err &= (p1w[i] == p1r[i]);
	      err &= (p2w[i] == p2r[i]);};

	 p3r = tar5_t[2*l].b;
	 p4r = tar5_t[2*l+1].b;
	 for (i = 0; i < N_DOUBLE; i++)
	     {err &= DOUBLE_EQUAL(p3w[i], p3r[i]);
	      err &= DOUBLE_EQUAL(p4w[i], p4r[i]);};};

    for (l = 0; l < 2; l++)
        {p1r = tar5_r[2*l].a;
	 p2r = tar5_r[2*l+1].a;
	 for (i = 0; i < N_INT; i++)
	     {err &= (p1w[i] == p1r[i]);
	      err &= (p2w[i] == p2r[i]);};

	 p3r = tar5_r[2*l].b;
	 p4r = tar5_r[2*l+1].b;
	 for (i = 0; i < N_DOUBLE; i++)
	     {err &= DOUBLE_EQUAL(p3w[i], p3r[i]);
	      err &= DOUBLE_EQUAL(p4w[i], p4r[i]);};};

    PRINT(fp, "\n");

    return(err_tot);}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* TEST_5 - test the PDBLib functions handling indirections and appends
 *        - read and write structures with alignment difficulties
 *        - tests can be targeted
 */

static int test_5(base, tgt, n)
   char *base, *tgt;
   int n;
   {PDBfile *strm;
    char datfile[MAXLINE], fname[MAXLINE];
    int err;
    FILE *fp;

/* target the file as asked */
    test_target(tgt, base, n, fname, datfile);

    fp = fopen(fname, "w");

/* create the named file */
    strm = PD_create(datfile);
    if (strm == NULL)
       {PRINT(fp, "Test couldn't create file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s created\n", datfile);

    prep_test_5_data();

    strm->previous_file = SC_strsavef(base, "char*:TEST_5:prev");

/* make a few defstructs */
    PD_defstr(strm, "lev1",
              "integer *a",
	      "double *b",
	      "char *c",
              LAST);

/* write the test data */
    write_test_5_data(strm);

/* close the file */
    if (!PD_close(strm))
       {PRINT(fp, "Test couldn't close file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s closed\n", datfile);

/* reopen the file */
    strm = PD_open(datfile, "r");
    if (strm == NULL)
       {PRINT(fp, "Test couldn't open file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s opened\n", datfile);

/* read the structs */
    read_test_5_data(strm);

/* compare the original data with that read in */
    err = compare_test_5_data(strm, fp);

/* print out the results */
    print_test_5_data(fp);

/* close the file */
    if (!PD_close(strm))
       {PRINT(fp, "Test couldn't close file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s closed\n", datfile);

/* clean up test data memory */
    cleanup_test_5();

    if (debug_mode)
       SC_mem_map(STDOUT, FALSE);

    fclose(fp);
    if (err)
       REMOVE(fname);

    return(err);}

/*--------------------------------------------------------------------------*/

/*                            TEST #6 ROUTINES                              */

/*--------------------------------------------------------------------------*/

/* PREP_TEST_6_DATA - prepare the test data */

static void prep_test_6_data()
   {int i, n;
    double *p1, *p2;

    n = 10;

    d61_w    = FMAKE(st61, "PREP_TEST_6_DATA:d61_w");
    d61_w->n = n;

    d62_w    = FMAKE(st62, "PREP_TEST_6_DATA:d62_w");
    d62_w->n = n;
    d62_w->a = FMAKE_N(double, n, "PREP_TEST_6_DATA:a");

    p1 = d61_w->a;
    p2 = d62_w->a;
    for (i = 0; i < n; i++)
        {p1[i] = 0.1*((double) i);
         p2[i] = -0.1*((double) i);};

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* CLEANUP_TEST_6 - free all known test data memory */

static void cleanup_test_6()
   {

    if (d61_w != NULL)
       SFREE(d61_w);

    if (d62_w != NULL)
       {SFREE(d62_w->a);
	SFREE(d62_w);};

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* WRITE_TEST_6_DATA - write out the data into the PDB file */

static void write_test_6_data(strm)
   PDBfile *strm;
   {

    if (!PD_write(strm, "d61", "st61", d61_w))
       {PRINT(STDOUT, "D61 WRITE FAILED - WRITE_TEST_6_DATA\n");
        exit(1);};

    if (!PD_write(strm, "d62", "st62", d62_w))
       {PRINT(STDOUT, "D62 WRITE FAILED - WRITE_TEST_6_DATA\n");
        exit(1);};

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* READ_TEST_6_DATA - read the test data from the file */

static int read_test_6_data(strm)
   PDBfile *strm;
   {int err;

    err = PD_read_as_dwim(strm, "d61.a", "float", 10, d61_a);
    err = PD_read_as_dwim(strm, "d62.a", "float", 10, d62_a);
    err = PD_read_as_dwim(strm, "d62.a", "float",  8, d62_s);

    return(err);}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* PRINT_TEST_6_DATA - print it out to the file */

static void print_test_6_data(fp)
   FILE *fp;
   {int i, n;

    n = d61_w->n;

    PRINT(fp, "\n");

    PRINT(fp, "D61 struct member A:\n");
    for (i = 0; i < n; i++)
        PRINT(fp, "%3d %5.2f\n", i, d61_a[i]);
    PRINT(fp, "\n");

    PRINT(fp, "D62 struct member A:\n");
    for (i = 0; i < n; i++)
        PRINT(fp, "%3d %5.2f\n", i, d62_a[i]);
    PRINT(fp, "\n");

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* COMPARE_TEST_6_DATA - compare the test data */

static int compare_test_6_data(strm, fp)
   PDBfile *strm;
   FILE *fp;
   {int i, n;
    int err, err_tot;
    int float_nm;
    float fc1, fc2;
    double *p1w, *p2w;
    double float_tolerance;

    float_nm = min(strm->std->float_format[2],
		   strm->host_std->float_format[2]);

/* pad the absolute tolerance */
    float_tolerance = POW(2.0, -((double) float_nm));
    err_tot = TRUE;

    err = TRUE;
    p1w = d61_w->a;
    p2w = d62_w->a;

    n = d61_w->n;

    for (i = 0; i < n; i++)
        {fc1 = p1w[i];
	 fc2 = p2w[i];
	 err &= FLOAT_EQUAL(fc1, d61_a[i]);
	 err &= FLOAT_EQUAL(fc2, d62_a[i]);};

    err_tot &= err;

    n -= 2;
    for (i = 0; i < n; i++)
        {fc2 = p2w[i];
	 err &= FLOAT_EQUAL(fc2, d62_s[i]);};

    err_tot &= err;

    PRINT(fp, "\n");

    return(err_tot);}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* TEST_6 - test the PDBLib function PD_read_as_dwim */

static int test_6(base, tgt, n)
   char *base, *tgt;
   int n;
   {PDBfile *strm;
    char datfile[MAXLINE], fname[MAXLINE];
    int err;
    FILE *fp;

/* target the file as asked */
    test_target(tgt, base, n, fname, datfile);

    fp = fopen(fname, "w");

/* create the named file */
    strm = PD_create(datfile);
    if (strm == NULL)
       {PRINT(fp, "Test couldn't create file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s created\n", datfile);

    prep_test_6_data();

/* make a few defstructs */
    PD_defstr(strm, "st61",
              "int n",
	      "double a[10]",
              LAST);

    PD_defstr(strm, "st62",
              "int n",
	      "double *a",
              LAST);

/* write the test data */
    write_test_6_data(strm);

/* close the file */
    if (!PD_close(strm))
       {PRINT(fp, "Test couldn't close file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s closed\n", datfile);

/* reopen the file */
    strm = PD_open(datfile, "r");
    if (strm == NULL)
       {PRINT(fp, "Test couldn't open file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s opened\n", datfile);

/* read the structs */
    read_test_6_data(strm);

/* compare the original data with that read in */
    err = compare_test_6_data(strm, fp);

/* print out the results */
    print_test_6_data(fp);

/* close the file */
    if (!PD_close(strm))
       {PRINT(fp, "Test couldn't close file %s\r\n", datfile);
        exit(2);};
    PRINT(fp, "File %s closed\n", datfile);

/* clean up test data memory */
    cleanup_test_6();

    if (debug_mode)
       SC_mem_map(STDOUT, FALSE);

    fclose(fp);
    if (err)
       REMOVE(fname);

    return(err);}

/*--------------------------------------------------------------------------*/

/*                              DRIVER ROUTINES                             */

/*--------------------------------------------------------------------------*/

/* RUN_TEST - run a particular test through all targeting modes */

static void run_test(test, n, host)
   PFInt test;
   int n;
   char *host;
   {int cs;
    long bytaa, bytfa, bytab, bytfb;
    char s[MAXLINE], msg[MAXLINE];
    double time;
    static int debug = 0;

/* NOTE: under the debugger set debug to 1 or 2 for additional
 *       memory leak monitoring
 */
    cs = SC_mem_monitor(0, debug, "B", msg);

    SC_mem_stats(&bytab, &bytfb, NULL, NULL);

    time = SC_wall_clock_time();

    if (!native_only)

/* Cray target test */
       {strcpy(s, "cray");
        if (!(*test)(host, s, n))
           PRINT(STDOUT, "Test #%d %s failed\n", n, s);

/* Sun4 target test */
        strcpy(s, "sun4");
        if (!(*test)(host, s, n))
           PRINT(STDOUT, "Test #%d %s failed\n", n, s);

/* Mips target test */
        strcpy(s, "mips");
        if (!(*test)(host, s, n))
           PRINT(STDOUT, "Test #%d %s failed\n", n, s);

/* Mips64 target test */
        strcpy(s, "mips64");
        if (!(*test)(host, s, n))
           PRINT(STDOUT, "Test #%d %s failed\n", n, s);

/* Alpha64 target test */
        strcpy(s, "alpha64");
        if (!(*test)(host, s, n))
           PRINT(STDOUT, "Test #%d %s failed\n", n, s);

/* Dos target test */
        strcpy(s, "dos");
        if (!(*test)(host, s, n))
           PRINT(STDOUT, "Test #%d %s failed\n", n, s);

/* Macintosh target test */
        strcpy(s, "mac");
        if (!(*test)(host, s, n))
           PRINT(STDOUT, "Test #%d %s failed\n", n, s);

/* Sun3 target test */
        strcpy(s, "sun3");
        if (!(*test)(host, s, n))
           PRINT(STDOUT, "Test #%d %s failed\n", n, s);

/* Vax target test */
        strcpy(s, "vax");
        if (!(*test)(host, s, n))
           PRINT(STDOUT, "Test #%d %s failed\n", n, s);};

/* native test */
    if (!(*test)(host, NULL, n))
       PRINT(STDOUT, "Test #%d native failed\n", n);

    SC_mem_stats(&bytaa, &bytfa, NULL, NULL);

    bytaa -= bytab;
    bytfa -= bytfb;
    time   = SC_wall_clock_time() - time;

    cs = SC_mem_monitor(cs, debug, "B", msg);

    PRINT(STDOUT,
          "\t\t     %3d     %7d   %7d   %7d     %.2g\n",
          n, bytaa, bytfa, bytaa - bytfa, time);

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* PRINT_HELP - print a help message */

static void print_help()
   {PRINT(STDOUT, "\nPDTEST - run basic PDB test suite\n\n");
    PRINT(STDOUT, "Usage: pdtest [-d] [-h] [-n] [-1] [-2] [-3] [-4] [-5] [-6]\n");
    PRINT(STDOUT, "\n");
    PRINT(STDOUT, "       d - turn on debug mode to display memory maps\n");
    PRINT(STDOUT, "       h - print this help message and exit\n");
    PRINT(STDOUT, "       n - run native mode test only\n");
    PRINT(STDOUT, "       1 - do NOT run test #1\n");
    PRINT(STDOUT, "       2 - do NOT run test #2\n");
    PRINT(STDOUT, "       3 - do NOT run test #3\n");
    PRINT(STDOUT, "       4 - do NOT run test #4\n");
    PRINT(STDOUT, "       5 - do NOT run test #5\n");
    PRINT(STDOUT, "       6 - do NOT run test #6\n");
    PRINT(STDOUT, "\n");

    return;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* MAIN - test the PDB Library system */

int main(argc, argv)
   int argc;
   char **argv;
   {int i;
    int test_one, test_two, test_three, test_four, test_five, test_six;

    PD_init_threads(1, NULL);

    SC_zero_space(0);
    debug_mode  = FALSE;
    native_only = FALSE;
    test_one    = TRUE;
    test_two    = TRUE;
    test_three  = TRUE;
    test_four   = TRUE;
    test_five   = TRUE;
    test_six    = TRUE;
    for (i = 1; i < argc; i++)
        {if (argv[i][0] == '-')
            {switch (argv[i][1])
                {case 'd' : debug_mode  = TRUE;
                            SC_mm_debug = TRUE;
                            break;
                 case 'h' : print_help();
                            return(1);
                 case 'n' : native_only = TRUE;
                            break;
                 case '1' : test_one = FALSE;
                            break;
                 case '2' : test_two = FALSE;
                            break;
                 case '3' : test_three = FALSE;
                            break;
                 case '4' : test_four = FALSE;
                            break;
                 case '5' : test_five = FALSE;
                            break;
                 case '6' : test_six = FALSE;
                            break;};}
         else
            break;};

    SIGNAL(SIGINT, SIG_DFL);

    if (PD_DEFSTR_S == NULL)
       {LAST        = FMAKE(int, "MAIN:LAST");
        *LAST       = 0;
        PD_DEFSTR_S = SC_strsavef("defstr *", "char*:PDBTST:defstr");
        PD_SYMENT_S = SC_strsavef("syment *", "char*:PDBTST:syment");};

    PRINT(STDOUT, "\n");
    PRINT(STDOUT, "\t\t                      Memory                Time\n");
    PRINT(STDOUT, "\t\t                     (bytes)               (secs)\n");
    PRINT(STDOUT, "\t\t     Test  Allocated     Freed      Diff\n");

    if (test_one)
       run_test(test_1, 1, DATFILE);
    if (test_two)
       run_test(test_2, 2, DATFILE);
    if (test_three)
       run_test(test_3, 3, DATFILE);
    if (test_four)
       run_test(test_4, 4, DATFILE);
    if (test_five)
       run_test(test_5, 5, DATFILE);
    if (test_six)
       run_test(test_6, 6, DATFILE);

    PRINT(STDOUT, "\n");

    SFREE(LAST);
    SFREE(PD_DEFSTR_S);
    SFREE(PD_SYMENT_S);

    return(0);}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
