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