[gnu.gcc.bug] gcc -pedantic doesn't check for bad file ends

eggert@twinsun.com (Paul Eggert) (09/21/89)

Draft ANSI C (2.1.1.2) requires that ``A source file that is not empty shall
end in a new-line character, which shall not be immediately preceded by a
backslash character.''  GCC 1.35 doesn't check this requirement.  Here is a
patch to make it check the requirement if the -pedantic option is set.
Although the check is partly performed when the file is initially input, the
error message is deferred until after the input is scanned, so that the user
is not confused by an initial error message that refers to the end of the
file.

*** old/cccp.c	Wed Sep 20 14:59:04 1989
--- new/cccp.c	Wed Sep 20 14:55:50 1989
***************
*** 272,277 ****
--- 272,303 ----
  
  /* List of other included files.  */
  struct file_name_list *all_include_files = 0;
+ 
+ /* Make sure data ends with a newline.  And put a null after it.
+    Yield nonzero if we had to append a newline. */
+ 
+ int
+ ensure_proper_end (fp)
+      register FILE_BUF *fp;
+ {
+   int adjusted = 0;
+   if (fp->length > 0 && fp->buf[fp->length-1] != '\n') {
+     fp->buf[fp->length++] = '\n';
+     adjusted = 1;
+   }
+   fp->buf[fp->length] = '\0';
+   return adjusted;
+ }
+ 
+ check_proper_end (fp, adjusted)
+       register FILE_BUF *fp;
+       int adjusted;
+ {
+   if (adjusted)
+     error ("last character is not a newline");
+   if (fp->length > 1 && fp->buf[fp->length-2] == '\\')
+     error ("last line ends in a backslash");
+ }
  
  /* Structure allocated for every #define.  For a simple replacement
     such as
***************
*** 512,517 ****
--- 538,544 ----
    char **pend_undefs = (char **) xmalloc (argc * sizeof (char *));
    int inhibit_predefs = 0;
    int no_standard_includes = 0;
+   int adjusted;
  
    /* Non-0 means don't output the preprocessed program.  */
    int inhibit_output = 0;
***************
*** 955,965 ****
    if (!no_trigraphs)
      trigraph_pcp (fp);
  
!   /* Make sure data ends with a newline.  And put a null after it.  */
! 
!   if (fp->length > 0 && fp->buf[fp->length-1] != '\n')
!     fp->buf[fp->length++] = '\n';
!   fp->buf[fp->length] = '\0';
  
    /* Now that we know the input file is valid, open the output.  */
  
--- 982,988 ----
    if (!no_trigraphs)
      trigraph_pcp (fp);
  
!   adjusted = ensure_proper_end (fp);
  
    /* Now that we know the input file is valid, open the output.  */
  
***************
*** 974,979 ****
--- 997,1005 ----
  
    rescan (&outbuf, 0);
  
+   if (pedantic)
+     check_proper_end (fp, adjusted);
+ 
    /* Now we have processed the entire input
       Write whichever kind of output has been requested.  */
  
***************
*** 2533,2538 ****
--- 2559,2565 ----
    long i;
    FILE_BUF *fp;			/* For input stack frame */
    int success = 0;
+   int adjusted;
  
    if (file_size_and_mode (f, &st_mode, &st_size) < 0)
      goto nope;		/* Impossible? */
***************
*** 2597,2605 ****
    if (!no_trigraphs)
      trigraph_pcp (fp);
  
!   if (fp->length > 0 && fp->buf[fp->length-1] != '\n')
!     fp->buf[fp->length++] = '\n';
!   fp->buf[fp->length] = '\0';
  
    success = 1;
    indepth++;
--- 2624,2630 ----
    if (!no_trigraphs)
      trigraph_pcp (fp);
  
!   adjusted = ensure_proper_end (fp);
  
    success = 1;
    indepth++;
***************
*** 2606,2611 ****
--- 2631,2638 ----
  
    output_line_command (fp, op, 0);
    rescan (op, 0);
+   if (pedantic)
+     check_proper_end (fp, adjusted);
    indepth--;
    output_line_command (&instack[indepth], op, 0);