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