ab49257b10611d57de47ee9f9f3dd9c3b50c6a20
[cacao.git] / src / vm / properties.c
1 /* src/vm/properties.c - handling commandline properties
2
3    Copyright (C) 1996-2005, 2006, 2007 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    $Id: properties.c 8236 2007-07-27 10:18:17Z twisti $
26
27 */
28
29
30 #include "config.h"
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/utsname.h>
35 #include <time.h>
36
37 #include "vm/types.h"
38
39 #include "mm/memory.h"
40
41 #include "native/jni.h"
42
43 #include "vm/global.h"                      /* required by java_lang_String.h */
44 #include "native/include/java_lang_String.h"
45
46 #include "toolbox/list.h"
47 #include "toolbox/util.h"
48
49 #include "vm/properties.h"
50 #include "vm/stringlocal.h"
51 #include "vm/vm.h"
52
53 #include "vm/jit/asmpart.h"
54
55 #include "vmcore/method.h"
56 #include "vmcore/options.h"
57
58
59 /* internal property structure ************************************************/
60
61 typedef struct list_properties_entry list_properties_entry;
62
63 struct list_properties_entry {
64         char       *key;
65         char       *value;
66         listnode_t  linkage;
67 };
68
69
70 /* global variables ***********************************************************/
71
72 static list_t *list_properties = NULL;
73
74
75 /* properties_init *************************************************************
76
77    Initialize the properties list and fill the list with default
78    values.
79
80 *******************************************************************************/
81
82 bool properties_init(void)
83 {
84 #if defined(ENABLE_JAVASE)
85         char           *env_java_home;
86         char           *java_home;
87         s4              len;
88
89 # if defined(WITH_CLASSPATH_GNU)
90         char           *cwd;
91         char           *env_user;
92         char           *env_home;
93         char           *env_lang;
94         char           *extdirs;
95         char           *lang;
96         char           *country;
97         struct utsname *utsnamebuf;
98 # endif
99 #endif
100
101         /* create the properties list */
102
103         list_properties = list_create(OFFSET(list_properties_entry, linkage));
104
105 #if defined(ENABLE_JAVASE)
106
107         /* get properties from system */
108
109         env_java_home = getenv("JAVA_HOME");
110
111         /* set JAVA_HOME to default prefix if not defined */
112
113         if (env_java_home == NULL)
114                 env_java_home = cacao_prefix;
115
116         /* fill in system properties */
117
118         /* add /jre to java.home property */
119
120         len = strlen(env_java_home) + strlen("/jre") + strlen("0");
121
122         java_home = MNEW(char, len);
123
124         strcpy(java_home, env_java_home);
125         strcat(java_home, "/jre");
126
127         properties_add("java.home", java_home);
128
129         properties_add("java.vm.specification.version", "1.0");
130         properties_add("java.vm.specification.vendor", "Sun Microsystems Inc.");
131         properties_add("java.vm.specification.name", "Java Virtual Machine Specification");
132         properties_add("java.vm.version", VERSION);
133         properties_add("java.vm.vendor", "CACAO Team");
134         properties_add("java.vm.name", "CACAO");
135
136 # if defined(ENABLE_INTRP)
137         if (opt_intrp) {
138                 /* XXX We don't support java.lang.Compiler */
139 /*              properties_add("java.compiler", "cacao.intrp"); */
140                 properties_add("java.vm.info", "interpreted mode");
141         }
142         else
143 # endif
144         {
145                 /* XXX We don't support java.lang.Compiler */
146 /*              properties_add("java.compiler", "cacao.jit"); */
147                 properties_add("java.vm.info", "JIT mode");
148         }
149
150 # if defined(WITH_CLASSPATH_GNU)
151
152         /* get properties from system */
153
154         cwd      = _Jv_getcwd();
155
156         env_user = getenv("USER");
157         env_home = getenv("HOME");
158         env_lang = getenv("LANG");
159
160         utsnamebuf = NEW(struct utsname);
161
162         uname(utsnamebuf);
163
164         properties_add("java.runtime.version", VERSION);
165         properties_add("java.runtime.name", "CACAO");
166
167         properties_add("java.specification.version", "1.5");
168         properties_add("java.specification.vendor", "Sun Microsystems Inc.");
169         properties_add("java.specification.name", "Java Platform API Specification");
170
171         properties_add("java.version", JAVA_VERSION);
172         properties_add("java.vendor", "GNU Classpath");
173         properties_add("java.vendor.url", "http://www.gnu.org/software/classpath/");
174
175         properties_add("java.class.path", _Jv_classpath);
176         properties_add("java.class.version", CLASS_VERSION);
177
178         /* Set bootclasspath properties. One for GNU classpath and the
179            other for compatibility with Sun (required by most
180            applications). */
181
182         properties_add("java.boot.class.path", _Jv_bootclasspath);
183         properties_add("sun.boot.class.path", _Jv_bootclasspath);
184
185 #  if defined(WITH_STATIC_CLASSPATH)
186         properties_add("gnu.classpath.boot.library.path", ".");
187         properties_add("java.library.path" , ".");
188 #  else
189         /* fill gnu.classpath.boot.library.path with GNU Classpath library
190        path */
191
192         properties_add("gnu.classpath.boot.library.path", classpath_libdir);
193         properties_add("java.library.path", _Jv_java_library_path);
194 #  endif
195
196         properties_add("java.io.tmpdir", "/tmp");
197
198 #  if defined(ENABLE_INTRP)
199         if (opt_intrp) {
200                 properties_add("gnu.java.compiler.name", "cacao.intrp");
201         }
202         else
203 #  endif
204         {
205                 properties_add("gnu.java.compiler.name", "cacao.jit");
206         }
207
208         /* set the java.ext.dirs property */
209
210         len = strlen(env_java_home) + strlen("/jre/lib/ext") + strlen("0");
211
212         extdirs = MNEW(char, len);
213
214         strcpy(extdirs, env_java_home);
215         strcat(extdirs, "/jre/lib/ext");
216
217         properties_add("java.ext.dirs", extdirs);
218
219         properties_add("java.endorsed.dirs", ""CACAO_PREFIX"/jre/lib/endorsed");
220
221 #  if defined(DISABLE_GC)
222         /* When we disable the GC, we mmap the whole heap to a specific
223            address, so we can compare call traces. For this reason we have
224            to add the same properties on different machines, otherwise
225            more memory may be allocated (e.g. strlen("i386")
226            vs. strlen("alpha"). */
227
228         properties_add("os.arch", "unknown");
229         properties_add("os.name", "unknown");
230         properties_add("os.version", "unknown");
231 #  else
232         /* We need to set the os.arch hardcoded to be compatible with SUN. */
233
234 #   if defined(__I386__)
235         /* map all x86 architectures (i386, i486, i686) to i386 */
236
237         properties_add("os.arch", "i386");
238 #   elif defined(__POWERPC__)
239         properties_add("os.arch", "ppc");
240 #   elif defined(__X86_64__)
241         properties_add("os.arch", "amd64");
242 #   else
243         /* default to what uname returns */
244
245         properties_add("os.arch", utsnamebuf->machine);
246 #   endif
247
248         properties_add("os.name", utsnamebuf->sysname);
249         properties_add("os.version", utsnamebuf->release);
250 #  endif
251
252 #  if defined(WITH_STATIC_CLASSPATH)
253         /* This is just for debugging purposes and can cause troubles in
254        GNU Classpath. */
255
256         properties_add("gnu.cpu.endian", "unknown");
257 #  else
258 #   if WORDS_BIGENDIAN == 1
259         properties_add("gnu.cpu.endian", "big");
260 #   else
261         properties_add("gnu.cpu.endian", "little");
262 #   endif
263 #  endif
264
265         properties_add("file.separator", "/");
266         properties_add("path.separator", ":");
267         properties_add("line.separator", "\n");
268
269         properties_add("user.name", env_user ? env_user : "null");
270         properties_add("user.home", env_home ? env_home : "null");
271         properties_add("user.dir", cwd ? cwd : "null");
272
273         /* get locale */
274
275         if (env_lang != NULL) {
276                 /* get the local stuff from the environment */
277
278                 if (strlen(env_lang) <= 2) {
279                         properties_add("user.language", env_lang);
280                 }
281                 else {
282                         if ((env_lang[2] == '_') && (strlen(env_lang) >= 5)) {
283                                 lang = MNEW(char, 3);
284                                 strncpy(lang, (char *) &env_lang[0], 2);
285                                 lang[2] = '\0';
286
287                                 country = MNEW(char, 3);
288                                 strncpy(country, (char *) &env_lang[3], 2);
289                                 country[2] = '\0';
290
291                                 properties_add("user.language", lang);
292                                 properties_add("user.country", country);
293                         }
294                 }
295         }
296         else {
297                 /* if no default locale was specified, use `en_US' */
298
299                 properties_add("user.language", "en");
300                 properties_add("user.country", "US");
301         }
302
303 # elif defined(WITH_CLASSPATH_SUN)
304
305         properties_add("sun.boot.library.path", classpath_libdir);
306
307 # else
308
309 #  error unknown classpath configuration
310
311 # endif
312
313 #elif defined(ENABLE_JAVAME_CLDC1_1)
314
315     properties_add("microedition.configuration", "CLDC-1.1");
316     properties_add("microedition.platform", "generic");
317     properties_add("microedition.encoding", "ISO8859_1");
318     properties_add("microedition.profiles", "");
319
320 #else
321
322 # error unknown Java configuration
323
324 #endif
325
326         /* everything's ok */
327
328         return true;
329 }
330
331
332 /* properties_add **************************************************************
333
334    Adds a property entry to the internal property list.  If there's
335    already an entry with the same key, replace it.
336
337 *******************************************************************************/
338
339 void properties_add(char *key, char *value)
340 {
341         list_properties_entry *pe;
342
343         /* search for the entry */
344
345         for (pe = list_first_unsynced(list_properties); pe != NULL;
346                  pe = list_next_unsynced(list_properties, pe)) {
347                 if (strcmp(pe->key, key) == 0) {
348                         /* entry was found, replace the value */
349
350                         pe->value = value;
351
352                         return;
353                 }
354         }
355
356         /* entry was not found, insert a new one */
357
358         pe = NEW(list_properties_entry);
359
360         pe->key   = key;
361         pe->value = value;
362
363         list_add_last_unsynced(list_properties, pe);
364 }
365
366
367 /* properties_get **************************************************************
368
369    Get a property entry from the internal property list.
370
371 *******************************************************************************/
372
373 char *properties_get(char *key)
374 {
375         list_properties_entry *pe;
376
377         for (pe = list_first_unsynced(list_properties); pe != NULL;
378                  pe = list_next_unsynced(list_properties, pe)) {
379                 if (strcmp(pe->key, key) == 0)
380                         return pe->value;
381         }
382
383         return NULL;
384 }
385
386
387 /* properties_system_add *******************************************************
388
389    Adds a given property to the Java system properties.
390
391 *******************************************************************************/
392
393 void properties_system_add(java_objectheader *p, char *key, char *value)
394 {
395         methodinfo        *m;
396         java_objectheader *k;
397         java_objectheader *v;
398
399         /* search for method to add properties */
400
401         m = class_resolveclassmethod(p->vftbl->class,
402                                                                  utf_put,
403                                                                  utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
404                                                                  NULL,
405                                                                  true);
406
407         if (m == NULL)
408                 return;
409
410         /* add to the Java system properties */
411
412         k = javastring_new_from_utf_string(key);
413         v = javastring_new_from_utf_string(value);
414
415         (void) vm_call_method(m, p, k, v);
416 }
417
418
419 /* properties_system_add_all ***************************************************
420
421    Adds all properties from the properties list to the Java system
422    properties.
423
424    ARGUMENTS:
425        p.... is actually a java_util_Properties structure
426
427 *******************************************************************************/
428
429 #if defined(ENABLE_JAVASE)
430 void properties_system_add_all(java_objectheader *p)
431 {
432         list_properties_entry *pe;
433         methodinfo            *m;
434         java_objectheader     *key;
435         java_objectheader     *value;
436
437         /* search for method to add properties */
438
439         m = class_resolveclassmethod(p->vftbl->class,
440                                                                  utf_put,
441                                                                  utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
442                                                                  NULL,
443                                                                  true);
444
445         if (m == NULL)
446                 return;
447
448         /* process all properties stored in the internal table */
449
450         for (pe = list_first(list_properties); pe != NULL;
451                  pe = list_next(list_properties, pe)) {
452                 /* add to the Java system properties */
453
454                 key   = javastring_new_from_utf_string(pe->key);
455                 value = javastring_new_from_utf_string(pe->value);
456
457                 (void) vm_call_method(m, (java_objectheader *) p, key, value);
458         }
459 }
460 #endif /* defined(ENABLE_JAVASE) */
461
462
463 /*
464  * These are local overrides for various environment variables in Emacs.
465  * Please do not remove this and leave it at the end of the file, where
466  * Emacs will automagically detect them.
467  * ---------------------------------------------------------------------
468  * Local variables:
469  * mode: c
470  * indent-tabs-mode: t
471  * c-basic-offset: 4
472  * tab-width: 4
473  * End:
474  */