Patch for setting system properties from environment

Anthony Green green@cygnus.com
Thu Oct 14 23:08:00 GMT 1999


Here are some patches I've had kicking around for a while.  It's an
implementation of Matt Welsh's idea of having a single environment
variable, GCJ_PROPERTIES, with which to set system properites for gcj
compiled programs.

He wrote:
> How about a single env var which has the format
> 
> 	property.name=value property.name=value ...
> 
> so we can avoid cluttering the env var namespace? Call it GCJ_PROPERTIES.

Use the configure option --disable-getenv-properties to turn it off.
It is on by default for most targets.  Edit configure.host to change
the default on a per-target basis.

I've committed it to the trunk.

1999-10-14  Anthony Green  <green@cygnus.com>

	* libtool-version: Catch up by incrementing current.

	* configure.host: Disable use of GCJ_PROPERTIES for mips-tx39.
	* configure, include/config.h.in: Rebuilt.
	* acconfig.h (DISABLE_GETENV_PROPERTIES): Undefine.
	* configure.in: Added --disable-getenv-properties and new define
	`DISABLE_GETENV_PROPERTIES'.

	* prims.cc (PROCESS_GCJ_PROPERTIES): Define.
	(next_property_key): New function.
	(next_property_value): New function.
	(process_gcj_properties): New function.
	(JvRunMain): Call process_gcj_properties.
	(_JvRunMain): Ditto.

	* java/lang/natSystem.cc (init_properties): Set properties defined
	in GCJ_PROPERTIES.  Also add 1.2 style versioning properties.

	* include/java-props.h: New file.

	* java/lang/natSystem.cc (init_properties): Add new properties to
	conform with Java Product Versioning Specification.

Index: libjava/acconfig.h
===================================================================
RCS file: /cvs/java/libgcj/libjava/acconfig.h,v
retrieving revision 1.10
diff -u -r1.10 acconfig.h
--- acconfig.h	1999/10/02 00:19:00	1.10
+++ acconfig.h	1999/10/15 05:55:17
@@ -112,3 +112,7 @@
 
 /* Define if java.net native functions should be stubbed out.  */
 #undef DISABLE_JAVA_NET
+
+/* Define if system properties shouldn't be read from
+   getenv("GCJ_PROPERTIES").  */
+#undef DISABLE_GETENV_PROPERTIES
Index: libjava/configure
===================================================================
RCS file: /cvs/java/libgcj/libjava/configure.host,v
retrieving revision 1.4
diff -u -r1.4 configure.host
--- configure.host	1999/10/02 00:19:00	1.4
+++ configure.host	1999/10/15 05:55:20
@@ -53,6 +53,7 @@
 	# Use "Ecos" processes since they are a no-op.
 	PROCESS=Ecos
  	enable_java_net_default=no
+ 	enable_getenv_properties_default=no
 	;;
   i686-*|i586-*)
 	libgcj_flags="${libgcj_flags} -ffloat-store"
Index: libjava/configure.in
===================================================================
RCS file: /cvs/java/libgcj/libjava/configure.in,v
retrieving revision 1.38
diff -u -r1.38 configure.in
--- configure.in	1999/10/13 00:00:35	1.38
+++ configure.in	1999/10/15 05:55:21
@@ -9,7 +9,7 @@
 dnl We use these options to decide which functions to include.
 AC_ARG_WITH(target-subdir,
 [  --with-target-subdir=SUBDIR
-                          configuring in a subdirectory])
+                           configuring in a subdirectory])
 AC_ARG_WITH(cross-host,
 [  --with-cross-host=HOST  configuring with a cross compiler])
 
@@ -35,6 +35,20 @@
 [  --enable-fast-character prefer speed over size for Character],
 # Nothing
 , AC_DEFINE(COMPACT_CHARACTER))
+
+dnl Should the runtime set system properties by examining the 
+dnl environment variable GCJ_PROPERTIES?
+AC_ARG_ENABLE(getenv-properties,
+[  --disable-getenv-properties
+                          don't set system properties from GCJ_PROPERTIES])
+
+dnl Whether GCJ_PROPERTIES is used depends on the target.
+if test -n "$enable_getenv_properties"; then
+   enable_getenv_properties=${enable_getenv_properties_default-yes}
+fi
+if test "$enable_getenv_properties" = no; then
+   AC_DEFINE(DISABLE_GETENV_PROPERTIES)
+fi
 
 dnl See if the user has requested runtime debugging.
 AC_ARG_ENABLE(libgcj-debug,
Index: libjava/libtool-version
===================================================================
RCS file: /cvs/java/libgcj/libjava/libtool-version,v
retrieving revision 1.1
diff -u -r1.1 libtool-version
--- libtool-version	1999/05/07 17:00:51	1.1
+++ libtool-version	1999/10/15 05:55:21
@@ -3,4 +3,4 @@
 # a separate file so that version updates don't involve re-running
 # automake.
 # CURRENT:REVISION:AGE
-0:0:0
+1:0:0
Index: libjava/prims.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/prims.cc,v
retrieving revision 1.10
diff -u -r1.10 prims.cc
--- prims.cc	1999/09/23 18:50:59	1.10
+++ prims.cc	1999/10/15 05:55:21
@@ -23,6 +23,14 @@
 #include <java-signal.h>
 #include <java-threads.h>
 
+#ifndef DISABLE_GETENV_PROPERTIES
+#include <ctype.h>
+#include <java-props.h>
+#define PROCESS_GCJ_PROPERTIES process_gcj_properties()
+#else
+#define PROCESS_GCJ_PROPERTIES
+#endif // DISABLE_GETENV_PROPERTIES
+
 #include <java/lang/Class.h>
 #include <java/lang/Runtime.h>
 #include <java/lang/String.h>
@@ -55,6 +63,10 @@
 // Largest representable size_t.
 #define SIZE_T_MAX ((size_t) (~ (size_t) 0))
 
+#ifndef DISABLE_GETENV_PROPERTIES
+// Property key/value pairs.
+property_pair *_Jv_Environment_Properties;
+#endif
 
 
 #ifdef HANDLE_SEGV
@@ -621,9 +633,154 @@
   sigaction (SIGPIPE, &act, NULL);
 }
 
+#ifndef DISABLE_GETENV_PROPERTIES
+
+static char *
+next_property_key (char *s, size_t *length)
+{
+  size_t l = 0;
+
+  JvAssert (s);
+
+  // Skip over whitespace
+  while (isspace (*s))
+    s++;
+
+  // If we've reached the end, return NULL.  Also return NULL if for
+  // some reason we've come across a malformed property string.
+  if (*s == 0
+      || *s == ':'
+      || *s == '=')
+    return NULL;
+
+  // Determine the length of the property key.
+  while (s[l] != 0
+	 && ! isspace (s[l])
+	 && s[l] != ':'
+	 && s[l] != '=')
+    {
+      if (s[l] == '\\'
+	  && s[l+1] != 0)
+	l++;
+      l++;
+    }
+
+  *length = l;
+
+  return s;
+}
+
+static char *
+next_property_value (char *s, size_t *length)
+{
+  size_t l = 0;
+
+  JvAssert (s);
+
+  while (isspace (*s))
+    s++;
+
+  if (*s == ':'
+      || *s == '=')
+    s++;
+
+  while (isspace (*s))
+    s++;
+
+  // If we've reached the end, return NULL.
+  if (*s == 0)
+    return NULL;
+
+  // Determine the length of the property value.
+  while (s[l] != 0
+	 && ! isspace (s[l])
+	 && s[l] != ':'
+	 && s[l] != '=')
+    {
+      if (s[l] == '\\'
+	  && s[l+1] != 0)
+	l += 2;
+      else
+	l++;
+    }
+
+  *length = l;
+
+  return s;
+}
+
+static void
+process_gcj_properties ()
+{
+  char *props = getenv("GCJ_PROPERTIES");
+  char *p = props;
+  size_t length;
+  size_t property_count = 0;
+
+  if (NULL == props)
+    return;
+
+  // Whip through props quickly in order to count the number of
+  // property values.
+  while (p && (p = next_property_key (p, &length)))
+    {
+      // Skip to the end of the key
+      p += length;
+
+      p = next_property_value (p, &length);
+      if (p)
+	p += length;
+      
+      property_count++;
+    }
+
+  // Allocate an array of property value/key pairs.
+  _Jv_Environment_Properties = 
+    (property_pair *) malloc (sizeof(property_pair) 
+			      * (property_count + 1));
+
+  // Go through the properties again, initializing _Jv_Properties
+  // along the way.
+  p = props;
+  property_count = 0;
+  while (p && (p = next_property_key (p, &length)))
+    {
+      _Jv_Environment_Properties[property_count].key = p;
+      _Jv_Environment_Properties[property_count].key_length = length;
+
+      // Skip to the end of the key
+      p += length;
+
+      p = next_property_value (p, &length);
+      
+      _Jv_Environment_Properties[property_count].value = p;
+      _Jv_Environment_Properties[property_count].value_length = length;
+
+      if (p)
+	p += length;
+
+      property_count++;
+    }
+  memset ((void *) &_Jv_Environment_Properties[property_count], 
+	  0, sizeof (property_pair));
+  {
+    size_t i = 0;
+
+    // Null terminate the strings.
+    while (_Jv_Environment_Properties[i].key)
+      {
+	_Jv_Environment_Properties[i].key[_Jv_Environment_Properties[i].key_length] = 0;
+	_Jv_Environment_Properties[i++].value[_Jv_Environment_Properties[i].value_length] = 0;
+      }
+  }
+}
+#endif // DISABLE_GETENV_PROPERTIES
+
 void
 JvRunMain (jclass klass, int argc, const char **argv)
 {
+  PROCESS_GCJ_PROPERTIES;
+
   main_init ();
 
   arg_vec = JvConvertArgv (argc - 1, argv + 1);
@@ -639,6 +796,8 @@
 void
 _Jv_RunMain (const char *class_name, int argc, const char **argv)
 {
+  PROCESS_GCJ_PROPERTIES;
+
   main_init ();
 
   arg_vec = JvConvertArgv (argc - 1, argv + 1);
Index: libjava/include/config.h.in
===================================================================
RCS file: /cvs/java/libgcj/libjava/include/config.h.in,v
retrieving revision 1.14
diff -u -r1.14 config.h.in
--- config.h.in	1999/10/02 00:19:01	1.14
+++ config.h.in	1999/10/15 05:55:21
@@ -128,6 +128,10 @@
 /* Define if java.net native functions should be stubbed out.  */
 #undef DISABLE_JAVA_NET
 
+/* Define if system properties shouldn't be read from
+   getenv("GCJ_PROPERTIES").  */
+#undef DISABLE_GETENV_PROPERTIES
+
 /* Define if you have the access function.  */
 #undef HAVE_ACCESS
 
Index: libjava/java/lang/natSystem.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/lang/natSystem.cc,v
retrieving revision 1.11
diff -u -r1.11 natSystem.cc
--- natSystem.cc	1999/09/10 22:03:08	1.11
+++ natSystem.cc	1999/10/15 05:55:22
@@ -40,6 +40,7 @@
 
 #include <gcj/cni.h>
 #include <jvm.h>
+#include <java-props.h>
 #include <java/lang/System.h>
 #include <java/lang/Class.h>
 #include <java/lang/ArrayStoreException.h>
@@ -52,6 +53,7 @@
 #define SystemClass _CL_Q34java4lang6System
 extern java::lang::Class SystemClass;
 
+extern property_pair *_Jv_Environment_Properties;
 
 
 #if defined (ECOS)
@@ -274,10 +276,23 @@
   // A convenience define.
 #define SET(Prop,Val) \
 	properties->put(JvNewStringLatin1 (Prop), JvNewStringLatin1 (Val))
+
+  // A mixture of the Java Product Versioning Specification
+  // (introduced in 1.2), and earlier versioning properties.
   SET ("java.version", VERSION);
   SET ("java.vendor", "Cygnus Solutions");
   SET ("java.vendor.url", " http://sourceware.cygnus.com/java/ ");
   SET ("java.class.version", GCJVERSION);
+  SET ("java.vm.specification.version", "1.1");
+  SET ("java.vm.specification.name", "Java(tm) Virtual Machine Specification");
+  SET ("java.vm.specification.vendor", "Sun Microsystems Inc.");
+  SET ("java.vm.version", GCJVERSION);
+  SET ("java.vm.vendor", "Cygnus Solutions");
+  SET ("java.vm.name", "libgcj");
+  SET ("java.specification.version", "1.1");
+  SET ("java.specification.name", "Java(tm) Language Specification");
+  SET ("java.specification.vendor", "Sun Microsystems Inc.");
+
   // FIXME: how to set these given location-independence?
   // SET ("java.home", "FIXME");
   // SET ("java.class.path", "FIXME");
@@ -363,4 +378,17 @@
   if (buffer != NULL)
     free (buffer);
 #endif
+
+  // Set the system properties from the user's environment.
+  if (_Jv_Environment_Properties)
+    {
+      size_t i = 0;
+
+      while (_Jv_Environment_Properties[i].key)
+	{
+	  SET (_Jv_Environment_Properties[i].key, 
+	       _Jv_Environment_Properties[i].value);
+	  i++;
+	}
+    }
 }

-- 
Anthony Green                                               Cygnus Solutions
                                                       Sunnyvale, California


More information about the Java-patches mailing list