/* Utility routines for finding and reading Java(TM) .class files.
   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004
   Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  

Java and all Java-based marks are trademarks or registered trademarks
of Sun Microsystems, Inc. in the United States and other countries.
The Free Software Foundation is independent of Sun Microsystems, Inc.  */

/* Written by Per Bothner <bothner@cygnus.com>, February 1996. */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"

#include "jcf.h"
#include "tree.h"
#include "toplev.h"
#include "java-tree.h"
#include "hashtab.h"
#if JCF_USE_SCANDIR
#include <dirent.h>
#include <fnmatch.h>
#endif

#include "zlib.h"

/* DOS brain-damage */
#ifndef O_BINARY
#define O_BINARY 0 /* MS-DOS brain-damage */
#endif

int
jcf_unexpected_eof (JCF *jcf, int count ATTRIBUTE_UNUSED)
{
  if (jcf->filename)
    fprintf (stderr, "Premature end of .class file %s.\n", jcf->filename);
  else
    fprintf (stderr, "Premature end of .class file <stdin>.\n");
  exit (-1);
}

void
jcf_trim_old_input (JCF *jcf)
{
  int count = jcf->read_ptr - jcf->buffer;
  if (count > 0)
    {
      memmove (jcf->buffer, jcf->read_ptr, jcf->read_end - jcf->read_ptr);
      jcf->read_ptr -= count;
      jcf->read_end -= count;
    }
}

int
jcf_filbuf_from_stdio (JCF *jcf, int count)
{
  FILE *file = (FILE*) (jcf->read_state);
  if (count > jcf->buffer_end - jcf->read_ptr)
    {
      JCF_u4 old_read_ptr = jcf->read_ptr - jcf->buffer;
      JCF_u4 old_read_end = jcf->read_end - jcf->buffer;
      JCF_u4 old_size = jcf->buffer_end - jcf->buffer;
      JCF_u4 new_size = (old_size == 0 ? 2000 : 2 * old_size) + count;
      unsigned char *new_buffer = jcf->buffer == NULL ? ALLOC (new_size)
	: REALLOC (jcf->buffer, new_size);
      jcf->buffer = new_buffer;
      jcf->buffer_end = new_buffer + new_size;
      jcf->read_ptr = new_buffer + old_read_ptr;
      jcf->read_end = new_buffer + old_read_end;
    }
  count -= jcf->read_end - jcf->read_ptr;
  if (count <= 0)
    return 0;
  if ((int) fread (jcf->read_end, 1, count, file) != count)
    jcf_unexpected_eof (jcf, count);
  jcf->read_end += count;
  return 0;
}

#include "zipfile.h"

struct ZipFile *SeenZipFiles = NULL;

/* Open a zip file with the given name, and cache directory and file
   descriptor.  If the file is missing, treat it as an empty archive.
   Return NULL if the .zip file is malformed.
*/

ZipFile *
opendir_in_zip (const char *zipfile, int is_system)
{
  struct ZipFile* zipf;
  char magic [4];
  int fd;
  for (zipf = SeenZipFiles;  zipf != NULL;  zipf = zipf->next)
    {
      if (strcmp (zipf->name, zipfile) == 0)
	return zipf;
    }

  zipf = ALLOC (sizeof (struct ZipFile) + strlen (zipfile) + 1);
  zipf->next = SeenZipFiles;
  zipf->name = (char*)(zipf+1);
  strcpy (zipf->name, zipfile);
  fd = open (zipfile, O_RDONLY | O_BINARY);
  zipf->fd = fd;
  if (fd < 0)
    {
      /* A missing zip file is not considered an error.
       We may want to re-consider that.  FIXME. */
      zipf->count = 0;
      zipf->dir_size = 0;
      zipf->central_directory = NULL;
    }
  else
    {
      jcf_dependency_add_file (zipfile, is_system);
      if (read (fd, magic, 4) != 4 || GET_u4 (magic) != (JCF_u4)ZIPMAGIC)
	return NULL;
      lseek (fd, 0L, SEEK_SET);
      if (read_zip_archive (zipf) != 0)
	return NULL;
    }

  SeenZipFiles = zipf;  
  return zipf;
}

/* Returns:
   0:  OK - zipmember found.
   -1: Not found.
   -2: Malformed archive.
*/

int
open_in_zip (JCF *jcf, const char *zipfile, const char *zipmember,
	     int is_system)
{
  ZipDirectory *zipd;
  int i, len;
  ZipFile *zipf = opendir_in_zip (zipfile, is_system);

  if (zipf == NULL)
    return -2;

  if (!zipmember)
    return 0;

  len = strlen (zipmember);
  
  zipd = (struct ZipDirectory*) zipf->central_directory;
  for (i = 0; i < zipf->count; i++, zipd = ZIPDIR_NEXT (zipd))
    {
      if (len == zipd->filename_length &&
	  strncmp (ZIPDIR_FILENAME (zipd), zipmember, len) == 0)
	{
	  JCF_ZERO (jcf);

	  jcf->filename = xstrdup (zipfile);
	  jcf->classname = xstrdup (zipmember);
	  return read_zip_member(jcf, zipd, zipf);
	}
    }
  return -1;
}

/* Read data from zip archive member. */

int
read_zip_member (JCF *jcf,  ZipDirectory *zipd, ZipFile *zipf)
{
  jcf->filbuf = jcf_unexpected_eof;
  jcf->zipd = (void *)zipd;

  if (zipd->compression_method == Z_NO_COMPRESSION)
    {
      jcf->buffer = ALLOC (zipd->size);
      jcf->buffer_end = jcf->buffer + zipd->size;
      jcf->read_ptr = jcf->buffer;
      jcf->read_end = jcf->buffer_end;
      if (lseek (zipf->fd, zipd->filestart, 0) < 0
	  || read (zipf->fd, jcf->buffer, zipd->size) != (long) zipd->size)
	return -2;
    }
  else
    {
      char *buffer;
      z_stream d_stream; /* decompression stream */
      d_stream.zalloc = (alloc_func) 0;
      d_stream.zfree = (free_func) 0;
      d_stream.opaque = (voidpf) 0;

      jcf->buffer = ALLOC (zipd->uncompressed_size);
      d_stream.next_out = jcf->buffer;
      d_stream.avail_out = zipd->uncompressed_size;
      jcf->buffer_end = jcf->buffer + zipd->uncompressed_size;
      jcf->read_ptr = jcf->buffer;
      jcf->read_end = jcf->buffer_end;
      buffer = ALLOC (zipd->size);
      d_stream.next_in = (unsigned char *) buffer;
      d_stream.avail_in = zipd->size;
      if (lseek (zipf->fd, zipd->filestart, 0) < 0
	  || read (zipf->fd, buffer, zipd->size) != (long) zipd->size)
	return -2;
      /* Handle NO_HEADER using undocumented zlib feature.
	 This is a very common hack.  */
      inflateInit2 (&d_stream, -MAX_WBITS);
      inflate (&d_stream, Z_NO_FLUSH);
      inflateEnd (&d_stream);
      FREE (buffer);
    }

  return 0;
}

const char *
open_class (const char *filename, JCF *jcf, int fd, const char *dep_name)
{
  if (jcf)
    {
      struct stat stat_buf;
      if (fstat (fd, &stat_buf) != 0
	  || ! S_ISREG (stat_buf.st_mode))
	{
	  perror ("Could not figure length of .class file");
	  return NULL;
	}
      if (dep_name != NULL)
	jcf_dependency_add_file (dep_name, 0);
      JCF_ZERO (jcf);
      jcf->buffer = ALLOC (stat_buf.st_size);
      jcf->buffer_end = jcf->buffer + stat_buf.st_size;
      jcf->read_ptr = jcf->buffer;
      jcf->read_end = jcf->buffer_end;
      jcf->read_state = NULL;
      jcf->filename = filename;
      if (read (fd, jcf->buffer, stat_buf.st_size) != stat_buf.st_size)
	{
	  perror ("Failed to read .class file");
	  return NULL;
	}
      close (fd);
      jcf->filbuf = jcf_unexpected_eof;
    }
  else
    close (fd);
  return filename;
}


const char *
find_classfile (char *filename, JCF *jcf, const char *dep_name)
{
  int fd = open (filename, O_RDONLY | O_BINARY);
  if (fd < 0)
    return NULL;
  return open_class (filename, jcf, fd, dep_name);
}

#if JCF_USE_SCANDIR

/* A comparison function (as for qsort) that compares KEY (a char *
   giving the basename of a file) with the name stored in ENTRY (a
   dirent **).  */

static int
compare_path (const void *key, const void *entry)
{
  return strcmp ((const char *) key, 
		 (*((const struct dirent **) entry))->d_name);
}

/* Returns nonzero if ENTRY names a .java or .class file.  */

static int
java_or_class_file (const struct dirent *entry)
{
  const char *base = lbasename (entry->d_name);
  return (fnmatch ("*.java", base, 0) == 0 || 
	  fnmatch ("*.class", base, 0) == 0);
}

/* Information about the files present in a particular directory.  */
typedef struct memoized_dirlist_entry 
{
  /* The name of the directory.  */
  const char *dir;
  /* The number of .java and .class files present, or -1 if we could
     not, for some reason, obtain the list.  */
  int num_files;
  /* The .java and .class files in the directory, in alphabetical
     order.  */
  struct dirent **files;
} memoized_dirlist_entry;

/* Returns true if ENTRY (a memoized_dirlist_entry *) corresponds to
   the directory given by KEY (a char *) giving the directory 
   name.  */

static int
memoized_dirlist_lookup_eq (const void *entry, const void *key)
{
  return strcmp ((const char *) key,
		 ((const memoized_dirlist_entry *) entry)->dir) == 0;
}

/* A hash table mapping directory names to the lists of .java and
   .class files in that directory.  */

static htab_t memoized_dirlists;

#endif

/* Like stat, but avoids actually making the stat system call if we
   know that it cannot succeed.  FILENAME and BUF are as for stat.  */

static int
caching_stat (char *filename, struct stat *buf)
{
#if JCF_USE_SCANDIR
  char *sep;
  char origsep = 0;
  char *base;
  memoized_dirlist_entry *dent;
  void **slot;
  
  /* If the hashtable has not already been created, create it now.  */
  if (!memoized_dirlists)
    memoized_dirlists = htab_create (37,
				     htab_hash_string,
				     memoized_dirlist_lookup_eq,
				     NULL);

  /* Get the name of the directory.  */
  sep = strrchr (filename, DIR_SEPARATOR);
#ifdef DIR_SEPARATOR_2
  if (! sep)
    sep = strrchr (filename, DIR_SEPARATOR_2);
#endif
  if (sep)
    {
      origsep = *sep;
      *sep = '\0';
      base = sep + 1;
    }
  else
    base = filename;

  /* Obtain the entry for this directory from the hash table.  */
  slot = htab_find_slot (memoized_dirlists, filename, INSERT);
  if (!*slot)
    {
      /* We have not already scanned this directory; scan it now.  */
      dent = ((memoized_dirlist_entry *) 
	      ALLOC (sizeof (memoized_dirlist_entry)));
      dent->dir = xstrdup (filename);
      /* Unfortunately, scandir is not fully standardized.  In
	 particular, the type of the function pointer passed as the
	 third argument sometimes takes a "const struct dirent *"
	 parameter, and sometimes just a "struct dirent *".  We cast
	 to (void *) and use __extension__ so that either way it is
	 quietly accepted.  FIXME: scandir is not in POSIX.  */
      dent->num_files = __extension__ scandir (filename, &dent->files, 
					       (void *) java_or_class_file, 
					       alphasort);
      *slot = dent;
    }
  else
    dent = *((memoized_dirlist_entry **) slot);

  /* Put the separator back.  */
  if (sep)
    *sep = origsep;

  /* If the file is not in the list, there is no need to stat it; it
     does not exist.  */
  if (dent->num_files != -1
      && !bsearch (base, dent->files, dent->num_files,
		   sizeof (struct dirent *), compare_path))
    return -1;
#endif
  
  return stat (filename, buf);
}

/* Returns 1 if the CLASSNAME (really a char *) matches the name
   stored in TABLE_ENTRY (also a char *).  */

static int
memoized_class_lookup_eq (const void *table_entry, const void *classname)
{
  return strcmp ((const char *)classname, (const char *)table_entry) == 0;
}

/* A hash table keeping track of class names that were not found
   during class lookup.  (There is no need to cache the values
   associated with names that were found; they are saved in
   IDENTIFIER_CLASS_VALUE.)  */
static htab_t memoized_class_lookups;

/* Returns a freshly malloc'd string with the fully qualified pathname
   of the .class file for the class CLASSNAME.  CLASSNAME must be
   allocated in permanent storage; this function may retain a pointer
   to it.  Returns NULL on failure.  If JCF != NULL, it is suitably
   initialized.  SOURCE_OK is true if we should also look for .java
   file. */

const char *
find_class (const char *classname, int classname_length, JCF *jcf,
	    int source_ok)
{
  int fd;
  int i, k, java = -1, class = -1;
  struct stat java_buf, class_buf;
  char *dep_file;
  void *entry;
  char *java_buffer;
  int buflen;
  char *buffer;
  hashval_t hash;

  /* Create the hash table, if it does not already exist.  */
  if (!memoized_class_lookups)
    memoized_class_lookups = htab_create (37, 
					  htab_hash_string, 
					  memoized_class_lookup_eq,
					  NULL);

  /* Loop for this class in the hashtable.  If it is present, we've
     already looked for this class and failed to find it.  */
  hash = htab_hash_string (classname);
  if (htab_find_with_hash (memoized_class_lookups, classname, hash))
    return NULL;

  /* Allocate and zero out the buffer, since we don't explicitly put a
     null pointer when we're copying it below.  */
  buflen = jcf_path_max_len () + classname_length + 10;
  buffer = ALLOC (buflen);
  memset (buffer, 0, buflen);

  java_buffer = alloca (buflen);

  jcf->java_source = 0;

  for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
    {
      const char *path_name = jcf_path_name (entry);
      if (class != 0)
	{
	  int dir_len;

	  strcpy (buffer, path_name);
	  i = strlen (buffer);

	  /* This is right because we know that `.zip' entries will have a
	     trailing slash.  See jcf-path.c.  */
	  dir_len = i - 1;

	  for (k = 0; k < classname_length; k++, i++)
	    {
	      char ch = classname[k];
	      buffer[i] = ch == '.' ? '/' : ch;
	    }
	  strcpy (buffer+i, ".class");

	  if (jcf_path_is_zipfile (entry))
	    {
	      int err_code;
	      JCF _jcf;
	      buffer[dir_len] = '\0';
	      SOURCE_FRONTEND_DEBUG 
		(("Trying [...%s]:%s", 
		  &buffer[dir_len-(dir_len > 15 ? 15 : dir_len)], 
		  buffer+dir_len+1));
	      if (jcf == NULL)
		jcf = &_jcf;
	      err_code = open_in_zip (jcf, buffer, buffer+dir_len+1,
				      jcf_path_is_system (entry));
	      if (err_code == 0)
		{
		  /* Should we check if .zip is out-of-date wrt .java? */
		  buffer[dir_len] = '(';
		  strcpy (buffer+i, ".class)");
		  if (jcf == &_jcf)
		    JCF_FINISH (jcf);
		  return buffer;
		}
	      else
		continue;
	    }
	  class = caching_stat(buffer, &class_buf);
	}

      if (source_ok)
	{
	  /* Compute name of .java file.  */
	  int l, m;
	  strcpy (java_buffer, path_name);
	  l = strlen (java_buffer);
	  for (m = 0; m < classname_length; ++m)
	    java_buffer[m + l] = (classname[m] == '.'
				  ? DIR_SEPARATOR : classname[m]);
	  strcpy (java_buffer + m + l, ".java");
	  java = caching_stat (java_buffer, &java_buf);
	  if (java == 0)
	    break;
	}
    }

  /* We preferably pick a class file if we have a chance. If the source
     file is newer than the class file, we issue a warning and parse the
     source file instead.
     There should be a flag to allow people have the class file picked
     up no matter what. FIXME. */
  if (! java && ! class && java_buf.st_mtime > class_buf.st_mtime)
    {
      if (flag_newer)
	warning ("source file for class %qs is newer than its matching class file.  Source file %qs used instead", classname, java_buffer);
      class = -1;
    }

  if (! java)
    dep_file = java_buffer;
  else
    dep_file = buffer;
  if (!class)
    {
      SOURCE_FRONTEND_DEBUG ((stderr, "[Class selected: %s]\n",
			      classname+classname_length-
			      (classname_length <= 30 ? 
			       classname_length : 30)));
      fd = JCF_OPEN_EXACT_CASE (buffer, O_RDONLY | O_BINARY);
      if (fd >= 0)
	goto found;
    }
  /* Give .java a try, if necessary */
  if (!java)
    {
      strcpy (buffer, java_buffer);
      SOURCE_FRONTEND_DEBUG ((stderr, "[Source selected: %s]\n",
			      classname+classname_length-
			      (classname_length <= 30 ? 
			       classname_length : 30)));
      fd = JCF_OPEN_EXACT_CASE (buffer, O_RDONLY);
      if (fd >= 0)
	{
	  jcf->java_source = 1;
	  goto found;
	}
    }

  free (buffer);

  /* Remember that this class could not be found so that we do not
     have to look again.  */
  *htab_find_slot_with_hash (memoized_class_lookups, classname, hash, INSERT) 
    = (void *) classname;

  return NULL;
 found:
  if (jcf->java_source)
    {
      JCF_ZERO (jcf);		/* JCF_FINISH relies on this */
      jcf->java_source = 1;
      jcf->filename = xstrdup (buffer);
      close (fd);		/* We use STDIO for source file */
    }
  else
    buffer = (char *) open_class (buffer, jcf, fd, dep_file);
  jcf->classname = xstrdup (classname);
  return buffer;
}

void
jcf_print_char (FILE *stream, int ch)
{
  switch (ch)
    {
    case '\'':
    case '\\':
    case '\"':
      fprintf (stream, "\\%c", ch);
      break;
    case '\n':
      fprintf (stream, "\\n");
      break;
    case '\t':
      fprintf (stream, "\\t");
      break;
    case '\r':
      fprintf (stream, "\\r");
      break;
    default:
      if (ch >= ' ' && ch < 127)
	putc (ch, stream);
      else if (ch < 256)
	fprintf (stream, "\\%03x", ch);
      else
	fprintf (stream, "\\u%04x", ch);
    }
}

/* Print UTF8 string at STR of length LENGTH bytes to STREAM. */

void
jcf_print_utf8 (FILE *stream, const unsigned char *str, int length)
{
  const unsigned char * limit = str + length;
  while (str < limit)
    {
      int ch = UTF8_GET (str, limit);
      if (ch < 0)
	{
	  fprintf (stream, "\\<invalid>");
	  return;
	}
      jcf_print_char (stream, ch);
    }
}

/* Same as jcf_print_utf8, but print IN_CHAR as OUT_CHAR. */

void
jcf_print_utf8_replace (FILE *stream, const unsigned char *str, int length,
			int in_char, int out_char)
{
  const unsigned char *limit = str + length;
  while (str < limit)
    {
      int ch = UTF8_GET (str, limit);
      if (ch < 0)
	{
	  fprintf (stream, "\\<invalid>");
	  return;
	}
      jcf_print_char (stream, ch == in_char ? out_char : ch);
    }
}

/* Check that all the cross-references in the constant pool are
   valid.  Returns 0 on success.
   Otherwise, returns the index of the (first) invalid entry.
   Only checks internal consistency, but does not check that
   any classes, fields, or methods are valid.*/

int
verify_constant_pool (JCF *jcf)
{
  int i, n;
  for (i = 1; i < JPOOL_SIZE (jcf); i++)
    {
      switch (JPOOL_TAG (jcf, i))
	{
	case CONSTANT_NameAndType:
	  n = JPOOL_USHORT2 (jcf, i);
	  if (n <= 0 || n >= JPOOL_SIZE(jcf)
	      || JPOOL_TAG (jcf, n) != CONSTANT_Utf8)
	    return i;
	  /* ... fall through ... */
	case CONSTANT_Class:
	case CONSTANT_String:
	  n = JPOOL_USHORT1 (jcf, i);
	  if (n <= 0 || n >= JPOOL_SIZE(jcf)
	      || JPOOL_TAG (jcf, n) != CONSTANT_Utf8)
	    return i;
	  break;
	case CONSTANT_Fieldref:
	case CONSTANT_Methodref:
	case CONSTANT_InterfaceMethodref:
	  n = JPOOL_USHORT1 (jcf, i);
	  if (n <= 0 || n >= JPOOL_SIZE(jcf)
	      || JPOOL_TAG (jcf, n) != CONSTANT_Class)
	    return i;
	  n = JPOOL_USHORT2 (jcf, i);
	  if (n <= 0 || n >= JPOOL_SIZE(jcf)
	      || JPOOL_TAG (jcf, n) != CONSTANT_NameAndType)
	    return i;
	  break;
	case CONSTANT_Long:
	case CONSTANT_Double:
	  i++;
	  break;
	case CONSTANT_Float:
	case CONSTANT_Integer:
	case CONSTANT_Utf8:
	case CONSTANT_Unicode:
	  break;
	default:
	  return i;
	}
    }
  return 0;
}

void
format_uint (char *buffer, uint64 value, int base)
{
#define WRITE_BUF_SIZE (4 + sizeof(uint64) * 8)
  char buf[WRITE_BUF_SIZE];
  char *buf_ptr = buf+WRITE_BUF_SIZE; /* End of buf. */
  int chars_written;
  int i;

  /* Now do the actual conversion, placing the result at the *end* of buf. */
  /* Note this code does not pretend to be optimized. */
  do {
    int digit = value % base;
    static const char digit_chars[] = "0123456789abcdefghijklmnopqrstuvwxyz";
    *--buf_ptr = digit_chars[digit];
    value /= base;
  } while (value != 0);

  chars_written = buf+WRITE_BUF_SIZE - buf_ptr;
  for (i = 0; i < chars_written; i++)
    buffer[i] = *buf_ptr++;
  buffer[i] = 0;
}

void
format_int (char *buffer, jlong value, int base)
{
  uint64 abs_value;
  if (value < 0)
    {
      abs_value = -(uint64)value;
      *buffer++ = '-';
    }
  else
    abs_value = (uint64) value;
  format_uint (buffer, abs_value, base);
}
