Metropoli BBS
VIEWER: gfft.c MODE: TEXT (ASCII)
/***************************************************************************
 *		  Copyright (C) 1994  Charles P. Peterson                  *
 *	     4007 Enchanted Sun, San Antonio, Texas 78244-1254             *
 *              Email: Charles_P_Peterson@fcircus.sat.tx.us                *
 *                                                                         *
 *		  This is free software with NO WARRANTY.                  *
 *			  See below for details.                           *
 *		      Support is available for a fee.                      *
 ***************************************************************************
 *
 * Program:     gfft--General FFT analysis
 * File:        gfft.c
 * Purpose:     main() function--get args and/or commands
 * Author:      Charles Peterson (CPP)
 * History:     27-May-1993 CPP; Created.
 *              6-July-1994 CPP (0.74); allow simultaneous MORE sessions
 *              21-July-1994 CPP (1.02); remove "delete failed..." msgs
 *              19-Jan-1995 CPP (1.20); Workbench mode is default
 *              20-Jan-1995 CPP; (1.23) Use Icon Tooltypes
 *              10-Feb-1995 CPP; (1.36) Allow interrupt from CLI
 *              11-Feb-1995 CPP; (1.40) LoadSettings command
 */

/*
 *  Copyright (C) 1994  Charles P. Peterson
 *  4007 Enchanted Sun, San Antonio, TX 78244-1254
 *  Email: Charles_P_Peterson@fcircus.sat.tx.us
 *
 *  Please refer to the README file included in this distribution
 *  concerning low-cost support and update services available from the
 *  author, as well as encouragement to make suggestions, bug reports,
 *  usage reports, enhancement requests, donations, equipment loans, and
 *  ports to different systems.  If the README files is unavailable, Email
 *  or send a SASE to the author (address above).  A limited amount of free
 *  help may also be available by Email or mail (SASE required).  If
 *  address has changed, try finding the most recent distribution.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  The
 *  GNU General Public License should be in a file named 'COPYING'.
 *  Do not contact the Free Software Foundation for any other information
 *  about this program; contact the author instead.
 *
 */

#include <stdlib.h>    /* exit(), system() */
#include <stdio.h>     /* printf()   */
#include <dos.h>       /* _CXBRK */
#include <math.h>      /* _CXFERR */
#include <string.h>
#include <ctype.h>     /* tolower() */

#define DEFINE_HERE
#include "gfft.h"
#undef DEFINE_HERE
#include "settings.h"

extern Name_Info_St Gfft_Command[];  /* GFFT commands */

char *StartupPathList[] = STARTUP_PATH_LIST;  /* From Xdef.h where X is sys */

static void cleanup (void);
static void delete_temp_files (void);
static BOOLEAN cli_string (char *string);
static void startup_error_trap (void);
static void execute_Command (void (*error_trap)(void));


#define CLI_ARG (argc == 2  &&  cli_string (argv[1]))

void main (int argc, char *argv[])
{

    CATCH_ERROR  /* This is the ultimate safety net */
    {

	startup_cli_file ();

/**************************************************************************\
 * Workbench Mode                                                         *
\**************************************************************************/

#ifdef AMIGA

	if (argc <= 1)
	{
	    CommandMode = WORKBENCH_MODE;
	    Plot = ANY_PLOT;
	    workbench_main ();  /* Failures gabort() directly */
	    quit (NullString);  /* Successful exit */
	}

#endif

/**************************************************************************\
 * CLI-Batch Mode                                                         *
\**************************************************************************/

	if (argc > 1 && !CLI_ARG)
	{
        /*
         * This is a non-interactive (i.e. batch) session
         * qabort on error (indicated by longjmp).
         */
	    CommandMode = BATCH_MODE;
	    Plot = NO_PLOT;
	    CATCH_ERROR
	    {
		batch_command (argc, argv);
		quit (NullString);
	    }
	    ON_ERROR
	    {
		gabort (EXIT_FAILURE);
	    }
	    END_CATCH_ERROR;

	} /* End of batch session handling */

/**************************************************************************\
 * CLI-Interactive Mode (gets called from here)                           *
\**************************************************************************/

	Plot = ANY_PLOT;
	banner_message (NullString);
	cli_interactive_loop (TRUE);

/* Shouldn't get here; quit() or gabort() are called somewhere to exit */
    }

#ifdef _DEBUG
    ON_ERROR
    {
    /*
     * WARNING!  Do not put any code (or calls) here which could possibly
     * raise an error.  If it does, the 'ultimate' safety net will be
     * leaky, and a system crash could result!
     */
	fprintf (stderr,"\nWarning.  Error caught by safety net.\n");
    }
#endif /* ifdef _DEBUG */

    END_CATCH_ERROR;  /* End of the ultimate safety net. */

/* Shouldn't get here; quit() or gabort() are called somewhere to exit */

}


/**************************************************************************\
 * CLI-Interactive Mode (implemented here)                                *
\**************************************************************************/

void cli_interactive_loop (BOOLEAN started_from_cli)
{
    int previous_command_mode = CommandMode;

    CommandMode = INTERACTIVE_MODE;
    while (started_from_cli || CommandMode == INTERACTIVE_MODE)
    {
	Interrupt_Count = 0;
	prompt_command ();  /* Might gabort() from here on EOF */
	CATCH_ERROR
	{
	    invoke_method (Command, Gfft_Command);
	}
	END_CATCH_ERROR;  /* We don't break loop on error here */
    }
    CommandMode = previous_command_mode;
}


void startup_cli_file ()
{
    FILE * startup_file_ptr = NULL;

    if ( startup_file_ptr = gopen (StartupPathList, ".gfft", "r"))
    {
	execute_file_commands (startup_file_ptr);
	fclose (startup_file_ptr);
    }
}

void execute_file_commands (FILE *fptr)
{
    int previous_command_mode = CommandMode;
    char *next_command = Command;

    CommandMode = BATCH_MODE;

    while (next_command)
    {
	next_command = fgets (Command, COMMAND_BUFFER_SIZE, fptr);
	if (next_command)
	{
	    execute_Command (startup_error_trap);
	}
    }
    CommandMode = previous_command_mode;
}


void execute_command_line (char *command_line, void (*error_trap)(void))
{
    strcpy (Command, command_line);
    execute_Command (error_trap);
}

static void execute_Command (void (*error_trap)(void))
{
    int length = strlen (Command);
		
    if (length == 0) return;
    if (Command[length-1] == '\n')
    {
	Command[length-1] = '\0';
	if (length == 1) return;
    }
    if (COMMENT_DELIMITER(Command[0]))
    {
	return;
    }
    CATCH_ERROR
    {
	invoke_method (Command, Gfft_Command);
    }
    ON_ERROR
    {
	if (error_trap)	(*error_trap)();
    }
    END_CATCH_ERROR
}

static void startup_error_trap (void)
{
    error_message (STARTUP_FILE_ERROR);
    gabort (EXIT_FAILURE);
}

/**************************************************************************\
 * Termination Handlers                                                   *
\**************************************************************************/

/*
 * The system function exit() should not be called directly except
 * by quit() and gabort(), which follow.
 */


char *quit (char *arguments)
{
    cleanup ();
    exit (EXIT_SUCCESS);
    return arguments;    /* This is a dummy to make compiler happy */
}

void gabort (int status)
{
    delay (5);
    cleanup ();
    exit (status);
}

static void cleanup (void)
{
    delete_temp_files ();
#ifdef AMIGA
    close_amiga_stuff ();
#endif
}

static void delete_temp_files (void)  /* rework when adding other systems */
{
    char buffer[COMMAND_BUFFER_SIZE];

    if (Plot && CommandMode == BATCH_MODE)
    {
	error_message (CANT_CLEANUP_BATCH_PLOT);
	return;
    }

    sprintf (buffer, 
	     "run >nil: delete >nil: %s QUIET\n", DATA_FILE_WILDCARD);
    system (buffer);

    sprintf (buffer, 
	     "run >nil: delete >nil: %s QUIET\n", MESSAGE_FILE_WILDCARD);
    system (buffer);

    sprintf (buffer, 
	     "run >nil: delete >nil: %s QUIET\n", COMMAND_FILE_WILDCARD);
    system (buffer);

    remove (GNUPLOT_COMMAND_FILE_NAME);
}

/*
 * Disabling SAS/C interrupt handler cause it doesn't clean up intuition.
 * Also, I'm "making a note of the interrupt so that I can interrupt
 * FFT operations when running from the CLI.  It's not safe to actually
 * raise the error from here (though that might be more elegant).
 * Anyway, AmigaDOS only gets here during I/O or chkabort, so there's
 * no penalty for checking this value at those points.
 */

void __regargs _CXBRK(void) 
{ 
    Interrupt_Count++;
    return; 
}
    
/*
 * This was part of an attempt to intercept the divide by zero error
 * so the damned requester doesn't come up.
 * Unfortunately, FFP library doesn't follow ANSI C,
 * so this didn't work.
 * I'd have to write processor dependent assy code to intercept the error.
 */

#if FALSE
void _CXFERR (int code)
{
    _FPERR = code;
    return;
}
#endif


/*
 * Identify the 'CLI' argument needed to force
 * CLI-interactive mode
 */

static BOOLEAN cli_string (char *arg)
{
    return 
      (strlen(arg) == 3 &&
       tolower(arg[0]) == 'c' &&
       tolower(arg[1]) == 'l' &&
       tolower(arg[2]) == 'i') ||
	 (strlen(arg) == 2 &&
	  tolower(arg[0]) == 'c' &&
	  tolower(arg[1]) == 'l');
}    
[ RETURN TO DIRECTORY ]