* src/vm/properties.c (properties_init) [ENABLE_JAVASE]: Allocate the
[cacao.git] / src / vm / properties.c
1 /* src/vm/properties.c - handling commandline properties
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Christian Thalinger
28
29    $Id: properties.c 5991 2006-11-15 18:26:40Z twisti $
30
31 */
32
33
34 #include "config.h"
35
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sys/utsname.h>
39 #include <time.h>
40
41 #include "vm/types.h"
42
43 #include "mm/memory.h"
44
45 #include "vm/global.h"
46 #include "native/include/java_lang_String.h"
47 #include "native/include/java_util_Properties.h"
48 #include "toolbox/list.h"
49 #include "toolbox/util.h"
50 #include "vm/method.h"
51 #include "vm/options.h"
52 #include "vm/properties.h"
53 #include "vm/stringlocal.h"
54 #include "vm/vm.h"
55 #include "vm/jit/asmpart.h"
56
57
58 /* internal property structure ************************************************/
59
60 typedef struct list_properties_entry list_properties_entry;
61
62 struct list_properties_entry {
63         char     *key;
64         char     *value;
65         listnode linkage;
66 };
67
68
69 /* global variables ***********************************************************/
70
71 static list *list_properties = NULL;
72
73
74 /* properties_init *************************************************************
75
76    Initialize the properties list and fill the list with default
77    values.
78
79 *******************************************************************************/
80
81 bool properties_init(void)
82 {
83 #if defined(ENABLE_JAVASE)
84         char           *cwd;
85         char           *env_java_home;
86         char           *env_user;
87         char           *env_home;
88         char           *env_lang;
89         char           *java_home;
90         char           *extdirs;
91         char           *lang;
92         char           *country;
93         struct utsname *utsnamebuf;
94         s4              len;
95 #endif
96
97         /* create the properties list */
98
99         list_properties = list_create(OFFSET(list_properties_entry, linkage));
100
101 #if defined(ENABLE_JAVASE)
102         /* get properties from system */
103
104         cwd           = _Jv_getcwd();
105         env_java_home = getenv("JAVA_HOME");
106         env_user      = getenv("USER");
107         env_home      = getenv("HOME");
108         env_lang      = getenv("LANG");
109
110         utsnamebuf = NEW(struct utsname);
111
112         uname(utsnamebuf);
113
114         /* set JAVA_HOME to default prefix if not defined */
115
116         if (env_java_home == NULL)
117                 env_java_home = cacao_prefix;
118
119         /* fill in system properties */
120
121         properties_add("java.version", JAVA_VERSION);
122         properties_add("java.vendor", "GNU Classpath");
123         properties_add("java.vendor.url", "http://www.gnu.org/software/classpath/");
124
125         /* add /jre to java.home property */
126
127         len = strlen(env_java_home) + strlen("/jre") + strlen("0");
128
129         java_home = MNEW(char, len);
130
131         strcpy(java_home, env_java_home);
132         strcat(java_home, "/jre");
133
134         properties_add("java.home", java_home);
135
136         properties_add("java.vm.specification.version", "1.0");
137         properties_add("java.vm.specification.vendor", "Sun Microsystems Inc.");
138         properties_add("java.vm.specification.name", "Java Virtual Machine Specification");
139         properties_add("java.vm.version", VERSION);
140         properties_add("java.vm.vendor", "CACAO Team");
141         properties_add("java.vm.name", "CACAO");
142         properties_add("java.specification.version", "1.4");
143         properties_add("java.specification.vendor", "Sun Microsystems Inc.");
144         properties_add("java.specification.name", "Java Platform API Specification");
145         properties_add("java.class.version", CLASS_VERSION);
146         properties_add("java.class.path", _Jv_classpath);
147
148         properties_add("java.runtime.version", VERSION);
149         properties_add("java.runtime.name", "CACAO");
150
151         /* Set bootclasspath properties. One for GNU classpath and the
152            other for compatibility with Sun (required by most
153            applications). */
154
155         properties_add("java.boot.class.path", _Jv_bootclasspath);
156         properties_add("sun.boot.class.path", _Jv_bootclasspath);
157
158 #if defined(WITH_STATIC_CLASSPATH)
159         properties_add("gnu.classpath.boot.library.path", ".");
160         properties_add("java.library.path" , ".");
161 #else
162         /* fill gnu.classpath.boot.library.path with GNU Classpath library
163        path */
164
165         properties_add("gnu.classpath.boot.library.path", classpath_libdir);
166         properties_add("java.library.path", _Jv_java_library_path);
167 #endif
168
169         properties_add("java.io.tmpdir", "/tmp");
170
171 #if defined(ENABLE_INTRP)
172         if (opt_intrp) {
173                 /* XXX We don't support java.lang.Compiler */
174 /*              properties_add("java.compiler", "cacao.intrp"); */
175                 properties_add("java.vm.info", "interpreted mode");
176                 properties_add("gnu.java.compiler.name", "cacao.intrp");
177         }
178         else
179 #endif
180         {
181                 /* XXX We don't support java.lang.Compiler */
182 /*              properties_add("java.compiler", "cacao.jit"); */
183                 properties_add("java.vm.info", "JIT mode");
184                 properties_add("gnu.java.compiler.name", "cacao.jit");
185         }
186
187         /* set the java.ext.dirs property */
188
189         len = strlen(env_java_home) + strlen("/jre/lib/ext") + strlen("0");
190
191         extdirs = MNEW(char, len);
192
193         strcpy(extdirs, env_java_home);
194         strcat(extdirs, "/jre/lib/ext");
195
196         properties_add("java.ext.dirs", extdirs);
197
198         properties_add("java.endorsed.dirs", ""CACAO_PREFIX"/jre/lib/endorsed");
199
200 #if defined(DISABLE_GC)
201         /* When we disable the GC, we mmap the whole heap to a specific
202            address, so we can compare call traces. For this reason we have
203            to add the same properties on different machines, otherwise
204            more memory may be allocated (e.g. strlen("i386")
205            vs. strlen("alpha"). */
206
207         properties_add("os.arch", "unknown");
208         properties_add("os.name", "unknown");
209         properties_add("os.version", "unknown");
210 #else
211         /* We need to set the os.arch hardcoded to be compatible with SUN. */
212
213 # if defined(__I386__)
214         /* map all x86 architectures (i386, i486, i686) to i386 */
215
216         properties_add("os.arch", "i386");
217 # elif defined(__POWERPC__)
218         properties_add("os.arch", "ppc");
219 # elif defined(__X86_64__)
220         properties_add("os.arch", "amd64");
221 # else
222         /* default to what uname returns */
223
224         properties_add("os.arch", utsnamebuf->machine);
225 # endif
226
227         properties_add("os.name", utsnamebuf->sysname);
228         properties_add("os.version", utsnamebuf->release);
229 #endif
230
231         properties_add("file.separator", "/");
232         properties_add("path.separator", ":");
233         properties_add("line.separator", "\n");
234         properties_add("user.name", env_user ? env_user : "null");
235         properties_add("user.home", env_home ? env_home : "null");
236         properties_add("user.dir", cwd ? cwd : "null");
237
238 #if defined(WITH_STATIC_CLASSPATH)
239         /* This is just for debugging purposes and can cause troubles in
240        GNU Classpath. */
241
242         properties_add("gnu.cpu.endian", "unknown");
243 #else
244 # if WORDS_BIGENDIAN == 1
245         properties_add("gnu.cpu.endian", "big");
246 # else
247         properties_add("gnu.cpu.endian", "little");
248 # endif
249 #endif
250
251         /* get locale */
252
253         if (env_lang != NULL) {
254                 /* get the local stuff from the environment */
255
256                 if (strlen(env_lang) <= 2) {
257                         properties_add("user.language", env_lang);
258                 }
259                 else {
260                         if ((env_lang[2] == '_') && (strlen(env_lang) >= 5)) {
261                                 lang = MNEW(char, 3);
262                                 strncpy(lang, (char *) &env_lang[0], 2);
263                                 lang[2] = '\0';
264
265                                 country = MNEW(char, 3);
266                                 strncpy(country, (char *) &env_lang[3], 2);
267                                 country[2] = '\0';
268
269                                 properties_add("user.language", lang);
270                                 properties_add("user.country", country);
271                         }
272                 }
273         }
274         else {
275                 /* if no default locale was specified, use `en_US' */
276
277                 properties_add("user.language", "en");
278                 properties_add("user.country", "US");
279         }
280 #elif defined(ENABLE_JAVAME_CLDC1_1)
281     properties_add("microedition.configuration", "CLDC-1.1");
282     properties_add("microedition.platform", "PowerPC");
283     properties_add("microedition.encoding", "ISO-8859-1");
284     properties_add("microedition.profiles", "");
285 #else
286 #error unknown Java configuration
287 #endif
288
289         /* everything's ok */
290
291         return true;
292 }
293
294
295 /* properties_postinit *********************************************************
296
297    Re-set some properties that may have changed during command-line
298    parsing.
299
300 *******************************************************************************/
301
302 bool properties_postinit(void)
303 {
304 #if defined(ENABLE_JAVASE)
305         properties_add("java.class.path", _Jv_classpath);
306         properties_add("java.boot.class.path", _Jv_bootclasspath);
307         properties_add("sun.boot.class.path", _Jv_bootclasspath);
308 #endif
309
310         /* everything's ok */
311
312         return true;
313 }
314
315
316 /* properties_add **************************************************************
317
318    Adds a property entry to the internal property list.
319
320 *******************************************************************************/
321
322 void properties_add(char *key, char *value)
323 {
324         list_properties_entry *p;
325
326         p = NEW(list_properties_entry);
327
328         p->key   = key;
329         p->value = value;
330
331         list_add_last_unsynced(list_properties, p);
332 }
333
334
335 /* properties_get **************************************************************
336
337    Get a property entry from the internal property list.
338
339 *******************************************************************************/
340
341 char *properties_get(char *key)
342 {
343         list_properties_entry *pe;
344
345         /* We search backwards, so we get the newest entry for a key, as
346            the list may contain more than one entry for a specific key. */
347
348         for (pe = list_last(list_properties); pe != NULL;
349                  pe = list_prev(list_properties, pe)) {
350                 if (strcmp(pe->key, key) == 0)
351                         return pe->value;
352         }
353
354         return NULL;
355 }
356
357
358 /* properties_system_add_all ***************************************************
359
360    Adds all properties from the properties list to the Java system
361    properties.
362
363 *******************************************************************************/
364
365 #if defined(ENABLE_JAVASE)
366 void properties_system_add_all(java_util_Properties *p)
367 {
368         list_properties_entry *pe;
369         methodinfo            *m;
370         java_lang_String      *key;
371         java_lang_String      *value;
372
373         /* search for method to add properties */
374
375         m = class_resolveclassmethod(p->header.vftbl->class,
376                                                                  utf_new_char("put"),
377                                                                  utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
378                                                                  NULL,
379                                                                  true);
380
381         if (m == NULL)
382                 return;
383
384         /* process all properties stored in the internal table */
385
386         for (pe = list_first(list_properties); pe != NULL;
387                  pe = list_next(list_properties, pe)) {
388                 /* add to the Java system properties */
389
390                 key   = javastring_new_from_utf_string(pe->key);
391                 value = javastring_new_from_utf_string(pe->value);
392
393                 (void) vm_call_method(m, (java_objectheader *) p, key, value);
394         }
395 }
396 #endif /* defined(ENABLE_JAVASE) */
397
398
399 /*
400  * These are local overrides for various environment variables in Emacs.
401  * Please do not remove this and leave it at the end of the file, where
402  * Emacs will automagically detect them.
403  * ---------------------------------------------------------------------
404  * Local variables:
405  * mode: c
406  * indent-tabs-mode: t
407  * c-basic-offset: 4
408  * tab-width: 4
409  * End:
410  */