Skip to content
Snippets Groups Projects
atopkge.c 11.92 KiB
/*                        
 
 This file is property of the Colorado School of Mines.
 
 Copyright (C) 2007, Colorado School of Mines,
 All rights reserved.
 
 
 Redistribution and use in source and binary forms, with or 
 without modification, are permitted provided that the following 
 conditions are met:
 
 *  Redistributions of source code must retain the above copyright 
 notice, this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above 
 copyright notice, this list of conditions and the following 
 disclaimer in the documentation and/or other materials provided 
 with the distribution.
 *  Neither the name of the Colorado School of Mines nor the names of
 its contributors may be used to endorse or promote products 
 derived from this software without specific prior written permission.
 
 Warranty Disclaimer:
 THIS SOFTWARE IS PROVIDED BY THE COLORADO SCHOOL OF MINES AND CONTRIBUTORS 
 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 COLORADO SCHOOL OF MINES OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 POSSIBILITY OF SUCH DAMAGE.
 
 
 Export Restriction Disclaimer:
 We believe that CWP/SU: Seismic Un*x is a low technology product that does
 not appear on the Department of Commerce CCL list of restricted exports.
 Accordingly, we believe that our product meets the qualifications of
 an ECCN (export control classification number) of EAR99 and we believe
 it fits the qualifications of NRR (no restrictions required), and
 is thus not subject to export restrictions of any variety.
 
 Approved Reference Format:
 In publications, please refer to SU as per the following example:
 Cohen, J. K. and Stockwell, Jr. J. W., (200_), CWP/SU: Seismic Un*x 
 Release No. __: an open source software  package for seismic 
 research and processing, 
 Center for Wave Phenomena, Colorado School of Mines.
 
 Articles about SU in peer-reviewed journals:
 Saeki, T., (1999), A guide to Seismic Un*x (SU)(2)---examples of data processing (part 1), data input and preparation of headers, Butsuri-Tansa (Geophysical Exploration), vol. 52, no. 5, 465-477.
 Stockwell, Jr. J. W. (1999), The CWP/SU: Seismic Un*x Package, Computers and Geosciences, May 1999.
 Stockwell, Jr. J. W. (1997), Free Software in Education: A case study of CWP/SU: Seismic Un*x, The Leading Edge, July 1997.
 Templeton, M. E., Gough, C.A., (1998), Web Seismic Un*x: Making seismic reflection processing more accessible, Computers and Geosciences.
 
 Acknowledgements:
 SU stands for CWP/SU:Seismic Un*x, a processing line developed at Colorado 
 School of Mines, partially based on Stanford Exploration Project (SEP) 
 software.
 */

/*********************** self documentation **********************/
/***************************************************************************
ATOPKGE - convert ascii to arithmetic and with error checking

 
eatoh		ascii to short
eatou		ascii to unsigned short
eatoi		ascii to int
eatop		ascii to unsigned
eatol		ascii to long
eatov		ascii to unsigned long
eatof		ascii to float
eatod		ascii to double

****************************************************************************
Function Prototypes:
short eatoh(char *s);
unsigned short eatou(char *s);
int eatoi(char *s);
unsigned int eatop(char *s);
long eatol(char *s);
unsigned long eatov(char *s);
float eatof(char *s);
double eatod(char *s);

****************************************************************************
Input:
s		string 

Returned:	type indicated
 
****************************************************************************
Notes:
Each of these routines acts like atoi, but has error checking:

This is a major revision of the tedious code required before
vendors implemented the ANSI C strtol, strtoul and strtod.

In addition to the size checks for each integer type, a
specific test on errno is required.  For example, INT_MAX
may (and probably does) equal LONG_MAX.  In this case,
if fed a number exceeding INT_MAX (and LONG_MAX), strtol
will make a quiet return with the wrong answer and it is up
to the user to check if errno == ERANGE.

Size limits are machine dependent and are read from the
ANSI C include files limits.h and float.h.

Bug Report: With NeXT c and Gnucc, when x > DBL_MAX (x <-DBL_MAX),
the return value from strtod was +Infinity (-Infinity), not HUGE_VAL
and more important, errno was not set to ERANGE.  To cope with this,
I put explicit size checks in eatod (which would not be needed if
errno were set as it should be in ANSI C.    jkc 01/29/94

On IBM RS6000, the return value from strtod was +-Inf on
overflow, but errno was set correctly.

****************************************************************************
References:
For old code:
Plum: Reliable Data Structures in C, p. 2-17.
Kernighan and Ritchie: The C Programming Language, p. 58.

CWP: Jack K. Cohen, Brian Sumner
 
For new code:
ANSI C routines with a little help from Jack

****************************************************************************
Author: Jack Cohen, Center for Wave Phenomena, 1994.
***************************************************************************/
/**************** end self doc ********************************/

#include "par.h"
#include <float.h>
#include <limits.h>
#include <stdarg.h>
#include <errno.h>

/* eatoh - convert string s to short integer {SHRT_MIN:SHRT_MAX} */
short eatoh(char *s)
{
	long n = strtol(s, NULL, 10);
	
	if ( (n > SHRT_MAX) || (n < SHRT_MIN) || (errno == ERANGE) )
		err("%s: eatoh: overflow", __FILE__);

	return (short) n;
}


/* eatou - convert string s to unsigned short integer {0:USHRT_MAX} */
unsigned short eatou(char *s)
{
	unsigned long n = strtoul(s, NULL, 10);

	if ( (n > USHRT_MAX) || (errno == ERANGE) )
		err("%s: eatou: overflow", __FILE__);

	return (unsigned short) n;
}


/* eatoi - convert string s to integer {INT_MIN:INT_MAX} */
int eatoi(char *s)
{
	long n = strtol(s, NULL, 10);

	if ( (n > INT_MAX) || (n < INT_MIN) || (errno == ERANGE) )
		err("%s: eatoi: overflow", __FILE__);

	return (int) n;
}


/* eatop - convert string s to unsigned integer {0:UINT_MAX} */
unsigned int eatop(char *s)
{
	unsigned long n = strtoul(s, NULL, 10);

	if ( (n > UINT_MAX) || (errno == ERANGE) )
		err("%s: eatop: overflow", __FILE__);

	return (unsigned int) n;
}


/* eatol - convert string s to long integer {LONG_MIN:LONG_MAX} */
long eatol(char *s)
{
	long n = strtol(s, NULL, 10);

	if (errno == ERANGE)
		err("%s: eatol: overflow", __FILE__);

	return n;
}


/* eatov - convert string s to unsigned long {0:ULONG_MAX} */
unsigned long eatov(char *s)
{
	unsigned long n = strtoul(s, NULL, 10);

	if (errno == ERANGE)
		err("%s: eatov: overflow", __FILE__);

	return n;
}


/* eatof - convert string s to float {-FLT_MAX:FLT_MAX} */
float eatof(char *s)
{
	float x = strtod(s, NULL);

	if ( (x > FLT_MAX) || (x < -FLT_MAX) || (errno == ERANGE) )
		err("%s: eatof: overflow", __FILE__);

	return (float) x;
}


/* eatod - convert string s to double {-DBL_MAX:DBL_MAX} */
double eatod(char *s)
{
	double x = strtod(s, NULL);

	/* errno == ERANGE suffices if compiler sets errno on overflow */
	if ( (errno == ERANGE) || (x > DBL_MAX) || (x < -DBL_MAX) )
		err("%s: eatod: overflow", __FILE__);

	return x;
}


/**************************************************************************
ERRPKGE - routines for reporting errors

err	print warning on application program error and die
warn	print warning on application program error
syserr	print warning on application program error using errno and die

***************************************************************************
Function Prototypes:
void err (char *fmt, ...);
void warn (char *fmt, ...);
void syserr (char *fmt, ...);

***************************************************************************
Return: void

***************************************************************************
Notes:
fmt		a printf format string ("\n" not needed)
...		the variables referenced in the format string

Examples:
	err("Cannot divide %f by %f", x, y);
	warn("fmax = %f exceeds half nyquist= %f", fmax, 0.25/dt);
 
	if (NULL == (fp = fopen(xargv[1], "r")))
 		err("can't open %s", xargv[1]);
 	...
 	if (-1 == close(fd))
 		err("close failed");

***************************************************************************
References:
Kernighan and Pike, "The UNIX Programming Environment", page 207.
Also Rochkind, "Advanced UNIX Programming", page 13.

***************************************************************************
Authors:SEP: Jeff Thorson, Stew Levin	CWP: Shuki Ronen, Jack Cohen
**************************************************************************/

void err(char *fmt, ...)
{
	va_list args;

 
	if (EOF == fflush(stdout)) {
		fprintf(stderr, "\nerr: fflush failed on stdout");
	}
	fprintf(stderr, "\n%s: ", xargv[0]);
	va_start(args,fmt);
	vfprintf(stderr, fmt, args);
	va_end(args);
	fprintf(stderr, "\n");
	exit(EXIT_FAILURE);
}


void warn(char *fmt, ...)
{
	va_list args;

	if (EOF == fflush(stdout)) {
		fprintf(stderr, "\nwarn: fflush failed on stdout");
	}
	fprintf(stderr, "\n%s: ", xargv[0]);
	va_start(args,fmt);
	vfprintf(stderr, fmt, args);
	va_end(args);
	fprintf(stderr, "\n");
	return;
}


void syserr(char *fmt, ...)
{
    va_list args;

    if (EOF == fflush(stdout)) {
        fprintf(stderr, "\nsyserr: fflush failed on stdout");
    }
    fprintf(stderr, "\n%s: ", xargv[0]);
    va_start(args,fmt);
    vfprintf(stderr, fmt, args);
    va_end(args);
    fprintf(stderr, " (%s)\n", strerror(errno));
    exit(EXIT_FAILURE);
}

#ifdef TEST
main(int argc, char **argv)
{
	char s[BUFSIZ];
	short nh;
	unsigned short nu;
	int ni;
	unsigned int np;
	long nl;
	unsigned long nv;

	initargs(argc, argv);


	/* Test code for eatoh */
	if (SHRT_MAX == LONG_MAX) {
	    warn("Warning: eatoh not used on this machine.\n");
	} else {
	    warn("\n");
	}
	strcpy(s, "0");
	nh = eatoh(s);
	warn("eatoh(%s) = %hd\n", s, nh);

	strcpy(s, "32767");
	nh = eatoh(s);
	warn("eatoh(%s) = %hd\n", s, nh);

	strcpy(s, "-32768");
	nh = eatoh(s);
	warn("eatoh(%s) = %hd\n", s, nh);


	/* Test code for eatou */
	if (USHRT_MAX == ULONG_MAX) {
	    warn("Warning: eatou not used on this machine.\n");
	} else {
	    warn("\n");
	}
	strcpy(s, "0");
	nu = eatou(s);
	warn("eatou(%s) = %hu\n", s, nu);

	strcpy(s, "65535");
	nu = eatou(s);
	warn("eatou(%s) = %hu\n", s, nu);


	/* Test code for eatoi */
	if (INT_MAX == LONG_MAX) {
	    warn("Warning: eatoi not used on this machine.\n");
	} else {
	    warn("\n");
	}
	strcpy(s, "0");
	ni = eatoi(s);
	warn("eatoi(%s) = %d\n", s, ni);

	strcpy(s, "2147483647");
	ni = eatoi(s);
	warn("eatoi(%s) = %d\n", s, ni);


	strcpy(s, "-2147483648");
	ni = eatoi(s);
	warn("eatoi(%s) = %d\n", s, ni);


	/* Test code for eatop */
	if (INT_MAX == LONG_MAX) {
	    warn("Warning: eatop not used on this machine.\n");
	} else {
	    warn("\n");
	}
	strcpy(s, "0");
	np = eatop(s);
	warn("eatop(%s) = %lu\n", s, np);

	strcpy(s, "4294967295");
	np = eatop(s);
	warn("eatop(%s) = %lu\n", s, np);


	/* Test code for eatol */
	warn("\n");
	strcpy(s, "0");
	nl = eatol(s);
	warn("eatol(%s) = %ld\n", s, nl);

	strcpy(s, "2147483647");
	nl = eatol(s);
	warn("eatol(%s) = %ld\n", s, nl);

	strcpy(s, "-2147483648");
	nl = eatol(s);
	warn("eatol(%s) = %ld\n", s, nl);


	/* Test code for eatov */
	strcpy(s, "0");
	nv = eatov(s);
	warn("eatov(%s) = %lu\n", s, nv);

	strcpy(s, "4294967295");
	nv = eatov(s);
	warn("eatov(%s) = %lu\n", s, nv);

	warn("Now we feed in 4294967296, expecting fatal error exit\n");
	strcpy(s, "4294967296");
	nv = eatov(s);
	warn("eatov(%s) = %lu\n", s, nv);

	return EXIT_SUCCESS;
}
#endif