From: RHEA::DECWRL::"decvax!minow" 7-OCT-1984 19:52 To: decwrl!rhea!rex!minow Received: from DECWRL by DEC-RHEA with SMTP; Sun, 7 Oct 84 16:52-PDT Received: by decwrl.ARPA (4.22.01/4.7.34) id AA25578; Sun, 7 Oct 84 16:52:47 pdt Received: by decvax.UUCP (4.12/1.0) id AA27822; Sun, 7 Oct 84 19:03:48 edt Date: Sun, 7 Oct 84 19:03:48 edt Return-Path: Message-Id: <8410072303.AA27822@decvax.UUCP> From idis!george Sun Oct 7 00:15:32 1984 Received: by decvax.UUCP (4.12/1.0) id AA15585; Sun, 7 Oct 84 00:15:11 edt Received: by idis.UUCP (4.12/4.7) id AA22864; Fri, 5 Oct 84 12:20:41 edt Date: Fri, 5 Oct 84 12:20:41 edt From: idis!george (George Rosenberg) Message-Id: <8410051620.AA22864@idis.UUCP> To: minow@decvax Subject: scannumber in decus cpp Status: R I received the copy of cpp that you sent me through the mail. I have not yet had a chance to compile it. I have looked over scannumber() and get(). Before I rewrote scannumber() I attempted to modify the existing copy. It's control flow wasn't structured appropriately, so I gave up the attempt to modify it and rewrote it instead. What you consolidated into the new cpp looks more like my aborted attempt. I checked my copy of the mail I sent you, thinking I may have sent you that early attempt by mistake. I had sent you my rewrite. Apparently you unsuccessfully attempted to consolidate my changes into the previously existing routine. Your resulting routine is wrong, I believe that mine is correct. 02.e3 My routine correctly parses this as a floating point constant. I believe that your new version of the routine would parse this as an integer constant (followed by a period and an identifier). .L My routine correctly parsed this as a period (followed by an identifier). It was not a special case. I think your new version also correctly parsed this, but I think the below statement from it is redundant (and very awkward). if (!hasdigit) goto gotcha; /* Catch ".l" */ Assuming neither 'l' nor 'L' was passed to scannumber as an argument, a digit must have been scanned before the 'l' or 'L', so this will always be false. .e5 According to k&r 2.4.4 this is not a floating point constant. "Either the integer part or the fraction part (not both) may be missing." This is also not a floating point constant according to ANSI X3J11 draft 84-131. My routine correctly parses this as a period (followed by an identifier). I believe that your new version of the routine also does this correctly. There seems to be a curious comment in your routine indicating that something is wrong with this. Less serious is a stylistic problem. The below will work with both ASCII and EBCDIC but it is not portable in principle. I assume this problem exists in other routines also. } while ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')); } else { while (c >= '0' && c <= '7') { /* It's octal */ I have appended another copy of my version of scannumber(). The only difference from the previous copy I sent you is that "hasdigit" now is declared with storage class "register". George Rosenberg idis!george /* * Process a number */ scannumber(ch,outfun) register int ch ; register int (*outfun)() ; { register int hasdigit ; hasdigit = FALSE ; if (ch == '0') { hasdigit = TRUE ; (*outfun)(ch) ; ch = get() ; if (ch == 'x' || ch == 'X') for (;;) { (*outfun)(ch) ; ch = get() ; switch (ch) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': #if 'a' != 'A' case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': #endif continue ; } if (ch == 'l' || ch == 'L') { (*outfun)(ch) ; return ; } unget() ; return ; } } while (type[ch] == DIG) { hasdigit = TRUE ; (*outfun)(ch) ; ch = get() ; } if (ch == 'l' || ch == 'L') { (*outfun)(ch) ; return ; } if (ch == '.') { (*outfun)(ch) ; ch = get() ; if (hasdigit == FALSE && type[ch] != DIG) { unget() ; return ; } } while (type[ch] == DIG) { (*outfun)(ch) ; ch = get() ; } if (ch == 'e' || ch == 'E') { (*outfun)(ch) ; ch = get() ; if (ch == '+' || ch == '-') { (*outfun)(ch) ; ch = get() ; } while (type[ch] == DIG) { (*outfun)(ch) ; ch = get() ; } } unget() ; }