/* @(#)traf.c 17.1.1.1 (ES0-DMD) 01/25/02 17:47:38 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*+++++++++ .MODULE traf.c .AUTHOR Francois Ochsenbein [ESO] .LANGUAGE C .CATEGORY Conversion from character to double. .COMMENTS .VERSION 1.0 20-Oct-1988: Creation -----------------------------------------------*/ #include #include #include #define issign(c) ((c == '+') || (c == '-')) #define FINISH goto FIN #define GobbleSpaces(s,l) s += oscspan(s, l, _SPACE_, main_ascii) MID_EXTERN struct trerr_s *trerror; MID_STATIC char *stopped; /* To communicate the stopping char */ /*===========================================================================*/ static int traf(str, len, value) /*++++++ .PURPOSE Converts a string to a floating point. Input is assumed to be in decimal. .RETURNS Number of significant digits / -1 for error (message logged) .REMARKS Return 0 if string contains only spaces. Stopped index returned in static `stopped'. --------*/ char *str; /* IN: String to scan */ int len; /* IN: Length of str */ double *value; /* OUT: result */ { char *p, *pe, *ps, x; int i, nd; double atof(); trerror->errno = 0; *value = 0.0e0, nd = 0; p = str, pe = p + len; GobbleSpaces(p,len); if (p == pe) { trerror->errno = TRERR_VOID; FINISH; } ps = p; /* Starting point of string */ if (issign(*p)) p++; p += oscskip(p, pe-p, '0'); /* Skip leading zeroes, not significant */ if (p == pe) FINISH; /* Zero */ nd = oscspan(p, pe-p, _DIGIT_, main_ascii), p += nd; if (p == pe) goto GET_VALUE; if (*p == '.') p++; if (nd == 0) /* Skip leading zeroes */ p += oscskip(p, pe-p, '0'); i = oscspan(p, pe-p, _DIGIT_, main_ascii); /* Decimals */ p += i, nd += i; /* Look for Exponent */ if ((p < pe) && (isalpha(*p))) { x = toupper(*p); if ((x == 'E') || (x == 'D')) /* Exponent */ { if (p == ps) trerror->errno = TRERR_VOID; p++; if (issign(*p)) p++; p += oscspan(p, pe-p, _DIGIT_, main_ascii); } } GET_VALUE: if (p == ps) trerror->errno = TRERR_VOID; x = *p, *p = '\0', *value = atof(str), *p = x; FIN: stopped = p; return(nd); } /*===========================================================================*/ int tr_af(str, len, value) /*++++++ .PURPOSE Converts a string to a floating point. Input is assumed to be in decimal. .RETURNS Number of significant digits / -1 for error (message logged) .REMARKS Return 0 if string contains only spaces. --------*/ char *str; /* IN: String to scan */ int len; /* IN: Length of str */ double *value; /* OUT: result */ { char *p, *pe, x; int i, nd; p = str, pe = p + len; nd = traf(p, len, value); if (nd < 0) FINISH; p = stopped; GobbleSpaces(p, pe-p); if (p != pe) { trerror->errno = TRERR_DIGIT, trerror->str = str, trerror->len = len, trerror->offset = p - str, nd = -1; tr_error(); FINISH; } FIN: if ( (nd == 0) && (trerror->errno == 0)) nd = 1; return(nd); } /*===========================================================================*/ int tr_af1(str, len, value, n) /*++++++ .PURPOSE Converts a string to a vector of numbers. Numbers may be separated by blanks or any punctuation character, .RETURNS Number of found numbers (<= n) / -1 for error (message logged) .REMARKS Return 0 if string contains only spaces. --------*/ char *str; /* IN: String to scan */ int len; /* IN: Length of str */ double *value; /* OUT: result */ int n; /* IN: Number of values */ { char *p, *pe; int i; trerror->errno = 0; p = str, pe = p + len; for (i=0; (perrno) break; /* Void number */ p = stopped; if (p == pe) continue; if (isspace(*p)) continue; if (issign(*p)) continue; if (*p == '.') continue; p++; } if (trerror->errno == 0) { GobbleSpaces(p, pe-p); if (p < pe) trerror->errno = TRERR_TOOMANY; } if (trerror->errno) { trerror->str = str, trerror->len = len, trerror->offset = (p - str); tr_error(); } return((trerror->errno ? -1 : i)); } /*===========================================================================*/ int tr_afn(str, len, value, n) /*++++++ .PURPOSE Converts a string to a vector of double numbers. Numbers may be separated by blanks or any punctuation character. .RETURNS n for success / -1 for failure .REMARKS --------*/ char *str; /* IN: String to scan */ int len; /* IN: Length of str */ double *value; /* OUT: array result */ int n; /* IN: Number of values */ { int i; i = tr_af1(str, len, value, n); if ((i >= 0) && (i < n)) /* Too few numbers */ { trerror->errno = TRERR_TOOFEW; trerror->str = str, trerror->len = len, trerror->offset = len; tr_error(); } return((trerror->errno ? -1 : i)); }