   % cat newado.mail 6 From seismo!umcp-cs!elsie!ado Sun Sep 23 20:43:29 1984# Received: by decvax.UUCP (4.12/1.0)W/         id AA04152; Sun, 23 Sep 84 20:43:24 edt  From: seismo!umcp-cs!elsie!adoQ Received: from umcp-cs.UUCP by seismo.ARPA with UUCP; Sun, 23 Sep 84 19:01:23 EDT % Received: by maryland.ARPA (4.12/4.7) /         id AA11780; Sun, 23 Sep 84 18:52:09 edt ! Date: Sun, 23 Sep 84 18:52:09 edt . Message-Id: <8409232252.AA11780@maryland.ARPA> To: minow@decvaxK Subject: A truly pathological bug...and (less kludgy?) line numbering fixesp	 Status: Rd  B 1.      The truly pathological bug is the treatment of lines like:         ,                 #include "a /* comment */ b"  >         which tell you about being unable to open file "a  b".<         (I suppose SOME pervert could name a file "a/**/b".)!         The "fix" to "doinclude":0           #ifdef OLDVERSION L                 while ((c = get()) != EOF_CHAR && c != '\n' && c != delim) {         #if COMMENT_INVISIBLEc'                     if (c != COM_SPACE)l                          save(c);
         #else                      save(c);         #endif                 }                  save(EOS);                 if (c != delim)                       goto incerr;
         #else                   instring = TRUE;,                 while ((c = get()) != delim)7                         if (c == EOF_CHAR || c == '\n') ,                                 goto incerr;(                         else    save(c);                 save(EOS);!                 instring = FALSE;          #endif  I 2.  Here's my latest combination of changes to the last "cpp1.c" you sent L     that's designed to deal with line numbering.  It seems a bit better than     my last set to me.  1     First, eliminate newline faking in "addfile":= > #ifdef OLDVERSION J >       file->buffer[0] = '\n';         /* Fake initial newline to      */J >       file->buffer[1] = EOS;          /* initialize for first read    */J >       line = 0;                       /* Note correct line number     */ > #elseE >       file->buffer[0] = EOS; >       line = 1;i > #endif  J     Since we no longer put in the phony new line, we avoid diddling "line"     in "cppmain":b   >               /*J >                * Explicitly output a #line at the start of cpp output soI >                * that lint (etc.) knows the name of the original sourceeD >                * file.  If we don't do this explicitly, we may get? >                * the name of the first #include file instead.* >                */m >       #ifdef OLDVERSION  >               line = 1;  >               sharp(); >               line = 0;p
 >       #else  >               sharp(); >       #endif  K     We also need not worry about the count being off the first time we do ae     "sharp" call, so the   X #ifdef OLDVERSION*J X               if (counter > 4)                /* pending newlines.    */ X #elsefJ X                                               /* pending newlines.    */$ X               if (line == counter)P X                       --counter;              /* Forget addfile's fake '\n' */  X               if (counter > 4) X #endif  )     business of my last letter reverts to J >               if (counter > 4)                /* pending newlines.    */  0     Double counting of lines is STILL a problem;$     the line skipping loop is still:          > #ifdef OLDVERSIONi+ >           for (counter = 0;; counter++) {  > #else  >           counter = 0; >           for ( ; ; ) {  > #endifJ >               while (type[(c = get())] == SPA) /* Skip leading blanks */J >                   ;                           /* in this line.        */J >               if (c == '\n')                  /* If line's all blank, */ > #ifdef OLDVERSIONnJ >                   ;                           /* Do nothing now       */ > #elseeJ >                   ++counter;                  /* just count it        */ > #endifJ >               else if (c == '#')              /* Is 1st non-space '#' */J >                   counter = control(counter); /* Yes, do a #command   */J >               else if (c == EOF_CHAR)         /* At end of file?      */ >                   break; > #ifdef OLDVERSION J >               else if (flevel > 0)            /* #ifdef false?        */J >                   skipnl();                   /* Skip to newline      */ > #else J >               else if (flevel > 0) {          /* #ifdef false?        */J >                   skipnl();                   /* Skip to newline      */ >                   ++counter; >               }s > #endif >               else {J >                   break;                      /* Actual token         */ >               }i
 >           }   H     We also STILL toss in the extra newline in "sharp" when appropriate:   > FILE_LOCAL	 > sharp()l > /* >  * Output a line number line.e >  *// > {e& >       register char           *name; >  > #ifndef OLDVERSION >       if (keepcomments)  >               putchar('\n'); > #endif  '     We still fix the typo in "control":+ > #ifdef OLDVERSION B >       if (control > 0 && (hash == L_line || hash == L_option)) { > #else B >       if (counter > 0 && (hash == L_line || hash == L_option)) { > #endif  H     And finally, we get to make this change in "control", to ensure that:     the first line of an included file does not disappear:   > #if 1/ > #ifdef OLDVERSIONtJ >       skipnl();                       /* Dump rest of control line    */J >       counter++;                      /* Count it, too.               */ > #else"K >       if (hash != L_include) {        /* If haven't already eaten line */=J >               skipnl();               /* Dump rest of control line    */J >               counter++;              /* Count it, too.               */	 >       }  > #endif > #else   %                                 --adoo    1 From tektronix!tomk@orca Sun Sep 23 21:54:48 1984 # Received: by decvax.UUCP (4.12/1.0)m/         id AA04987; Sun, 23 Sep 84 21:54:43 edt  From: tektronix!tomk@orcat To: tektronix!decvax!minow Fcc: outbox  Return-Path: <tomk@orca>= Received: from orca.TEK by tektronix ; 23 Sep 84 13:33:23 PDT O Received: by orca.TEK (1.138/Tek) ,     id AA03938; Sun, 23 Sep 84 13:33:49 pdte) Message-Id: <8409232033.AA03938@orca.TEK> ! Date: Sun, 23 Sep 84 13:33:41 PDTe Subject: DECUS C bugs, etc. 	 Status: R-  @ Hi!  I just grabbed your cpp submission off the net.  Looks like> an interesting addition to DECUS C.  I totally forgot that you' offered to send me a test copy earlier.c  > I discovered a bug in "t" running under RT11 a few months ago.A If there's a null character stuck in a line, "t" refuses to print @ everything after the null.  DIR.SAV seems to stick a null at the< first of a line when there's only one file in the directory.> DIR probably shouldn't stick the null there, but I developed a= quick and sleazy fix to "t" to eliminate the bug.  Here's the ! change to "t.h" (Nov'83 version):d         [input to SLP]
         -3%          * Kloos version of 09-Jun-84y         -35          #ifndef rt11         -36n
         #elsem$         #define FWILDMODE       "ru"         -37l         #endif	         /   > Do you know of any problems with "sortc" as distributed in the? Nov'83 release?  When I have less than about 43K of user memory @ and a big file to sort, it munches the output.  Extra charactersC appear in some places and a few are missing from others.  I haven'tt? had the time to dissect the code yet and am hoping that someone + else may have fixed it already.  Any hints?   D Are there any updates to the RT-11 version of DECUS C since the last, care package I received from you (late May)?   Regards,* -Tom Kloos, Tektronix, Wilsonville, OregonB                                 Ignore paths in header.  Use this:F uucp:   ..{ucbvax,decvax,uw-beaver,hplabs,allegra}!tektronix!orca!tomk    6 From seismo!umcp-cs!elsie!ado Mon Sep 24 12:26:31 1984# Received: by decvax.UUCP (4.12/1.0)i/         id AA17918; Mon, 24 Sep 84 12:26:24 edte From: seismo!umcp-cs!elsie!adoQ Received: from umcp-cs.UUCP by seismo.ARPA with UUCP; Mon, 24 Sep 84 12:04:14 EDTh% Received: by maryland.ARPA (4.12/4.7)u/         id AA26652; Mon, 24 Sep 84 11:37:58 edtW! Date: Mon, 24 Sep 84 11:37:58 edt . Message-Id: <8409241537.AA26652@maryland.ARPA> To: minow@decvax Subject: Re: re: cpp1.cb	 Status: Rt   Got your letter--thanks.  - Here's a notion--submitted for your approval.4; It's the code to squelch output of comments that are eithero.         1.  on preprocessor directive lines orD         2.  in conditionally-compiled code that's not being emitted.  ) Fairly straightforward changes, actually:n  *         a.  Add this at the top of cpp1.c:  J > int           keepcomments = FALSE;   /* Write out comments flag      */ > #ifndef OLDVERSIONA > static int    cflag = FALSE;          /* as per command line */o > #endif  $         b.  Add this to "dooptions":  J >               case 'C':                       /* Keep comments        */ > #ifndef OLDVERSION! >                   cflag = TRUE;  > #endif( >                   keepcomments = TRUE; >                   break; >   8         c.  And finally, change the call to "docontrol":  J >               else if (c == '#')              /* Is 1st non-space '#' */ > #ifdef OLDVERSIONnJ >                   counter = control(counter); /* Yes, do a #command   */ > #else  >                       {h- >                       keepcomments = FALSE; 3 >                       counter = control(counter);i> >                       keepcomments = cflag && (flevel == 0); >                       }m > #endif  7 Should cut down the computer usage bills of lint users.l%                                 --ado     6 From seismo!umcp-cs!elsie!ado Mon Sep 24 12:26:51 1984# Received: by decvax.UUCP (4.12/1.0) /         id AA17925; Mon, 24 Sep 84 12:26:44 edtY From: seismo!umcp-cs!elsie!adoQ Received: from umcp-cs.UUCP by seismo.ARPA with UUCP; Mon, 24 Sep 84 12:04:23 EDT % Received: by maryland.ARPA (4.12/4.7)n/         id AA26659; Mon, 24 Sep 84 11:38:08 edtl! Date: Mon, 24 Sep 84 11:38:08 edt . Message-Id: <8409241538.AA26659@maryland.ARPA> To: minow@decvax0 Subject: Perfect hashing and a warped human mind	 Status: R   > Here's a possible replacement for "perfect hashing" in cpp1.c.K It makes for both a smaller cpp1.c source file and (at least on our system) I a smaller executable cpp.  It may also be easier for folks to understand.w%                                 --ado  #ifdef OLDVERSIONn /*:  * The following is generated by a "perfect hash" routine.  */ ! #define L_else                  4 ! #define L_line                  5y! #define L_define                6c! #define L_elif                  7a! #define L_endif                 8i! #define L_if                    9g" #define L_undef                 10" #define L_include               11" #define L_ifdef                 12" #define L_ifndef                13" #define L_assert                14" #define L_option                15 #define FIRST   'a'e #define LAST    'u'e static int px_assoc[] = {n         0,      /* 'a' */          -1,     /* 'b' */_         -1,     /* 'c' */d         0,      /* 'd' */          0,      /* 'e' */          3,      /* 'f' */i         -1,     /* 'g' */n         -1,     /* 'h' */g         4,      /* 'i' */          -1,     /* 'j' */          -1,     /* 'k' */_         1,      /* 'l' */d         -1,     /* 'm' */          9,      /* 'n' */          0,      /* 'o' */i         -1,     /* 'p' */n         -1,     /* 'q' */T         -1,     /* 'r' */o         -1,     /* 's' */*         8,      /* 't' */*         2,      /* 'u' */* }; static char *px_table[] = {**         NULL,                   /*  0   */*         NULL,                   /*  1   */*         NULL,                   /*  2   */*         NULL,                   /*  3   */*         "else",                 /*  4   */*         "line",                 /*  5   */*         "define",               /*  6   */*         "elif",                 /*  7   */*         "endif",                /*  8   */*         "if",                   /*  9   */*         "undef",                /* 10   */*         "include",              /* 11   */*         "ifdef",                /* 12   */*         "ifndef",               /* 13   */*         "assert",               /* 14   */*         "option",               /* 15   */ };   FILE_LOCAL int control(counter)J int             counter;        /* Pending newline counter              */ /*A  * Process #control lines.  Simple commands are processed inline, 5  * while complex commands have their own subroutines.   *?  * The counter is used to force out a newline before #line, and D  * #option commands.  This prevents these commands from ending up atE  * the end of the previous line if cpp is invoked with the -C option.   */  {/"         register int            c;$         register char           *tp;%         register int            hash; $         char                    *ep;           c = skipws();s'         if (c == '\n' || c == EOF_CHAR)c!             return (counter + 1);m         if (!isdigit(c))J             scanid(c);                  /* Get #word to token[]         */         else {J             unget();                    /* Hack -- allow #123 as a      */J             strcpy(token, "line");      /* synonym for #line 123        */	         } 
         /*H          * Look for keyword (string of alpha) in the perfect hash table.@          * Set hash to the index (L_xxx value) or 0 if not found          */(0         if (token[0] < FIRST || token[0] > LAST)             hash = 0;          else {0             for (tp = token; isalpha(*tp); tp++)                 ;               hash = (tp - token);,             if (*--tp < FIRST || *tp > LAST)                 hash = 0;              else {I                 hash += px_assoc[*token - FIRST] + px_assoc[*tp - FIRST]; *                 if (px_table[hash] == NULL2                  || !streq(token, px_table[hash]))                     hash = 0;t
             } 	         } 
         /*A          * hash is now set to a unique value corresponding to thee>          * control keyword (or zero if it's not in the table).          */  #else  /*4  * The following is generated by human perverseness.  */S  * #define L_else          ('e' + ('s' << 1))* #define L_line          ('l' + ('n' << 1))* #define L_define        ('d' + ('f' << 1))* #define L_elif          ('e' + ('i' << 1))* #define L_endif         ('e' + ('d' << 1))* #define L_if            ('i' + (EOS << 1))* #define L_undef         ('u' + ('d' << 1))* #define L_include       ('i' + ('c' << 1))* #define L_ifdef         ('i' + ('d' << 1))* #define L_ifndef        ('i' + ('n' << 1))* #define L_assert        ('a' + ('s' << 1))* #define L_option        ('o' + ('t' << 1))   FILE_LOCAL int control(counter)J int             counter;        /* Pending newline counter              */ /*A  * Process #control lines.  Simple commands are processed inline, 5  * while complex commands have their own subroutines.O  *?  * The counter is used to force out a newline before #line, anddD  * #option commands.  This prevents these commands from ending up atE  * the end of the previous line if cpp is invoked with the -C option.'  */( { "         register int            c;$         register char           *tp;%         register int            hash; $         char                    *ep;           c = skipws();s'         if (c == '\n' || c == EOF_CHAR)c!             return (counter + 1);m         if (!isdigit(c))J             scanid(c);                  /* Get #word to token[]         */         else {J             unget();                    /* Hack -- allow #123 as a      */J             strcpy(token, "line");      /* synonym for #line 123        */	         } 4         switch (hash = token[0] + (token[2] << 1)) {>                 case L_else:    tp = "else";            break;>                 case L_line:    tp = "line";            break;>                 case L_define:  tp = "define";          break;>                 case L_elif:    tp = "elif";            break;>                 case L_endif:   tp = "endif";           break;>                 case L_if:      tp = "if";              break;>                 case L_undef:   tp = "undef";           break;>                 case L_include: tp = "include";         break;>                 case L_ifdef:   tp = "ifdef";           break;>                 case L_ifndef:  tp = "ifndef";          break;>                 case L_assert:  tp = "assert";          break;>                 case L_option:  tp = "option";          break;>                 default:        tp = ""; hash = 0;      break;	         }          if (!streq(tp, token))                 hash = 0; 
         /*A          * hash is now set to a unique value corresponding to theL?          * control keyword (or zero if we think it's nonsense).i          */" #endif%                                 --adoL    6 From seismo!umcp-cs!elsie!ado Tue Sep 25 14:27:42 1984# Received: by decvax.UUCP (4.12/1.0) /         id AA13453; Tue, 25 Sep 84 14:27:38 edti From: seismo!umcp-cs!elsie!adoQ Received: from umcp-cs.UUCP by seismo.ARPA with UUCP; Tue, 25 Sep 84 13:03:08 EDTq% Received: by maryland.ARPA (4.12/4.7) /         id AA13754; Tue, 25 Sep 84 12:27:47 edtq! Date: Tue, 25 Sep 84 12:27:47 edt . Message-Id: <8409251627.AA13754@maryland.ARPA> To: minow@decvax Subject: cpp.h addition 	 Status: R    Appending ad#         extern char     *sprintf(); , lint to "cpp.h" saves a bit of "lint" grief.%                                 --adou    4 From seismo!cmcl2!hipl!tony Fri Sep 28 03:19:55 1984# Received: by decvax.UUCP (4.12/1.0)m/         id AA15286; Fri, 28 Sep 84 03:19:30 edteO Received: from cmcl2.UUCP by seismo.ARPA with UUCP; Thu, 27 Sep 84 20:51:40 EDT 8 Received: by NYU-CMCL2.ARPA; Thu, 27 Sep 84 19:06:13 edt! Received: by hipl.UUCP (4.12/4.7) /         id AA01328; Thu, 27 Sep 84 18:28:22 edt ! Date: Thu, 27 Sep 84 18:28:22 edta+ From: seismo!cmcl2!hipl!tony (Tony Movshon)i* Message-Id: <8409272228.AA01328@hipl.UUCP> To: minow@decvax Subject: cpp	 Status: Rt  M I retrieved cpp from net.sources and have installed it under RT11. I have not1H tested it exhaustively, but it appears to work fine. One minor point: inL cppdef.h, you have it define HOST as SYS_RSX even if the compiler predefinesL "rt11" (this was presumably for testing). It would be more humane to have it define HOST as SYS_RT11.M You mentioned some bug-fixes affecting RT11 that you installed since the lastvJ DECUS release: could you send them to me for my planned RT11 resubmission?   % 