From: RHEA::DECWRL::"[email-masked]" 30-MAY-1985 12:08
To: seismo!minow%rex.DEC@decwrl

Date: Thu, 30 May 85 12:05:38 EDT

> Have you been talking to Alan Feuer or what.  He sent exactly
> the same two comments today!

Pure coincidence.  Still astonishing.

> The bloddy committee has added double to #if's, so you probably
> have to do that conversion.  (And properly handle integer divide
> and modulus).

Wonderful--so now programs with
	#if alpha == 2.0
directives won't be portable to "old" (read:  ALL existing that I know of)
compilers.  I'm sure there's some overwhelming benefit to the ability to put
floats in "#if"s that compensates for this--I'd sure like to hear it.

> by the way, I don't think trigraphs will survive: the ANSI character
> set committee found out about that hack and are planning to protest.

Good to hear.  What's the latest word on "sizeof" in "#if" directives?

> > One of our fine-toothed-comb types has discovered that the routine
> > scannumber botches parsing of floating point numbers.  It fails to
> > recognize
> > 
> > 	21e04
> > 	.21e+04
> > 
> > as floats. . .

Well, "21e04" got handled correctly by the "cpp" we have, but the second
case (and also "21e+04") got mishandled.  The problem was that the variable
"signseen" in the function "scannumber" got inappropriately set to TRUE at
the bottom of the "for" loop.

Here's my notion of a fix, conditioned on "OLDVERSION":

scannumber(c, outfun)
register int	c;				/* First char of number	*/
register int	(*outfun)();			/* Output/store func	*/
/*
 * Process a number.  We know that c is from 0 to 9 or dot.
 * Algorithm from Dave Conroy's Decus C.
 */
{
	register int	radix;			/* 8, 10, or 16		*/
	int		expseen;		/* 'e' seen in floater	*/
#ifdef OLDVERSION
	int		signseen;		/* '+' or '-' seen	*/
#endif
	int		octal89;		/* For bad octal test	*/
	int		dotflag;		/* TRUE if '.' was seen	*/

	expseen = FALSE;			/* No exponent seen yet	*/
#ifdef OLDVERSION
	signseen = TRUE;			/* No +/- allowed yet	*/
#endif
	octal89 = FALSE;			/* No bad octal yet	*/
	radix = 10;				/* Assume decimal	*/
	if ((dotflag = (c == '.')) != FALSE) {	/* . something?		*/
	    (*outfun)('.');			/* Always out the dot	*/
	    if (type[(c = get())] != DIG) {	/* If not a float numb,	*/
		unget();			/* Rescan strange char	*/
		return;				/* All done for now	*/
	    }
	}					/* End of float test	*/
	else if (c == '0') {			/* Octal or hex?	*/
	    (*outfun)(c);			/* Stuff initial zero	*/
	    radix = 8;				/* Assume it's octal	*/
	    c = get();				/* Look for an 'x'	*/
	    if (c == 'x' || c == 'X') {		/* Did we get one?	*/
		radix = 16;			/* Remember new radix	*/
		(*outfun)(c);			/* Stuff the 'x'	*/
		c = get();			/* Get next character	*/
	    }
	}
	for (;;) {				/* Process curr. char.	*/
	    /*
	     * Note that this algorithm accepts "012e4" and "03.4"
	     * as legitimate floating-point numbers.
	     */
	    if (radix != 16 && (c == 'e' || c == 'E')) {
		if (expseen)			/* Already saw 'E'?	*/
		    break;			/* Exit loop, bad nbr.	*/
		expseen = TRUE;			/* Set exponent seen	*/
#ifdef OLDVERSION
		signseen = FALSE;		/* We can read '+' now	*/
#endif
		radix = 10;			/* Decimal exponent	*/
#ifndef OLDVERSION
		(*outfun)(c);
		if ((c = get()) != '+' && c != '-')
			continue;
#endif
	    }
	    else if (radix != 16 && c == '.') {
		if (dotflag)			/* Saw dot already?	*/
		    break;			/* Exit loop, two dots	*/
		dotflag = TRUE;			/* Remember the dot	*/
		radix = 10;			/* Decimal fraction	*/
	    }
#ifdef OLDVERSION
	    else if (c == '+' || c == '-') {	/* 1.0e+10		*/
		if (signseen)			/* Sign in wrong place?	*/
		    break;			/* Exit loop, not nbr.	*/
		/* signseen = TRUE; */		/* Remember we saw it	*/
	    }
#endif
	    else {				/* Check the digit	*/
		switch (c) {
		case '8': case '9':		/* Sometimes wrong	*/
		    octal89 = TRUE;		/* Do check later	*/
		case '0': case '1': case '2': case '3':
		case '4': case '5': case '6': case '7':
		    break;			/* Always ok		*/

		case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
		case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
		    if (radix == 16)		/* Alpha's are ok only 	*/
			break;			/* if reading hex.	*/
		default:			/* At number end	*/
		    goto done;			/* Break from for loop	*/
		}				/* End of switch	*/
	    }					/* End general case	*/
	    (*outfun)(c);			/* Accept the character	*/
#ifdef OLDVERSION
	    signseen = TRUE;			/* Don't read sign now	*/
#endif
	    c = get();				/* Read another char	*/
	}					/* End of scan loop	*/
	.
	.
	.

				--ado