Hi Mohammad.

> 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.

I think it would be better to have just one version of a68_file_size and
a68_file_read, that simply works on file descriptors.  Callers can the
use fileno or whatever is appropriate.

>       (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.

We still need a test for this.  I suggest to build a little module and
extract its exports section to a foo.m68 with objcopy -j .a68_exports.

> ---
>  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);

Reply via email to