/*************************************************************************** * 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 gfft.c, or run program itself, for details. * * Support is available for a fee. * *************************************************************************** * * Program: gfft--General FFT analysis * File: settings.c * Purpose: set values, names, and operation types * Author: Charles Peterson (CPP) * History: 31-May-1993 CPP; Created. * 9-Aug-94 CPP (1.10); Hidden3D option * 19-Jan-95 CPP (1.21); Topaz command * 10-Feb-95 CPP (1.39; save settings or parameters * 14-Feb-95 CPP (1.42); PlotCommands */ #include /* printf */ #include /* strtok, strlen */ #include /* strtoul */ #include /* errno */ #include "gfft.h" #define DEFINE_HERE #include "settings.h" #undef DEFINE_HERE extern Name_Info_St Gfft_Command[]; /* GFFT commands */ static char *set_ulong (char *arguments, unsigned long *longp, int gt_0_req, int arg_req); static char *set_double (char *arguments, double *doublep, int gt_0_req, int arg_req); static char *get_filename (char *arguments, char **filename_pp); static char *add_calibration (char *arguments, BOOLEAN db_scale); char *set (char *arguments) { /* * Dummy command which invokes its arguments as a command string */ if (arguments && arguments != NullString) { invoke_method (arguments, Gfft_Command); } return arguments; } /* * Functions to set various parameters */ char *set_time_offset (char *arguments) { char *more_arguments; ULONG time_offset; TimeOffset = INVALID_SET; /* unless this succeeds */ more_arguments = set_ulong (arguments, &time_offset, FALSE, FALSE); if (more_arguments == NullString) { TimeOffset = NOT_SET; } else { Time3D = TRUE; if (time_offset > 0 && time_offset < LONG_MAX) { TimeOffset = (long) time_offset; } else { command_error_message (BAD_ARGUMENT, more_arguments-1); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } } return more_arguments; } char *set_time_segments (char *arguments) { char *more_arguments; ULONG time_segments; TimeSegments = INVALID_SET; /* unless this succeeds */ more_arguments = set_ulong (arguments, &time_segments, FALSE, FALSE); if (more_arguments == NullString) { TimeSegments = NOT_SET; } else { Time3D = TRUE; TimeSegSize = NOT_SET; if (time_segments > 0 && time_segments < LONG_MAX) { TimeSegments = (long) time_segments; } else { command_error_message (BAD_ARGUMENT, more_arguments-1); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } } return more_arguments; } char *set_key (char *arguments) { char *more_arguments; more_arguments = set_ulong (arguments, &Key, FALSE, FALSE); return more_arguments; } char *set_time_seg_size (char *arguments) { char *more_arguments; ULONG time_seg_size; TimeSegSize = INVALID_SET; /* unless this succeeds */ more_arguments = set_ulong (arguments, &time_seg_size, FALSE, FALSE); if (more_arguments == NullString) { TimeSegSize = NOT_SET; } else { Time3D = TRUE; TimeSegments = NOT_SET; if (time_seg_size > 0 && time_seg_size < LONG_MAX) { TimeSegSize = (long) time_seg_size; } else { command_error_message (BAD_ARGUMENT, more_arguments-1); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } } return more_arguments; } char *set_smoothing_segments (char *arguments) { char *more_arguments; ULONG smoothing_segs; SmoothingSegments = INVALID_SMOOTHING; /* unless this succeeds */ more_arguments = set_ulong (arguments, &smoothing_segs, TRUE, FALSE); if (more_arguments == NullString) { SmoothingSegments = NO_SMOOTHING; } else { if (smoothing_segs <= LONG_MAX) { SmoothingSegments = (long) smoothing_segs; } else { command_error_message (BAD_ARGUMENT, more_arguments-1); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } } return more_arguments; } char *set_time_3d (char *arguments) { Time3D = TRUE; return arguments; } char *set_no_time_3d (char *arguments) { Time3D = FALSE; return arguments; } char *set_hidden_3d (char *arguments) { Hidden3D = TRUE; return arguments; } char *set_no_hidden_3d (char *arguments) { Hidden3D = FALSE; return arguments; } char *set_signed (char *arguments) { InputFormat.zero = 0; return arguments; } char *set_unsigned (char *arguments) { int sample_width = (InputFormat.bits > 8) ? 16 : 8; InputFormat.zero = ((unsigned long) 0xffffffff >> (33 - sample_width)) + (unsigned long) 1; /* * This is re-done at time of 'ok' command to be sure bits spec is final */ return arguments; } char *set_terminal (char *arguments) { char *more_arguments; char *terminal; if (Terminal && Terminal != NullString) { gfree (Terminal); Terminal = NULL; } more_arguments = get_filename (arguments, &terminal); if (terminal == NullString || strlen (terminal) == 0) { Terminal = NULL; } else { Terminal = terminal; } return more_arguments; } char *set_plot_output (char *arguments) { char *more_arguments; char *plot_output; if (PlotOutput && PlotOutput != NullString) { gfree (PlotOutput); PlotOutput = NULL; } more_arguments = get_filename (arguments, &plot_output); if (plot_output == NullString || strlen (plot_output) == 0) { PlotOutput = NULL; } else { PlotOutput = plot_output; } return more_arguments; } char *set_save_memory (char *arguments) { SaveMemory = TRUE; return arguments; } char *set_no_save_memory (char *arguments) { SaveMemory = FALSE; return arguments; } char *set_psdensity (char *arguments) { PSDensity = TRUE; return arguments; } char *set_no_psdensity (char *arguments) { PSDensity = FALSE; return arguments; } char *set_squared_smoothing (char *arguments) { SquaredSmoothing = TRUE; return arguments; } char *set_no_squared_smoothing (char *arguments) { SquaredSmoothing = FALSE; return arguments; } char *set_combine_plots (char *arguments) { extern int Old_File_Count; if (!CombinePlots) { CombinePlots = TRUE; Old_File_Count = (Old_File_Count > 0) ? 1 : 0; } return arguments; } char *set_no_combine_plots (char *arguments) { CombinePlots = FALSE; Old_File_Count = 0; return arguments; } char *cut_combined_plot (char *arguments) { if (Old_File_Count > 0) Old_File_Count--; return arguments; } char *set_db (char *arguments) { Db = TRUE; return arguments; } char *set_header (char *arguments) { Header = TRUE; return arguments; } char *set_no_header (char *arguments) { Header = FALSE; return arguments; } char *set_logx (char *arguments) { LogX = TRUE; return arguments; } char *set_logy (char *arguments) { LogY = TRUE; return arguments; } char *set_no_logx (char *arguments) { LogX = FALSE; return arguments; } char *set_no_logy (char *arguments) { LogY = FALSE; return arguments; } char *set_no_db (char *arguments) { Db = FALSE; return arguments; } char *set_time_overlap (char *arguments) { char *beyond_argument; TimeOverlap = INVALID_SET; beyond_argument = set_double (arguments, &TimeOverlap, FALSE, FALSE); if (beyond_argument == NullString) { TimeOverlap = DEFAULT_TIME_OVERLAP; } else { Time3D = TRUE; TimeOffset = NOT_SET; if (TimeOverlap >= 1.0 || TimeOverlap < 0.0) { TimeOverlap = INVALID_SET; command_error_message (BAD_ARGUMENT, beyond_argument-1); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } } return beyond_argument; } char *set_no_quantization (char *arguments) { Quantization = MIN_QUANTIZATION; return arguments; } char *set_quantization (char *arguments) { double quantization = 0.0; char *beyond_argument; Quantization = BAD_QUANTIZATION; beyond_argument = set_double (arguments, &quantization, FALSE, FALSE); if (beyond_argument == NullString || quantization == 0.0) { Quantization = MIN_QUANTIZATION; /* Default value if no argument */ } else if (quantization < 0.0) { command_error_message (BAD_ARGUMENT, arguments); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } else { Quantization = quantization; } return beyond_argument; } char *set_multiply (char *arguments) { char *beyond_argument; beyond_argument = set_double (arguments, &Multiply, FALSE, FALSE); if (beyond_argument == NullString) { Multiply = 1.0L; /* Default value if no argument */ } return beyond_argument; } char *set_no_one_shot_only (char *arguments) { OneShotOnly = FALSE; return arguments; } char *set_topaz (char *arguments) { Topaz = TRUE; return arguments; } char *set_no_repeat_only (char *arguments) { RepeatOnly = FALSE; return arguments; } char *set_bits (char *arguments) { char *more_arguments; ULONG bits; more_arguments = set_ulong (arguments, &bits, TRUE, FALSE); if (more_arguments == NullString) { bits = DEFAULT_INPUT_BITS; } else if (1 > bits || bits > 16) { command_error_message (BAD_ARGUMENT, arguments); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } else { InputFormat.bits = bits; } return more_arguments; } char *set_octave (char *arguments) { char *more_arguments; more_arguments = set_ulong (arguments, &Octave, FALSE, FALSE); if (more_arguments == NullString) { Octave = 1L; } return more_arguments; } char *set_one_shot_only (char *arguments) { OneShotOnly = TRUE; RepeatOnly = FALSE; return arguments; } char *set_repeat_only (char *arguments) { RepeatOnly = TRUE; OneShotOnly = FALSE; return arguments; } char *set_ignore_format (char *arguments) { IgnoreFormat = TRUE; return arguments; } char *set_no_ignore_format (char *arguments) { IgnoreFormat = FALSE; return arguments; } char *set_pink (char *arguments) { Pink = TRUE; return arguments; } char *set_no_pink (char *arguments) { Pink = FALSE; return arguments; } char *set_parseval (char *arguments) { Parseval = TRUE; return arguments; } char *set_no_parseval (char *arguments) { Parseval = FALSE; return arguments; } char *set_overlap (char *arguments) { Overlap = TRUE; return arguments; } char *set_no_overlap (char *arguments) { Overlap = FALSE; return arguments; } char *set_high_frequency (char *arguments) { char *more_arguments; more_arguments = set_double (arguments, &HighFrequency, FALSE, FALSE); if (more_arguments == NullString) { HighFrequency = HIGHEST_FREQUENCY; /* No arg, return to default */ } return more_arguments; } char *set_low_frequency (char *arguments) { char *more_arguments; more_arguments = set_double (arguments, &LowFrequency, FALSE, FALSE); if (more_arguments == NullString) { LowFrequency = LOWEST_FREQUENCY; /* No arg, return to default */ } return more_arguments; } char *set_low_y (char *arguments) { char *more_arguments; more_arguments = set_double (arguments, &LowY, FALSE, FALSE); if (more_arguments == NullString) { LowY = LOWEST_Y; /* No arg, return to default */ } return more_arguments; } char *set_high_y (char *arguments) { char *more_arguments; more_arguments = set_double (arguments, &HighY, FALSE, FALSE); if (more_arguments == NullString) { HighY = HIGHEST_Y; /* No arg, return to default */ } return more_arguments; } char *set_channel (char *arguments) { char *more_arguments; Channel = 0L; /* Purposely set to invalid value here */ more_arguments = set_ulong (arguments, &Channel, TRUE, FALSE); if (more_arguments == NullString) { Channel = 1L; /* Return to default if no argument */ } if (Channel > FileChannels || Channel < 1) { error_message (SPEC_CHANNEL_UNAVAIL); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } return more_arguments; } char *set_start_byte (char *arguments) { char *more_arguments; more_arguments = set_ulong (arguments, &StartByte, FALSE, FALSE); if (more_arguments == NullString) { StartByte = 0; /* Return to default if no argument */ } return more_arguments; } char *set_start_frame (char *arguments) { char *more_arguments; more_arguments = set_ulong (arguments, &StartFrame, FALSE, FALSE); if (more_arguments == NullString) { StartFrame = 0; /* Return to default if no argument */ } return more_arguments; } char *set_frames (char *arguments) { char *more_arguments; more_arguments = set_ulong (arguments, &Frames, FALSE, FALSE); if (more_arguments == NullString) { Frames = ULONG_MAX; /* Return to default if no argument */ } return more_arguments; } char *set_pad (char *arguments) { Pad = TRUE; return arguments; } char *set_no_pad (char *arguments) { Pad = FALSE; return arguments; } char *set_no_numerical (char *arguments) { Numerical = FALSE; return arguments; } char *set_numerical (char *arguments) { #ifdef NUMERICAL_RECIPES_AVAILABLE Numerical = TRUE; #else error_message (NO_NUMERICAL); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ #endif return arguments; } #define GNUPLOT 1 static char *set_plot_gnuplot (char *arguments) { Plot = GNUPLOT_PLOT; return arguments; } static Name_Info_St plotter_names[] = { {"GNUPLOT","G", set_plot_gnuplot}, {"","", default_argument}, }; char *set_plot (char *arguments) { char *arg; arg = strtok (arguments, " "); if (!arg) /* No argument present */ { Plot = ANY_PLOT; /* use the default plotter */ } else { invoke_method (arg, plotter_names); } return arguments; } char *set_no_plot (char *arguments) { Plot = NO_PLOT; return arguments; } #define ASCII 1 #define BINARY 2 static char *set_output_format_binary (char *arguments) { OutputFormat.binary = TRUE; return arguments; } static char *set_output_format_ascii (char *arguments) { OutputFormat.binary = FALSE; return arguments; } static Name_Info_St output_format_names[] = { {"ASCII","A", set_output_format_ascii}, {"BINARY","B", set_output_format_binary}, {"","", default_argument}, }; char *set_output (char *arguments) { char *arg; arg = strtok (arguments, " "); if (!arg) /* No argument present */ { command_error_message (MISSING_ARGUMENT, arguments); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } invoke_method (arg, output_format_names); return arguments; } char *set_amplitude (char *arguments) { Amplitude = TRUE; Power = FALSE; return arguments; } char *set_power (char *arguments) { Power = TRUE; Amplitude = FALSE; return arguments; } char *set_fft (char *arguments) { Power = FALSE; Amplitude = FALSE; return arguments; } char *set_mean (char *arguments) { Mean = TRUE; return arguments; } char *set_sum (char *arguments) { Mean = FALSE; return arguments; } char *set_hann (char *arguments) { WindowType = HANN_WINDOW; return arguments; } char *set_hamming (char *arguments) { WindowType = HAMMING_WINDOW; return arguments; } char *set_parzen (char *arguments) { WindowType = PARZEN_WINDOW; return arguments; } char *set_rectangle (char *arguments) { WindowType = RECTANGLE_WINDOW; return arguments; } char *set_triangle (char *arguments) { WindowType = TRIANGLE_WINDOW; return arguments; } char *set_blackman_harris_74db (char *arguments) { WindowType = BLACKMAN_HARRIS_74DB_WINDOW; return arguments; } char *set_blackman_harris_92db (char *arguments) { WindowType = BLACKMAN_HARRIS_92DB_WINDOW; return arguments; } char *set_welch (char *arguments) { WindowType = WELCH_WINDOW; return arguments; } char *set_rotation_x (char *arguments) { char *more_arguments; double rot_x; RotX = INVALID_ROTATION; more_arguments = set_double (arguments, &rot_x, FALSE, FALSE); if (more_arguments == NullString) { RotX = DEF_ROT_X; } else if (0. <= rot_x && rot_x <= 180.) { RotX = rot_x; } else { command_error_message (BAD_ARGUMENT, arguments); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } return more_arguments; } char *set_rotation_z (char *arguments) { char *more_arguments; double rot_z; RotZ = INVALID_ROTATION; more_arguments = set_double (arguments, &rot_z, FALSE, FALSE); if (more_arguments == NullString) { RotZ = DEF_ROT_Z; } else if (0. <= rot_z && rot_z <= 360.) { RotZ = rot_z; } else { command_error_message (BAD_ARGUMENT, arguments); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } return more_arguments; } char *set_rate (char *arguments) { char *more_arguments; Rate = INVALID_RATE; /* Preset to rate */ more_arguments = set_double (arguments, &Rate, TRUE, FALSE); if (more_arguments == NullString) { Rate = AUTO_RATE; /* Set to rate */ } return more_arguments; } char *set_interleave (char *arguments) { char *end_argument; ULONG interleave = 0; Interleave = INVALID_INTERLEAVE; /* Force flagged value on error */ end_argument = set_ulong (arguments, &interleave, TRUE, TRUE); if (interleave < 2) { command_error_message (BAD_ARGUMENT, end_argument-1); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } else { Interleave = interleave; } return end_argument; } char *set_no_interleave (char *arguments) { Interleave = 1; return arguments; } char *set_bins (char *arguments) { unsigned long bins = 1; unsigned long okbins = 1; char *new_arguments; NumberBins = INVALID_BINS; /* Preset invalid value in case of error */ new_arguments = set_ulong (arguments, &bins, FALSE, FALSE); if (new_arguments != NullString) { if (bins == 0) { NumberBins = 0; return new_arguments; } okbins = get_pos_power_2 (bins); if (okbins > LONG_MAX) { okbins = get_pos_power_2 (LONG_MAX / 2L); } NumberBins = (long) okbins; if (NumberBins != bins) { bins_s_message (); } } else { NumberBins = MAX_BINS; /* Default...based on data count of file */ } return new_arguments; } unsigned long get_pos_power_2 (unsigned long i) { unsigned long j = 1; /* minimum useful value */ unsigned long max = ULONG_MAX / 2; /* max value we can safely handle */ for (j = 1; j < max; j *= 2) { if (j >= i) break; } return j; } char *set_no_calibrations (char *arguments) { calibration_list__cancel (&CalibrationList); CalibrationList = NULL; return arguments; } char *set_db_calibration (char *arguments) { arguments = add_calibration (arguments, TRUE); return arguments; } char *set_calibration (char *arguments) { arguments = add_calibration (arguments, FALSE); return arguments; } static char *add_calibration (char *arguments, BOOLEAN db_scale) { char *more_arguments; FILE *cal_file; char *cal_name; more_arguments = get_filename (arguments, &cal_name); if (cal_name == NullString) { command_error_message (MISSING_ARGUMENT, arguments); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here */ } if (!(cal_file = fopen (cal_name,"r"))) { error_message (CANT_OPEN_INPUT_FILE); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here */ } calibration_list__add (&CalibrationList, cal_name, cal_file, db_scale); return more_arguments; } char *load_settings (char *arguments) { char *more_arguments; char *filename; FILE *fptr; more_arguments = get_filename (arguments, &filename); if (filename == NullString) { command_error_message (MISSING_ARGUMENT, arguments); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } if (!(fptr = fopen (filename,"r"))) { error_message (CANT_OPEN_INPUT_FILE); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } CATCH_ERROR { execute_file_commands (fptr); } END_CATCH_ERROR; fclose (fptr); return more_arguments; } char *set_read (char *arguments) { char *more_arguments; if (ReadName && ReadName != NullString) { gfree (ReadName); ReadName = NullString; } if (ReadPtr != NULL && ReadPtr != stdin) { fclose (ReadPtr); } if (Save_Data) { gfree (Save_Data); Save_Data = NULL; } more_arguments = get_filename (arguments, &ReadName); if (ReadName == NullString) { reset_format (); ReadPtr = NULL; ReadName = NULL; return more_arguments; } if (strlen (ReadName) == 4 && !strcmp (ReadName,"con:")) { reset_format (); ReadPtr = stdin; return more_arguments; } if (!(ReadPtr = fopen (ReadName,"r"))) { error_message (CANT_OPEN_INPUT_FILE); reset_format (); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } else { read_format (); } return more_arguments; } char *set_append (char *arguments) { char *more_arguments; Appending = FALSE; if (WriteName && WriteName != NullString) { /* gfree (WriteName); aliased name! unsafe to free! */ WriteName = NullString; } if (WritePtr != NULL && WritePtr != stdout) { fclose (WritePtr); } WritePtr = NULL; more_arguments = get_filename (arguments, &WriteName); if (WriteName == NullString) { Appending = TRUE; WriteName = NULL; return more_arguments; } WritePtr = fopen (WriteName,"a"); if (!WritePtr) { error_message (CANT_CREATE_OUTPUT_FILE); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } Appending = TRUE; return more_arguments; } char *set_write (char *arguments) { /* * The following is intended to maximize portability * by using (ultimately) only ANSI C functions and notions * * Note: If the first characters match the TEMP_DATAFILE_NAME, the * previous version will be overwritten with impunity, otherwise: * if a file exists with the same name, it will be renamed to backup. * Only one level of backup files is created. * It will fail if filesystem does not allow a one character suffix. * If the backup fails, file is not opened for output. */ char *more_arguments; FILE *temp_ptr; Appending = FALSE; if (WriteName && WriteName != NullString) { /* gfree (WriteName); aliased name! unsafe to free! */ WriteName = NullString; } if (WritePtr != NULL && WritePtr != stdout) { fclose (WritePtr); } WritePtr = NULL; more_arguments = get_filename (arguments, &WriteName); if (WriteName == NullString) { WriteName = NULL; return more_arguments; } if (strlen (WriteName) == 4 && !strcmp (WriteName,"con:")) { WritePtr = stdout; return more_arguments; } if (!is_temp_file (WriteName)) { if (temp_ptr = fopen (WriteName,"r")) { int oldlen; char *newname; int old_backup_deleted = FALSE; fclose (temp_ptr); oldlen = strlen (WriteName); newname = gmalloc (oldlen + 2, NOTHING_SPECIAL); strcpy (newname, WriteName); newname[oldlen] = BACKUP_FILE_CHARACTER; newname[oldlen + 1] = '\0'; if (temp_ptr = fopen (newname,"r")) { old_backup_deleted = TRUE; fclose (temp_ptr); remove (newname); } if (rename (WriteName, newname)) { error_message (OUTPUT_BACKUP_FAILURE); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } else if (old_backup_deleted) { error_message (BACKUP_OVERWRITTEN); /* Warning only. */ } else { error_message (BACKUP_CREATED); /* Warning only. */ } gfree (newname); } } WritePtr = fopen (WriteName,"w"); if (!WritePtr) { error_message (CANT_CREATE_OUTPUT_FILE); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } return more_arguments; } char *clear_plot_commands (char *arguments) { PlotCommands = NULL; return arguments; } char *add_plot_command (char *arguments) { struct list_st **plot_basep = &PlotCommands; char *command; while (*plot_basep != NULL) { plot_basep = &((*plot_basep)->next); } *plot_basep = (struct list_st *) gcalloc (1, sizeof (struct list_st), NOTHING_SPECIAL); command = (char *) gmalloc (1+strlen(arguments), NOTHING_SPECIAL); strcpy (command, arguments); (*plot_basep)->node = (void *) command; (*plot_basep)->next = NULL; return NullString; } void write_plot_commands (FILE *fp, char *cstr, char *name, struct list_st *plot_commands) { while (plot_commands) { /* fortunately, GNUPLOT ignores leading whitespace */ fprintf (fp, "%s%s %s\n", cstr, name, (char *) plot_commands->node); plot_commands = plot_commands->next; } } /* Utility functions *****************************************************/ /* * Set an unsigned long value * decimal, octal, or hex accepted * handle error, incl. termination by other than NULL, space, or newline * on error, longjmp (to command loop) * a flag determines if value greater than 0 is required * a flag determines if argument is mandatory (then longjmp if not present) * if argument not mandatory, return NullString if no arg found, * otherwise, return string pointer to first char past end of filename * (this may be simply a pointer to a '\0' byte) * value is only set if found and successful */ static char *set_ulong (char *arguments, unsigned long *valuep, int gt_0_req, int arg_req) { char *arg; char *beyondpointer = NULL; unsigned long newvalue; arg = strtok (arguments, " "); if (!arg) /* No argument present */ { if (arg_req) { command_error_message (MISSING_ARGUMENT, arguments); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } return NullString; } errno = 0; newvalue = strtoul (arg, &beyondpointer, 0); if (errno || (newvalue == 0 && gt_0_req)) { command_error_message (BAD_ARGUMENT, arg); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } if (*beyondpointer != ' ' && *beyondpointer != '\0' && *beyondpointer != '\n') /* illegal character in number */ { command_error_message (BAD_ARGUMENT, beyondpointer); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } *valuep = newvalue; return beyondpointer; } /* * Set a double value * handle error, incl. termination by other than NULL, space, or newline * on error, longjmp (to command loop) * a flag determines if value greater than 0 is required * a flag determines if argument is mandatory (then longjmp if not present) * if argument not mandatory, return NullString if no argument found * otherwise, return string ptr to character following argument * (this may be a string ptr to a '\0' byte) * value is only set if found and successful */ static char *set_double (char *arguments, double *valuep, int gt_0_req, int arg_req) { char *arg; char *beyondpointer = NULL; double newvalue; arg = strtok (arguments, " "); if (!arg) /* No argument present */ { if (arg_req) { command_error_message (MISSING_ARGUMENT, arguments); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } return NullString; } errno = 0; newvalue = strtod (arg, &beyondpointer); if (errno || (newvalue <= 0.0L && gt_0_req)) { command_error_message (BAD_ARGUMENT, arg); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } if (*beyondpointer != ' ' && *beyondpointer != '\0' && *beyondpointer != '\n') /* illegal character in number */ { command_error_message (BAD_ARGUMENT, beyondpointer); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } *valuep = newvalue; return beyondpointer; /* beyondpointer points to char past arg */ } static char* get_filename (char *arguments, char **filename_pp) { char *arg; char *end; char *name; char old_endc; int len; arg = strtok (arguments, "\n"); if (!arg) { if (CommandMode == INTERACTIVE_MODE || CommandMode == WORKBENCH_MODE) { *filename_pp = NullString; /* Default to stdin or stdout */ return NullString; } else { command_error_message (MISSING_ARGUMENT, arguments); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } } if (*arg == '\"' || *arg == '\'') /* filename in quotes */ { end = arg + 1; while (*end != '\0' && *end != *arg && *end != '\n') { end++; } if (*end != *arg) { command_error_message (BAD_NAME, end); RAISE_ERROR (NOTHING_SPECIAL); } arg++; /* Pass initial quote */ } else { end = arg; while (*end != '\0' && *end != ' ' && *end != '\n') { end++; } } old_endc = *end; /* save original termination */ *end = '\0'; /* terminate name string */ len = strlen (arg); name = gmalloc (len + 1, NOTHING_SPECIAL); /* Leave room for null! */ strcpy (name,arg); *filename_pp = name; if (old_endc != '\0') { *end++ = old_endc; /* restore original term, then skip it */ } return end; } BOOLEAN is_temp_file (char *filename) { char *template = TEMP_NAME_PREFIX; char fchar, tchar; if (!filename || filename == NullString) { return FALSE; } while (tchar = *template++) { if (!(fchar = *filename++)) return FALSE; if (fchar != tchar) return FALSE; } return TRUE; } ULONG magic_number (char *string) { ULONG magic = 0; for (;*string;magic+=*string,string++); return magic; } char *save_settings (char *arguments) { return save_settings_or_parameters (arguments, FALSE); } char *save_parameters (char *arguments) { return save_settings_or_parameters (arguments, TRUE); } char *save_settings_or_parameters (char *arguments, BOOLEAN parameters_only) { /* * This follows much of the same logic as is used for opening a spectrum * * If a file exists with the same name, it will be renamed to backup. * Only one level of backup files is created. * It will fail if filesystem does not allow a one character suffix. * If the backup fails, file is not opened for output. */ char *more_arguments; FILE *temp_ptr = NULL; FILE *savefile_ptr = NULL; char *savefile_name; more_arguments = get_filename (arguments, &savefile_name); if (savefile_name == NullString) { command_error_message (MISSING_ARGUMENT, arguments); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } if (temp_ptr = fopen (savefile_name, "r")) { int oldlen; char *newname; int old_backup_deleted = FALSE; fclose (temp_ptr); oldlen = strlen (savefile_name); newname = gmalloc (oldlen + 2, NOTHING_SPECIAL); strcpy (newname, savefile_name); newname[oldlen] = BACKUP_FILE_CHARACTER; newname[oldlen + 1] = '\0'; if (temp_ptr = fopen (newname,"r")) { old_backup_deleted = TRUE; fclose (temp_ptr); remove (newname); } if (rename (savefile_name, newname)) { error_message (OUTPUT_BACKUP_FAILURE); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } else if (old_backup_deleted) { error_message (BACKUP_OVERWRITTEN); /* Warning only. */ } else { error_message (BACKUP_CREATED); /* Warning only. */ } gfree (newname); } savefile_ptr = fopen (savefile_name,"w"); if (!savefile_ptr) { error_message (CANT_CREATE_OUTPUT_FILE); RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */ } write_settings (savefile_ptr, NullString, parameters_only, parameters_only); fclose (savefile_ptr); return more_arguments; }