Signed-off-by: Mohammad-Reza Nabipoor <[email protected]>

gcc/algol68/ChangeLog

        * a68.h (a68_file_size_fd): New function declaration.
        (a68_file_read_fd): Likewise.
        * a68-parser-scanner.cc (a68_file_size_fd): New function.
        (a68_file_read_fd): Likewise.
        (a68_file_size): Adapt to use `a68_file_size_fd'.
        (a68_file_read): Adapt to use `a68_file_read_fd'.
        * a68-imports.cc (a68_find_export_data): Implement
        reading from module's .m68 file if available.
---
 gcc/algol68/a68-imports.cc        | 45 +++++++++++++++++++++++++++----
 gcc/algol68/a68-parser-scanner.cc | 34 ++++++++++++++++-------
 gcc/algol68/a68.h                 |  2 ++
 3 files changed, 67 insertions(+), 14 deletions(-)

diff --git a/gcc/algol68/a68-imports.cc b/gcc/algol68/a68-imports.cc
index 2fbe15d4156..213974cbe07 100644
--- a/gcc/algol68/a68-imports.cc
+++ b/gcc/algol68/a68-imports.cc
@@ -269,15 +269,51 @@ a68_find_export_data (const std::string &filename, int 
fd, size_t *psize)
     }
 
   char buf[A68_EXPORT_MAGIC_LEN];
-  ssize_t c = ::read(fd, buf, A68_EXPORT_MAGIC_LEN);
+  ssize_t c = read (fd, buf, A68_EXPORT_MAGIC_LEN);
   if (c < A68_EXPORT_MAGIC_LEN)
     return NULL;
 
   /* Check for a file containing nothing but Algol 68 export data.  */
-  if (buf[0] == '\x0a' && buf[1] == '\xad')
+  if (buf[0] == '\x0a' && buf[1] == '\x68')
     {
-      /* XXX read whole file.  */
-      return exports;
+      /* read whole file.  */
+
+      char *buf;
+      ssize_t len, nread;
+
+      len = a68_file_size_fd (fd);
+      if (len == -1)
+        {
+          a68_error (NO_NODE, "a68_file_size_fd failed for Z",
+                     filename.c_str ());
+          return NULL;
+        }
+
+      buf = XNEWVEC (char, len);
+      if (buf == NULL)
+        {
+          a68_error (NO_NODE,
+                     "memory allocation failed while reading export data");
+          return NULL;
+        }
+
+      nread = a68_file_read_fd (fd, buf, len);
+      if (nread < 0)
+        {
+          free (buf);
+          a68_error (NO_NODE, "read failed while reading export data");
+          return NULL;
+        }
+
+      if (nread < len)
+        {
+          free (buf);
+          a68_error (NO_NODE, "short read while reading export data");
+          return NULL;
+        }
+
+      *psize = len;
+      return buf;
     }
 
 #if 0
@@ -287,7 +323,6 @@ a68_find_export_data (const std::string &filename, int fd, 
size_t *psize)
 #endif
 
   return NULL;
-
 }
 
 /* Given *PFILENAME, where *PFILENAME does not exist, try various suffixes.  If
diff --git a/gcc/algol68/a68-parser-scanner.cc 
b/gcc/algol68/a68-parser-scanner.cc
index 94647d52882..ed42a5a642e 100644
--- a/gcc/algol68/a68-parser-scanner.cc
+++ b/gcc/algol68/a68-parser-scanner.cc
@@ -119,37 +119,36 @@ supper_postlude[] = {
     }                                                                  \
   while (0)
 
-/* Get the size of a file given a stream pointer FILE.  In case the size of
+/* Get the size of a file given a file descriptor FD.  In case the size of
    the file cannot be determined then this function returns -1.  */
 
 ssize_t
-a68_file_size (FILE *file)
+a68_file_size_fd (int fd)
 {
   ssize_t fsize;
   off_t off, save;
 
-  save = ftell (file);
-  if (save == -1)
+  save = lseek (fd, 0, SEEK_CUR);
+  if (save == (off_t) -1)
     return -1;
 
-  off = lseek (fileno (file), 0, SEEK_END);
+  off = lseek (fd, 0, SEEK_END);
   if (off == (off_t) -1)
     return -1;
   fsize = (ssize_t) off;
 
-  off = lseek (fileno (file), save, SEEK_SET);
+  off = lseek (fd, save, SEEK_SET);
   if (off == (off_t) -1)
     return -1;
 
   return fsize;
 }
 
-/* Read bytes from file into buffer.  */
+/* Read bytes from file into buffer given a file descriptor.  */
 
 ssize_t
-a68_file_read (FILE *file, void *buf, size_t n)
+a68_file_read_fd (int fd, void *buf, size_t n)
 {
-  int fd = fileno (file);
   size_t to_do = n;
   int restarts = 0;
   char *z = (char *) buf;
@@ -189,6 +188,23 @@ a68_file_read (FILE *file, void *buf, size_t n)
   return (ssize_t) n - (ssize_t) to_do;
 }
 
+/* Get the size of a file given a stream pointer FILE.  In case the size of
+   the file cannot be determined then this function returns -1.  */
+
+ssize_t
+a68_file_size (FILE *file)
+{
+  return a68_file_size_fd (fileno (file));
+}
+
+/* Read bytes from file into buffer given a stream pointer FILE.  */
+
+ssize_t
+a68_file_read (FILE *file, void *buf, size_t n)
+{
+  return a68_file_read_fd (fileno (file), buf, n);
+}
+
 /* Save scanner state, for character look-ahead.  */
 
 static void
diff --git a/gcc/algol68/a68.h b/gcc/algol68/a68.h
index 98730973bc7..e623376749d 100644
--- a/gcc/algol68/a68.h
+++ b/gcc/algol68/a68.h
@@ -281,6 +281,8 @@ void a68_scan_error (LINE_T *u, char *v, const char *txt, 
...);
 /* a68-parser-scanner.cc  */
 
 bool a68_lexical_analyser (const char *filename, bool *empty_file);
+ssize_t a68_file_size_fd (int fd);
+ssize_t a68_file_read_fd (int fd, void *buf, size_t n);
 ssize_t a68_file_size (FILE *file);
 ssize_t a68_file_read (FILE *file, void *buf, size_t n);
 
-- 
2.52.0

Reply via email to