📄 char_to_decimal.h
字号:
/* @(#)char_to_decimal.h 1.1 92/07/30 SMI *//* * Copyright (c) 1990 by Sun Microsystems, Inc. *//* * This file contains the common part of string_to_decimal, func_to_decimal, * and file_to_decimal. NEXT must be defined to cause CURRENT to contain the * next input character. ATEOF must be defined to be == EOF if an input * file is at EOF, != EOF otherwise. */{ int sigfound; int ids = 0; int i; int nzbp = 0, nzap = 0; /* Length of zero substring * before point, after point. */ char decpt; int nfast, nfastlimit; char *pfast; *pform = invalid_form; /* Invalid until we find something. */ *pechar = NULL; /* No exponent field assumed. */ pd->fpclass = fp_normal;/* Defaults. */ pd->sign = 0; /* Positive. */ pd->exponent = 0; pd->more = 0; /* Assume no overflow of digits on NaN * string. */ if (fortran_conventions != 0) decpt = '.'; else#ifdef PRE41 decpt = '.';#else decpt = *(localeconv()->decimal_point);#endif while (isspace(CURRENT)) { NEXT; } /* Skip white space. */ if (fortran_conventions >= 2) { /* * All white space - valid zero for Fortran formatted input. */ *pform = whitespace_form; if (isspace(*cp)) good = cp; else good = cp - 1; if ((nread >= nmax) && (CURRENT == NULL)) { /* Used up field width. */ pd->fpclass = fp_zero; goto done; } } if (CURRENT == '+') { NEXT; } else if (CURRENT == '-') { /* Negative. */ pd->sign = 1; NEXT; } sigfound = -1; /* -1 = no digits found yet. */ if (('1' <= CURRENT) && (CURRENT <= '9')) { good = cp; *pform = fixed_int_form; sigfound = 1; /* 1 = significant digits found. */ pd->ds[ids++] = CURRENT; NEXT; goto number; } else switch (CURRENT) { case ' ': if (fortran_conventions < 2) goto firstdefault; case '0': *pform = fixed_int_form; while ((CURRENT == '0') || ((fortran_conventions >= 2) && (CURRENT == ' '))) { NEXT; } /* Ignore leading zeros. */ if ((*cp == '0') || ((fortran_conventions >= 2) && (*cp == ' '))) good = cp; else good = cp - 1; sigfound = 0; /* 0 = only zeros found yet. */ goto number; case 'i': case 'I': { /* Try infinity. */ static char *infstring = "INFINITY"; int is, iagree;#define UCASE(c) ( (('a' <= c) && (c <= 'z')) ? c - 32 : c ) NEXT; is = 1; while ((UCASE(CURRENT) == infstring[is]) && (is <= 8)) { NEXT; is++; } if (UCASE(CURRENT) == infstring[is]) iagree = is + 1; else iagree = is; is++; /* To account for infstring indexing * starting at 0. */ if (iagree >= 3) { /* Found syntactically * valid infinity. */ if (iagree < 8) { /* INFxxxx */ good = cp - (is - 3); *pform = inf_form; } else { /* INFINITYxxx */ good = cp - (is - 8); *pform = infinity_form; } pd->fpclass = fp_infinity; sigfound = iagree; } goto done; } case 'n': case 'N': { /* Try NaN. */ static char *nanstring = "NAN("; int is; NEXT; is = 1; while (UCASE(CURRENT) == nanstring[is]) { NEXT; is++; } if ((is == 3)) { /* Found syntactically * valid NaN. */ *pform = nan_form; good = cp - 1; pd->fpclass = fp_quiet; sigfound = 1; } if (is == 4) { /* Found NaN followed by * parenthesis. */ good = cp - 2; *pform = nan_form; pd->fpclass = fp_quiet; sigfound = 1; while ((CURRENT != 0) && (CURRENT != ')') && (ids < (DECIMAL_STRING_LENGTH - 1))) { pd->ds[ids++] = CURRENT; NEXT; } while ((CURRENT != 0) && (CURRENT != ')') && (ATEOF != EOF)) { /* Pick up rest of * string. */ pd->more = 1; NEXT; } if (CURRENT == ')') { good = cp; NEXT; } *pform = nanstring_form; } goto done; } default: if (CURRENT == decpt) { NEXT; /* Try number. */ goto afterpoint; } firstdefault: goto done; }number:nextnumber: if (('1' <= CURRENT) && (CURRENT <= '9')) { if ((ids + nzbp + 2) >= DECIMAL_STRING_LENGTH) { /* Not enough room to * store it all: fake * end of string. */ pd->exponent += nzbp + 1; pd->more = 1; pd->ds[ids] = 0; /* Actual string termination. */ ids = DECIMAL_STRING_LENGTH - 1; /* To allow end of * program to terminate * again. */ } else { for (i = 0; (i < nzbp); i++) pd->ds[ids++] = '0'; pd->ds[ids++] = CURRENT; } *pform = fixed_int_form; sigfound = 1; nzbp = 0; NEXT; nfastlimit = DECIMAL_STRING_LENGTH - 3 - ids; if ((0 < nfastlimit) && ('1' <= CURRENT) && (CURRENT <= '9')) { /* Special handling for * common case. */ nfast = 0; pfast = &(pd->ds[ids]); do { pfast[nfast++] = CURRENT; NEXT; } while (('1' <= CURRENT) && (CURRENT <= '9') && (nfast < nfastlimit)); ids += nfast; } if (CURRENT == '0') goto nextnumberzero; /* common case */ good = cp; if (('1' > *good) || (*good > '9')) good--; /* look out if we fell off end */ goto nextnumber; } else switch (CURRENT) { case ' ': if (fortran_conventions < 2) goto numberdefault; if (fortran_conventions == 2) { NEXT; goto nextnumber; } case '0': *pform = fixed_int_form; nextnumberzero: while ((CURRENT == '0') || (CURRENT == ' ')) { /* Accumulate zero * substring. */ if (CURRENT == ' ') { if (fortran_conventions < 2) { good = cp - 1; goto numberdefault; } if (fortran_conventions == 2) { nzbp--; /* Undo effect of * following nzbp++ */ } } good = cp; nzbp++; NEXT; } goto nextnumber; case 'E': case 'e': efound: *pechar = cp; if (sigfound == -1) /* exp following no digits? * bad format */ goto done; if (sigfound > 0) pd->exponent += nzbp; goto exponent; case '+': case '-': case 'D': case 'd': case 'Q': case 'q': if (fortran_conventions != 0) goto efound; default: if (CURRENT == decpt) { NEXT; goto afterpoint; } numberdefault: if (sigfound > 0) pd->exponent += nzbp; goto done; }afterpoint: if (sigfound >= 0) { /* Better accept the point as good, but don't * accept the next character after. */ good = cp - 1; /* Assume cp points past. */ if (*good != decpt) /* If not, bump good. */ good++; } switch (*pform) { /* Revise *pform now that point has been * found. */ case invalid_form: case whitespace_form: *pform = fixed_dotfrac_form; break; case fixed_int_form: *pform = fixed_intdot_form; break; }switchafterpoint: if (('1' <= CURRENT) && (CURRENT <= '9')) { if (*pform == fixed_intdot_form) *pform = fixed_intdotfrac_form; good = cp; if (sigfound < 1) { /* No significant digits found so * far. */ sigfound = 1; pd->ds[ids++] = CURRENT; pd->exponent = -(nzap + 1); } else { /* Significant digits have begun. */ if ((ids + nzbp + nzap + 2) >= DECIMAL_STRING_LENGTH) { /* Not enough room to * store it all: fake * end of string. */ pd->exponent += nzbp; pd->more = 1; pd->ds[ids] = 0; /* Actual string * termination. */ ids = DECIMAL_STRING_LENGTH - 1; /* To allow end of * program to terminate * again. */ } else { for (i = 0; (i < (nzbp + nzap)); i++) pd->ds[ids++] = '0'; pd->ds[ids++] = CURRENT; pd->exponent -= nzap + 1; } } nzbp = 0; nzap = 0; NEXT; nfastlimit = DECIMAL_STRING_LENGTH - 3 - ids; if ((0 < nfastlimit) && ('1' <= CURRENT) && (CURRENT <= '9')) { /* Special handling for * common case. */ nfast = 0; pfast = &(pd->ds[ids]); do { pfast[nfast++] = CURRENT; NEXT; } while (('1' <= CURRENT) && (CURRENT <= '9') && (nfast < nfastlimit)); good = cp; if (('1' > *good) || (*good > '9')) good--; /* look out if we fell off end */ ids += nfast; pd->exponent -= nfast; } if (CURRENT == '0') goto zeroafterpoint; goto switchafterpoint; } else switch (CURRENT) { case ' ': if (fortran_conventions < 2) goto afterpointdefault; if (fortran_conventions == 2) { /* * To pass FCVS, all blanks after point must * count as if zero seen. */ if (sigfound == -1) sigfound = 0; NEXT; goto switchafterpoint; } case '0': if (*pform == fixed_intdot_form) *pform = fixed_intdotfrac_form; if (sigfound == -1) sigfound = 0; zeroafterpoint: good = cp; nzap++; NEXT; while ((CURRENT == '0') || (CURRENT == ' ')) { if (CURRENT == ' ') { /* Handle blanks and * Fortran. */ if (fortran_conventions < 2) { good = cp - 1; goto afterpointdefault; } if (fortran_conventions == 2) { nzap--; /* Undo following nzap++ */ } } nzap++; NEXT; } good = cp; if (*good != '0') good--; goto switchafterpoint; case 'E': case 'e': efound2: *pechar = cp; if (sigfound == -1) /* exp following no digits? * bad! */ goto done; if (sigfound > 0) pd->exponent += nzbp; goto exponent; case '+': case '-': case 'D': case 'd': case 'Q': case 'q': if (fortran_conventions != 0) goto efound2; default: afterpointdefault: if (sigfound > 0) pd->exponent += nzbp; goto done; }exponent: { unsigned explicitsign = 0, explicitexponent = 0; if ((CURRENT != '+') && (CURRENT != '-')) { /* Skip EeDd and * following blanks. */ NEXT; /* Pass the EeDd. */ if (fortran_conventions >= 2) while (CURRENT == ' ') { NEXT; } } if (CURRENT == '+') { NEXT; } else if (CURRENT == '-') { /* Negative explicit * exponent. */ NEXT; explicitsign = 1; } while ((('0' <= CURRENT) && (CURRENT <= '9')) || (CURRENT == ' ')) { /* Accumulate explicit * exponent. */ if (CURRENT == ' ') { /* Handle blanks and Fortran. */ if (fortran_conventions < 2) goto doneexp; if (fortran_conventions == 2) { NEXT; goto exploop; } CURRENT = '0'; } good = cp; if (explicitexponent <= 400000000) { explicitexponent = 10 * explicitexponent + CURRENT - '0'; } NEXT; switch (*pform) { case whitespace_form: case fixed_int_form: *pform = floating_int_form; break; case fixed_intdot_form: *pform = floating_intdot_form; break; case fixed_dotfrac_form: *pform = floating_dotfrac_form; break; case fixed_intdotfrac_form: *pform = floating_intdotfrac_form; break; } exploop: ; }doneexp: if (explicitsign == 1) pd->exponent -= explicitexponent; else pd->exponent += explicitexponent; }done: if (fortran_conventions >= 2) { /* Fill up field width with extra * blanks found. */ if (good == (cp - 1)) good = NULL; /* Flag that whole field was good up * to now. */ while (CURRENT == ' ') { NEXT; } if (good == NULL) good = cp - 1; } if (sigfound < 1) pd->fpclass = fp_zero; /* True zero found. */ pd->ds[ids] = 0; /* Terminate decimal string. */ pd->ndigits = ids; /* Save string length in ndigits. */ if (good >= cp0) { /* Valid token found. */ *ppc = good + 1;/* token found - point one past. */ } else { /* No valid token found. */ *pform = invalid_form; *ppc = cp0; /* No token found - revert to original value. */ pd->sign = 0; pd->fpclass = fp_signaling; /* If anyone looks, x will be * nan. */ }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -