OSDN Git Service

2006-06-06 Laurent GUERBY <laurent@guerby.net>
[pf3gnuchains/gcc-fork.git] / libjava / gij.cc
index 59c2fe9..817378f 100644 (file)
@@ -1,25 +1,20 @@
-/* Copyright (C) 1999, 2000, 2001, 2002, 2003  Free Software Foundation
+/* Copyright (C) 1999-2006  Free Software Foundation
 
    This file is part of libgcj.
 
-This software is copyrighted work licensed under the terms of the
-Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
-details.  */
-
-/* Author: Kresten Krab Thorup <krab@gnu.org>  */
+   This software is copyrighted work licensed under the terms of the
+   Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+   details. */
 
 #include <config.h>
 
 #include <jvm.h>
 #include <gcj/cni.h>
-#include <java-props.h>
 
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-
-#include <java/lang/System.h>
-#include <java/util/Properties.h>
+#include <unistd.h>
 
 static void
 help ()
@@ -31,9 +26,11 @@ help ()
   printf ("  --cp LIST         set class path\n");
   printf ("  --classpath LIST  set class path\n");
   printf ("  -DVAR=VAL         define property VAR with value VAL\n");
-  printf ("  --help            print this help, then exit\n");
+  printf ("  -?, --help        print this help, then exit\n");
+  printf ("  -X                print help on supported -X options, then exit\n");
   printf ("  --ms=NUMBER       set initial heap size\n");
   printf ("  --mx=NUMBER       set maximum heap size\n");
+  printf ("  --verbose[:class] print information about class loading\n");
   printf ("  --showversion     print version number, then keep going\n");
   printf ("  --version         print version number, then exit\n");
   printf ("\nOptions can be specified with `-' or `--'.\n");
@@ -44,102 +41,312 @@ help ()
 static void
 version ()
 {
+  printf ("java version \"" JV_VERSION "\"\n");
   printf ("gij (GNU libgcj) version %s\n\n", __VERSION__);
-  printf ("Copyright (C) 2002 Free Software Foundation, Inc.\n");
+  printf ("Copyright (C) 2006 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");
 }
 
+static void
+nonstandard_opts_help ()
+{
+  printf ("  -Xms<size>         set initial heap size\n");
+  printf ("  -Xmx<size>         set maximum heap size\n");
+  printf ("  -Xss<size>         set thread stack size\n");
+  exit (0);
+}
+
+static void
+add_option (JvVMInitArgs& vm_args, char const* option, void const* extra)
+{
+  vm_args.options =
+    (JvVMOption*) JvRealloc (vm_args.options,
+                             (vm_args.nOptions + 1) * sizeof (JvVMOption));
+
+  vm_args.options[vm_args.nOptions].optionString = const_cast<char*> (option);
+  vm_args.options[vm_args.nOptions].extraInfo = const_cast<void*> (extra);
+  ++vm_args.nOptions;
+}
+
 int
-main (int argc, const char **argv)
+main (int argc, char const** argv)
 {
-  /* We rearrange ARGV so that all the -D options appear near the
-     beginning.  */
-  int last_D_option = 0;
+  // libjawt.so must be installed in GCJ's versioned directory and not
+  // the main library directory so that it doesn't override other
+  // libjawt.so implementations.  Programs that use the AWT Native
+  // Interface contain a JNI library that links to libjawt.so.  We do
+  // not want to require that users explicitly add GCJ's versioned
+  // directory to LD_LIBRARY_PATH when running such programs.
+
+  // Simply adding GCJ's versioned directory to the module load path
+  // does not solve this problem since libltdl searches its module
+  // load path only for object that it will dlopen; dependencies of
+  // these dynamically loaded objects are searched for in
+  // LD_LIBRARY_PATH.
+
+  // In addition, setting LD_LIBRARY_PATH from within the current
+  // process does not alter the dependency search path, since it is
+  // computed on startup.  This behaviour makes sense since
+  // LD_LIBRARY_PATH is designed to allow users to override the path
+  // set by a program.  This re-spawning trick makes it impossible to
+  // override, using LD_LIBRARY_PATH, the versioned directories
+  // searched by gij.
+
+  // Check if LD_LIBRARY_PATH is already prefixed with
+  // GCJ_VERSIONED_LIBDIR.  If not, export LD_LIBRARY_PATH prefixed
+  // with GCJ_VERSIONED_LIBDIR and re-spawn gij.
+  char *libpath = getenv (LTDL_SHLIBPATH_VAR);
+  char *newpath = _Jv_PrependVersionedLibdir (libpath);
+
+  if (! libpath || strcmp (libpath, newpath))
+    {
+      char *buffer = (char *) JvMalloc (strlen (LTDL_SHLIBPATH_VAR)
+                                       + strlen (newpath) + 2);
+      strcpy (buffer, LTDL_SHLIBPATH_VAR);
+      strcat (buffer, "=");
+      strcat (buffer, newpath);
+      putenv (buffer);
+      JvFree (newpath);
+
+      int error_code = execvp (argv[0], (char* const*) argv);
+
+      fprintf (stderr, "error re-spawning gij with new "
+               LTDL_SHLIBPATH_VAR " value: %s\n", strerror (error_code));
+
+      return error_code;
+    }
+  JvFree (newpath);
+
+  JvVMInitArgs vm_args;
   bool jar_mode = false;
 
+  vm_args.options = NULL;
+  vm_args.nOptions = 0;
+  vm_args.ignoreUnrecognized = true;
+
+  // Command-line options always override the CLASSPATH environment
+  // variable.
+  char *classpath = getenv("CLASSPATH");
+
+  if (classpath)
+    {
+      char* darg = (char*) JvMalloc (strlen (classpath)
+                                     + sizeof ("-Djava.class.path="));
+      sprintf (darg, "-Djava.class.path=%s", classpath);
+      add_option (vm_args, darg, NULL);
+    }
+
+  // Handle arguments to the java command.  Store in vm_args arguments
+  // handled by the invocation API.
   int i;
   for (i = 1; i < argc; ++i)
     {
-      const char *arg = argv[i];
+      char* arg = const_cast<char*> (argv[i]);
 
-      /* A non-option stops processing.  */
+      // A non-option stops processing.
       if (arg[0] != '-')
        break;
-      /* A "--" stops processing.  */
+
+      // A "--" stops processing.
       if (! strcmp (arg, "--"))
        {
          ++i;
          break;
        }
 
-      if (! strncmp (arg, "-D", 2))
-       {
-         argv[last_D_option++] = arg + 2;
-         continue;
-       }
-
-      if (! strcmp (arg, "-jar"))
-       {
-         jar_mode = true;
-         continue;
-       }
-
-      /* Allow both single or double hyphen for all remaining
-        options.  */
+      // Allow both single or double hyphen for all options.
       if (arg[1] == '-')
        ++arg;
 
-      if (! strcmp (arg, "-help") || ! strcmp (arg, "-?"))
-       help ();
-      else if (! strcmp (arg, "-version"))
-       {
-         version ();
-         exit (0);
-       }
-      else if (! strcmp (arg, "-showversion"))
-       version ();
-      /* FIXME: use getopt and avoid the ugliness here.
-        We at least need to handle the argument in a better way.  */
-      else if (! strncmp (arg, "-ms=", 4))
-       _Jv_SetInitialHeapSize (arg + 4);
-      else if (! strcmp (arg, "-ms"))
-       {
-         if (i >= argc - 1)
-           {
+      // Ignore JIT options
+      if (! strcmp (arg, "-client"))
+        continue;
+      else if (! strcmp (arg, "-server"))
+        continue;
+      else if (! strcmp (arg, "-hotspot"))
+        continue;
+      else if (! strcmp (arg, "-jrockit"))
+        continue;
+      // Ignore JVM Tool Interface options
+      else if (! strncmp (arg, "-agentlib:", sizeof ("-agentlib:") - 1))
+        continue;
+      else if (! strncmp (arg, "-agentpath:", sizeof ("-agentpath:") - 1))
+        continue;
+      else if (! strcmp (arg, "-classpath") || ! strcmp (arg, "-cp"))
+        {
+          if (i >= argc - 1)
+            {
            no_arg:
              fprintf (stderr, "gij: option requires an argument -- `%s'\n",
                       argv[i]);
              fprintf (stderr, "Try `gij --help' for more information.\n");
              exit (1);
-           }
-         _Jv_SetInitialHeapSize (argv[++i]);
+            }
+
+          // Sun seems to translate the -classpath option into
+          // -Djava.class.path because if both -classpath and
+          // -Djava.class.path are specified on the java command line,
+          // the last one always wins.
+          char* darg = (char*) JvMalloc (strlen (argv[++i])
+                                         + sizeof ("-Djava.class.path="));
+          sprintf (darg, "-Djava.class.path=%s", argv[i]);
+          add_option (vm_args, darg, NULL);
+        }
+      else if (! strcmp (arg, "-debug"))
+        {
+          char* xarg = strdup ("-Xdebug");
+          add_option (vm_args, xarg, NULL);
+        }
+      else if (! strncmp (arg, "-D", sizeof ("-D") - 1))
+        add_option (vm_args, arg, NULL);
+      // Ignore 32/64-bit JIT options
+      else if (! strcmp (arg, "-d32") || ! strcmp (arg, "-d64"))
+        continue;
+      else if (! strncmp (arg, "-enableassertions", sizeof ("-enableassertions") - 1)
+               || ! strncmp (arg, "-ea", sizeof ("-ea") - 1))
+        {
+          // FIXME: hook up assertion support
+          continue;
+        }
+      else if (! strncmp (arg, "-disableassertions", sizeof ("-disableassertions") - 1)
+               || ! strncmp (arg, "-da", sizeof ("-da") - 1))
+        {
+          // FIXME: hook up assertion support
+          continue;
+        }
+      else if (! strcmp (arg, "-enablesystemassertions")
+               || ! strcmp (arg, "-esa"))
+        {
+          // FIXME: hook up system assertion support
+          continue;
+        }
+      else if (! strcmp (arg, "-disablesystemassertions")
+               || ! strcmp (arg, "-dsa"))
+        {
+          // FIXME
+          continue;
+        }
+      else if (! strcmp (arg, "-jar"))
+       {
+         jar_mode = true;
+         continue;
+       }
+      // Ignore java.lang.instrument option
+      else if (! strncmp (arg, "-javaagent:", sizeof ("-javaagent:") - 1))
+        continue;
+      else if (! strcmp (arg, "-noclassgc"))
+        {
+          char* xarg = strdup ("-Xnoclassgc");
+          add_option (vm_args, xarg, NULL);
+        }
+      // -ms=n
+      else if (! strncmp (arg, "-ms=", sizeof ("-ms=") - 1))
+        {
+          arg[1] = 'X';
+          arg[2] = 'm';
+          arg[3] = 's';
+          add_option (vm_args, arg, NULL);
+        }
+      // -ms n
+      else if (! strcmp (arg, "-ms"))
+       {
+         if (i >= argc - 1)
+            goto no_arg;
+
+          char* xarg = (char*) JvMalloc (strlen (argv[++i])
+                                         + sizeof ("-Xms"));
+          sprintf (xarg, "-Xms%s", argv[i]);
+          add_option (vm_args, xarg, NULL);
        }
-      else if (! strncmp (arg, "-mx=", 4))
-       _Jv_SetMaximumHeapSize (arg + 4);
+      // -msn
+      else if (! strncmp (arg, "-ms", sizeof ("-ms") - 1))
+       {
+          char* xarg = (char*) JvMalloc (strlen (arg) + sizeof ("X"));
+          sprintf (xarg, "-Xms%s", arg + sizeof ("-Xms") - 1);
+          add_option (vm_args, xarg, NULL);
+       }
+      // -mx=n
+      else if (! strncmp (arg, "-mx=", sizeof ("-mx=") - 1))
+        {
+          arg[1] = 'X';
+          arg[2] = 'm';
+          arg[3] = 'x';
+          add_option (vm_args, arg, NULL);
+        }
+      // -mx n
       else if (! strcmp (arg, "-mx"))
        {
          if (i >= argc - 1)
-           goto no_arg;
-         _Jv_SetMaximumHeapSize (argv[++i]);
+            goto no_arg;
+
+          char* xarg = (char*) JvMalloc (strlen (argv[++i])
+                                         + sizeof ("-Xmx"));
+          sprintf (xarg, "-Xmx%s", argv[i]);
+          add_option (vm_args, xarg, NULL);
+       }
+      // -mxn
+      else if (! strncmp (arg, "-mx", sizeof ("-mx") - 1))
+       {
+          char* xarg = (char*) JvMalloc (strlen (arg) + sizeof ("X"));
+          sprintf (xarg, "-Xmx%s", arg + sizeof ("-Xmx") - 1);
+          add_option (vm_args, xarg, NULL);
        }
-      else if (! strcmp (arg, "-cp") || ! strcmp (arg, "-classpath"))
+      // -ss=n
+      else if (! strncmp (arg, "-ss=", sizeof ("-ss=") - 1))
+        {
+          arg[1] = 'X';
+          arg[2] = 's';
+          arg[3] = 's';
+          add_option (vm_args, arg, NULL);
+        }
+      // -ss n
+      else if (! strcmp (arg, "-ss"))
        {
          if (i >= argc - 1)
-           goto no_arg;
-         // We set _Jv_Jar_Class_Path.  If the user specified `-jar'
-         // then the jar code will override this.  This is the
-         // correct behavior.
-         _Jv_Jar_Class_Path = argv[++i];
+            goto no_arg;
+
+          char* xarg = (char*) JvMalloc (strlen (argv[++i])
+                                         + sizeof ("-Xss"));
+          sprintf (xarg, "-Xss%s", argv[i]);
+          add_option (vm_args, xarg, NULL);
+       }
+      // -ssn
+      else if (! strncmp (arg, "-ss", sizeof ("-ss") - 1))
+       {
+          char* xarg = (char*) JvMalloc (strlen (arg) + sizeof ("X"));
+          sprintf (xarg, "-Xss%s", arg + sizeof ("-Xss") - 1);
+          add_option (vm_args, xarg, NULL);
        }
-      else if (arg[1] == 'X')
+      // This handles all the option variants that begin with
+      // -verbose.
+      else if (! strncmp (arg, "-verbose", 8))
+        add_option (vm_args, arg, NULL);
+      else if (! strcmp (arg, "-version"))
        {
-         if (arg[2] == '\0')
-           {
-             printf ("gij: currently no -X options are recognized\n");
-             exit (0);
-           }
-         /* Ignore other -X options.  */
+         version ();
+         exit (0);
+       }
+      else if (! strcmp (arg, "-fullversion"))
+        {
+          printf ("java full version \"gcj-" JV_VERSION "\"\n");
+          exit (0);
+        }
+      else if (! strcmp (arg, "-showversion"))
+        version ();
+      else if (! strcmp (arg, "-help") || ! strcmp (arg, "-?"))
+       help ();
+      else if (! strcmp (arg, "-X"))
+        nonstandard_opts_help ();
+      else if (! strncmp (arg, "-X", 2))
+        add_option (vm_args, arg, NULL);
+      // Obsolete options recognized for backwards-compatibility.
+      else if (! strcmp (arg, "-verify")
+               || ! strcmp (arg, "-verifyremote"))
+       continue;
+      else if (! strcmp (arg, "-noverify"))
+        {
+         gcj::verifyClasses = false;
        }
       else
        {
@@ -149,9 +356,6 @@ main (int argc, const char **argv)
        }
     }
 
-  argv[last_D_option] = NULL;
-  _Jv_Compiler_Properties = argv;
-
   if (argc - i < 1)
     {
       fprintf (stderr, "Usage: gij [OPTION] ... CLASS [ARGS] ...\n");
@@ -162,5 +366,16 @@ main (int argc, const char **argv)
       exit (1);
     }
 
-  _Jv_RunMain (NULL, argv[i], argc - i, argv + i, jar_mode);
+  // -jar mode overrides all other modes of specifying class path:
+  // CLASSPATH, -Djava.class.path, -classpath and -cp.
+  if (jar_mode)
+    {
+      char* darg = (char*) JvMalloc (strlen (argv[i])
+                                      + sizeof ("-Djava.class.path="));
+      sprintf (darg, "-Djava.class.path=%s", argv[i]);
+      add_option (vm_args, darg, NULL);
+    }
+
+  _Jv_RunMain (&vm_args, NULL, argv[i], argc - i,
+               (char const**) (argv + i), jar_mode);
 }