/* @(#)trfpic.c 17.1.1.1 (ES0-DMD) 01/25/02 17:47:39 */ /*=========================================================================== 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 trfpic.c .AUTHOR Francois Ochsenbein [ESO] .LANGUAGE C .CATEGORY Conversion from character to float (double) using a picture. .COMMENTS Definition of pictures are in edfpic.c \begin{TeX} \end{TeX} .VERSION 1.0 27-May-1988: Creation .VERSION 1.1 21-Oct-1988: Modified error report .VERSION 1.2 22-Mar-1990: Added stkfpic (tokenisation) .VERSION 1.3 16-May-1990: Allow trailing blanks / spaces -----------------------------------------------*/ #include #include #include #include #include MID_EXTERN struct trerr_s *trerror; #define FINISH goto FIN MID_STATIC char sign; MID_RSTATIC char emarks[] = {'.', 'E','e','D','d'}; MID_STATIC char stk = 0; /* Indicator for stkfpic */ MID_STATIC char edited[64]; /*===========================================================================*/ static int Sign(str, len) /*++++++ .PURPOSE Just scan the beginning of a string: skip leading blanks, and get the sign. .RETURNS Number of valid characters .REMARKS Not traced. --------*/ char *str; /* IN: The string to scan */ int len; /* IN: Length of the string */ { char *p, *pe; sign = 0; if (len <= 0) return(0); p = str + oscspan(str, len, _SPACE_, main_ascii); pe = str + len; if (p < pe) { switch(*p) { case '-': sign = 1; case '+': p++; break; } p += oscspan(p, pe-p, _SPACE_, main_ascii); /* Skip blanks */ } return(p-str); } /*===========================================================================*/ int tr_fpic(str, len, pic, value) /*++++++ .PURPOSE Converts a string to a double number according to a picture (see module edpic.c) .RETURNS Number of decimals / -1 for error or no number .REMARKS returned value is e.g. 101 for 1.01 --------*/ char *str; /* IN: String to scan */ int len; /* IN: Length of str */ char *pic; /* IN: The picture */ double *value; /* OUT: result */ { char *p, *pe, *pdot, *a, *ae, x; int nd, i, la; long int_part; double atof(); p = str + oscspan(str, len, _SPACE_, main_ascii); pe = str + len; *value = 0.e0; sign = 0; trerror->errno = 0; trerror->msg = pic; trerror->str = str; trerror->len = len; p += Sign(p, pe-p); /* Locate Sign */ pdot = pe; for (i=0; (i < sizeof(emarks)) && (pdot == pe); i++) pdot = p + oscloc(p, pe-p, emarks[i]); la = strlen(pic), a = pic + la; for (i=0; (i < sizeof(emarks)) && (*a == EOS); i++) a = pic + oscloc(pic, la, emarks[i]); x = *a, *a = '\0'; nd = tr_pic(p, pdot-p, pic, &int_part); *a = x; if (nd < 0) FINISH; /* Edit Number */ edited[0] = (sign ? '-' : ' '); for (i=11; --i>0; int_part /= 10) edited[i] = (int_part % 10) + '0'; edited[11] = '.'; /* Copy Remaining part. x is an indicator which takes values 1 when exponent starts 2 wneh number terminated */ x = 0, p = pdot, i = 12; if (p == pe) goto GET_VALUE; if (*p == '.') nd++, p++; for ( ; (p < pe) && (trerror->errno == 0); p++) { if (isspace(*p)) { x = 2; continue; } if (x == 2) { trerror->errno = TRERR_FLOAT; break; } switch(*p) { case 'd': case 'D' : case 'e' : case 'E': if (x) trerror->errno = TRERR_FLOAT; edited[i++] = 'e'; x = 1; break; case '+': case '-': if (x == 0) /* Error, E missing */ trerror->errno = TRERR_FLOAT; edited[i++] = *p; break; default: if (isdigit(*p)) edited[i++] = *p, nd++; else trerror->errno = TRERR_DIGIT; break; } if (i >= (sizeof(edited)-1)) trerror->errno = TRERR_UNDEF; } if ((p < pe) && (trerror->errno == 0)) trerror->errno = TRERR_FLOAT; GET_VALUE: edited[i] = '\0'; if (trerror->errno) /* Bad number */ { trerror->offset = (p-str); tr_error(); nd = -1; } else if (!stk) *value = atof(edited); FIN: if (stk) return(p - str); return(nd); } /*===========================================================================*/ int stkfpic(str, pic) /*++++++ .PURPOSE Compute the length of the tokenized string .RETURNS Length of str matched for specified picture .REMARKS --------*/ char *str; /* IN: String to scan */ char *pic; /* IN: The picture */ { int status; double value; stk = 1; /* Tells tr_fpic that we just tokenize */ status = tr_fpic (str, strlen(str), pic, &value); stk = 0; return(status); }