/*************************************************************************** * 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 /* exit(), system() */ #include /* printf() */ #include /* _CXBRK */ #include /* _CXFERR */ #include #include /* 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'); }