home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1997 #2 / amigaacscoverdisc / utilities / shareware / music / gfft-2.03 / source / gfft-2.03-source.lha / gfft.c < prev    next >
C/C++ Source or Header  |  1996-01-02  |  10KB  |  356 lines

  1. /***************************************************************************
  2.  *          Copyright (C) 1994  Charles P. Peterson                  *
  3.  *         4007 Enchanted Sun, San Antonio, Texas 78244-1254             *
  4.  *              Email: Charles_P_Peterson@fcircus.sat.tx.us                *
  5.  *                                                                         *
  6.  *          This is free software with NO WARRANTY.                  *
  7.  *              See below for details.                           *
  8.  *              Support is available for a fee.                      *
  9.  ***************************************************************************
  10.  *
  11.  * Program:     gfft--General FFT analysis
  12.  * File:        gfft.c
  13.  * Purpose:     main() function--get args and/or commands
  14.  * Author:      Charles Peterson (CPP)
  15.  * History:     27-May-1993 CPP; Created.
  16.  *              6-July-1994 CPP (0.74); allow simultaneous MORE sessions
  17.  *              21-July-1994 CPP (1.02); remove "delete failed..." msgs
  18.  *              19-Jan-1995 CPP (1.20); Workbench mode is default
  19.  *              20-Jan-1995 CPP; (1.23) Use Icon Tooltypes
  20.  *              10-Feb-1995 CPP; (1.36) Allow interrupt from CLI
  21.  *              11-Feb-1995 CPP; (1.40) LoadSettings command
  22.  */
  23.  
  24. /*
  25.  *  Copyright (C) 1994  Charles P. Peterson
  26.  *  4007 Enchanted Sun, San Antonio, TX 78244-1254
  27.  *  Email: Charles_P_Peterson@fcircus.sat.tx.us
  28.  *
  29.  *  Please refer to the README file included in this distribution
  30.  *  concerning low-cost support and update services available from the
  31.  *  author, as well as encouragement to make suggestions, bug reports,
  32.  *  usage reports, enhancement requests, donations, equipment loans, and
  33.  *  ports to different systems.  If the README files is unavailable, Email
  34.  *  or send a SASE to the author (address above).  A limited amount of free
  35.  *  help may also be available by Email or mail (SASE required).  If
  36.  *  address has changed, try finding the most recent distribution.
  37.  *
  38.  *  This program is free software; you can redistribute it and/or modify
  39.  *  it under the terms of the GNU General Public License as published by
  40.  *  the Free Software Foundation; either version 2 of the License, or
  41.  *  (at your option) any later version.
  42.  *
  43.  *  This program is distributed in the hope that it will be useful,
  44.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  45.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  46.  *  GNU General Public License for more details.
  47.  *
  48.  *  You should have received a copy of the GNU General Public License
  49.  *  along with this program; if not, write to the Free Software
  50.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  The
  51.  *  GNU General Public License should be in a file named 'COPYING'.
  52.  *  Do not contact the Free Software Foundation for any other information
  53.  *  about this program; contact the author instead.
  54.  *
  55.  */
  56.  
  57. #include <stdlib.h>    /* exit(), system() */
  58. #include <stdio.h>     /* printf()   */
  59. #include <dos.h>       /* _CXBRK */
  60. #include <math.h>      /* _CXFERR */
  61. #include <string.h>
  62. #include <ctype.h>     /* tolower() */
  63.  
  64. #define DEFINE_HERE
  65. #include "gfft.h"
  66. #undef DEFINE_HERE
  67. #include "settings.h"
  68.  
  69. extern Name_Info_St Gfft_Command[];  /* GFFT commands */
  70.  
  71. char *StartupPathList[] = STARTUP_PATH_LIST;  /* From Xdef.h where X is sys */
  72.  
  73. static void cleanup (void);
  74. static void delete_temp_files (void);
  75. static BOOLEAN cli_string (char *string);
  76. static void startup_error_trap (void);
  77. static void execute_Command (void (*error_trap)(void));
  78.  
  79.  
  80. #define CLI_ARG (argc == 2  &&  cli_string (argv[1]))
  81.  
  82. void main (int argc, char *argv[])
  83. {
  84.  
  85.     CATCH_ERROR  /* This is the ultimate safety net */
  86.     {
  87.  
  88.     startup_cli_file ();
  89.  
  90. /**************************************************************************\
  91.  * Workbench Mode                                                         *
  92. \**************************************************************************/
  93.  
  94. #ifdef AMIGA
  95.  
  96.     if (argc <= 1)
  97.     {
  98.         CommandMode = WORKBENCH_MODE;
  99.         Plot = ANY_PLOT;
  100.         workbench_main ();  /* Failures gabort() directly */
  101.         quit (NullString);  /* Successful exit */
  102.     }
  103.  
  104. #endif
  105.  
  106. /**************************************************************************\
  107.  * CLI-Batch Mode                                                         *
  108. \**************************************************************************/
  109.  
  110.     if (argc > 1 && !CLI_ARG)
  111.     {
  112.         /*
  113.          * This is a non-interactive (i.e. batch) session
  114.          * qabort on error (indicated by longjmp).
  115.          */
  116.         CommandMode = BATCH_MODE;
  117.         Plot = NO_PLOT;
  118.         CATCH_ERROR
  119.         {
  120.         batch_command (argc, argv);
  121.         quit (NullString);
  122.         }
  123.         ON_ERROR
  124.         {
  125.         gabort (EXIT_FAILURE);
  126.         }
  127.         END_CATCH_ERROR;
  128.  
  129.     } /* End of batch session handling */
  130.  
  131. /**************************************************************************\
  132.  * CLI-Interactive Mode (gets called from here)                           *
  133. \**************************************************************************/
  134.  
  135.     Plot = ANY_PLOT;
  136.     banner_message (NullString);
  137.     cli_interactive_loop (TRUE);
  138.  
  139. /* Shouldn't get here; quit() or gabort() are called somewhere to exit */
  140.     }
  141.  
  142. #ifdef _DEBUG
  143.     ON_ERROR
  144.     {
  145.     /*
  146.      * WARNING!  Do not put any code (or calls) here which could possibly
  147.      * raise an error.  If it does, the 'ultimate' safety net will be
  148.      * leaky, and a system crash could result!
  149.      */
  150.     fprintf (stderr,"\nWarning.  Error caught by safety net.\n");
  151.     }
  152. #endif /* ifdef _DEBUG */
  153.  
  154.     END_CATCH_ERROR;  /* End of the ultimate safety net. */
  155.  
  156. /* Shouldn't get here; quit() or gabort() are called somewhere to exit */
  157.  
  158. }
  159.  
  160.  
  161. /**************************************************************************\
  162.  * CLI-Interactive Mode (implemented here)                                *
  163. \**************************************************************************/
  164.  
  165. void cli_interactive_loop (BOOLEAN started_from_cli)
  166. {
  167.     int previous_command_mode = CommandMode;
  168.  
  169.     CommandMode = INTERACTIVE_MODE;
  170.     while (started_from_cli || CommandMode == INTERACTIVE_MODE)
  171.     {
  172.     Interrupt_Count = 0;
  173.     prompt_command ();  /* Might gabort() from here on EOF */
  174.     CATCH_ERROR
  175.     {
  176.         invoke_method (Command, Gfft_Command);
  177.     }
  178.     END_CATCH_ERROR;  /* We don't break loop on error here */
  179.     }
  180.     CommandMode = previous_command_mode;
  181. }
  182.  
  183.  
  184. void startup_cli_file ()
  185. {
  186.     FILE * startup_file_ptr = NULL;
  187.  
  188.     if ( startup_file_ptr = gopen (StartupPathList, ".gfft", "r"))
  189.     {
  190.     execute_file_commands (startup_file_ptr);
  191.     fclose (startup_file_ptr);
  192.     }
  193. }
  194.  
  195. void execute_file_commands (FILE *fptr)
  196. {
  197.     int previous_command_mode = CommandMode;
  198.     char *next_command = Command;
  199.  
  200.     CommandMode = BATCH_MODE;
  201.  
  202.     while (next_command)
  203.     {
  204.     next_command = fgets (Command, COMMAND_BUFFER_SIZE, fptr);
  205.     if (next_command)
  206.     {
  207.         execute_Command (startup_error_trap);
  208.     }
  209.     }
  210.     CommandMode = previous_command_mode;
  211. }
  212.  
  213.  
  214. void execute_command_line (char *command_line, void (*error_trap)(void))
  215. {
  216.     strcpy (Command, command_line);
  217.     execute_Command (error_trap);
  218. }
  219.  
  220. static void execute_Command (void (*error_trap)(void))
  221. {
  222.     int length = strlen (Command);
  223.         
  224.     if (length == 0) return;
  225.     if (Command[length-1] == '\n')
  226.     {
  227.     Command[length-1] = '\0';
  228.     if (length == 1) return;
  229.     }
  230.     if (COMMENT_DELIMITER(Command[0]))
  231.     {
  232.     return;
  233.     }
  234.     CATCH_ERROR
  235.     {
  236.     invoke_method (Command, Gfft_Command);
  237.     }
  238.     ON_ERROR
  239.     {
  240.     if (error_trap)    (*error_trap)();
  241.     }
  242.     END_CATCH_ERROR
  243. }
  244.  
  245. static void startup_error_trap (void)
  246. {
  247.     error_message (STARTUP_FILE_ERROR);
  248.     gabort (EXIT_FAILURE);
  249. }
  250.  
  251. /**************************************************************************\
  252.  * Termination Handlers                                                   *
  253. \**************************************************************************/
  254.  
  255. /*
  256.  * The system function exit() should not be called directly except
  257.  * by quit() and gabort(), which follow.
  258.  */
  259.  
  260.  
  261. char *quit (char *arguments)
  262. {
  263.     cleanup ();
  264.     exit (EXIT_SUCCESS);
  265.     return arguments;    /* This is a dummy to make compiler happy */
  266. }
  267.  
  268. void gabort (int status)
  269. {
  270.     delay (5);
  271.     cleanup ();
  272.     exit (status);
  273. }
  274.  
  275. static void cleanup (void)
  276. {
  277.     delete_temp_files ();
  278. #ifdef AMIGA
  279.     close_amiga_stuff ();
  280. #endif
  281. }
  282.  
  283. static void delete_temp_files (void)  /* rework when adding other systems */
  284. {
  285.     char buffer[COMMAND_BUFFER_SIZE];
  286.  
  287.     if (Plot && CommandMode == BATCH_MODE)
  288.     {
  289.     error_message (CANT_CLEANUP_BATCH_PLOT);
  290.     return;
  291.     }
  292.  
  293.     sprintf (buffer, 
  294.          "run >nil: delete >nil: %s QUIET\n", DATA_FILE_WILDCARD);
  295.     system (buffer);
  296.  
  297.     sprintf (buffer, 
  298.          "run >nil: delete >nil: %s QUIET\n", MESSAGE_FILE_WILDCARD);
  299.     system (buffer);
  300.  
  301.     sprintf (buffer, 
  302.          "run >nil: delete >nil: %s QUIET\n", COMMAND_FILE_WILDCARD);
  303.     system (buffer);
  304.  
  305.     remove (GNUPLOT_COMMAND_FILE_NAME);
  306. }
  307.  
  308. /*
  309.  * Disabling SAS/C interrupt handler cause it doesn't clean up intuition.
  310.  * Also, I'm "making a note of the interrupt so that I can interrupt
  311.  * FFT operations when running from the CLI.  It's not safe to actually
  312.  * raise the error from here (though that might be more elegant).
  313.  * Anyway, AmigaDOS only gets here during I/O or chkabort, so there's
  314.  * no penalty for checking this value at those points.
  315.  */
  316.  
  317. void __regargs _CXBRK(void) 
  318.     Interrupt_Count++;
  319.     return; 
  320. }
  321.     
  322. /*
  323.  * This was part of an attempt to intercept the divide by zero error
  324.  * so the damned requester doesn't come up.
  325.  * Unfortunately, FFP library doesn't follow ANSI C,
  326.  * so this didn't work.
  327.  * I'd have to write processor dependent assy code to intercept the error.
  328.  */
  329.  
  330. #if FALSE
  331. void _CXFERR (int code)
  332. {
  333.     _FPERR = code;
  334.     return;
  335. }
  336. #endif
  337.  
  338.  
  339. /*
  340.  * Identify the 'CLI' argument needed to force
  341.  * CLI-interactive mode
  342.  */
  343.  
  344. static BOOLEAN cli_string (char *arg)
  345. {
  346.     return 
  347.       (strlen(arg) == 3 &&
  348.        tolower(arg[0]) == 'c' &&
  349.        tolower(arg[1]) == 'l' &&
  350.        tolower(arg[2]) == 'i') ||
  351.      (strlen(arg) == 2 &&
  352.       tolower(arg[0]) == 'c' &&
  353.       tolower(arg[1]) == 'l');
  354. }    
  355.