* configure.ac (JAVA_ARCH): 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 8351 2007-08-19 17:56:23Z 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         properties_add("os.arch", JAVA_ARCH);
233         properties_add("os.name", utsnamebuf->sysname);
234         properties_add("os.version", utsnamebuf->release);
235 #  endif
236
237 #  if defined(WITH_STATIC_CLASSPATH)
238         /* This is just for debugging purposes and can cause troubles in
239        GNU Classpath. */
240
241         properties_add("gnu.cpu.endian", "unknown");
242 #  else
243 #   if WORDS_BIGENDIAN == 1
244         properties_add("gnu.cpu.endian", "big");
245 #   else
246         properties_add("gnu.cpu.endian", "little");
247 #   endif
248 #  endif
249
250         properties_add("file.separator", "/");
251         properties_add("path.separator", ":");
252         properties_add("line.separator", "\n");
253
254         properties_add("user.name", env_user ? env_user : "null");
255         properties_add("user.home", env_home ? env_home : "null");
256         properties_add("user.dir", cwd ? cwd : "null");
257
258         /* get locale */
259
260         if (env_lang != NULL) {
261                 /* get the local stuff from the environment */
262
263                 if (strlen(env_lang) <= 2) {
264                         properties_add("user.language", env_lang);
265                 }
266                 else {
267                         if ((env_lang[2] == '_') && (strlen(env_lang) >= 5)) {
268                                 lang = MNEW(char, 3);
269                                 strncpy(lang, (char *) &env_lang[0], 2);
270                                 lang[2] = '\0';
271
272                                 country = MNEW(char, 3);
273                                 strncpy(country, (char *) &env_lang[3], 2);
274                                 country[2] = '\0';
275
276                                 properties_add("user.language", lang);
277                                 properties_add("user.country", country);
278                         }
279                 }
280         }
281         else {
282                 /* if no default locale was specified, use `en_US' */
283
284                 properties_add("user.language", "en");
285                 properties_add("user.country", "US");
286         }
287
288 # elif defined(WITH_CLASSPATH_SUN)
289
290         properties_add("sun.boot.library.path", classpath_libdir);
291
292 # else
293
294 #  error unknown classpath configuration
295
296 # endif
297
298 #elif defined(ENABLE_JAVAME_CLDC1_1)
299
300     properties_add("microedition.configuration", "CLDC-1.1");
301     properties_add("microedition.platform", "generic");
302     properties_add("microedition.encoding", "ISO8859_1");
303     properties_add("microedition.profiles", "");
304
305 #else
306
307 # error unknown Java configuration
308
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_handle_t *p, char *key, char *value)
379 {
380         methodinfo    *m;
381         java_handle_t *k;
382         java_handle_t *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_handle_t *p)
416 {
417         list_properties_entry *pe;
418         methodinfo            *m;
419         java_handle_t         *key;
420         java_handle_t         *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_handle_t *) 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  */