⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 char_to_decimal.h

📁 操作系统SunOS 4.1.3版本的源码
💻 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 + -