home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 2 / goldfish_vol2_cd1.bin / files / misc / sci / gfft / source / settings.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-06  |  27.7 KB  |  1,306 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 gfft.c, or run program itself, for details.              *
  8.  *              Support is available for a fee.                      *
  9.  ***************************************************************************
  10.  *
  11.  * Program:     gfft--General FFT analysis
  12.  * File:        settings.c
  13.  * Purpose:     set values, names, and operation types
  14.  * Author:      Charles Peterson (CPP)
  15.  * History:     31-May-1993 CPP; Created.
  16.  *              9-Aug-94 CPP (1.10); Hidden3D option
  17.  */
  18.  
  19. #include <stdio.h>     /* printf */
  20. #include <string.h>    /* strtok, strlen */
  21. #include <stdlib.h>    /* strtoul */
  22. #include <errno.h>     /* errno */
  23.  
  24. #include "gfft.h"
  25.  
  26. #define DEFINE_HERE
  27. #include "settings.h"
  28. #undef DEFINE_HERE
  29.  
  30. extern Name_Info_St Gfft_Command[];  /* GFFT commands */
  31.  
  32. static char *set_ulong (char *arguments, unsigned long *longp, 
  33.                int gt_0_req, int arg_req);
  34.  
  35. static char *set_double (char *arguments, double *doublep, 
  36.                int gt_0_req, int arg_req);
  37.  
  38. static char *get_filename (char *arguments, char **filename_pp);
  39.  
  40. static char *add_calibration (char *arguments, BOOLEAN db_scale);
  41.  
  42. char *set (char *arguments)
  43. {
  44. /*
  45.  * Dummy command which invokes its arguments as a command string
  46.  */
  47.     if (arguments && arguments != NullString)
  48.     {
  49.     invoke_method (arguments, Gfft_Command);
  50.     }
  51.     return arguments;
  52. }
  53.  
  54. /*
  55.  * Functions to set various parameters
  56.  */
  57.  
  58. char *set_time_offset (char *arguments)
  59. {
  60.     char *more_arguments;
  61.     ULONG time_offset;
  62.  
  63.     TimeOffset = INVALID_SET;  /* unless this succeeds */
  64.     more_arguments = set_ulong (arguments, &time_offset, FALSE, FALSE);
  65.     if (more_arguments == NullString)
  66.     {
  67.     TimeOffset = NOT_SET;
  68.     }
  69.     else
  70.     {
  71.     Time3D = TRUE;
  72.     if (time_offset > 0 && time_offset < LONG_MAX)
  73.     {
  74.         TimeOffset = (long) time_offset;
  75.     }
  76.     else
  77.     {
  78.         command_error_message (BAD_ARGUMENT, more_arguments-1);
  79.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  80.     }
  81.     }
  82.     return more_arguments;
  83. }
  84.  
  85. char *set_time_segments (char *arguments)
  86. {
  87.     char *more_arguments;
  88.     ULONG time_segments;
  89.  
  90.     TimeSegments = INVALID_SET;  /* unless this succeeds */
  91.     more_arguments = set_ulong (arguments, &time_segments, FALSE, FALSE);
  92.     if (more_arguments == NullString)
  93.     {
  94.     TimeSegments = NOT_SET;
  95.     }
  96.     else
  97.     {
  98.     Time3D = TRUE;
  99.     TimeSegSize = NOT_SET;
  100.     if (time_segments > 0 && time_segments < LONG_MAX)
  101.     {
  102.         TimeSegments = (long) time_segments;
  103.     }
  104.     else
  105.     {
  106.         command_error_message (BAD_ARGUMENT, more_arguments-1);
  107.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  108.     }
  109.     }
  110.     return more_arguments;
  111. }
  112.  
  113. char *set_time_seg_size (char *arguments)
  114. {
  115.     char *more_arguments;
  116.     ULONG time_seg_size;
  117.  
  118.     TimeSegSize = INVALID_SET;  /* unless this succeeds */
  119.     more_arguments = set_ulong (arguments, &time_seg_size, FALSE, FALSE);
  120.     if (more_arguments == NullString)
  121.     {
  122.     TimeSegSize = NOT_SET;
  123.     }
  124.     else
  125.     {
  126.     Time3D = TRUE;
  127.     TimeSegments = NOT_SET;
  128.     if (time_seg_size > 0 && time_seg_size < LONG_MAX)
  129.     {
  130.         TimeSegSize = (long) time_seg_size;
  131.     }
  132.     else
  133.     {
  134.         command_error_message (BAD_ARGUMENT, more_arguments-1);
  135.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  136.     }
  137.     }
  138.     return more_arguments;
  139. }
  140.  
  141. char *set_smoothing_segments (char *arguments)
  142. {
  143.     char *more_arguments;
  144.     ULONG smoothing_segs;
  145.  
  146.     SmoothingSegments = INVALID_SMOOTHING;  /* unless this succeeds */
  147.     more_arguments = set_ulong (arguments, &smoothing_segs, TRUE, FALSE);
  148.     if (more_arguments == NullString)
  149.     {
  150.     SmoothingSegments = NO_SMOOTHING;
  151.     }
  152.     else
  153.     {
  154.     if (smoothing_segs <= LONG_MAX)
  155.     {
  156.         SmoothingSegments = (long) smoothing_segs;
  157.     }
  158.     else
  159.     {
  160.         command_error_message (BAD_ARGUMENT, more_arguments-1);
  161.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  162.     }
  163.     }
  164.     return more_arguments;
  165. }
  166.  
  167. char *set_time_3d (char *arguments)
  168. {
  169.     Time3D = TRUE;
  170.     return arguments;
  171. }
  172.  
  173. char *set_no_time_3d (char *arguments)
  174. {
  175.     Time3D = FALSE;
  176.     return arguments;
  177. }
  178.  
  179. char *set_hidden_3d (char *arguments)
  180. {
  181.     Hidden3D = TRUE;
  182.     return arguments;
  183. }
  184.  
  185. char *set_no_hidden_3d (char *arguments)
  186. {
  187.     Hidden3D = FALSE;
  188.     return arguments;
  189. }
  190.  
  191. char *set_signed (char *arguments)
  192. {
  193.     InputFormat.zero = 0;
  194.     return arguments;
  195. }
  196.  
  197. char *set_unsigned (char *arguments)
  198. {
  199.     int sample_width = (InputFormat.bits > 8) ? 16 : 8;
  200.     InputFormat.zero = ((unsigned long) 0xffffffff >> 
  201.                 (33 - sample_width)) + (unsigned long) 1;
  202. /*
  203.  * This is re-done at time of 'ok' command to be sure bits spec is final
  204.  */
  205.     return arguments;
  206. }
  207.  
  208. char *set_terminal (char *arguments)
  209. {
  210.     char *more_arguments;
  211.     char *terminal; 
  212.  
  213.     if (Terminal && Terminal != NullString)
  214.     {
  215.     gfree (Terminal);
  216.     Terminal = NULL;
  217.     }
  218.     more_arguments = get_filename (arguments, &terminal);
  219.     if (terminal == NullString || strlen (terminal) == 0)
  220.     {
  221.     Terminal = NULL;
  222.     }
  223.     else
  224.     {
  225.     Terminal = terminal;
  226.     }
  227.     return more_arguments;
  228. }
  229.  
  230.  
  231. char *set_plot_output (char *arguments)
  232. {
  233.     char *more_arguments;
  234.     char *plot_output; 
  235.  
  236.     if (PlotOutput && PlotOutput != NullString)
  237.     {
  238.     gfree (PlotOutput);
  239.     PlotOutput = NULL;
  240.     }
  241.     more_arguments = get_filename (arguments, &plot_output);
  242.     if (plot_output == NullString || strlen (plot_output) == 0)
  243.     {
  244.     PlotOutput = NULL;
  245.     }
  246.     else
  247.     {
  248.     PlotOutput = plot_output;
  249.     }
  250.     return more_arguments;
  251. }
  252.  
  253.  
  254. char *set_save_memory (char *arguments)
  255. {
  256.     SaveMemory = TRUE;
  257.     return arguments;
  258. }
  259.  
  260. char *set_no_save_memory (char *arguments)
  261. {
  262.     SaveMemory = FALSE;
  263.     return arguments;
  264. }
  265.  
  266. char *set_psdensity (char *arguments)
  267. {
  268.     PSDensity = TRUE;
  269.     return arguments;
  270. }
  271.  
  272. char *set_no_psdensity (char *arguments)
  273. {
  274.     PSDensity = FALSE;
  275.     return arguments;
  276. }
  277.  
  278. char *set_squared_smoothing (char *arguments)
  279. {
  280.     SquaredSmoothing = TRUE;
  281.     return arguments;
  282. }
  283.  
  284. char *set_no_squared_smoothing (char *arguments)
  285. {
  286.     SquaredSmoothing = FALSE;
  287.     return arguments;
  288. }
  289.  
  290. char *set_combine_plots (char *arguments)
  291. {
  292.     extern int Old_File_Count;
  293.  
  294.     if (!CombinePlots)
  295.     {
  296.     CombinePlots = TRUE;
  297.     Old_File_Count = (Old_File_Count > 0) ? 1 : 0;
  298.     }
  299.     return arguments;
  300. }
  301.  
  302. char *set_no_combine_plots (char *arguments)
  303. {
  304.     CombinePlots = FALSE;
  305.     Old_File_Count = 0;
  306.     return arguments;
  307. }
  308.  
  309. char *cut_combined_plot (char *arguments)
  310. {
  311.     if (Old_File_Count > 0) Old_File_Count--;
  312.     return arguments;
  313. }
  314.  
  315. char *set_db (char *arguments)
  316. {
  317.     Db = TRUE;
  318.     return arguments;
  319. }
  320.  
  321. char *set_logx (char *arguments)
  322. {
  323.     LogX = TRUE;
  324.     return arguments;
  325. }
  326.  
  327. char *set_logy (char *arguments)
  328. {
  329.     LogY = TRUE;
  330.     return arguments;
  331. }
  332.  
  333. char *set_no_logx (char *arguments)
  334. {
  335.     LogX = FALSE;
  336.     return arguments;
  337. }
  338.  
  339. char *set_no_logy (char *arguments)
  340. {
  341.     LogY = FALSE;
  342.     return arguments;
  343. }
  344.  
  345. char *set_no_db (char *arguments)
  346. {
  347.     Db = FALSE;
  348.     return arguments;
  349. }
  350.  
  351. char *set_time_overlap (char *arguments)
  352. {
  353.     char *beyond_argument;
  354.  
  355.     TimeOverlap = INVALID_SET;
  356.     beyond_argument = set_double (arguments, &TimeOverlap, FALSE, FALSE);
  357.     if (beyond_argument == NullString)
  358.     {
  359.     TimeOverlap = DEFAULT_TIME_OVERLAP;
  360.     }
  361.     else 
  362.     {
  363.     Time3D = TRUE;
  364.     TimeOffset = NOT_SET;
  365.     if (TimeOverlap >= 1.0 || TimeOverlap < 0.0)
  366.     {
  367.         TimeOverlap = INVALID_SET;
  368.         command_error_message (BAD_ARGUMENT, beyond_argument-1);
  369.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  370.     }
  371.     }
  372.     return beyond_argument;
  373. }
  374.  
  375. char *set_no_quantization (char *arguments)
  376. {
  377.     Quantization = MIN_QUANTIZATION;
  378.     return arguments;
  379. }
  380.  
  381. char *set_quantization (char *arguments)
  382. {
  383.     double quantization = 0.0;
  384.     char *beyond_argument;
  385.  
  386.     Quantization = BAD_QUANTIZATION;
  387.     beyond_argument = set_double (arguments, &quantization, FALSE, FALSE);
  388.     if (beyond_argument == NullString || quantization == 0.0)
  389.     {
  390.     Quantization = MIN_QUANTIZATION;  /* Default value if no argument */
  391.     }
  392.     else if (quantization < 0.0)
  393.     {
  394.     command_error_message (BAD_ARGUMENT, arguments);
  395.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  396.     }
  397.     else
  398.     {
  399.     Quantization = quantization;
  400.     }
  401.     return beyond_argument;
  402. }
  403.  
  404. char *set_multiply (char *arguments)
  405. {
  406.     char *beyond_argument;
  407.  
  408.     beyond_argument = set_double (arguments, &Multiply, FALSE, FALSE);
  409.     if (beyond_argument == NullString)
  410.     {
  411.     Multiply = 1.0L;  /* Default value if no argument */
  412.     }
  413.     return beyond_argument;
  414. }
  415.  
  416. char *set_no_one_shot_only (char *arguments)
  417. {
  418.     OneShotOnly = FALSE;
  419.     return arguments;
  420. }
  421.  
  422. char *set_no_repeat_only (char *arguments)
  423. {
  424.     RepeatOnly = FALSE;
  425.     return arguments;
  426. }
  427.  
  428. char *set_bits (char *arguments)
  429. {
  430.     char *more_arguments;
  431.     ULONG bits;
  432.  
  433.     more_arguments = set_ulong (arguments, &bits, TRUE, FALSE);
  434.     if (more_arguments == NullString)
  435.     {
  436.     bits = DEFAULT_INPUT_BITS;
  437.     }
  438.     else if (1 > bits || bits > 16)
  439.     {
  440.     command_error_message (BAD_ARGUMENT, arguments);
  441.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  442.     }
  443.     else
  444.     {
  445.     InputFormat.bits = bits;
  446.     }
  447.     return more_arguments;
  448. }
  449.  
  450. char *set_octave (char *arguments)
  451. {
  452.     char *more_arguments;
  453.  
  454.     more_arguments = set_ulong (arguments, &Octave, FALSE, FALSE);
  455.     if (more_arguments == NullString)
  456.     {
  457.     Octave = 1L;
  458.     }
  459.     return more_arguments;
  460. }
  461.  
  462. char *set_one_shot_only (char *arguments)
  463. {
  464.     OneShotOnly = TRUE;
  465.     RepeatOnly = FALSE;
  466.     return arguments;
  467. }
  468.  
  469. char *set_repeat_only (char *arguments)
  470. {
  471.     RepeatOnly = TRUE;
  472.     OneShotOnly = FALSE;
  473.     return arguments;
  474. }
  475.  
  476. char *set_ignore_format (char *arguments)
  477. {
  478.     IgnoreFormat = TRUE;
  479.     return arguments;
  480. }
  481.  
  482. char *set_no_ignore_format (char *arguments)
  483. {
  484.     IgnoreFormat = FALSE;
  485.     return arguments;
  486. }
  487.  
  488. char *set_pink (char *arguments)
  489. {
  490.     Pink = TRUE;
  491.     return arguments;
  492. }
  493.  
  494. char *set_no_pink (char *arguments)
  495. {
  496.     Pink = FALSE;
  497.     return arguments;
  498. }
  499.  
  500. char *set_parseval (char *arguments)
  501. {
  502.     Parseval = TRUE;
  503.     return arguments;
  504. }
  505.  
  506. char *set_no_parseval (char *arguments)
  507. {
  508.     Parseval = FALSE;
  509.     return arguments;
  510. }
  511.  
  512. char *set_overlap (char *arguments)
  513. {
  514.     Overlap = TRUE;
  515.     return arguments;
  516. }
  517.  
  518. char *set_no_overlap (char *arguments)
  519. {
  520.     Overlap = FALSE;
  521.     return arguments;
  522. }
  523.  
  524. char *set_high_frequency (char *arguments)
  525. {
  526.     char *more_arguments;
  527.  
  528.     more_arguments = set_double (arguments, &HighFrequency, FALSE, FALSE);
  529.     if (more_arguments == NullString)
  530.     {
  531.         HighFrequency = HIGHEST_FREQUENCY;   /* No arg, return to default */
  532.     }
  533.     return more_arguments;
  534. }
  535.  
  536. char *set_low_frequency (char *arguments)
  537. {
  538.     char *more_arguments;
  539.  
  540.     more_arguments = set_double (arguments, &LowFrequency, FALSE, FALSE);
  541.     if (more_arguments == NullString)
  542.     {
  543.     LowFrequency = LOWEST_FREQUENCY;   /* No arg, return to default */
  544.     }
  545.     return more_arguments;
  546. }
  547.  
  548. char *set_low_y (char *arguments)
  549. {
  550.     char *more_arguments;
  551.  
  552.     more_arguments = set_double (arguments, &LowY, FALSE, FALSE);
  553.     if (more_arguments == NullString)
  554.     {
  555.     LowY = LOWEST_Y;   /* No arg, return to default */
  556.     }
  557.     return more_arguments;
  558. }
  559.  
  560. char *set_high_y (char *arguments)
  561. {
  562.     char *more_arguments;
  563.  
  564.     more_arguments = set_double (arguments, &HighY, FALSE, FALSE);
  565.     if (more_arguments == NullString)
  566.     {
  567.     HighY = HIGHEST_Y;   /* No arg, return to default */
  568.     }
  569.     return more_arguments;
  570. }
  571.  
  572. char *set_channel (char *arguments)
  573. {
  574.     char *more_arguments;
  575.  
  576.     Channel = 0L;    /* Purposely set to invalid value here */
  577.     more_arguments = set_ulong (arguments, &Channel, TRUE, FALSE);
  578.     if (more_arguments == NullString)
  579.     {
  580.     Channel = 1L;   /* Return to default if no argument */
  581.     }
  582.     if (Channel > FileChannels || Channel < 1)
  583.     {
  584.     error_message (SPEC_CHANNEL_UNAVAIL);
  585.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  586.     }
  587.     return more_arguments;
  588. }
  589.  
  590. char *set_start_byte (char *arguments)
  591. {
  592.     char *more_arguments;
  593.  
  594.     more_arguments = set_ulong (arguments, &StartByte, FALSE, FALSE);
  595.     if (more_arguments == NullString)
  596.     {
  597.     StartByte = 0;   /* Return to default if no argument */
  598.     }
  599.     return more_arguments;
  600. }
  601.  
  602. char *set_start_frame (char *arguments)
  603. {
  604.     char *more_arguments;
  605.  
  606.     more_arguments = set_ulong (arguments, &StartFrame, FALSE, FALSE);
  607.     if (more_arguments == NullString)
  608.     {
  609.     StartFrame = 0;   /* Return to default if no argument */
  610.     }
  611.     return more_arguments;
  612. }
  613.  
  614. char *set_frames (char *arguments)
  615. {
  616.     char *more_arguments;
  617.  
  618.     more_arguments = set_ulong (arguments, &Frames, FALSE, FALSE);
  619.     if (more_arguments == NullString)
  620.     {
  621.     Frames = ULONG_MAX;   /* Return to default if no argument */
  622.     }
  623.     return more_arguments;
  624. }
  625.  
  626. char *set_pad (char *arguments)
  627. {
  628.     Pad = TRUE;
  629.     return arguments;
  630. }
  631.  
  632. char *set_no_pad (char *arguments)
  633. {
  634.     Pad = FALSE;
  635.     return arguments;
  636. }
  637.  
  638. char *set_no_numerical (char *arguments)
  639. {
  640.     Numerical = FALSE;
  641.     return arguments;
  642. }
  643.  
  644. char *set_numerical (char *arguments)
  645. {
  646. #ifdef NUMERICAL_RECIPES_AVAILABLE
  647.     Numerical = TRUE;
  648. #else
  649.     error_message (NO_NUMERICAL);
  650.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  651. #endif
  652.     return arguments;
  653. }
  654.  
  655.  
  656. #define GNUPLOT 1
  657.  
  658. static char *set_plot_gnuplot (char *arguments)
  659. {
  660.     Plot = GNUPLOT_PLOT;
  661.     return arguments;
  662. }
  663.  
  664. static Name_Info_St plotter_names[] = {
  665.   {"GNUPLOT","G", set_plot_gnuplot},
  666.   {"","", default_argument},
  667. };
  668.  
  669.  
  670. char *set_plot (char *arguments)
  671. {
  672.     char *arg;
  673.  
  674.     arg = strtok (arguments, " ");
  675.     if (!arg) /* No argument present */
  676.     {
  677.     Plot = ANY_PLOT;  /* use the default plotter */
  678.     }
  679.     else
  680.     {
  681.     invoke_method (arg, plotter_names);
  682.     }
  683.     return arguments;
  684. }
  685.  
  686. char *set_no_plot (char *arguments)
  687. {
  688.     Plot = NO_PLOT;
  689.     return arguments;
  690. }
  691.  
  692.  
  693. #define ASCII 1
  694. #define BINARY 2
  695.  
  696. static char *set_output_format_binary (char *arguments)
  697. {
  698.     OutputFormat.binary = TRUE;
  699.     return arguments;
  700. }
  701.  
  702. static char *set_output_format_ascii (char *arguments)
  703. {
  704.     OutputFormat.binary = FALSE;
  705.     return arguments;
  706. }
  707.  
  708. static Name_Info_St output_format_names[] = {
  709.   {"ASCII","A", set_output_format_ascii},
  710.   {"BINARY","B", set_output_format_binary},
  711.   {"","", default_argument},
  712. };
  713.  
  714. char *set_output (char *arguments)
  715. {
  716.     char *arg;
  717.  
  718.     arg = strtok (arguments, " ");
  719.     if (!arg) /* No argument present */
  720.     {
  721.     command_error_message (MISSING_ARGUMENT, arguments);
  722.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  723.     }
  724.     invoke_method (arg, output_format_names);
  725.     return arguments;
  726. }
  727.  
  728. char *set_amplitude (char *arguments)
  729. {
  730.     Amplitude = TRUE;
  731.     Power = FALSE;
  732.     return arguments;
  733. }
  734.  
  735. char *set_power (char *arguments)
  736. {
  737.     Power = TRUE;
  738.     Amplitude = FALSE;
  739.     return arguments;
  740. }
  741.  
  742. char *set_fft (char *arguments)
  743. {
  744.     Power = FALSE;
  745.     Amplitude = FALSE;
  746.     return arguments;
  747. }
  748.  
  749. char *set_mean (char *arguments)
  750. {
  751.     Mean = TRUE;
  752.     return arguments;
  753. }
  754.  
  755. char *set_sum (char *arguments)
  756. {
  757.     Mean = FALSE;
  758.     return arguments;
  759. }
  760.  
  761. char *set_hann (char *arguments)
  762. {
  763.     WindowType = HANN_WINDOW;
  764.     return arguments;
  765. }
  766.  
  767. char *set_hamming (char *arguments)
  768. {
  769.     WindowType = HAMMING_WINDOW;
  770.     return arguments;
  771. }
  772.  
  773. char *set_parzen (char *arguments)
  774. {
  775.     WindowType = PARZEN_WINDOW;
  776.     return arguments;
  777. }
  778.  
  779. char *set_rectangle (char *arguments)
  780. {
  781.     WindowType = RECTANGLE_WINDOW;
  782.     return arguments;
  783. }
  784.  
  785. char *set_triangle (char *arguments)
  786. {
  787.     WindowType = TRIANGLE_WINDOW;
  788.     return arguments;
  789. }
  790.  
  791. char *set_blackman_harris_74db (char *arguments)
  792. {
  793.     WindowType = BLACKMAN_HARRIS_74DB_WINDOW;
  794.     return arguments;
  795. }
  796.  
  797. char *set_blackman_harris_92db (char *arguments)
  798. {
  799.     WindowType = BLACKMAN_HARRIS_92DB_WINDOW;
  800.     return arguments;
  801. }
  802.  
  803. char *set_welch (char *arguments)
  804. {
  805.     WindowType = WELCH_WINDOW;
  806.     return arguments;
  807. }
  808.  
  809. char *set_rotation_x (char *arguments)
  810. {
  811.     char *more_arguments;
  812.     double rot_x;
  813.  
  814.     RotX = INVALID_ROTATION;
  815.     more_arguments = set_double (arguments, &rot_x, FALSE, FALSE);
  816.     if (more_arguments == NullString)
  817.     {
  818.     RotX = DEF_ROT_X;
  819.     }
  820.     else if (0. <= rot_x && rot_x <= 180.)
  821.     {
  822.     RotX = rot_x;
  823.     }
  824.     else
  825.     {
  826.     command_error_message (BAD_ARGUMENT, arguments);
  827.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  828.     }
  829.     return more_arguments;
  830. }
  831.  
  832. char *set_rotation_z (char *arguments)
  833. {
  834.     char *more_arguments;
  835.     double rot_z;
  836.  
  837.     RotZ = INVALID_ROTATION;
  838.     more_arguments = set_double (arguments, &rot_z, FALSE, FALSE);
  839.     if (more_arguments == NullString)
  840.     {
  841.     RotZ = DEF_ROT_Z;
  842.     }
  843.     else if (0. <= rot_z && rot_z <= 360.)
  844.     {
  845.     RotZ = rot_z;
  846.     }
  847.     else
  848.     {
  849.     command_error_message (BAD_ARGUMENT, arguments);
  850.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  851.     }
  852.     return more_arguments;
  853. }
  854.  
  855. char *set_rate (char *arguments)
  856. {
  857.     char *more_arguments;
  858.  
  859.     Rate = INVALID_RATE;   /* Preset to <invalid> rate */
  860.     more_arguments = set_double (arguments, &Rate, TRUE, FALSE);
  861.     if (more_arguments == NullString)
  862.     {
  863.     Rate = AUTO_RATE;   /* Set to <auto/default> rate */
  864.     }
  865.     return more_arguments;
  866. }
  867.  
  868. char *set_interleave (char *arguments)
  869. {
  870.     char *end_argument;
  871.     ULONG interleave = 0;
  872.  
  873.     Interleave = INVALID_INTERLEAVE;   /* Force flagged value on error */
  874.     end_argument = set_ulong (arguments, &interleave, TRUE, TRUE);
  875.     if (interleave < 2)
  876.     {
  877.     command_error_message (BAD_ARGUMENT, end_argument-1);
  878.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  879.     }
  880.     else
  881.     {
  882.     Interleave = interleave;
  883.     }
  884.     return end_argument;
  885. }
  886.  
  887. char *set_no_interleave (char *arguments)
  888. {
  889.     Interleave = 1;
  890.     return arguments;
  891. }
  892.  
  893. char *set_bins (char *arguments)
  894. {
  895.     unsigned long bins = 1;
  896.     unsigned long okbins = 1;
  897.     char *new_arguments;
  898.  
  899.     NumberBins = INVALID_BINS;   /* Preset invalid value in case of error */
  900.     new_arguments = set_ulong (arguments, &bins, FALSE, FALSE);
  901.     if (new_arguments != NullString)
  902.     {
  903.     if (bins == 0)
  904.     {
  905.         NumberBins = 0;
  906.         return new_arguments;
  907.     }
  908.     okbins = get_pos_power_2 (bins);
  909.     if (okbins > LONG_MAX)
  910.     {
  911.         okbins = get_pos_power_2 (LONG_MAX / 2L);
  912.     }
  913.     NumberBins = (long) okbins;
  914.     if (NumberBins != bins)
  915.     {
  916.         bins_s_message ();
  917.     }
  918.     }
  919.     else
  920.     {
  921.     NumberBins = MAX_BINS;  /* Default...based on data count of file */
  922.     }
  923.     return new_arguments;
  924. }
  925.  
  926.  
  927. unsigned long get_pos_power_2 (unsigned long i)
  928. {
  929.     unsigned long j = 1;                /* minimum useful value */
  930.     unsigned long max = ULONG_MAX / 2;  /* max value we can safely handle */
  931.  
  932.     for (j = 1; j < max; j *= 2)
  933.     {
  934.     if (j >= i) break;
  935.     }
  936.     return j;
  937. }
  938.  
  939. char *set_no_calibrations (char *arguments)
  940. {
  941.     calibration_list__cancel (&CalibrationList);
  942.     CalibrationList = NULL;
  943.     return arguments;
  944. }
  945.  
  946. char *set_db_calibration (char *arguments)
  947. {
  948.     arguments = add_calibration (arguments, TRUE);
  949.     return arguments;
  950. }
  951.  
  952. char *set_calibration (char *arguments)
  953. {
  954.     arguments = add_calibration (arguments, FALSE);
  955.     return arguments;
  956. }
  957.  
  958. static char *add_calibration (char *arguments, BOOLEAN db_scale)
  959. {
  960.     char *more_arguments;
  961.     FILE *cal_file;
  962.     char *cal_name;
  963.  
  964.     more_arguments = get_filename (arguments, &cal_name);
  965.     if (cal_name == NullString)
  966.     {
  967.     command_error_message (MISSING_ARGUMENT, arguments);
  968.     RAISE_ERROR (NOTHING_SPECIAL);   /* longjmp outa here */
  969.     }
  970.     if (!(cal_file = fopen (cal_name,"r")))
  971.     {
  972.     error_message (CANT_OPEN_INPUT_FILE);
  973.     RAISE_ERROR (NOTHING_SPECIAL);   /* longjmp outa here */
  974.     }
  975.     calibration_list__add (&CalibrationList, cal_name, cal_file, db_scale);
  976.     return more_arguments;
  977. }
  978.  
  979. char *set_read (char *arguments)
  980. {
  981.     char *more_arguments;
  982.  
  983.     if (ReadName && ReadName != NullString)
  984.     {
  985.     gfree (ReadName);
  986.     ReadName = NullString;
  987.     }
  988.     if (ReadPtr != NULL && ReadPtr != stdin)
  989.     {
  990.     fclose (ReadPtr);
  991.     }
  992.     if (Save_Data)
  993.     {
  994.     gfree (Save_Data);
  995.     Save_Data = NULL;
  996.     }
  997.     more_arguments = get_filename (arguments, &ReadName);
  998.     if (ReadName == NullString)
  999.     {
  1000.     reset_format ();
  1001.     ReadPtr = NULL;
  1002.     ReadName = NULL;
  1003.     return more_arguments;
  1004.     }
  1005.     if (strlen (ReadName) == 4 && !strcmp (ReadName,"con:"))
  1006.     {
  1007.     reset_format ();
  1008.     ReadPtr = stdin;
  1009.     return more_arguments;
  1010.     }
  1011.     if (!(ReadPtr = fopen (ReadName,"r")))
  1012.     {
  1013.     error_message (CANT_OPEN_INPUT_FILE);
  1014.     reset_format ();
  1015.     RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */
  1016.     }
  1017.     else
  1018.     {
  1019.     read_format ();
  1020.     }
  1021.     return more_arguments;
  1022. }
  1023.  
  1024. char *set_append (char *arguments)
  1025. {
  1026.     char *more_arguments;
  1027.  
  1028.     Appending = FALSE;
  1029.     if (WriteName && WriteName != NullString)
  1030.     {
  1031. /*    gfree (WriteName);      aliased name!  unsafe to free!  */
  1032.     WriteName = NullString;
  1033.     }
  1034.     if (WritePtr != NULL && WritePtr != stdout)
  1035.     {
  1036.     fclose (WritePtr);
  1037.     }
  1038.     WritePtr = NULL;
  1039.     more_arguments = get_filename (arguments, &WriteName);
  1040.     if (WriteName == NullString)
  1041.     {
  1042.     Appending = TRUE;
  1043.     WriteName = NULL;
  1044.     return more_arguments;
  1045.     }
  1046.     WritePtr = fopen (WriteName,"a");
  1047.     if (!WritePtr)
  1048.     {
  1049.     error_message (CANT_CREATE_OUTPUT_FILE);
  1050.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  1051.     }
  1052.     Appending = TRUE;
  1053.     return more_arguments;
  1054. }
  1055.  
  1056. char *set_write (char *arguments)
  1057. {
  1058. /*
  1059.  * The following is intended to maximize portability
  1060.  * by using (ultimately) only ANSI C functions and notions
  1061.  *
  1062.  * Note: If the first characters match the TEMP_DATAFILE_NAME, the
  1063.  *   previous version will be overwritten with impunity, otherwise:
  1064.  * if a file exists with the same name, it will be renamed to backup.
  1065.  * Only one level of backup files is created.
  1066.  * It will fail if filesystem does not allow a one character suffix.
  1067.  * If the backup fails, file is not opened for output.
  1068.  */
  1069.     char *more_arguments;
  1070.     FILE *temp_ptr;
  1071.  
  1072.     Appending = FALSE;
  1073.     if (WriteName && WriteName != NullString)
  1074.     {
  1075. /*    gfree (WriteName);      aliased name!  unsafe to free!  */
  1076.     WriteName = NullString;
  1077.     }
  1078.     if (WritePtr != NULL && WritePtr != stdout)
  1079.     {
  1080.     fclose (WritePtr);
  1081.     }
  1082.     WritePtr = NULL;
  1083.     more_arguments = get_filename (arguments, &WriteName);
  1084.     if (WriteName == NullString)
  1085.     {
  1086.     WriteName = NULL;
  1087.     return more_arguments;
  1088.     }
  1089.     if (strlen (WriteName) == 4 && !strcmp (WriteName,"con:"))
  1090.     {
  1091.     WritePtr = stdout;
  1092.     return more_arguments;
  1093.     }
  1094.     if (!is_temp_file (WriteName))
  1095.     {
  1096.     if (temp_ptr = fopen (WriteName,"r"))
  1097.     {
  1098.         int oldlen;
  1099.         char *newname;
  1100.         int old_backup_deleted = FALSE;
  1101.         
  1102.         fclose (temp_ptr);
  1103.         oldlen = strlen (WriteName);
  1104.         newname = gmalloc (oldlen + 2, NOTHING_SPECIAL);
  1105.         strcpy (newname, WriteName);
  1106.         newname[oldlen] = BACKUP_FILE_CHARACTER;
  1107.         newname[oldlen + 1] = '\0';
  1108.         if (temp_ptr = fopen (newname,"r"))
  1109.         {
  1110.         old_backup_deleted = TRUE;
  1111.         fclose (temp_ptr);
  1112.         remove (newname);
  1113.         }
  1114.         if (rename (WriteName, newname))
  1115.         {
  1116.         error_message (OUTPUT_BACKUP_FAILURE);
  1117.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  1118.         }
  1119.         else if (old_backup_deleted)
  1120.         {
  1121.         error_message (BACKUP_OVERWRITTEN);  /* Warning only. */
  1122.         }
  1123.         else
  1124.         {
  1125.         error_message (BACKUP_CREATED);  /* Warning only. */
  1126.         }
  1127.         gfree (newname);
  1128.     }
  1129.     }
  1130.     WritePtr = fopen (WriteName,"w");
  1131.     if (!WritePtr)
  1132.     {
  1133.     error_message (CANT_CREATE_OUTPUT_FILE);
  1134.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  1135.     }
  1136.     return more_arguments;
  1137. }
  1138.  
  1139. /*
  1140.  * Set an unsigned long value
  1141.  * decimal, octal, or hex accepted
  1142.  * handle error, incl. termination by other than NULL, space, or newline
  1143.  * on error, longjmp (to command loop)
  1144.  * a flag determines if value greater than 0 is required
  1145.  * a flag determines if argument is mandatory (then longjmp if not present)
  1146.  * if argument not mandatory, return NullString if no arg found, 
  1147.  *  otherwise, return string pointer to first char past end of filename
  1148.  *    (this may be simply a pointer to a '\0' byte)
  1149.  * value is only set if found and successful
  1150.  */
  1151. static char *set_ulong (char *arguments, unsigned long *valuep, 
  1152.                int gt_0_req, int arg_req)
  1153. {
  1154.     char *arg;
  1155.     char *beyondpointer = NULL;
  1156.     unsigned long newvalue;
  1157.  
  1158.     arg = strtok (arguments, " ");
  1159.     if (!arg) /* No argument present */
  1160.     {
  1161.     if (arg_req)
  1162.     {
  1163.         command_error_message (MISSING_ARGUMENT, arguments);
  1164.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  1165.     }
  1166.     return NullString;
  1167.     }
  1168.     errno = 0;
  1169.     newvalue = strtoul (arg, &beyondpointer, 0);
  1170.     if (errno || (newvalue == 0 && gt_0_req))
  1171.     {
  1172.     command_error_message (BAD_ARGUMENT, arg);
  1173.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  1174.     }
  1175.     if (*beyondpointer != ' ' && *beyondpointer != '\0' && 
  1176.     *beyondpointer != '\n')    /* illegal character in number */
  1177.     {
  1178.     command_error_message (BAD_ARGUMENT, beyondpointer);
  1179.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  1180.     }
  1181.     *valuep = newvalue;
  1182.     return beyondpointer;
  1183. }
  1184.  
  1185. /*
  1186.  * Set a double value
  1187.  * handle error, incl. termination by other than NULL, space, or newline
  1188.  * on error, longjmp (to command loop)
  1189.  * a flag determines if value greater than 0 is required
  1190.  * a flag determines if argument is mandatory (then longjmp if not present)
  1191.  * if argument not mandatory, return NullString if no argument found
  1192.  *   otherwise, return string ptr to character following argument
  1193.  *     (this may be a string ptr to a '\0' byte)
  1194.  * value is only set if found and successful
  1195.  */
  1196. static char *set_double (char *arguments, double *valuep,
  1197.                int gt_0_req, int arg_req)
  1198. {
  1199.     char *arg;
  1200.     char *beyondpointer = NULL;
  1201.     double newvalue;
  1202.  
  1203.     arg = strtok (arguments, " ");
  1204.     if (!arg) /* No argument present */
  1205.     {
  1206.     if (arg_req)
  1207.     {
  1208.         command_error_message (MISSING_ARGUMENT, arguments);
  1209.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  1210.     }
  1211.     return NullString;
  1212.     }
  1213.     errno = 0;
  1214.     newvalue = strtod (arg, &beyondpointer);
  1215.     if (errno || (newvalue  <= 0.0L && gt_0_req))
  1216.     {
  1217.     command_error_message (BAD_ARGUMENT, arg);
  1218.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  1219.     }
  1220.     if (*beyondpointer != ' ' && *beyondpointer != '\0' && 
  1221.     *beyondpointer != '\n')    /* illegal character in number */
  1222.     {
  1223.     command_error_message (BAD_ARGUMENT, beyondpointer);
  1224.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  1225.     }
  1226.     *valuep = newvalue;
  1227.     return beyondpointer;  /* beyondpointer points to char past arg */
  1228. }
  1229.  
  1230.  
  1231. static char* get_filename (char *arguments, char **filename_pp)
  1232. {
  1233.     char *arg;
  1234.     char *end;
  1235.     char *name;
  1236.     char old_endc;
  1237.     int len;
  1238.  
  1239.     arg = strtok (arguments, "\n");
  1240.     if (!arg)
  1241.     {
  1242.     if (CommandMode == INTERACTIVE_MODE || 
  1243.         CommandMode == WORKBENCH_MODE)
  1244.     {
  1245.         *filename_pp = NullString;  /* Default to stdin or stdout */
  1246.         return NullString;
  1247.     }
  1248.     else
  1249.     {
  1250.         command_error_message (MISSING_ARGUMENT, arguments);
  1251.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  1252.     }
  1253.     }
  1254.     if (*arg == '\"' || *arg == '\'')  /* filename in quotes */
  1255.     {
  1256.     end = arg + 1;
  1257.     while (*end != '\0' && *end != *arg && *end != '\n')
  1258.     {
  1259.         end++;
  1260.     }
  1261.     if (*end != *arg)
  1262.     {
  1263.         command_error_message (BAD_NAME, end);
  1264.         RAISE_ERROR (NOTHING_SPECIAL);
  1265.     }
  1266.     arg++;         /* Pass initial quote */
  1267.     }
  1268.     else
  1269.     {
  1270.     end = arg;
  1271.     while (*end != '\0' && *end != ' ' && *end != '\n')
  1272.     {
  1273.         end++;
  1274.     }
  1275.     }
  1276.     old_endc = *end;    /* save original termination */
  1277.     *end = '\0';        /* terminate name string */
  1278.     len = strlen (arg);
  1279.     name = gmalloc (len + 1, NOTHING_SPECIAL);    /* Leave room for null! */
  1280.     strcpy (name,arg);
  1281.     *filename_pp = name;
  1282.     if (old_endc != '\0')
  1283.     {
  1284.     *end++ = old_endc;  /* restore original term, then skip it */
  1285.     }
  1286.     return end;
  1287. }
  1288.  
  1289. BOOLEAN is_temp_file (char *filename)
  1290. {
  1291.     char *template = TEMP_NAME_PREFIX;
  1292.     char fchar, tchar;
  1293.  
  1294.     if (!filename || filename == NullString)
  1295.     {
  1296.     return FALSE;
  1297.     }
  1298.  
  1299.     while (tchar = *template++)
  1300.     {
  1301.     if (!(fchar = *filename++)) return FALSE;
  1302.     if (fchar != tchar) return FALSE;
  1303.     }
  1304.     return TRUE;
  1305. }
  1306.