bd7d38cb92211c99ae3f636531c2a1fcdff68e38
[cacao.git] / src / cacaoh / cacaoh.c
1 /* src/cacaoh/cacaoh.c - main for header generation (cacaoh)
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include "vm/types.h"
33
34 #include "cacaoh/headers.h"
35
36 #include "mm/gc.hpp"
37 #include "mm/memory.h"
38
39 #include "toolbox/hashtable.h"
40 #include "toolbox/logging.h"
41
42 #include "vm/global.h"
43 #include "vm/string.hpp"
44 #include "vm/vm.hpp"
45
46 #include "vmcore/classcache.h"
47 #include "vmcore/loader.h"
48 #include "vmcore/options.h"
49 #include "vmcore/statistics.h"
50 #include "vmcore/suck.h"
51
52
53 /* define cacaoh options ******************************************************/
54
55 enum {
56         OPT_HELP,
57         OPT_VERSION,
58         OPT_VERBOSE,
59         OPT_DIRECTORY,
60         OPT_CLASSPATH,
61         OPT_BOOTCLASSPATH,
62
63         DUMMY
64 };
65
66
67 opt_struct opts[] = {
68         { "help",             false, OPT_HELP          },
69         { "version",          false, OPT_VERSION       },
70         { "verbose",          false, OPT_VERBOSE       },
71         { "d",                true,  OPT_DIRECTORY     },
72         { "classpath",        true,  OPT_CLASSPATH     },
73         { "bootclasspath",    true,  OPT_BOOTCLASSPATH },
74         { NULL,               false, 0                 }
75 };
76
77
78 /* usage ***********************************************************************
79
80    Obviously prints usage information of cacaoh.
81
82 *******************************************************************************/
83
84 void usage(void)
85 {
86         printf("Usage: cacaoh [options] <classes>\n"
87                    "\n"
88                    "Options:\n"
89                    "    -help                 Print this message\n"
90                    "    -classpath <path>     \n"
91                    "    -bootclasspath <path> \n"
92                    "    -d <dir>              Output directory\n"
93                    "    -version              Print version information\n"
94                    "    -verbose              Enable verbose output\n");
95
96         /* exit with error code */
97
98         exit(1);
99 }
100
101
102 /* version *********************************************************************
103
104    Prints cacaoh version information.
105
106 *******************************************************************************/
107
108 static void version(void)
109 {
110         printf("cacaoh version "VERSION"\n");
111         printf("Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,\n");
112         printf("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,\n");
113         printf("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,\n");
114         printf("J. Wenninger, Institut f. Computersprachen - TU Wien\n\n");
115
116         printf("This program is free software; you can redistribute it and/or\n");
117         printf("modify it under the terms of the GNU General Public License as\n");
118         printf("published by the Free Software Foundation; either version 2, or (at\n");
119         printf("your option) any later version.\n\n");
120
121         printf("This program is distributed in the hope that it will be useful, but\n");
122         printf("WITHOUT ANY WARRANTY; without even the implied warranty of\n");
123         printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n");
124         printf("General Public License for more details.\n");
125
126         exit(0);
127 }
128
129
130 /* forward declarations *******************************************************/
131
132 static JavaVMInitArgs *cacaoh_options_prepare(int argc, char **argv);
133
134
135 /* main ************************************************************************
136
137    Main program.
138    
139 *******************************************************************************/
140
141 int main(int argc, char **argv)
142 {
143         JavaVMInitArgs *vm_args;
144         s4 i, j;
145         s4 opt;
146         classinfo *c;
147         char *opt_directory;
148
149         /********** internal (only used by main) *****************************/
150    
151         char *bootclasspath;
152         char *classpath;
153         char *cp;
154         s4    cplen;
155
156         if (argc < 2)
157                 usage();
158
159         /* set the bootclasspath */
160
161         cp = getenv("BOOTCLASSPATH");
162
163         if (cp) {
164                 bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
165                 strcpy(bootclasspath, cp);
166         }
167         else {
168                 cplen =
169 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
170                         strlen(CACAO_VM_ZIP) +
171                         strlen(":") +
172 #endif
173                         strlen(JAVA_RUNTIME_LIBRARY_CLASSES) +
174                         strlen("0");
175
176                 bootclasspath = MNEW(char, cplen);
177 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
178                 strcat(bootclasspath, CACAO_VM_ZIP);
179                 strcat(bootclasspath, ":");
180 #endif
181                 strcat(bootclasspath, JAVA_RUNTIME_LIBRARY_CLASSES);
182         }
183
184
185         /* set the classpath */
186
187         cp = getenv("CLASSPATH");
188
189         if (cp != NULL) {
190                 classpath = MNEW(char, strlen(cp) + strlen("0"));
191                 strcat(classpath, cp);
192         }
193         else {
194                 classpath = MNEW(char, strlen(".") + strlen("0"));
195                 strcpy(classpath, ".");
196         }
197
198
199         /* initialize options with default values */
200
201         opt_verbose = false;
202         opt_directory = NULL;
203
204
205         /* parse the options ******************************************************/
206
207         vm_args = cacaoh_options_prepare(argc, argv);
208
209         while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
210                 switch (opt) {
211                 case OPT_IGNORE:
212                         break;
213
214                 case OPT_HELP:
215                         usage();
216                         break;
217
218                 case OPT_CLASSPATH:
219                         /* forget old classpath and set the argument as new classpath */
220                         MFREE(classpath, char, strlen(classpath));
221
222                         classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
223                         strcpy(classpath, opt_arg);
224                         break;
225
226                 case OPT_BOOTCLASSPATH:
227                         /* Forget default bootclasspath and set the argument as
228                            new boot classpath. */
229                         MFREE(bootclasspath, char, strlen(bootclasspath));
230
231                         bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
232                         strcpy(bootclasspath, opt_arg);
233                         break;
234
235                 case OPT_DIRECTORY:
236                         opt_directory = MNEW(char, strlen(opt_arg) + strlen("0"));
237                         strcpy(opt_directory, opt_arg);
238                         break;
239
240                 case OPT_VERSION:
241                         version();
242                         break;
243
244                 case OPT_VERBOSE:
245                         opt_verbose = true;
246                         loadverbose = true;
247                         break;
248
249                 default:
250                         usage();
251                 }
252         }
253                         
254         /**************************** Program start **************************/
255
256         if (opt_verbose) {
257                 log_init(NULL);
258                 log_println("Java - header-generator started"); 
259         }
260
261         utf8_init();
262
263         /* initialize the classcache hashtable stuff: lock, hashtable
264            (must be done _after_ threads_preinit) */
265
266         if (!classcache_init())
267                 vm_abort("classcache_init failed\n");
268
269         /* initialize the loader with bootclasspath (must be done _after_
270            thread_preinit) */
271
272         if (!suck_init())
273                 vm_abort("suck_init failed\n");
274
275         suck_add(bootclasspath);
276
277         /* Also add the normal classpath, so the bootstrap class loader
278            can find the files. */
279
280         suck_add(classpath);
281
282         /* AFTER: classcache_init */
283
284         loader_preinit();
285         loader_init();
286
287
288         /* load Java classes ******************************************************/
289         
290         for (i = opt_index; i < vm_args->nOptions; i++) {
291                 cp = vm_args->options[i].optionString;
292
293                 /* convert classname */
294
295                 for (j = strlen(cp) - 1; j >= 0; j--) {
296                         switch (cp[j]) {
297                         case '.':
298                                 cp[j] = '/';
299                                 break;
300                         case '_':
301                                 cp[j] = '$';
302                                 break;
303                         }
304                 }
305         
306                 /* exceptions are catched with new_exception call */
307
308                 if (!(c = load_class_bootstrap(utf_new_char(cp))))
309                         vm_abort("java.lang.NoClassDefFoundError: %s\n", cp);
310
311                 if (!link_class(c))
312                         vm_abort("java.lang.LinkageError: %s\n", cp);
313
314                 headerfile_generate(c, opt_directory);
315         }
316
317         /************************ Release all resources **********************/
318
319         loader_close();
320
321         if (opt_verbose) {
322                 log_println("Java - header-generator stopped");
323 #if defined(ENABLE_STATISTICS)
324                 statistics_print_memory_usage();
325 #endif
326         }
327         
328         return 0;
329 }
330
331
332 /* cacaoh_options_prepare ******************************************************
333
334    Prepare the JavaVMInitArgs.
335
336 *******************************************************************************/
337
338 static JavaVMInitArgs *cacaoh_options_prepare(int argc, char **argv)
339 {
340         JavaVMInitArgs *vm_args;
341         s4              i;
342
343         vm_args = NEW(JavaVMInitArgs);
344
345         vm_args->nOptions = argc - 1;
346         vm_args->options  = MNEW(JavaVMOption, argc);
347
348         for (i = 1; i < argc; i++)
349                 vm_args->options[i - 1].optionString = argv[i];
350
351         return vm_args;
352 }
353
354
355 /*
356  * These are local overrides for various environment variables in Emacs.
357  * Please do not remove this and leave it at the end of the file, where
358  * Emacs will automagically detect them.
359  * ---------------------------------------------------------------------
360  * Local variables:
361  * mode: c
362  * indent-tabs-mode: t
363  * c-basic-offset: 4
364  * tab-width: 4
365  * End:
366  */