OSDN Git Service

* java-tree.h, class.c, expr.c, jcf-parse.c, parse.y,
[pf3gnuchains/gcc-fork.git] / gcc / java / jcf-dump.c
index cb962cb..aa90374 100644 (file)
@@ -1,7 +1,7 @@
 /* Program to dump out a Java(TM) .class file.
    Functionally similar to Sun's javap.
 
-   Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -46,11 +46,16 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
  */
     
 
-#include <config.h>
+#include "config.h"
 #include "system.h"
 
-#include <stdio.h>
 #include "jcf.h"
+#include "tree.h"
+#include "java-tree.h"
+
+#include "version.h"
+
+#include <getopt.h>
 
 /* Outout file. */
 FILE *out;
@@ -66,6 +71,10 @@ int flag_print_fields = 1;
 int flag_print_methods = 1;
 int flag_print_attributes = 1;
 
+/* When non zero, warn when source file is newer than matching class
+   file.  */
+int flag_newer = 1;
+
 /* Print names of classes that have a "main" method. */
 int flag_print_main = 0;
 
@@ -77,22 +86,28 @@ int class_access_flags = 0;
 /* Print in format similar to javap.  VERY IMCOMPLETE. */
 int flag_javap_compatible = 0;
 
-static int print_access_flags PROTO ((FILE *, uint16));
-static void print_constant_terse PROTO ((FILE*, JCF*, int, int));
-static void print_constant PROTO ((FILE *, JCF *, int, int));
-static void print_constant_ref PROTO ((FILE *, JCF *, int));
-static void disassemble_method PROTO ((JCF*, unsigned char *, int));
-static void print_name PROTO ((FILE*, JCF*, int));
-static void print_signature PROTO ((FILE*, JCF*, int, int));
+static void print_access_flags PARAMS ((FILE *, uint16, char));
+static void print_constant_terse PARAMS ((FILE*, JCF*, int, int));
+static void print_constant PARAMS ((FILE *, JCF *, int, int));
+static void print_constant_ref PARAMS ((FILE *, JCF *, int));
+static void disassemble_method PARAMS ((JCF*, const unsigned char *, int));
+static void print_name PARAMS ((FILE*, JCF*, int));
+static void print_signature PARAMS ((FILE*, JCF*, int, int));
+static int utf8_equal_string PARAMS ((struct JCF*, int, const char *));
+static void usage PARAMS ((void)) ATTRIBUTE_NORETURN;
+static void help PARAMS ((void)) ATTRIBUTE_NORETURN;
+static void version PARAMS ((void)) ATTRIBUTE_NORETURN;
+static void process_class PARAMS ((struct JCF *));
+static void print_constant_pool PARAMS ((struct JCF *));
+static void print_exception_table PARAMS ((struct JCF *,
+                                         const unsigned char *entries, int));
 
 #define PRINT_SIGNATURE_RESULT_ONLY 1
 #define PRINT_SIGNATURE_ARGS_ONLY 2
 
-extern char* open_class();
-
-int
+static int
 DEFUN(utf8_equal_string, (jcf, index, value),
-      JCF *jcf AND int index AND char * value)
+      JCF *jcf AND int index AND const char * value)
 {
   if (CPOOL_INDEX_IN_RANGE (&jcf->cpool, index)
       && JPOOL_TAG (jcf, index) == CONSTANT_Utf8)
@@ -109,8 +124,8 @@ DEFUN(utf8_equal_string, (jcf, index, value),
   this_class_index = 0; \
   if (flag_print_class_info) \
     fprintf (out, \
-             "Magic number: 0x%0x, minor_version: %d, major_version: %d.\n", \
-            MAGIC, MINOR, MAJOR)
+             "Magic number: 0x%0lx, minor_version: %ld, major_version: %ld.\n",\
+            (long) MAGIC, (long) MINOR, (long) MAJOR)
 
 #define HANDLE_START_CONSTANT_POOL(COUNT) \
   if (flag_print_constant_pool) \
@@ -127,7 +142,7 @@ DEFUN(utf8_equal_string, (jcf, index, value),
   class_access_flags = ACCESS_FLAGS; \
   if (flag_print_class_info) \
     { fprintf (out, "\nAccess flags: 0x%x", ACCESS_FLAGS); \
-      print_access_flags (out, ACCESS_FLAGS); \
+      print_access_flags (out, ACCESS_FLAGS, 'c'); \
       fputc ('\n', out); \
       fprintf (out, "This class: "); \
       if (flag_print_constant_pool) \
@@ -163,7 +178,7 @@ DEFUN(utf8_equal_string, (jcf, index, value),
   if (flag_print_fields) \
     { fprintf (out, "Field name:"); \
       print_constant_terse (out, jcf, NAME, CONSTANT_Utf8); \
-      print_access_flags (out, ACCESS_FLAGS); \
+      print_access_flags (out, ACCESS_FLAGS, 'f'); \
       fprintf (out, " Signature: "); \
       if (flag_print_constant_pool) \
         fprintf (out, "%d=", SIGNATURE); \
@@ -194,7 +209,7 @@ DEFUN(utf8_equal_string, (jcf, index, value),
       if (flag_javap_compatible) \
         { \
          fprintf (out, "    "); \
-         print_access_flags (out, ACCESS_FLAGS); \
+         print_access_flags (out, ACCESS_FLAGS, 'm'); \
          fputc (' ', out); \
          print_signature (out, jcf, SIGNATURE, PRINT_SIGNATURE_RESULT_ONLY); \
          fputc (' ', out); \
@@ -206,7 +221,7 @@ DEFUN(utf8_equal_string, (jcf, index, value),
        { \
          fprintf (out, "\nMethod name:"); \
          print_constant_terse (out, jcf, NAME, CONSTANT_Utf8); \
-         print_access_flags (out, ACCESS_FLAGS); \
+         print_access_flags (out, ACCESS_FLAGS, 'm'); \
          fprintf (out, " Signature: "); \
          if (flag_print_constant_pool) \
            fprintf (out, "%d=", SIGNATURE); \
@@ -238,8 +253,8 @@ DEFUN(utf8_equal_string, (jcf, index, value),
 
 #define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
 { COMMON_HANDLE_ATTRIBUTE(JCF, attribute_name, attribute_length); \
-  fprintf (out, ", max_stack:%d, max_locals:%d, code_length:%d\n", \
-    MAX_STACK, MAX_LOCALS, CODE_LENGTH); \
+  fprintf (out, ", max_stack:%ld, max_locals:%ld, code_length:%ld\n", \
+    (long) MAX_STACK, (long) MAX_LOCALS, (long) CODE_LENGTH); \
   disassemble_method (jcf, jcf->read_ptr, CODE_LENGTH); }
 
 #define HANDLE_EXCEPTION_TABLE(ENTRIES, COUNT) \
@@ -283,6 +298,38 @@ DEFUN(utf8_equal_string, (jcf, index, value),
   else \
     JCF_SKIP (jcf, 4 * n); }
 
+#define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT)                               \
+{ int n = (COUNT);                                                         \
+  COMMON_HANDLE_ATTRIBUTE(jcf, attribute_name, attribute_length);          \
+  while (n--)                                                              \
+    {                                                                      \
+      uint16 inner_class_info_index = JCF_readu2 (jcf);                            \
+      uint16 outer_class_info_index = JCF_readu2 (jcf);                            \
+      uint16 inner_name_index = JCF_readu2 (jcf);                          \
+      uint16 inner_class_access_flags = JCF_readu2 (jcf);                  \
+                                                                           \
+      if (flag_print_class_info)                                           \
+       {                                                                   \
+         fprintf (out, "\n  class: ");                                     \
+         if (flag_print_constant_pool)                                     \
+           fprintf (out, "%d=", inner_class_info_index);                   \
+         print_constant_terse (out, jcf,                                   \
+                               inner_class_info_index, CONSTANT_Class);    \
+         fprintf (out, " (%d=", inner_name_index);                         \
+         print_constant_terse (out, jcf, inner_name_index, CONSTANT_Utf8); \
+         fprintf (out, "), access flags: 0x%x", inner_class_access_flags); \
+         print_access_flags (out, inner_class_access_flags, 'c');          \
+         fprintf (out, ", outer class: ");                                 \
+         if (flag_print_constant_pool)                                     \
+           fprintf (out, "%d=", outer_class_info_index);                   \
+         print_constant_terse (out, jcf,                                   \
+                               outer_class_info_index, CONSTANT_Class);    \
+       }                                                                   \
+    }                                                                      \
+      if (flag_print_class_info)                                           \
+       fputc ('\n', out);                                                  \
+}
+
 #define PROCESS_OTHER_ATTRIBUTE(JCF, INDEX, LENGTH) \
 { COMMON_HANDLE_ATTRIBUTE(JCF, INDEX, LENGTH); \
   fputc ('\n', out); JCF_SKIP (JCF, LENGTH); }
@@ -305,21 +352,32 @@ DEFUN(print_constant_ref, (stream, jcf, index),
   fprintf (stream, ">");
 }
 
-static int
-DEFUN (print_access_flags, (stream, flags),
-       FILE *stream AND uint16 flags)
+/* Print the access flags given by FLAGS.
+   The CONTEXT is one of 'c' (class flags), 'f' (field flags),
+   or 'm' (method flags). */
+
+static void
+DEFUN (print_access_flags, (stream, flags, context),
+       FILE *stream AND uint16 flags AND char context)
 {
   if (flags & ACC_PUBLIC) fprintf (stream, " public");
   if (flags & ACC_PRIVATE) fprintf (stream, " private");
   if (flags & ACC_PROTECTED) fprintf (stream, " protected");
+  if (flags & ACC_ABSTRACT) fprintf (stream, " abstract");
   if (flags & ACC_STATIC) fprintf (stream, " static");
   if (flags & ACC_FINAL) fprintf (stream, " final");
-  if (flags & ACC_SYNCHRONIZED) fprintf (stream, " synchronized");
-  if (flags & ACC_VOLATILE) fprintf (stream, " volatile");
   if (flags & ACC_TRANSIENT) fprintf (stream, " transient");
+  if (flags & ACC_VOLATILE) fprintf (stream, " volatile");
   if (flags & ACC_NATIVE) fprintf (stream, " native");
+  if (flags & ACC_SYNCHRONIZED)
+    {
+      if (context == 'c')
+       fprintf (stream, " super");
+      else
+       fprintf (stream, " synchronized");
+    }
   if (flags & ACC_INTERFACE) fprintf (stream, " interface");
-  if (flags & ACC_ABSTRACT) fprintf (stream, " abstract");
+  if (flags & ACC_STRICT) fprintf (stream, " strictfp");
 }
 
 
@@ -337,7 +395,7 @@ DEFUN(print_name, (stream, jcf, name_index),
 /* If the type of the constant at INDEX matches EXPECTED,
    print it tersely, otherwise more verbosely. */
 
-void
+static void
 DEFUN(print_constant_terse, (out, jcf, index, expected),
       FILE *out AND JCF *jcf AND int index AND int expected)
 {
@@ -364,14 +422,19 @@ DEFUN(print_constant, (out, jcf, index, verbosity),
 {
   int j, n;
   jlong num;
-  char *str;
+  const char *str;
   int kind = JPOOL_TAG (jcf, index);
   switch (kind)
     {
     case CONSTANT_Class:
       n = JPOOL_USHORT1 (jcf, index);
       if (verbosity > 0)
-       fprintf (out, verbosity > 1 ? "Class name: %d=" : "Class ", n);
+       {
+         if (verbosity > 1)
+           fprintf (out, "Class name: %d=", n);
+         else
+           fprintf (out, "Class ");
+       }
       if (! CPOOL_INDEX_IN_RANGE (&jcf->cpool, n))
        fprintf (out, "<out of range>");
       else if (verbosity < 2 && JPOOL_TAG (jcf, n) == CONSTANT_Utf8)
@@ -397,8 +460,10 @@ DEFUN(print_constant, (out, jcf, index, verbosity),
        else if (verbosity > 0)
            fprintf (out, "%s ", str);
        print_constant_terse (out, jcf, tclass, CONSTANT_Class);
-       fprintf (out, verbosity < 2 ? "." : " name_and_type: %d=<",
-                name_and_type);
+       if (verbosity < 2)
+         fprintf (out, ".");
+       else
+         fprintf (out, " name_and_type: %d=<", name_and_type);
        print_constant_terse (out, jcf, name_and_type, CONSTANT_NameAndType);
        if (verbosity == 2)
          fputc ('>', out);
@@ -407,7 +472,12 @@ DEFUN(print_constant, (out, jcf, index, verbosity),
     case CONSTANT_String:
       j = JPOOL_USHORT1 (jcf, index);
       if (verbosity > 0)
-       fprintf (out, verbosity > 1 ? "String %d=" : "String ", j);
+       {
+         if (verbosity > 1)
+           fprintf (out, "String %d=", j);
+         else
+           fprintf (out, "String ");
+       }
       print_constant_terse (out, jcf, j, CONSTANT_Utf8);
       break;
     case CONSTANT_Integer:
@@ -435,7 +505,7 @@ DEFUN(print_constant, (out, jcf, index, verbosity),
     case CONSTANT_Float:
       {
        jfloat fnum = JPOOL_FLOAT (jcf, index);
-       fprintf (out, "%s%.10g", verbosity > 1 ? "Float " : "", (double) fnum);
+       fprintf (out, "%s%.10g", verbosity > 0 ? "Float " : "", (double) fnum);
        if (verbosity > 1)
          fprintf (out, ", bits = 0x%08lx", (long) (* (int32 *) &fnum));
        break;
@@ -443,7 +513,7 @@ DEFUN(print_constant, (out, jcf, index, verbosity),
     case CONSTANT_Double:
       {
        jdouble dnum = JPOOL_DOUBLE (jcf, index);
-       fprintf (out, "%s%.20g", verbosity > 1 ? "Double " : "", dnum);
+       fprintf (out, "%s%.20g", verbosity > 0 ? "Double " : "", dnum);
        if (verbosity > 1)
          {
            int32 hi, lo;
@@ -458,8 +528,12 @@ DEFUN(print_constant, (out, jcf, index, verbosity),
        uint16 name = JPOOL_USHORT1 (jcf, index);
        uint16 sig = JPOOL_USHORT2 (jcf, index);
        if (verbosity > 0)
-         fprintf (out, verbosity > 1 ? "%s name: %d=" : "%s ",
-                  "NameAndType", name);
+         {
+           if (verbosity > 1)
+             fprintf (out, "NameAndType name: %d=", name);
+           else
+             fprintf (out, "NameAndType ");
+         }
        print_name (out, jcf, name);
        if (verbosity <= 1)
          fputc (' ', out);
@@ -470,7 +544,7 @@ DEFUN(print_constant, (out, jcf, index, verbosity),
       break;
     case CONSTANT_Utf8:
       {
-       register unsigned char *str = JPOOL_UTF_DATA (jcf, index);
+       register const unsigned char *str = JPOOL_UTF_DATA (jcf, index);
        int length = JPOOL_UTF_LENGTH (jcf, index);
        if (verbosity > 0)
          { /* Print as 8-bit bytes. */
@@ -491,7 +565,7 @@ DEFUN(print_constant, (out, jcf, index, verbosity),
     }
 }
 
-void
+static void
 DEFUN(print_constant_pool, (jcf),
       JCF *jcf)
 {
@@ -518,10 +592,9 @@ DEFUN(print_signature_type, (stream, ptr, limit),
     {
     case '[':
       array_size = -1;
-      for ((*ptr)++; (*ptr) < limit && isdigit (**ptr); (*ptr)++)
+      for ((*ptr)++; (*ptr) < limit && ISDIGIT (**ptr); (*ptr)++)
        {
-         int digit = 
-           array_size = (array_size < 0 ? 0 : 10 * array_size) + *(*ptr) - '0';
+         array_size = (array_size < 0 ? 0 : 10 * array_size) + *(*ptr) - '0';
        }
       print_signature_type (stream, ptr, limit);
       if (array_size == -1)
@@ -578,7 +651,6 @@ DEFUN(print_signature, (stream, jcf, signature_index, int options),
     print_constant_terse (out, jcf, signature_index, CONSTANT_Utf8);
   else
     {
-      int j;
       const unsigned char *str = JPOOL_UTF_DATA (jcf, signature_index);
       int length = JPOOL_UTF_LENGTH (jcf, signature_index);
       const unsigned char *limit;
@@ -593,7 +665,7 @@ DEFUN(print_signature, (stream, jcf, signature_index, int options),
            }
          if (options & PRINT_SIGNATURE_ARGS_ONLY)
            {
-             *str++;
+             str++;
              fputc ('(', stream);
              while (str < limit && *str != ')')
                {
@@ -620,13 +692,13 @@ DEFUN(print_signature, (stream, jcf, signature_index, int options),
 
 static void
 DEFUN(print_exception_table, (jcf, entries, count),
-      JCF *jcf AND unsigned char *entries AND int count)
+      JCF *jcf AND const unsigned char *entries AND int count)
 {
   /* Print exception table. */
   int i = count;
   if (i > 0)
     {
-      unsigned char *ptr = entries;
+      const unsigned char *ptr = entries;
       fprintf (out, "Exceptions (count: %d):\n", i);
       for (; --i >= 0;  ptr+= 8)
        {
@@ -650,14 +722,7 @@ DEFUN(print_exception_table, (jcf, entries, count),
 
 #include "jcf-reader.c"
 
-int
-DEFUN (usage, (), )
-{
-  fprintf (stderr, "Usage: jcf-dump [-o outputfile] [-c] classname\n");
-  exit(1);
-}
-
-void
+static void
 DEFUN(process_class, (jcf),
       JCF *jcf)
 {
@@ -703,58 +768,152 @@ DEFUN(process_class, (jcf),
   jcf->filename = NULL;
 }
 
+\f
+
+/* This is used to mark options with no short value.  */
+#define LONG_OPT(Num)  ((Num) + 128)
+
+#define OPT_classpath     LONG_OPT (0)
+#define OPT_CLASSPATH     OPT_classpath
+#define OPT_bootclasspath LONG_OPT (1)
+#define OPT_extdirs       LONG_OPT (2)
+#define OPT_HELP          LONG_OPT (3)
+#define OPT_VERSION       LONG_OPT (4)
+#define OPT_JAVAP         LONG_OPT (5)
+
+static const struct option options[] =
+{
+  { "classpath",     required_argument, NULL, OPT_classpath },
+  { "bootclasspath", required_argument, NULL, OPT_bootclasspath },
+  { "extdirs",       required_argument, NULL, OPT_extdirs },
+  { "CLASSPATH",     required_argument, NULL, OPT_CLASSPATH },
+  { "help",          no_argument,       NULL, OPT_HELP },
+  { "verbose",       no_argument,       NULL, 'v' },
+  { "version",       no_argument,       NULL, OPT_VERSION },
+  { "javap",         no_argument,       NULL, OPT_JAVAP },
+  { "print-main",    no_argument,      &flag_print_main, 1 },
+  { NULL,            no_argument,       NULL, 0 }
+};
+
+static void
+usage ()
+{
+  fprintf (stderr, "Try `jcf-dump --help' for more information.\n");
+  exit (1);
+}
+
+static void
+help ()
+{
+  printf ("Usage: jcf-dump [OPTION]... CLASS...\n\n");
+  printf ("Display contents of a class file in readable form.\n\n");
+  printf ("  -c                      Disassemble method bodies\n");
+  printf ("  --javap                 Generate output in `javap' format\n");
+  printf ("\n");
+  printf ("  --classpath PATH        Set path to find .class files\n");
+  printf ("  -IDIR                   Append directory to class path\n");
+  printf ("  --bootclasspath PATH    Override built-in class path\n");
+  printf ("  --extdirs PATH          Set extensions directory path\n");
+  printf ("  -o FILE                 Set output file name\n");
+  printf ("\n");
+  printf ("  --help                  Print this help, then exit\n");
+  printf ("  --version               Print version number, then exit\n");
+  printf ("  -v, --verbose           Print extra information while running\n");
+  printf ("\n");
+  printf ("For bug reporting instructions, please see:\n");
+  printf ("%s.\n", GCCBUGURL);
+  exit (0);
+}
+
+static void
+version ()
+{
+  printf ("jcf-dump (GCC) %s\n\n", version_string);
+  printf ("Copyright (C) 2002 Free Software Foundation, Inc.\n");
+  printf ("This is free software; see the source for copying conditions.  There is NO\n");
+  printf ("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
+  exit (0);
+}
+
 int
 DEFUN(main, (argc, argv),
       int argc AND char** argv)
 {
   JCF jcf[1];
-  int argi;
+  int argi, opt;
+
   if (argc <= 1)
-    usage ();
+    {
+      fprintf (stderr, "jcf-dump: no classes specified\n");
+      usage ();
+    }
 
   jcf_path_init ();
 
-  for (argi = 1; argi < argc; argi++)
+  /* We use getopt_long_only to allow single `-' long options.  For
+     some of our options this is more natural.  */
+  while ((opt = getopt_long_only (argc, argv, "o:I:vc", options, NULL)) != -1)
     {
-      char *arg = argv[argi];
+      switch (opt)
+       {
+       case 0:
+         /* Already handled.  */
+         break;
 
-      if (arg[0] != '-' || ! strcmp (arg, "--"))
-       break;
+        case 'o':
+         output_file = optarg;
+         break;
 
-      /* Just let all arguments be given in either "-" or "--" form.  */
-      if (arg[1] == '-')
-       ++arg;
-
-      if (strcmp (arg, "-o") == 0 && argi + 1 < argc)
-       output_file = argv[++argi];
-      else if (strcmp (arg, "-classpath") == 0 && argi + 1 < argc)
-       jcf_path_classpath_arg (argv[++argi]);
-      else if (strcmp (arg, "-CLASSPATH") == 0 && argi + 1 < argc)
-       jcf_path_CLASSPATH_arg (argv[++argi]);
-      else if (strncmp (arg, "-I", 2) == 0)
-       jcf_path_include_arg (arg + 2);
-      else if (strcmp (arg, "-verbose") == 0)
-       verbose++;
-      else if (strcmp (arg, "-print-main") == 0)
-       flag_print_main++;
-      else if (strcmp (arg, "-c") == 0)
-       flag_disassemble_methods++;
-      else if (strcmp (arg, "-javap") == 0)
-       {
+       case 'I':
+         jcf_path_include_arg (optarg);
+         break;
+
+       case 'v':
+         verbose++;
+         break;
+
+       case 'c':
+         flag_disassemble_methods = 1;
+         break;
+
+       case OPT_classpath:
+         jcf_path_classpath_arg (optarg);
+         break;
+
+       case OPT_bootclasspath:
+         jcf_path_bootclasspath_arg (optarg);
+         break;
+
+       case OPT_extdirs:
+         jcf_path_extdirs_arg (optarg);
+         break;
+
+       case OPT_HELP:
+         help ();
+         break;
+
+       case OPT_VERSION:
+         version ();
+         break;
+
+       case OPT_JAVAP:
          flag_javap_compatible++;
          flag_print_constant_pool = 0;
-       }
-      else
-       {
-         fprintf (stderr, "%s: illegal argument\n", argv[argi]);
-         exit (FATAL_EXIT_CODE);
+         flag_print_attributes = 0;
+         break;
+
+       default:
+         usage ();
        }
     }
 
-  if (argi == argc)
-    usage ();
+  if (optind == argc)
+    {
+      fprintf (stderr, "jcf-dump: no classes specified\n");
+      usage ();
+    }
 
-  jcf_path_seal ();
+  jcf_path_seal (verbose);
 
   if (flag_print_main)
     {
@@ -768,37 +927,33 @@ DEFUN(main, (argc, argv),
   if (output_file)
     {
       out = fopen (output_file, "w");
-      if (out)
+      if (out)
        {
          fprintf (stderr, "Cannot open '%s' for output.\n", output_file);
-         exit (FATAL_EXIT_CODE);
+         return FATAL_EXIT_CODE;
        }
     }
   else
     out = stdout;
 
-  if (argi >= argc)
+  if (optind >= argc)
     {
       fprintf (out, "Reading .class from <standard input>.\n");
-#if JCF_USE_STDIO
-      open_class ("<stdio>", jcf, stdin, NULL);
-#else
       open_class ("<stdio>", jcf, 0, NULL);
-#endif
       process_class (jcf);
     }
   else
     {
-      for (; argi < argc; argi++)
+      for (argi = optind; argi < argc; argi++)
        {
          char *arg = argv[argi];
-         char* class_filename = find_class (arg, strlen (arg), jcf, 0);
+         const char *class_filename = find_class (arg, strlen (arg), jcf, 0);
          if (class_filename == NULL)
            class_filename = find_classfile (arg, jcf, NULL);
          if (class_filename == NULL)
            {
              perror ("Could not find class");
-             exit (FATAL_EXIT_CODE);
+             return FATAL_EXIT_CODE;
            }
          JCF_FILL (jcf, 4);
          if (GET_u4 (jcf->read_ptr) == ZIPMAGIC)
@@ -806,7 +961,7 @@ DEFUN(main, (argc, argv),
              long compressed_size, member_size;
              int compression_method, filename_length, extra_length;
              int general_purpose_bits;
-             char *filename;
+             const char *filename;
              int total_length;
              if (flag_print_class_info)
                fprintf (out, "Reading classes from archive %s.\n",
@@ -821,7 +976,7 @@ DEFUN(main, (argc, argv),
                  if (magic != 0x04034b50) /* ZIPMAGIC (little-endian) */
                    {
                      fprintf (stderr, "bad format of .zip/.jar archive\n");
-                     exit (FATAL_EXIT_CODE);
+                     return FATAL_EXIT_CODE;
                    }
                  JCF_FILL (jcf, 26);
                  JCF_SKIP (jcf, 2);
@@ -895,12 +1050,14 @@ DEFUN(main, (argc, argv),
        }
     }
 
-  exit (SUCCESS_EXIT_CODE);
+  return SUCCESS_EXIT_CODE;
 }
 
+\f
+
 static void
 DEFUN(disassemble_method, (jcf, byte_ops, len),
-      JCF* jcf AND unsigned char *byte_ops AND int len)
+      JCF* jcf AND const unsigned char *byte_ops AND int len)
 {
 #undef AND /* Causes problems with opcodes for iand and land. */
 #undef PTR
@@ -914,7 +1071,6 @@ DEFUN(disassemble_method, (jcf, byte_ops, len),
     {
       int oldpc = PC;
       int saw_index;
-      jlong LONG_temp;
       jint INT_temp;
       switch (byte_ops[PC++])
        {
@@ -990,19 +1146,17 @@ DEFUN(disassemble_method, (jcf, byte_ops, len),
 #define ARRAY_NEW(TYPE) ARRAY_NEW_##TYPE
 #define ARRAY_NEW_NUM \
  INT_temp = IMMEDIATE_u1; \
- { char *str; \
-  switch (INT_temp) {  \
-    case  4: str = "boolean"; break; \
-    case  5: str = "char"; break; \
-    case  6: str = "float"; break; \
-    case  7: str = "double"; break; \
-    case  8: str = "byte"; break; \
-    case  9: str = "short"; break; \
-    case 10: str = "int"; break; \
-    case 11: str = "long"; break; \
-    default: str = "<unknown type code %d>"; break; \
-  } \
-  fputc (' ', out); fprintf (out, str, INT_temp); }
+ { switch ((int) INT_temp) {  \
+    case  4: fputs (" boolean", out); break; \
+    case  5: fputs (" char", out); break; \
+    case  6: fputs (" float", out); break; \
+    case  7: fputs (" double", out); break; \
+    case  8: fputs (" byte", out); break; \
+    case  9: fputs (" short", out); break; \
+    case 10: fputs (" int", out); break; \
+    case 11: fputs (" long", out); break; \
+    default: fprintf (out, " <unknown type code %ld>", (long)INT_temp); break;\
+  } }
 
 #define ARRAY_NEW_PTR  \
   fputc (' ', out); print_constant_ref (out, jcf, IMMEDIATE_u2);
@@ -1016,24 +1170,24 @@ DEFUN(disassemble_method, (jcf, byte_ops, len),
 
 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
   saw_index = 0, INT_temp = (OPERAND_VALUE); \
-  fprintf (out, " %d", saw_index ? INT_temp : oldpc + INT_temp)
+  fprintf (out, " %ld", (long) (saw_index ? INT_temp : oldpc + INT_temp))
 
 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
   saw_index = 0, INT_temp = (OPERAND_VALUE); \
-  fprintf (out, " %d", saw_index ? INT_temp : oldpc + INT_temp)
+  fprintf (out, " %ld", (long) (saw_index ? INT_temp : oldpc + INT_temp))
 
 #undef RET /* Defined by config/i386/i386.h */
 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
   INT_temp = saw_wide ? IMMEDIATE_u2 : (OPERAND_VALUE); \
   saw_wide = 0; \
-  fprintf (out, " %d", INT_temp);
+  fprintf (out, " %ld", (long) INT_temp);
 
 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
   PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
 
 #define LOOKUP_SWITCH \
   { jint default_offset = IMMEDIATE_s4;  jint npairs = IMMEDIATE_s4; \
-    fprintf (out, " npairs=%d, default=%d", npairs, default_offset+oldpc); \
+    fprintf (out, " npairs=%ld, default=%ld", (long) npairs, (long) default_offset+oldpc); \
     while (--npairs >= 0) { \
      jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
      fprintf (out, "\n%10ld: %ld", (long)match, (long)(offset+oldpc)); } \
@@ -1042,8 +1196,8 @@ DEFUN(disassemble_method, (jcf, byte_ops, len),
 #define TABLE_SWITCH \
   { jint default_offset = IMMEDIATE_s4; \
     jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
-    fprintf (out, " low=%d, high=%d, default=%d", \
-      low, high, default_offset+oldpc); \
+    fprintf (out, " low=%ld, high=%ld, default=%ld", \
+      (long) low, (long) high, (long) default_offset+oldpc); \
     for (; low <= high; low++) { \
      jint offset = IMMEDIATE_s4; \
      fprintf (out, "\n%10ld: %ld", (long)low, (long)(offset+oldpc)); } \
@@ -1055,7 +1209,7 @@ DEFUN(disassemble_method, (jcf, byte_ops, len),
 #define SPECIAL_IINC(OPERAND_TYPE) \
   i = saw_wide ? IMMEDIATE_u2 : IMMEDIATE_u1; \
   fprintf (out, " %d", i); \
-  INT_temp = saw_wide ? IMMEDIATE_s2 : IMMEDIATE_s1; \
+  i = saw_wide ? IMMEDIATE_s2 : IMMEDIATE_s1; \
   saw_wide = 0; \
   fprintf (out, " %d", i)
 
@@ -1080,7 +1234,7 @@ DEFUN(disassemble_method, (jcf, byte_ops, len),
          else
            {
              saw_wide = 0;
-             fprintf (out, " %d", INT_temp);
+             fprintf (out, " %ld", (long) INT_temp);
            }
          fputc ('\n', out);
          break;