/* DEC *ConvAsciiToDecimal(dst,src1) * * ARGUMENT * dst is a pointer to the destination DEC structure. * src1 is a ptr to the ascii string to be converted. * * DESCRIPTION * Converts an ascii string to an internal format number * and puts it into the dst DEC structure. The id is the * number of digits past the decimal point. * * SIDE EFFECTS * None. The destination structure is indeterminate if * an overflow of significant digits occured during conversion. * * RETURNS * Returns a pointer to the dest structure unless overflow. * Otherwise, returns a GM_NULL(a C false). On error, the error * is in wGMError, unless an error was already there. * Note that truncation of insignificant digits is not fatal, but * sets a warning flag for the caller to determine if that is fatal * for their application. * * POSSIBLE ERROR CODES * * GM_NULLSTRING * GM_NAN * GM_CNVRE * GM_CNVRW * * AUTHOR * Andy Anderson 13-JAN-1987 14:30 * Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved. * * MODIFICATIONS * * Mark Nelson 23-Jan-1990 * Modified to handle leading and trailing whitespace, like atoi(); */ #include #include "gm.h" #include "gmsystem.h" DEC *ConvAsciiToDecimal( dst, s ) DEC *dst; char *s; { DEC dx, *x=&dx; int digright; int sign, k, j, exp, expisn=0, equid, xtra=0; mbool trwarn=FALSE; unsigned c10; register int i, fd; _MacStart(GM_ATOD); fd = 0; sign = 1; /* assume a positive sign */ /* If he hands us a null string, _MacRet error to user */ if (!s) { _MacErr(GM_NULLSTRING); _MacRet(GM_NULL); } _MacOutVar(dst, GM_NULL); /* First strip any leading whitespace */ for (; s[fd] == ' ' || s[fd] == '\t' ; fd++ ) ; /* Then check for an empty string */ if (s[fd] == '\0') { _MacErr(GM_NULLSTRING); _MacRet(GM_NULL); } /* fix sign */ for (; ((s[fd] == '-') || (s[fd] == '+')); fd++) { if (s[fd] == '-') sign = -1; } /* Strip leading zeroes from the string */ while ( s[fd] == '0' ) fd++; /* Search for 'e' or 'E' signifying scientfic notation */ for ( j = fd; ; j++ ) { if ( s[j] == '\0' ) break; if ( s[j] == 'e' ) break; if ( s[j] == 'E' ) break; if ( s[j] == ' ' ) break; if ( s[j] == '\t' ) break; } /* If there is an exponent, calculate it or _MacRet GM_NAN */ exp = 0; if ((s[j] == 'e' || s[j] == 'E')) { k=j+1; if ((s[k]=='+') || (s[k]=='-')) { expisn = (s[k]=='-') ? 1 : 0; k++; } do { if ((s[k]<'0') || (s[k]>'9')) { _MacErr(GM_NAN); _MacRet (GM_NULL); } exp = 10*exp + s[k] - 0x30; k++; } while (s[k] != 0 && s[k] != ' ' && s[k] != '\t' ); if (expisn) exp = -exp; } /* check for bad characters */ for (i=fd; i '9')) && (s[i] != '.') && (s[i] != ',')) { _MacErr(GM_NAN); _MacRet (GM_NULL); } /* set equal to 0 */ _MacDZero(x); x->dc.id = 0; if (fd == j) { _MacDCopy(dst,x); _MacRet(dst); } /* everything else */ digright = 0; /* digits before decimal point */ for (i=fd; (i= '0') && (s[i] <= '9')) { c10=s[i] - 0x30; if (x->dc.sl[3] < 3276L) (void) _MulUnsArrP10AndAddInt( x->dc.sl, c10); else { if((s[i] >= '5') && wfGMRound) /* round off */ (void) _IncrementUnsArr( x->dc.sl); for (; ((s[i]!='.') && (i0) { _MacErr(GM_CNVRE); _MacRet(GM_NULL); } i=j; trwarn=TRUE; break; } } if (s[i] == '.') { i++; break; } } /* digits after decimal point */ for (; i= '0') && (s[i] <= '9')) { /* after decimal point */ if ((digright-expdc.sl[3]<3276L)) { /* room for digit */ c10=s[i] - 0x30; (void) _MulUnsArrP10AndAddInt( x->dc.sl, c10); digright++; } else { /* no room for digit */ if((s[i] >= '5') && wfGMRound) { /* round off */ (void) _IncrementUnsArr( x->dc.sl); } trwarn=TRUE; break; } } if (s[i] == '.') { /* two decimal points */ _MacErr(GM_NAN); _MacRet (GM_NULL); } } /* adjust for exponential */ equid = digright-xtra-exp; if ((equid>=GM_MINID) && (equid<=GM_MAXID)) x->ls.lid=equid; if (equid>GM_MAXID) { x->ls.lid=GM_MAXID; trwarn=TRUE; if (!_MacIsDecZ(x)) { if (wfGMRound) _DivUnsArrByPwrOf10( x->dc.sl, 5, equid-GM_MAXID); else _DivUnsArrByPwrOf10( x->dc.sl, 5, equid-GM_MAXID); if (_MacIsDecZ(x)) { _MacErr(GM_CNVRE); } } } if (equiddc.sl, GM_MINID-equid, 5); if ((k!=GM_SUCCESS) || (x->dc.msd!=0) || (x->dc.sl[3] > 32767L)) { _MacErr(GM_CNVRE); _MacRet(GM_NULL); } x->dc.id=GM_MINID; } /* adjust for sign */ if (sign == -1) _MacDChgs(x); _MacDCopy(dst, x); if (trwarn) _MacErr(GM_CNVRW); _MacRet(dst); }