Ok this is an embarrassing one.  A source file that is either empty or
that contains just blanks, characters and/or pragmats, is not a proper
particular program nor a prelude packet.  This patch makes ga68 to
emit an error mesage rather than ICEing.

Signed-off-by: Jose E. Marchesi <[email protected]>

gcc/algol68/ChangeLog

        * a68-parser-scanner.cc (a68_lexical_analyser): New argument
        empty_program.
        * a68.h: Update prototype of a68_lexical_analyser.
        * a68-parser.cc (a68_parser): Emit error for empty input files.
---
 gcc/algol68/a68-parser-scanner.cc | 27 +++++++++++++++++++--------
 gcc/algol68/a68-parser.cc         | 12 +++++-------
 gcc/algol68/a68.h                 |  2 +-
 3 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/gcc/algol68/a68-parser-scanner.cc 
b/gcc/algol68/a68-parser-scanner.cc
index 966ebdf6ed1..8c0694de9ba 100644
--- a/gcc/algol68/a68-parser-scanner.cc
+++ b/gcc/algol68/a68-parser-scanner.cc
@@ -328,12 +328,7 @@ read_source_file (const char *filename)
     fatal_error (UNKNOWN_LOCATION, "specified file %s is a directory",
                 filename);
 
-  if ((source_file_size = get_source_size ()) == 0)
-    {
-      /* The source file is empty.  */
-      ret = false;
-      goto done;
-    }
+  source_file_size = get_source_size ();
 
   /* Allocate A68_PARSER (scan_buf), which is an auxiliary buffer used by the
      scanner known to be big enough to hold any string contained in the source
@@ -395,7 +390,6 @@ read_source_file (const char *filename)
   /* Include files.  */
   include_files (TOP_LINE (&A68_JOB));
 
- done:
   if (fclose (FILE_SOURCE_FD (&A68_JOB)) != 0)
     gcc_unreachable ();
   return ret;
@@ -2279,7 +2273,7 @@ tokenise_source (NODE_T **root, int level, bool in_format,
 /* Tokenise source file, build initial syntax tree.  */
 
 bool
-a68_lexical_analyser (const char *filename)
+a68_lexical_analyser (const char *filename, bool *empty_program)
 {
   LINE_T *l = NO_LINE, *start_l = NO_LINE;
   char *s = NO_TEXT, *start_c = NO_TEXT;
@@ -2295,6 +2289,23 @@ a68_lexical_analyser (const char *filename)
     s = STRING (l);
   tokenise_source (&root, 0, false, &l, &s, &start_l, &start_c);
 
+  /* Detemine whether the actual file contents resulted in some token.  This is
+     used in order to provide better diagnostics for empty source files or
+     files containing only comments or pragmats.  These are not valid Algol 68
+     packets.  */
+
+  *empty_program = true;
+  for (NODE_T *p = TOP_NODE (&A68_JOB); p != NO_NODE; FORWARD (p))
+    {
+      LINE_T *l = LINE (INFO (p));
+      if (strcmp (FILENAME (l), "prelude") != 0
+         && strcmp (FILENAME (l), "postlude") != 0)
+       {
+         *empty_program = false;
+         break;
+       }
+    }
+
   /* If the source is a prelude packet then we should remove the prelude and
      postlude nodes from the token stream.  We distinguish these nodes by
      location.
diff --git a/gcc/algol68/a68-parser.cc b/gcc/algol68/a68-parser.cc
index f01ecbee434..c43efe3ba19 100644
--- a/gcc/algol68/a68-parser.cc
+++ b/gcc/algol68/a68-parser.cc
@@ -454,17 +454,15 @@ a68_parser (const char *filename)
   /* Tokeniser.  */
   if (ERROR_COUNT (&A68_JOB) == 0)
     {
-      bool ok = a68_lexical_analyser (filename);
+      bool empty_program;
+      bool ok = a68_lexical_analyser (filename, &empty_program);
 
       if (!ok)
        return;
 
-      /* An empty file is not a valid program.  */
-      if (TOP_NODE (&A68_JOB) == NO_NODE)
-       {
-         a68_error (NO_NODE, "file is empty, expected a program");
-         return;
-       }
+      if (empty_program)
+       a68_error (NO_NODE,
+                  "particular program or prelude packet not found in source 
file");
 
       TREE_LISTING_SAFE (&A68_JOB) = true;
       renum = 0;
diff --git a/gcc/algol68/a68.h b/gcc/algol68/a68.h
index 92dc28e222f..40ceec9ddc3 100644
--- a/gcc/algol68/a68.h
+++ b/gcc/algol68/a68.h
@@ -280,7 +280,7 @@ void a68_scan_error (LINE_T *u, char *v, const char *txt, 
...);
 
 /* a68-parser-scanner.cc  */
 
-bool a68_lexical_analyser (const char *filename);
+bool a68_lexical_analyser (const char *filename, bool *empty_file);
 
 /* a68-parser.cc  */
 
-- 
2.30.2

Reply via email to