This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC: Non-traditional CPP


Hello,

currently, CPP is called in traditional CPP mode to prevent all kind of problems, however, this limits the supported features. Several other Fortran compilers support newer CPP features and also users keep requesting/expecting them. (See also PR 28662 and PR 29671 and http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/f6a26f74557d7324 )
My idea is to enhance libcpp such to allow newer CPP features with Fortran.


The attached draft patch properly recognizes comment lines and ignores those. I'm positive that this is not enough but currently I do not see where it will fail. I therefore need your help. I also plan to add an option to CPP for Fortran preprocessing.

The easiest way to test is to run: gfortran -E file.F90 (please also check fixed-form .F files.).

I know that the following case fails (without traditional it now prints a warning). The problem is that '...& \n &....' is not recognized as one long string.

#define Paul Hans
! Paul's string
print *,'Hello &
 &Paul'
end

Anything else? Other suggestions, comments, remark to the patch?

Tobias

PS: Two test cases to make sure I don't loose them. Esp. fixed-form test cases are needed.


#define a 2 #if (a != 2) print *, 'Wrong' #else print *, 'OK' #endif end


! Should the // be a comment sign or for ! concating the string? ifort and sunf95 ! don't regard it as comment marker, ! gfortran does neither. #define STR 'From A ' // /* ... */ 'to Z' print *, STR//'!' end
Index: libcpp/include/cpplib.h
===================================================================
--- libcpp/include/cpplib.h	(Revision 138294)
+++ libcpp/include/cpplib.h	(Arbeitskopie)
@@ -280,6 +280,12 @@ struct cpp_options
      "#import".  */
   unsigned char objc;
 
+  /* Nonzero means handle Fortran files.  */
+  unsigned char fortran;
+
+  /* Nonzero means handle fixed-format Fortran files.  */
+  unsigned char fixed_fortran;
+
   /* Nonzero means don't copy comments into the output file.  */
   unsigned char discard_comments;
 
Index: libcpp/lex.c
===================================================================
--- libcpp/lex.c	(Revision 138294)
+++ libcpp/lex.c	(Arbeitskopie)
@@ -686,12 +686,14 @@ save_comment (cpp_reader *pfile, cpp_tok
     len--;
 
   /* If we are currently in a directive, then we need to store all
-     C++ comments as C comments internally, and so we need to
-     allocate a little extra space in that case.
+     C++ comments as C comments internally, and so we
+     need to allocate a little extra space in that case.
 
      Note that the only time we encounter a directive here is
      when we are saving comments in a "#define".  */
-  clen = (pfile->state.in_directive && type == '/') ? len + 2 : len;
+  clen = (pfile->state.in_directive && type == '/')
+	 ? len + 2
+	 : len;
 
   buffer = _cpp_unaligned_alloc (pfile, clen);
 
@@ -699,12 +701,14 @@ save_comment (cpp_reader *pfile, cpp_tok
   token->val.str.len = clen;
   token->val.str.text = buffer;
 
-  buffer[0] = '/';
   memcpy (buffer + 1, from, len - 1);
 
+  buffer[0] = CPP_OPTION (pfile, fortran) ? type : '/';
+  
   /* Finish conversion to a C comment, if necessary.  */
   if (pfile->state.in_directive && type == '/')
     {
+      buffer[0] = '/';
       buffer[1] = '*';
       buffer[clen - 2] = '*';
       buffer[clen - 1] = '/';
@@ -994,6 +998,7 @@ _cpp_lex_direct (cpp_reader *pfile)
 	result->flags |= PREV_WHITE;
     }
   buffer = pfile->buffer;
+
  update_tokens_line:
   result->src_loc = pfile->line_table->highest_line;
 
@@ -1009,6 +1014,17 @@ _cpp_lex_direct (cpp_reader *pfile)
   LINEMAP_POSITION_FOR_COLUMN (result->src_loc, pfile->line_table,
 			       CPP_BUF_COLUMN (buffer, buffer->cur));
 
+  /* Skip fixed-form Fortran comment lines, i.e. lines where in
+     column one a "!", "*" or "C" is.   */
+  if (CPP_OPTION (pfile, fixed_fortran) && CPP_BUF_COL (buffer) == 1
+      && (c == '!' || c == '*' || c == 'C' || c == 'c'))
+    {
+	  comment_start = buffer->cur;
+	  skip_line_comment (pfile);
+	  save_comment (pfile, result, comment_start, c);
+	  return result; 
+    }
+
   switch (c)
     {
     case ' ': case '\t': case '\f': case '\v': case '\0':
@@ -1094,7 +1110,8 @@ _cpp_lex_direct (cpp_reader *pfile)
 	  /* Warn about comments only if pedantically GNUC89, and not
 	     in system headers.  */
 	  if (CPP_OPTION (pfile, lang) == CLK_GNUC89 && CPP_PEDANTIC (pfile)
-	      && ! buffer->warned_cplusplus_comments)
+	      && ! buffer->warned_cplusplus_comments
+	      && (!CPP_OPTION (pfile, fortran) || pfile->state.in_directive))
 	    {
 	      cpp_error (pfile, CPP_DL_PEDWARN,
 			 "C++ style comments are not allowed in ISO C90");
@@ -1103,7 +1120,9 @@ _cpp_lex_direct (cpp_reader *pfile)
 	      buffer->warned_cplusplus_comments = 1;
 	    }
 
-	  if (skip_line_comment (pfile) && CPP_OPTION (pfile, warn_comments))
+	  if ((!CPP_OPTION (pfile, fortran) || pfile->state.in_directive)
+	      && skip_line_comment (pfile)
+	      && CPP_OPTION (pfile, warn_comments))
 	    cpp_error (pfile, CPP_DL_WARNING, "multi-line comment");
 	}
       else if (c == '=')
@@ -1260,9 +1279,22 @@ _cpp_lex_direct (cpp_reader *pfile)
 	}
       break;
 
+    case '!':
+      /* Ignore Fortran comments. For fixed-form source, a "!" at
+	 column 6 is not a comment.  */
+      if (CPP_OPTION (pfile, fortran) && !pfile->state.in_directive
+	  &&  CPP_BUF_COL (buffer) != 6)
+	{
+	  comment_start = buffer->cur;
+	  skip_line_comment (pfile);
+	  save_comment (pfile, result, comment_start, c);
+	}
+      else
+	IF_NEXT_IS ('=', CPP_NOT_EQ, CPP_NOT);
+      break;
+
     case '*': IF_NEXT_IS ('=', CPP_MULT_EQ, CPP_MULT); break;
     case '=': IF_NEXT_IS ('=', CPP_EQ_EQ, CPP_EQ); break;
-    case '!': IF_NEXT_IS ('=', CPP_NOT_EQ, CPP_NOT); break;
     case '^': IF_NEXT_IS ('=', CPP_XOR_EQ, CPP_XOR); break;
     case '#': IF_NEXT_IS ('#', CPP_PASTE, CPP_HASH); break;
 
Index: gcc/fortran/cpp.c
===================================================================
--- gcc/fortran/cpp.c	(Revision 138327)
+++ gcc/fortran/cpp.c	(Arbeitskopie)
@@ -444,7 +444,9 @@ gfc_cpp_post_options (void)
   gcc_assert (cpp_option);
 
   /* TODO: allow non-traditional modes, e.g. by -cpp-std=...?  */
-  cpp_option->traditional = 1;
+  cpp_option->traditional = 0;
+  cpp_option->fortran = 1;
+  cpp_option->fixed_fortran = gfc_current_form == FORM_FIXED ? 1 : 0;
   cpp_option->cplusplus_comments = 0;
 
   cpp_option->pedantic = pedantic;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]