[PATCH, fortran] tabs are evil

Steve Kargl sgk@troutmask.apl.washington.edu
Sat Mar 11 01:47:00 GMT 2006


On Sun, Mar 05, 2006 at 04:12:56PM -0800, Steve Kargl wrote:
> The attached patch issues an error if one uses a 
> tab in a context where a member of the Fortran
> Character Set is expected.  By default gfortran
> will accept a tab as whitespace, which is its
> current behavior.  I have added the -ftabs option.
> For -ftabs, we accept tabs as whitespace, and 
> for -fno-tabs we issue an error.  Note that
> -pedantic and/or -std=f95 will trigger the error.
> Also, note that "-std=f95 -ftabs" accepts tabs
> as whitespaces.
> 
> 
> 2006-03-05  Steven G. Kargl  <kargls@comcast.net>
> 
> 	* gfortran.h: Wrap Copyright line.
> 	(gfc_option_t): add flag_tabs member.
> 	* lang.opt: Update Coyright year.  Add the ftabs.
> 	* scanner.c (gfc_gobble_whitespace): Use flag_tabs.
> 	(load_line): Add seen_comment.  Use it and flag_tabs.
> 	* options.c (gfc_init_options): Initialize flag_tabs.
> 	(gfc_post_options): Adjust flag_tabs depending on -pedantic.
> 	(gfc_handle_option):  Process command-line option -f[no-]tabs
> 
> 
> I just realized that I didn't update gfortran.texi.  I'll
> add a description of the new option before I commit.
> 

Due to the underwhelming comments on the "Tabs are evil" patch,
I will be committing this slightly modified patch.  The
new patch downgrades the severity of a fatal error to a
warning.  IMHO, it should be a fatal error, but I grow
weary of this topic.

2006-03-05  Steven G. Kargl  <kargls@comcast.net>

	* gfortran.h: Wrap Copyright line.
	(gfc_option_t): add warn_tabs member.
	* lang.opt: Update Coyright year.  Add the Wtabs.
	* invoke.texi: Document -Wtabs.
	* scanner.c (gfc_gobble_whitespace): Use warn_tabs.  Add linenum to
	suppress multiple warnings.
	(load_line): Use warn_tabs.  Add linenum, current_line, seen_comment
    to suppress multiple warnings.
	* options.c (gfc_init_options): Initialize warn_tabs.
	(set_Wall): set warn_tabs for -Wall.
	(gfc_post_options): Adjust flag_tabs depending on -pedantic.
	(gfc_handle_option):  Process command-line option -W[no-]tabs

-- 
Steve
-------------- next part --------------

Index: gfortran.h
===================================================================
--- gfortran.h	(revision 111958)
+++ gfortran.h	(working copy)
@@ -1,6 +1,6 @@
 /* gfortran header file
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software 
-   Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
    Contributed by Andy Vaught
 
 This file is part of GCC.
@@ -1605,8 +1605,9 @@ typedef struct
   int warn_conversion;
   int warn_implicit_interface;
   int warn_line_truncation;
-  int warn_underflow;
   int warn_surprising;
+  int warn_tabs;
+  int warn_underflow;
   int warn_unused_labels;
 
   int flag_default_double;
Index: lang.opt
===================================================================
--- lang.opt	(revision 111958)
+++ lang.opt	(working copy)
@@ -1,5 +1,5 @@
 ; Options for the Fortran 95 front end.
-; Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+; Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 ;
 ; This file is part of GCC.
 ;
@@ -60,6 +60,10 @@ Warn about usage of non-standard intrins
 Wsurprising
 Fortran
 Warn about \"suspicious\" constructs
+
+Wtabs
+Fortran
+Warn about nonconforming uses of the tab character
 
 Wunderflow
 Fortran
Index: invoke.texi
===================================================================
--- invoke.texi	(revision 111958)
+++ invoke.texi	(working copy)
@@ -128,8 +128,8 @@ by type.  Explanations are in the follow
 @xref{Warning Options,,Options to Request or Suppress Warnings}.
 @gccoptlist{
 -fsyntax-only  -pedantic  -pedantic-errors @gol
--w  -Wall  -Waliasing  -Wconversion @gol
--Wimplicit-interface  -Wnonstd-intrinsics  -Wsurprising  -Wunderflow @gol
+-w  -Wall  -Waliasing  -Wconversion -Wimplicit-interface @gol
+-Wtabs -Wnonstd-intrinsics -Wsurprising -Wunderflow @gol
 -Wunused-labels -Wline-truncation -W}
 
 @item Debugging Options
@@ -378,8 +378,8 @@ Inhibit all warning messages.
 Enables commonly used warning options that which pertain to usage that
 we recommend avoiding and that we believe is easy to avoid.
 This currently includes @option{-Wunused-labels}, @option{-Waliasing},
-@option{-Wsurprising}, @option{-Wnonstd-intrinsic} and
-@option{-Wline-truncation}.
+@option{-Wsurprising}, @option{-Wnonstd-intrinsic},  @option{-Wno-tabs},
+and @option{-Wline-truncation}.
 
 
 @cindex -Waliasing option
@@ -444,6 +444,15 @@ lower value is greater than its upper va
 @item
 A LOGICAL SELECT construct has three CASE statements.
 @end itemize
+
+@cindex -Wtabs
+@cindex options, -Wtabs
+@item -Wtabs
+@cindex Tabs
+By default, tabs are accepted as whitespace, but tabs are not members
+of the Fortran Character Set.  @option{-Wno-tabs} will cause an warning
+to be issued if a tab is encounter. Note, @option{-Wno-tabs} is active
+for @option{-pedantic}, @option{-std=f95}, and @option{-Wall}.
 
 @cindex -Wunderflow
 @cindex options, -Wunderflow
Index: scanner.c
===================================================================
--- scanner.c	(revision 111958)
+++ scanner.c	(working copy)
@@ -836,6 +836,7 @@ gfc_error_recovery (void)
 void
 gfc_gobble_whitespace (void)
 {
+  static int linenum = 0;
   locus old_loc;
   int c;
 
@@ -843,6 +844,15 @@ gfc_gobble_whitespace (void)
     {
       old_loc = gfc_current_locus;
       c = gfc_next_char_literal (0);
+      /* Issue a warning for nonconforming tabs.  We keep track of the line
+	 number because the Fortran matchers will often back up and the same
+	 line will be scanned multiple times.  */
+      if (!gfc_option.warn_tabs && c == '\t'
+	  && gfc_current_locus.lb->linenum != linenum)
+	{
+	  linenum = gfc_current_locus.lb->linenum;
+	  gfc_warning_now ("Nonconforming tab character at %C");
+	}
     }
   while (gfc_is_whitespace (c));
 
@@ -865,8 +875,9 @@ gfc_gobble_whitespace (void)
 static int
 load_line (FILE * input, char **pbuf, int *pbuflen)
 {
+  static int linenum = 0, current_line = 1;
   int c, maxlen, i, preprocessor_flag, buflen = *pbuflen;
-  int trunc_flag = 0;
+  int trunc_flag = 0, seen_comment = 0;
   char *buffer;
 
   /* Determine the maximum allowed line length.
@@ -932,8 +943,24 @@ load_line (FILE * input, char **pbuf, in
 	  break;
 	}
 
+      /* Is this a fixed-form comment?  */
+      if (gfc_current_form == FORM_FIXED && i == 0
+	  && (c == '*' || c == 'c' || c == 'd'))
+	seen_comment = 1;
+
       if (gfc_current_form == FORM_FIXED && c == '\t' && i <= 6)
-	{			/* Tab expansion.  */
+	{
+	  /* The error machinery isn't available at this point, so we can't
+	     easily report line and column numbers consistent with other 
+	     parts of gfortran.  */
+	  if (!gfc_option.warn_tabs && seen_comment == 0
+	      && current_line != linenum)
+	    {
+	      linenum = current_line;
+	      gfc_warning_now (
+		"Nonconforming tab character in column 1 of line %d", linenum);
+	    }
+
 	  while (i <= 6)
 	    {
 	      *buffer++ = ' ';
@@ -985,6 +1012,7 @@ load_line (FILE * input, char **pbuf, in
 
   *buffer = '\0';
   *pbuflen = buflen;
+  current_line++;
 
   return trunc_flag;
 }
Index: options.c
===================================================================
--- options.c	(revision 111958)
+++ options.c	(working copy)
@@ -55,8 +55,9 @@ gfc_init_options (unsigned int argc ATTR
   gfc_option.warn_conversion = 0;
   gfc_option.warn_implicit_interface = 0;
   gfc_option.warn_line_truncation = 0;
-  gfc_option.warn_underflow = 1;
   gfc_option.warn_surprising = 0;
+  gfc_option.warn_tabs = 1;
+  gfc_option.warn_underflow = 1;
   gfc_option.warn_unused_labels = 0;
 
   gfc_option.flag_default_double = 0;
@@ -283,11 +284,12 @@ set_Wall (void)
 
   gfc_option.warn_aliasing = 1;
   gfc_option.warn_line_truncation = 1;
-  gfc_option.warn_underflow = 1;
+  gfc_option.warn_nonstd_intrinsics = 1;
   gfc_option.warn_surprising = 1;
+  gfc_option.warn_tabs = 0;
+  gfc_option.warn_underflow = 1;
   gfc_option.warn_unused_labels = 1;
-  gfc_option.warn_nonstd_intrinsics = 1;
-
+ 
   set_Wunused (1);
   warn_return_type = 1;
   warn_switch = 1;
@@ -395,14 +397,18 @@ gfc_handle_option (size_t scode, const c
       gfc_option.warn_line_truncation = value;
       break;
 
-    case OPT_Wunderflow:
-      gfc_option.warn_underflow = value;
-      break;
-
     case OPT_Wsurprising:
       gfc_option.warn_surprising = value;
       break;
 
+    case OPT_Wtabs:
+      gfc_option.warn_tabs = value;
+      break;
+
+    case OPT_Wunderflow:
+      gfc_option.warn_underflow = value;
+      break;
+
     case OPT_Wunused_labels:
       gfc_option.warn_unused_labels = value;
       break;
@@ -547,6 +553,7 @@ gfc_handle_option (size_t scode, const c
       gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F95 | GFC_STD_F77;
       gfc_option.warn_std = GFC_STD_F95_OBS;
       gfc_option.max_identifier_length = 31;
+      gfc_option.warn_tabs = 0;
       break;
 
     case OPT_std_f2003:


More information about the Fortran mailing list