/*ScianPreInstall.c
  Eric Pepke
  October 10, 1991
  Pre-installation program for SciAn
*/

#include <stdio.h>
#include "machine.h"

#if (MACHINE == CRAYYMP) || (MACHINE == CONVEX)
/*fgets doesn't work properly on stdin*/
#define FGETS_IS_SO_STUPID
#endif

int okSoFar = 1;

#define MAXLINE		400
char curLine[MAXLINE + 1];		/*Current line read from console or file*/
char linkLine[MAXLINE + 1];		/*Link flags line*/
char compLine[MAXLINE + 1];		/*Compilation flags line*/
char tempStr[MAXLINE + 1];		/*Temporary string*/

/*File names*/
#define LINKMAKEFILE	"lfiles.make"	/*File containing link flags*/

/*Library directories to search*/
char *libDir[] =
    {
	"/lib",
	"/usr/lib",
	"/usr/local/lib"
    };

#define NYESSTRINGS	6

/*Strings that count as "yes"*/
char *yesStrings[NYESSTRINGS] =
    {
	"y",
	"yes",
	"yeah",
	"yep",
	"ok",
	"sure"
    };

#define NNOSTRINGS	4

/*Strings that count as "no"*/
char *noStrings[NNOSTRINGS] = 
    {
	"n",
	"no",
	"nah",
	"nope"
    };

void CopyFile(source, dest)
char *source, *dest;
/*Copies a file source to dest; blows up if it can't*/
{
    FILE *inFile, *outFile;

    inFile = fopen(source, "r");
    if (!inFile)
    {
	perror("ScianPreInstall");
	exit(-1);
    }
    outFile = fopen(dest, "w");
    if (!inFile)
    {
	perror("ScianPreInstall");
	exit(-1);
    }
    while (fgets(curLine, MAXLINE, inFile))
    {
	fputs(curLine, outFile);
    }
    fclose(inFile);
    fclose(outFile);
}

void ReadFirstLine(fileName, s)
char *fileName, *s;
/*Reads first line of fileName into s; blows up if it can't*/
{
    FILE *inFile;
    int k;

    inFile = fopen(fileName, "r");
    if (!inFile)
    {
	perror("ScianPreInstall");
	exit(-1);
    }
    fgets(s, MAXLINE, inFile);
    fclose(inFile);

    /*Take the newline off the end*/
    for (k = 0; s[k] && s[k] != '\n'; ++k);
    s[k] = 0;
}

void EmitLinks()
/*Emits the link commands.  If it fails, blows up.*/
{
    FILE *outFile;

    /*Terminate links with a newline*/
    strcat(linkLine, "\n");

    /*Emit them into the file*/
    outFile = fopen(LINKMAKEFILE, "w");
    if (!outFile)
    {
	perror("ScianPreInstall");
	exit(-1);
    }
    fputs(linkLine, outFile);
    fclose(outFile);
}

void FailAbort()
/*Fails and aborts*/
{
    printf("After you have made the changes to 'machine.h,' please try 'make INSTALL'\n");
    printf("once more.\n");
    exit(-1);
}

int YorNp()
/*Asks for an answer to a yes-or-no question*/
{
    char *s, *t;
    int k;

    for (;;)
    {
#if FGETS_IS_SO_STUPID
	gets(curLine);
#else
	fgets(curLine, MAXLINE, stdin);
#endif
	s = curLine;
	while (*s && isspace(*s)) ++s;
	t = s;

	while (isalpha(*t)) *t++ = tolower(*t);
	*t = 0;

	for (k = 0; k < NYESSTRINGS; ++k)
	{
	    if (0 == strcmp(s, yesStrings[k])) return 1;
	}
	for (k = 0; k < NNOSTRINGS; ++k)
	{
	    if (0 == strcmp(s, noStrings[k])) return 0;
	}
	printf("Please answer yes or no: ");
    }
}

void GuessMachine()
/*Guesses the machine type*/
{
#if MACHINE == IRIS4D
    printf("Your computer appears to be a Silicon Graphics IRIS.\n");
#else
#if MACHINE == RS6000
    printf("Your computer appears to be an IBM RISC computer.\n");
#else
#if MACHINE == GENCOMP
    printf("Your computer appears to be a generic computational node.\n");
#else
    printf("The type of your computer could not be determined.  You will need to enter it\n");
    printf("by hand.  Please edit the file 'machine.h' and look for the defined constant\n");
    printf("MACHINE.\n\n");
    FailAbort();
#endif
#endif
#endif
    printf("Is this correct? ");
    if (!YorNp())
    {
	printf("\nYou will need to enter the type of your computer by hand.  Please edit the\n");
	printf("file 'machine.h' and look for the defined constant MACHINE.\n\n");
	FailAbort();
    }
#if MACHINE == RS6000
    printf("* * * * * * * * * WARNING * * * * * * * * *\n");
    printf("Not all versions of the IBM RS/6000 support SciAn.  In order to run,\n");
    printf("your system MUST have one of the graphics cards that support the GL library,\n");
    printf("and it MUST be equipped with a Z-buffer.  If this is not the case, SciAn\n");
    printf("will compile fine, but it will give an error when you try to run it.\n\n");


    ReadFirstLine("lfiles.ibm6k.make", linkLine);
    CopyFile("flags.ibm6k.make", "flags.make");
#else
#if MACHINE == IRIS4D
    ReadFirstLine("lfiles.sgi4d.make", linkLine);
    CopyFile("flags.sgi4d.make", "flags.make");
#else
#if MACHINE == GENCOMP
    ReadFirstLine("lfiles.gencomp.make", linkLine);
    CopyFile("flags.gencomp.make", "flags.make");
#else
#endif
#endif
#endif
    printf("\n");
}

void FindMalloc()
/*Finds the malloc library according to MALLOCH and appends the string to lfiles*/
{
    int requested, found;
    int k;

    /*See if the faster malloc library has been requested*/
#ifdef MALLOCH
    requested = 1;
#else
    requested = 0;
#endif

    /*See if the library can be found*/
    found = 0;
    for (k = 0; k < sizeof(libDir) / sizeof(char *); ++k)
    {
	FILE *temp;
	sprintf(tempStr, "%s/lib%s.a", libDir[k], LIBMALLOC);
	temp = fopen(tempStr, "r");
	if (temp)
	{
	    found = 1;
	    fclose(temp);
	    break;
	}
    }

    if (requested && found)
    {
	printf("The fast malloc library will be used.\n\n");
    }
    else if (!requested && !found)
    {
	printf("The standard malloc library will be used.\n\n");
    }
    else if (requested && !found)
    {
	printf("The fast malloc library is specified in 'machine.h' but could not be found\n\
in the library search path.  SciAn will not compile and link until you either\n\
remove the define of MALLOCH from 'machine.h' or install the faster malloc\n\
library 'lib%s.a' on your computer.\n\n", LIBMALLOC);
	okSoFar = 0;
    }
    else if (!requested && found)
    {
	printf("The fast malloc library appears to be available on your machine, but it is\n\
not specified in the 'machine.h' include file.  You may wish to consider using\n\
the library, as it can speed up SciAn quite a bit.  To use the library, edit\n\
'machine.h' and look for the constant MALLOCH.\n\n");
    }

    if (requested)
    {
	sprintf(tempStr, " -l%s", LIBMALLOC);
	strcat(linkLine, tempStr);
    }
}

void FindHDF()
/*Finds the NCSA HDF library according to HDFDEF and appends the string to lfiles*/
{
    int requested, found;
    int k;

    /*See if the HDF library has been requested*/
#ifdef HDFDEF
    requested = 1;
#else
    requested = 0;
#endif

    /*See if the library can be found*/
    found = 0;
    for (k = 0; k < sizeof(libDir) / sizeof(char *); ++k)
    {
	FILE *temp;
	sprintf(tempStr, "%s/lib%s.a", libDir[k], LIBHDF);
	temp = fopen(tempStr, "r");
	if (temp)
	{
	    found = 1;
	    fclose(temp);
	    break;
	}
    }

    if (requested && found)
    {
	printf("The NCSA HDF library will be used.\n\n");
    }
    else if (!requested && !found)
    {
	printf("The NCSA HDF library will not be used.\n\n");
    }
    else if (requested && !found)
    {
	printf("The NCSA HDF library is specified in 'machine.h' but could not be found\n\
in the library search path.  SciAn will not compile and link until you either\n\
remove the define of HDFDEF from 'machine.h' or install the NCSA HDF library\n\
'lib%s.a' on your computer.  The HDF library is available via anonymous\n\
ftp from the fine folks at the National Center for Supercomputing Applications\n\
at the University of Illinois at Champaign-Urbana.\n\n", LIBHDF);
	okSoFar = 0;
    }
    else if (!requested && found)
    {
	printf("The NCSA HDF library appears to be available on your machine, but it is\n\
not specified in the 'machine.h' include file.  You may wish to consider using\n\
the library, as it gives you the ability to read scientific data sets in the \n\
HDF format.  To use the library, edit 'machine.h' and look for the constant\n\
HDFDEF.\n\n");
    }

    if (requested)
    {
	sprintf(tempStr, " -l%s", LIBHDF);
	strcat(linkLine, tempStr);
    }
}

main()
{
    printf("\nScianPreInstall version 0.3 by Eric Pepke\n\n");
    printf("The way SciAn will be compiled on your computer depends mostly on predefined\n");
    printf("symbols and various flags defined in the 'machine.h' include file.  This\n");
    printf("program determines whether 'machine.h' is consistent with the characteristics\n");
    printf("of your computer and tells you what to do if they are not.\n\n");
    
    GuessMachine();

    FindMalloc();

    FindHDF();
    
    if (!okSoFar)
    {
	FailAbort();
    }

    EmitLinks();

    printf("The link commands should now be set up properly.  To make SciAn, enter\n");
    printf("make scian\n\n");
#if MACHINE == IRIS4D
    printf("If you have more than one processor on your computer, use pmake\n");
    printf("instead of make to speed things up.\n\n");
#endif
    exit(0);
}
