OSDN Git Service

2010-12-11 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / fortran / scanner.c
index 5842290..c226bae 100644 (file)
@@ -1,6 +1,6 @@
 /* Character scanner.
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
-   Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+   2010 Free Software Foundation, Inc.
    Contributed by Andy Vaught
 
 This file is part of GCC.
@@ -44,7 +44,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "gfortran.h"
-#include "toplev.h"
+#include "toplev.h"    /* For set_src_pwd.  */
 #include "debug.h"
 #include "flags.h"
 #include "cpp.h"
@@ -76,8 +76,6 @@ const char *gfc_source_file;
 static FILE *gfc_src_file;
 static gfc_char_t *gfc_src_preprocessor_lines[2];
 
-extern int pedantic;
-
 static struct gfc_file_change
 {
   const char *filename;
@@ -390,7 +388,8 @@ gfc_release_include_path (void)
 
 
 static FILE *
-open_included_file (const char *name, gfc_directorylist *list, bool module)
+open_included_file (const char *name, gfc_directorylist *list,
+                   bool module, bool system)
 {
   char *fullname;
   gfc_directorylist *p;
@@ -407,7 +406,12 @@ open_included_file (const char *name, gfc_directorylist *list, bool module)
 
       f = gfc_open_file (fullname);
       if (f != NULL)
-       return f;
+       {
+         if (gfc_cpp_makedep ())
+           gfc_cpp_add_dep (fullname, system);
+
+         return f;
+       }
     }
 
   return NULL;
@@ -421,28 +425,37 @@ open_included_file (const char *name, gfc_directorylist *list, bool module)
 FILE *
 gfc_open_included_file (const char *name, bool include_cwd, bool module)
 {
-  FILE *f;
+  FILE *f = NULL;
 
-  if (IS_ABSOLUTE_PATH (name))
-    return gfc_open_file (name);
-
-  if (include_cwd)
+  if (IS_ABSOLUTE_PATH (name) || include_cwd)
     {
       f = gfc_open_file (name);
-      if (f != NULL)
-       return f;
+      if (f && gfc_cpp_makedep ())
+       gfc_cpp_add_dep (name, false);
     }
 
-  return open_included_file (name, include_dirs, module);
+  if (!f)
+    f = open_included_file (name, include_dirs, module, false);
+
+  return f;
 }
 
 FILE *
 gfc_open_intrinsic_module (const char *name)
 {
+  FILE *f = NULL;
+
   if (IS_ABSOLUTE_PATH (name))
-    return gfc_open_file (name);
+    {
+      f = gfc_open_file (name);
+      if (f && gfc_cpp_makedep ())
+       gfc_cpp_add_dep (name, true);
+    }
 
-  return open_included_file (name, intrinsic_modules_dirs, true);
+  if (!f)
+    f = open_included_file (name, intrinsic_modules_dirs, true, true);
+
+  return f;
 }
 
 
@@ -614,7 +627,7 @@ next_char (void)
 
 /* Skip a comment.  When we come here the parse pointer is positioned
    immediately after the comment character.  If we ever implement
-   compiler directives withing comments, here is where we parse the
+   compiler directives within comments, here is where we parse the
    directive.  */
 
 static void
@@ -732,7 +745,7 @@ skip_free_comments (void)
             2) handle OpenMP conditional compilation, where
                !$ should be treated as 2 spaces (for initial lines
                only if followed by space).  */
-         if (gfc_option.flag_openmp && at_bol)
+         if (gfc_option.gfc_flag_openmp && at_bol)
            {
              locus old_loc = gfc_current_locus;
              if (next_char () == '$')
@@ -858,7 +871,7 @@ skip_fixed_comments (void)
              && continue_line < gfc_linebuf_linenum (gfc_current_locus.lb))
            continue_line = gfc_linebuf_linenum (gfc_current_locus.lb);
 
-         if (gfc_option.flag_openmp)
+         if (gfc_option.gfc_flag_openmp)
            {
              if (next_char () == '$')
                {
@@ -984,7 +997,7 @@ gfc_skip_comments (void)
    context or not.  */
 
 gfc_char_t
-gfc_next_char_literal (int in_string)
+gfc_next_char_literal (gfc_instring in_string)
 {
   locus old_loc;
   int i, prev_openmp_flag;
@@ -1029,6 +1042,17 @@ restart:
          goto done;
        }
 
+      /* Check to see if the continuation line was truncated.  */
+      if (gfc_option.warn_line_truncation && gfc_current_locus.lb != NULL
+         && gfc_current_locus.lb->truncated)
+       {
+         int maxlen = gfc_option.free_line_length;
+         gfc_current_locus.lb->truncated = 0;
+         gfc_current_locus.nextc += maxlen;
+         gfc_warning_now ("Line truncated at %L", &gfc_current_locus);
+         gfc_current_locus.nextc -= maxlen;
+       }
+
       if (c != '&')
        goto done;
 
@@ -1122,10 +1146,10 @@ restart:
        {
          if (in_string)
            {
-             if (gfc_option.warn_ampersand)
-               gfc_warning_now ("Missing '&' in continued character "
-                                "constant at %C");
              gfc_current_locus.nextc--;
+             if (gfc_option.warn_ampersand && in_string == INSTRING_WARN)
+               gfc_warning ("Missing '&' in continued character "
+                            "constant at %C");
            }
          /* Both !$omp and !$ -fopenmp continuation lines have & on the
             continuation line only optionally.  */
@@ -1139,7 +1163,7 @@ restart:
            }
        }
     }
-  else
+  else /* Fixed form.  */
     {
       /* Fixed form continuation.  */
       if (!in_string && c == '!')
@@ -1158,6 +1182,14 @@ restart:
       if (c != '\n')
        goto done;
 
+      /* Check to see if the continuation line was truncated.  */
+      if (gfc_option.warn_line_truncation && gfc_current_locus.lb != NULL
+         && gfc_current_locus.lb->truncated)
+       {
+         gfc_current_locus.lb->truncated = 0;
+         gfc_warning_now ("Line truncated at %L", &gfc_current_locus);
+       }
+
       prev_openmp_flag = openmp_flag;
       continue_flag = 1;
       old_loc = gfc_current_locus;
@@ -1238,7 +1270,7 @@ gfc_next_char (void)
 
   do
     {
-      c = gfc_next_char_literal (0);
+      c = gfc_next_char_literal (NONSTRING);
     }
   while (gfc_current_form == FORM_FIXED && gfc_is_whitespace (c));
 
@@ -1339,7 +1371,7 @@ gfc_gobble_whitespace (void)
   do
     {
       old_loc = gfc_current_locus;
-      c = gfc_next_char_literal (0);
+      c = gfc_next_char_literal (NONSTRING);
       /* 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.  */
@@ -1386,7 +1418,7 @@ load_line (FILE *input, gfc_char_t **pbuf, int *pbuflen, const int *first_char)
   static int linenum = 0, current_line = 1;
   int c, maxlen, i, preprocessor_flag, buflen = *pbuflen;
   int trunc_flag = 0, seen_comment = 0;
-  int seen_printable = 0, seen_ampersand = 0;
+  int seen_printable = 0, seen_ampersand = 0, quoted = ' ';
   gfc_char_t *buffer;
   bool found_tab = false;
 
@@ -1468,6 +1500,18 @@ load_line (FILE *input, gfc_char_t **pbuf, int *pbuflen, const int *first_char)
          && (c == '*' || c == 'c' || c == 'd'))
        seen_comment = 1;
 
+      if (quoted == ' ')
+       {
+         if (c == '\'' || c == '"')
+           quoted = c;
+       }
+      else if (c == quoted)
+       quoted = ' ';
+
+      /* Is this a free-form comment?  */
+      if (c == '!' && quoted == ' ')
+        seen_comment = 1;
+
       /* Vendor extension: "<tab>1" marks a continuation line.  */
       if (found_tab)
        {
@@ -1516,17 +1560,34 @@ load_line (FILE *input, gfc_char_t **pbuf, int *pbuflen, const int *first_char)
        }
       else if (i >= maxlen)
        {
+         bool trunc_warn = true;
+
+         /* Enhancement, if the very next non-space character is an ampersand
+            or comment that we would otherwise warn about, don't mark as
+            truncated.  */
+
          /* Truncate the rest of the line.  */
          for (;;)
            {
              c = getc (input);
-             if (c == '\r')
+             if (c == '\r' || c == ' ')
                continue;
 
              if (c == '\n' || c == EOF)
                break;
 
-             trunc_flag = 1;
+             if (!trunc_warn && c != '!')
+               trunc_warn = true;
+
+             if (trunc_warn && ((gfc_current_form == FORM_FIXED && c == '&')
+                 || c == '!'))
+               trunc_warn = false;
+
+             if (c == '!')
+               seen_comment = 1;
+
+             if (trunc_warn && !seen_comment)
+               trunc_flag = 1;
            }
 
          c = '\n';
@@ -1751,7 +1812,7 @@ include_line (gfc_char_t *line)
 
   c = line;
 
-  if (gfc_option.flag_openmp)
+  if (gfc_option.gfc_flag_openmp)
     {
       if (gfc_current_form == FORM_FREE)
        {
@@ -1806,7 +1867,9 @@ include_line (gfc_char_t *line)
                   read by anything else.  */
 
   filename = gfc_widechar_to_char (begin, -1);
-  load_file (filename, NULL, false);
+  if (load_file (filename, NULL, false) == FAILURE)
+    exit (1);
+
   gfc_free (filename);
   return true;
 }