2002-04-02 David S. Miller <davem@redhat.com>
[official-gcc.git] / gcc / java / gjavah.c
blobb88ca8c118b7b52f6c6363583378ab98623acbaa
1 /* Program to write C++-suitable header files from a Java(TM) .class
2 file. This is similar to SUN's javah.
4 Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
21 Java and all Java-based marks are trademarks or registered trademarks
22 of Sun Microsystems, Inc. in the United States and other countries.
23 The Free Software Foundation is independent of Sun Microsystems, Inc. */
25 /* Written by Per Bothner <bothner@cygnus.com>, February 1996. */
27 #include "config.h"
28 #include "system.h"
29 #include <math.h>
31 #include "jcf.h"
32 #include "tree.h"
33 #include "javaop.h"
34 #include "java-tree.h"
35 #include "java-opcodes.h"
37 #include <getopt.h>
41 /* The output file. */
42 FILE *out = NULL;
44 /* Nonzero on failure. */
45 static int found_error = 0;
47 /* Nonzero if we're generating JNI output. */
48 static int flag_jni = 0;
50 /* When non zero, warn when source file is newer than matching class
51 file. */
52 int flag_newer = 1;
54 /* Directory to place resulting files in. Set by -d option. */
55 const char *output_directory = "";
57 /* Directory to place temporary file. Set by -td option. Currently unused. */
58 const char *temp_directory = "/tmp";
60 /* Number of friend functions we have to declare. */
61 static int friend_count;
63 /* A class can optionally have a `friend' function declared. If
64 non-NULL, this is that function. */
65 static char **friend_specs = NULL;
67 /* Number of lines we are prepending before the class. */
68 static int prepend_count;
70 /* We can prepend extra lines before the class's start. */
71 static char **prepend_specs = NULL;
73 /* Number of lines we are appending at the end of the class. */
74 static int add_count;
76 /* We can append extra lines just before the class's end. */
77 static char **add_specs = NULL;
79 /* Number of lines we are appending after the class. */
80 static int append_count;
82 /* We can append extra lines after the class's end. */
83 static char **append_specs = NULL;
85 int verbose = 0;
87 int stubs = 0;
89 struct JCF *current_jcf;
91 /* This holds access information for the last field we examined. They
92 let us generate "private:", "public:", and "protected:" properly.
93 If 0 then we haven't previously examined any field. */
94 static JCF_u2 last_access;
96 /* Pass this macro the flags for a class and for a method. It will
97 return true if the method should be considered `final'. */
98 #define METHOD_IS_FINAL(Class, Method) \
99 (((Class) & ACC_FINAL) || ((Method) & (ACC_FINAL | ACC_PRIVATE)))
101 /* Pass this macro the flags for a method. It will return true if the
102 method is native. */
103 #define METHOD_IS_NATIVE(Method) \
104 ((Method) & ACC_NATIVE)
106 /* We keep a linked list of all method names we have seen. This lets
107 us determine if a method name and a field name are in conflict. */
108 struct method_name
110 unsigned char *name;
111 int length;
112 unsigned char *signature;
113 int sig_length;
114 struct method_name *next;
117 /* List of method names we've seen. */
118 static struct method_name *method_name_list;
120 static void print_field_info PARAMS ((FILE*, JCF*, int, int, JCF_u2));
121 static void print_mangled_classname PARAMS ((FILE*, JCF*, const char*, int));
122 static int print_cxx_classname PARAMS ((FILE*, const char*, JCF*, int));
123 static void print_method_info PARAMS ((FILE*, JCF*, int, int, JCF_u2));
124 static void print_c_decl PARAMS ((FILE*, JCF*, int, int, int, const char *,
125 int));
126 static void print_stub_or_jni PARAMS ((FILE*, JCF*, int, int, int,
127 const char *, int));
128 static void print_full_cxx_name PARAMS ((FILE*, JCF*, int, int, int,
129 const char *, int));
130 static void decompile_method PARAMS ((FILE*, JCF*, int));
131 static void add_class_decl PARAMS ((FILE*, JCF*, JCF_u2));
133 static int java_float_finite PARAMS ((jfloat));
134 static int java_double_finite PARAMS ((jdouble));
135 static void print_name PARAMS ((FILE *, JCF *, int));
136 static void print_base_classname PARAMS ((FILE *, JCF *, int));
137 static int utf8_cmp PARAMS ((const unsigned char *, int, const char *));
138 static char *cxx_keyword_subst PARAMS ((const unsigned char *, int));
139 static void generate_access PARAMS ((FILE *, JCF_u2));
140 static int name_is_method_p PARAMS ((const unsigned char *, int));
141 static char *get_field_name PARAMS ((JCF *, int, JCF_u2));
142 static void print_field_name PARAMS ((FILE *, JCF *, int, JCF_u2));
143 static const unsigned char *super_class_name PARAMS ((JCF *, int *));
144 static void print_include PARAMS ((FILE *, const unsigned char *, int));
145 static const unsigned char *decode_signature_piece
146 PARAMS ((FILE *, const unsigned char *, const unsigned char *, int *));
147 static void print_class_decls PARAMS ((FILE *, JCF *, int));
148 static void usage PARAMS ((void)) ATTRIBUTE_NORETURN;
149 static void help PARAMS ((void)) ATTRIBUTE_NORETURN;
150 static void version PARAMS ((void)) ATTRIBUTE_NORETURN;
151 static int overloaded_jni_method_exists_p PARAMS ((const unsigned char *, int,
152 const char *, int));
153 static void jni_print_char PARAMS ((FILE *, int));
154 static void decompile_return_statement PARAMS ((FILE *, JCF *, int, int, int));
156 JCF_u2 current_field_name;
157 JCF_u2 current_field_value;
158 JCF_u2 current_field_signature;
159 JCF_u2 current_field_flags;
161 #define HANDLE_START_FIELD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
162 ( current_field_name = (NAME), current_field_signature = (SIGNATURE), \
163 current_field_flags = (ACCESS_FLAGS), current_field_value = 0)
165 /* We pass over fields twice. The first time we just note the types
166 of the fields and then the start of the methods. Then we go back
167 and parse the fields for real. This is ugly. */
168 static int field_pass;
169 /* Likewise we pass over methods twice. The first time we generate
170 class decl information; the second time we generate actual method
171 decls. */
172 static int method_pass;
174 #define HANDLE_END_FIELD() \
175 if (field_pass) \
177 if (out && ! stubs && ! flag_jni) \
178 print_field_info (out, jcf, current_field_name, \
179 current_field_signature, \
180 current_field_flags); \
182 else if (! stubs && ! flag_jni) \
183 add_class_decl (out, jcf, current_field_signature);
185 #define HANDLE_CONSTANTVALUE(VALUEINDEX) current_field_value = (VALUEINDEX)
187 static int method_declared = 0;
188 static int method_access = 0;
189 static int method_printed = 0;
190 static int method_synthetic = 0;
191 static int method_signature = 0;
193 #define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
195 method_synthetic = 0; \
196 method_printed = 0; \
197 decompiled = 0; \
198 method_signature = SIGNATURE; \
199 if (ATTRIBUTE_COUNT) \
200 method_synthetic = peek_attribute (jcf, ATTRIBUTE_COUNT, \
201 (const char *)"Synthetic", 9); \
202 /* If a synthetic methods have been declared, its attribute aren't \
203 worth reading (and triggering side-effects). We skip them an \
204 set ATTRIBUTE_COUNT to zero so that they'll be skipped in \
205 jcf_parse_one_method. */ \
206 if (method_synthetic) \
208 skip_attribute (jcf, ATTRIBUTE_COUNT); \
209 ATTRIBUTE_COUNT = 0; \
211 if (method_pass && !method_synthetic) \
213 if (out) \
214 print_method_info (out, jcf, NAME, SIGNATURE, \
215 ACCESS_FLAGS); \
217 else if (!method_synthetic) \
219 print_method_info (NULL, jcf, NAME, SIGNATURE, \
220 ACCESS_FLAGS); \
221 if (! stubs && ! flag_jni) \
222 add_class_decl (out, jcf, SIGNATURE); \
226 #define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
227 if (out && method_declared) decompile_method (out, jcf, CODE_LENGTH);
229 static int decompiled = 0;
230 #define HANDLE_END_METHOD() \
231 if (out && method_printed && !method_synthetic) \
232 fputs (decompiled || stubs ? "\n" : ";\n", out);
234 /* We're going to need {peek,skip}_attribute, enable their definition. */
235 #define NEED_PEEK_ATTRIBUTE
236 #define NEED_SKIP_ATTRIBUTE
238 #include "jcf-reader.c"
240 /* Some useful constants. */
241 #define F_NAN_MASK 0x7f800000
242 #if (1 == HOST_FLOAT_WORDS_BIG_ENDIAN) && ! defined (HOST_WORDS_BIG_ENDIAN)
243 #define D_NAN_MASK 0x000000007ff00000LL
244 #else
245 #define D_NAN_MASK 0x7ff0000000000000LL
246 #endif
248 /* Return 1 if F is not Inf or NaN. */
249 static int
250 java_float_finite (f)
251 jfloat f;
253 union Word u;
254 u.f = f;
256 /* We happen to know that F_NAN_MASK will match all NaN values, and
257 also positive and negative infinity. That's why we only need one
258 test here. See The Java Language Specification, section 20.9. */
259 return (u.i & F_NAN_MASK) != F_NAN_MASK;
262 /* Return 1 if D is not Inf or NaN. */
263 static int
264 java_double_finite (d)
265 jdouble d;
267 union DWord u;
268 u.d = d;
270 /* Now check for all NaNs. */
271 return (u.l & D_NAN_MASK) != D_NAN_MASK;
274 /* Print a character, appropriately mangled for JNI. */
276 static void
277 jni_print_char (stream, ch)
278 FILE *stream;
279 int ch;
281 if (! flag_jni)
282 jcf_print_char (stream, ch);
283 else if (ch == '(' || ch == ')')
285 /* Ignore. */
287 else if (ch == '_')
288 fputs ("_1", stream);
289 else if (ch == ';')
290 fputs ("_2", stream);
291 else if (ch == '[')
292 fputs ("_3", stream);
293 else if (ch == '/')
294 fputs ("_", stream);
295 else if (ISALNUM (ch))
296 fputc (ch, stream);
297 else
299 /* "Unicode" character. */
300 fprintf (stream, "_0%04x", ch);
304 /* Print a name from the class data. If the index does not point to a
305 string, an error results. */
307 static void
308 DEFUN(print_name, (stream, jcf, name_index),
309 FILE* stream AND JCF* jcf AND int name_index)
311 if (JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
313 fprintf (stream, "<not a UTF8 constant>");
314 found_error = 1;
316 else if (! flag_jni)
317 jcf_print_utf8 (stream, JPOOL_UTF_DATA (jcf, name_index),
318 JPOOL_UTF_LENGTH (jcf, name_index));
319 else
321 /* For JNI we must correctly quote each character. */
322 const unsigned char *str = JPOOL_UTF_DATA (jcf, name_index);
323 int length = JPOOL_UTF_LENGTH (jcf, name_index);
324 const unsigned char *limit = str + length;
325 while (str < limit)
327 int ch = UTF8_GET (str, limit);
328 if (ch < 0)
330 fprintf (stream, "\\<invalid>");
331 return;
333 jni_print_char (stream, ch);
338 /* Print base name of class. The base name is everything after the
339 final separator. */
341 static void
342 print_base_classname (stream, jcf, index)
343 FILE *stream;
344 JCF *jcf;
345 int index;
347 int name_index = JPOOL_USHORT1 (jcf, index);
348 int len;
349 const unsigned char *s, *p, *limit;
351 s = JPOOL_UTF_DATA (jcf, name_index);
352 len = JPOOL_UTF_LENGTH (jcf, name_index);
353 limit = s + len;
354 p = s;
355 while (s < limit)
357 int c = UTF8_GET (s, limit);
358 if (c == '/')
359 p = s;
362 while (p < limit)
364 int ch = UTF8_GET (p, limit);
365 if (ch == '/')
366 fputs ("::", stream);
367 else
368 jcf_print_char (stream, ch);
372 /* Return 0 if NAME is equal to STR, -1 if STR is "less" than NAME,
373 and 1 if STR is "greater" than NAME. */
375 static int
376 utf8_cmp (str, length, name)
377 const unsigned char *str;
378 int length;
379 const char *name;
381 const unsigned char *limit = str + length;
382 int i;
384 for (i = 0; name[i]; ++i)
386 int ch = UTF8_GET (str, limit);
387 if (ch != name[i])
388 return ch - name[i];
391 return str == limit ? 0 : 1;
394 /* This is a sorted list of all C++ keywords. */
396 static const char *const cxx_keywords[] =
398 "_Complex",
399 "__alignof",
400 "__alignof__",
401 "__asm",
402 "__asm__",
403 "__attribute",
404 "__attribute__",
405 "__builtin_va_arg",
406 "__complex",
407 "__complex__",
408 "__const",
409 "__const__",
410 "__extension__",
411 "__imag",
412 "__imag__",
413 "__inline",
414 "__inline__",
415 "__label__",
416 "__null",
417 "__real",
418 "__real__",
419 "__restrict",
420 "__restrict__",
421 "__signed",
422 "__signed__",
423 "__typeof",
424 "__typeof__",
425 "__volatile",
426 "__volatile__",
427 "and",
428 "and_eq",
429 "asm",
430 "auto",
431 "bitand",
432 "bitor",
433 "bool",
434 "break",
435 "case",
436 "catch",
437 "char",
438 "class",
439 "compl",
440 "const",
441 "const_cast",
442 "continue",
443 "default",
444 "delete",
445 "do",
446 "double",
447 "dynamic_cast",
448 "else",
449 "enum",
450 "explicit",
451 "export",
452 "extern",
453 "false",
454 "float",
455 "for",
456 "friend",
457 "goto",
458 "if",
459 "inline",
460 "int",
461 "long",
462 "mutable",
463 "namespace",
464 "new",
465 "not",
466 "not_eq",
467 "operator",
468 "or",
469 "or_eq",
470 "private",
471 "protected",
472 "public",
473 "register",
474 "reinterpret_cast",
475 "return",
476 "short",
477 "signed",
478 "sizeof",
479 "static",
480 "static_cast",
481 "struct",
482 "switch",
483 "template",
484 "this",
485 "throw",
486 "true",
487 "try",
488 "typedef",
489 "typeid",
490 "typename",
491 "typeof",
492 "union",
493 "unsigned",
494 "using",
495 "virtual",
496 "void",
497 "volatile",
498 "wchar_t",
499 "while",
500 "xor",
501 "xor_eq"
505 /* If NAME is the name of a C++ keyword, then return an override name.
506 This is a name that can be used in place of the keyword.
507 Otherwise, return NULL. The return value is malloc()d. */
509 static char *
510 cxx_keyword_subst (str, length)
511 const unsigned char *str;
512 int length;
514 int last = ARRAY_SIZE (cxx_keywords);
515 int first = 0;
516 int mid = (last + first) / 2;
517 int old = -1;
519 for (mid = (last + first) / 2;
520 mid != old;
521 old = mid, mid = (last + first) / 2)
523 int kwl = strlen (cxx_keywords[mid]);
524 int min_length = kwl > length ? length : kwl;
525 int r = utf8_cmp (str, min_length, cxx_keywords[mid]);
527 if (r == 0)
529 int i;
531 /* Skip all trailing `$'. */
532 for (i = min_length; i < length && str[i] == '$'; ++i)
534 /* We've only found a match if all the remaining characters
535 are `$'. */
536 if (i == length)
538 char *dup = xmalloc (2 + length - min_length + kwl);
539 strcpy (dup, cxx_keywords[mid]);
540 for (i = kwl; i < length + 1; ++i)
541 dup[i] = '$';
542 dup[i] = '\0';
543 return dup;
545 r = 1;
548 if (r < 0)
549 last = mid;
550 else
551 first = mid;
553 return NULL;
556 /* Generate an access control keyword based on FLAGS. */
558 static void
559 generate_access (stream, flags)
560 FILE *stream;
561 JCF_u2 flags;
563 if ((flags & ACC_VISIBILITY) == last_access)
564 return;
565 last_access = (flags & ACC_VISIBILITY);
567 switch (last_access)
569 case 0:
570 fputs ("public: // actually package-private\n", stream);
571 break;
572 case ACC_PUBLIC:
573 fputs ("public:\n", stream);
574 break;
575 case ACC_PRIVATE:
576 fputs ("private:\n", stream);
577 break;
578 case ACC_PROTECTED:
579 fputs ("public: // actually protected\n", stream);
580 break;
581 default:
582 found_error = 1;
583 fprintf (stream, "#error unrecognized visibility %d\n",
584 (flags & ACC_VISIBILITY));
585 break;
589 /* See if NAME is already the name of a method. */
590 static int
591 name_is_method_p (name, length)
592 const unsigned char *name;
593 int length;
595 struct method_name *p;
597 for (p = method_name_list; p != NULL; p = p->next)
599 if (p->length == length && ! memcmp (p->name, name, length))
600 return 1;
602 return 0;
605 /* If there is already a method named NAME, whose signature is not
606 SIGNATURE, then return true. Otherwise return false. */
607 static int
608 overloaded_jni_method_exists_p (name, length, signature, sig_length)
609 const unsigned char *name;
610 int length;
611 const char *signature;
612 int sig_length;
614 struct method_name *p;
616 for (p = method_name_list; p != NULL; p = p->next)
618 if (p->length == length
619 && ! memcmp (p->name, name, length)
620 && (p->sig_length != sig_length
621 || memcmp (p->signature, signature, sig_length)))
622 return 1;
624 return 0;
627 /* Get name of a field. This handles renamings due to C++ clash. */
628 static char *
629 get_field_name (jcf, name_index, flags)
630 JCF *jcf;
631 int name_index;
632 JCF_u2 flags;
634 unsigned char *name = JPOOL_UTF_DATA (jcf, name_index);
635 int length = JPOOL_UTF_LENGTH (jcf, name_index);
636 char *override;
638 if (name_is_method_p (name, length))
640 /* This field name matches a method. So override the name with
641 a dummy name. This is yucky, but it isn't clear what else to
642 do. FIXME: if the field is static, then we'll be in real
643 trouble. */
644 if ((flags & ACC_STATIC))
646 fprintf (stderr, "static field has same name as method\n");
647 found_error = 1;
648 return NULL;
651 override = xmalloc (length + 3);
652 memcpy (override, name, length);
653 strcpy (override + length, "__");
655 else
656 override = cxx_keyword_subst (name, length);
658 return override;
661 /* Print a field name. Convenience function for use with
662 get_field_name. */
663 static void
664 print_field_name (stream, jcf, name_index, flags)
665 FILE *stream;
666 JCF *jcf;
667 int name_index;
668 JCF_u2 flags;
670 char *override = get_field_name (jcf, name_index, flags);
672 if (override)
674 fputs (override, stream);
675 free (override);
677 else
678 jcf_print_utf8 (stream, JPOOL_UTF_DATA (jcf, name_index),
679 JPOOL_UTF_LENGTH (jcf, name_index));
682 static void
683 DEFUN(print_field_info, (stream, jcf, name_index, sig_index, flags),
684 FILE *stream AND JCF* jcf
685 AND int name_index AND int sig_index AND JCF_u2 flags)
687 char *override = NULL;
689 generate_access (stream, flags);
690 if (JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
692 fprintf (stream, "<not a UTF8 constant>");
693 found_error = 1;
694 return;
697 fputs (" ", out);
698 if ((flags & ACC_STATIC))
699 fputs ("static ", out);
701 if ((flags & ACC_FINAL))
703 if (current_field_value > 0)
705 char buffer[25];
706 int done = 1;
708 switch (JPOOL_TAG (jcf, current_field_value))
710 case CONSTANT_Integer:
712 jint num;
713 int most_negative = 0;
714 fputs ("const jint ", out);
715 print_field_name (out, jcf, name_index, 0);
716 fputs (" = ", out);
717 num = JPOOL_INT (jcf, current_field_value);
718 /* We single out the most negative number to print
719 specially. This avoids later warnings from g++. */
720 if (num == (jint) 0x80000000)
722 most_negative = 1;
723 ++num;
725 format_int (buffer, (jlong) num, 10);
726 fprintf (out, "%sL%s;\n", buffer, most_negative ? " - 1" : "");
728 break;
729 case CONSTANT_Long:
731 jlong num;
732 int most_negative = 0;
733 fputs ("const jlong ", out);
734 print_field_name (out, jcf, name_index, 0);
735 fputs (" = ", out);
736 num = JPOOL_LONG (jcf, current_field_value);
737 /* We single out the most negative number to print
738 specially.. This avoids later warnings from g++. */
739 if (num == (jlong) 0x8000000000000000LL)
741 most_negative = 1;
742 ++num;
744 format_int (buffer, num, 10);
745 fprintf (out, "%sLL%s;\n", buffer, most_negative ? " - 1" :"");
747 break;
748 case CONSTANT_Float:
750 jfloat fnum = JPOOL_FLOAT (jcf, current_field_value);
751 fputs ("const jfloat ", out);
752 print_field_name (out, jcf, name_index, 0);
753 if (! java_float_finite (fnum))
754 fputs (";\n", out);
755 else
756 fprintf (out, " = %.10g;\n", fnum);
758 break;
759 case CONSTANT_Double:
761 jdouble dnum = JPOOL_DOUBLE (jcf, current_field_value);
762 fputs ("const jdouble ", out);
763 print_field_name (out, jcf, name_index, 0);
764 if (! java_double_finite (dnum))
765 fputs (";\n", out);
766 else
767 fprintf (out, " = %.17g;\n", dnum);
769 break;
770 default:
771 /* We can't print this as a constant, but we can still
772 print something sensible. */
773 done = 0;
774 break;
777 if (done)
778 return;
782 override = get_field_name (jcf, name_index, flags);
783 print_c_decl (out, jcf, name_index, sig_index, 0, override, flags);
784 fputs (";\n", out);
786 if (override)
787 free (override);
791 static void
792 DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
793 FILE *stream AND JCF* jcf
794 AND int name_index AND int sig_index AND JCF_u2 flags)
796 const unsigned char *str;
797 int length, is_init = 0;
798 char *override = NULL;
800 method_declared = 0;
801 method_access = flags;
802 if (stream && JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
803 fprintf (stream, "<not a UTF8 constant>");
804 str = JPOOL_UTF_DATA (jcf, name_index);
805 length = JPOOL_UTF_LENGTH (jcf, name_index);
807 if (str[0] == '<')
809 /* Ignore the internally generated method <clinit>. However,
810 treat <init> as a constructor. */
811 if (! utf8_cmp (str, length, "<init>"))
812 is_init = 1;
813 else if (! METHOD_IS_FINAL (jcf->access_flags, flags)
814 && ! (flags & ACC_STATIC))
816 /* FIXME: i18n bug here. Order of prints should not be
817 fixed. */
818 fprintf (stderr, "ignored method `");
819 jcf_print_utf8 (stderr, str, length);
820 fprintf (stderr, "' marked virtual\n");
821 found_error = 1;
822 return;
824 else
825 return;
828 /* During the first method pass, build a list of method names. This will
829 be used to determine if field names conflict with method names. */
830 if (! stream)
832 struct method_name *nn;
834 nn = (struct method_name *) xmalloc (sizeof (struct method_name));
835 nn->name = (char *) xmalloc (length);
836 memcpy (nn->name, str, length);
837 nn->length = length;
838 nn->next = method_name_list;
839 nn->sig_length = JPOOL_UTF_LENGTH (jcf, sig_index);
840 nn->signature = (char *) xmalloc (nn->sig_length);
841 memcpy (nn->signature, JPOOL_UTF_DATA (jcf, sig_index),
842 nn->sig_length);
843 method_name_list = nn;
845 /* The rest of this function doesn't matter. */
846 return;
849 /* We don't worry about overrides in JNI mode. */
850 if (! flag_jni)
852 /* We can't generate a method whose name is a C++ reserved word.
853 We can't just ignore the function, because that will cause
854 incorrect code to be generated if the function is virtual
855 (not only for calls to this function for for other functions
856 after it in the vtbl). So we give it a dummy name instead. */
857 override = cxx_keyword_subst (str, length);
860 if (! stubs && ! flag_jni)
862 method_printed = 1;
864 generate_access (stream, flags);
866 fputs (" ", out);
867 if ((flags & ACC_STATIC))
868 fputs ("static ", out);
869 else if (! METHOD_IS_FINAL (jcf->access_flags, flags))
871 /* Don't print `virtual' if we have a constructor. */
872 if (! is_init)
873 fputs ("virtual ", out);
875 print_c_decl (out, jcf, name_index, sig_index, is_init, override, flags);
877 if ((flags & ACC_ABSTRACT))
878 fputs (" = 0", out);
879 else
880 method_declared = 1;
882 else
884 if (METHOD_IS_NATIVE (flags))
886 method_printed = 1;
887 print_stub_or_jni (out, jcf, name_index, sig_index,
888 is_init, override, flags);
892 if (override)
893 free (override);
896 /* A helper for the decompiler which prints a `return' statement where
897 the type is a reference type. If METHODTYPE and OBJECTTYPE are not
898 identical, we emit a cast. We do this because the C++ compiler
899 doesn't know that a reference can be cast to the type of an
900 interface it implements. METHODTYPE is the index of the method's
901 signature. NAMEINDEX is the index of the field name; -1 for
902 `this'. OBJECTTYPE is the index of the object's type. */
903 static void
904 decompile_return_statement (out, jcf, methodtype, nameindex, objecttype)
905 FILE *out;
906 JCF *jcf;
907 int methodtype, nameindex, objecttype;
909 int cast = 0;
910 int obj_name_len, method_name_len;
911 const unsigned char *obj_data, *method_data;
913 obj_name_len = JPOOL_UTF_LENGTH (jcf, objecttype);
914 obj_data = JPOOL_UTF_DATA (jcf, objecttype);
916 method_name_len = JPOOL_UTF_LENGTH (jcf, methodtype);
917 method_data = JPOOL_UTF_DATA (jcf, methodtype);
919 /* Skip forward to return type part of method. */
920 while (*method_data != ')')
922 ++method_data;
923 --method_name_len;
925 /* Skip past `)'. */
926 ++method_data;
927 --method_name_len;
929 /* If we see an `L', skip it and the trailing `;'. */
930 if (method_data[0] == 'L' && method_data[method_name_len - 1] == ';')
932 ++method_data;
933 method_name_len -= 2;
935 if (obj_data[0] == 'L' && obj_data[obj_name_len - 1] == ';')
937 ++obj_data;
938 obj_name_len -= 2;
941 /* FIXME: if METHODTYPE is a superclass of OBJECTTYPE then we don't
942 need a cast. Right now there is no way to determine if this is
943 the case. */
944 if (method_name_len != obj_name_len)
945 cast = 1;
946 else
948 int i;
949 for (i = 0; i < method_name_len; ++i)
951 if (method_data[i] != obj_data[i])
953 cast = 1;
954 break;
959 fputs (" { return ", out);
961 if (cast)
963 int array_depth = 0;
964 const unsigned char *limit;
966 fputs ("reinterpret_cast<", out);
968 while (*method_data == '[')
970 ++method_data;
971 ++array_depth;
972 --method_name_len;
973 fputs ("JArray<", out);
976 /* Leading space to avoid C++ digraphs. */
977 fputs (" ::", out);
979 /* If we see an `L', skip it and the trailing `;'. Only do this
980 if we've seen an array specification. If we don't have an
981 array then the `L' was stripped earlier. */
982 if (array_depth && method_data[0] == 'L'
983 && method_data[method_name_len - 1] == ';')
985 ++method_data;
986 method_name_len -= 2;
989 limit = method_data + method_name_len;
990 while (method_data < limit)
992 int ch = UTF8_GET (method_data, limit);
993 if (ch == '/')
994 fputs ("::", out);
995 else
996 jcf_print_char (out, ch);
998 fputs (" *", out);
1000 /* Close each array. */
1001 while (array_depth > 0)
1003 fputs ("> *", out);
1004 --array_depth;
1007 /* Close the cast. */
1008 fputs ("> (", out);
1011 if (nameindex == -1)
1012 fputs ("this", out);
1013 else
1014 print_field_name (out, jcf, nameindex, 0);
1016 if (cast)
1017 fputs (")", out);
1019 fputs ("; }", out);
1023 /* Try to decompile a method body. Right now we just try to handle a
1024 simple case that we can do. Expand as desired. */
1025 static void
1026 decompile_method (out, jcf, code_len)
1027 FILE *out;
1028 JCF *jcf;
1029 int code_len;
1031 const unsigned char *codes = jcf->read_ptr;
1032 int index;
1033 uint16 name_and_type, name;
1035 /* If the method is synchronized, don't touch it. */
1036 if ((method_access & ACC_SYNCHRONIZED))
1037 return;
1039 if (code_len == 5
1040 && codes[0] == OPCODE_aload_0
1041 && codes[1] == OPCODE_getfield
1042 && (codes[4] == OPCODE_areturn
1043 || codes[4] == OPCODE_dreturn
1044 || codes[4] == OPCODE_freturn
1045 || codes[4] == OPCODE_ireturn
1046 || codes[4] == OPCODE_lreturn))
1048 /* Found code like `return FIELD'. */
1049 index = (codes[2] << 8) | codes[3];
1050 /* FIXME: ensure that tag is CONSTANT_Fieldref. */
1051 name_and_type = JPOOL_USHORT2 (jcf, index);
1052 /* FIXME: ensure that tag is CONSTANT_NameAndType. */
1053 name = JPOOL_USHORT1 (jcf, name_and_type);
1054 if (codes[4] == OPCODE_areturn)
1055 decompile_return_statement (out, jcf, method_signature,
1056 name, JPOOL_USHORT2 (jcf, name_and_type));
1057 else
1059 fputs (" { return ", out);
1060 /* FIXME: flags. */
1061 print_field_name (out, jcf, name, 0);
1062 fputs ("; }", out);
1064 decompiled = 1;
1066 else if (code_len == 2
1067 && codes[0] == OPCODE_aload_0
1068 && codes[1] == OPCODE_areturn
1069 /* We're going to generate `return this'. This only makes
1070 sense for non-static methods. */
1071 && ! (method_access & ACC_STATIC))
1073 decompile_return_statement (out, jcf, method_signature, -1,
1074 JPOOL_USHORT1 (jcf, jcf->this_class));
1075 decompiled = 1;
1077 else if (code_len == 1 && codes[0] == OPCODE_return)
1079 /* Found plain `return'. */
1080 fputs (" { }", out);
1081 decompiled = 1;
1083 else if (code_len == 2
1084 && codes[0] == OPCODE_aconst_null
1085 && codes[1] == OPCODE_areturn)
1087 /* Found `return null'. We don't want to depend on NULL being
1088 defined. */
1089 fputs (" { return 0; }", out);
1090 decompiled = 1;
1094 /* Print one piece of a signature. Returns pointer to next parseable
1095 character on success, NULL on error. */
1096 static const unsigned char *
1097 decode_signature_piece (stream, signature, limit, need_space)
1098 FILE *stream;
1099 const unsigned char *signature, *limit;
1100 int *need_space;
1102 const char *ctype;
1103 int array_depth = 0;
1105 switch (signature[0])
1107 case '[':
1108 /* More spaghetti. */
1110 array_loop:
1111 for (signature++; (signature < limit
1112 && ISDIGIT (*signature)); signature++)
1114 switch (*signature)
1116 case 'B':
1117 ctype = "jbyteArray";
1118 break;
1119 case 'C':
1120 ctype = "jcharArray";
1121 break;
1122 case 'D':
1123 ctype = "jdoubleArray";
1124 break;
1125 case 'F':
1126 ctype = "jfloatArray";
1127 break;
1128 case 'I':
1129 ctype = "jintArray";
1130 break;
1131 case 'S':
1132 ctype = "jshortArray";
1133 break;
1134 case 'J':
1135 ctype = "jlongArray";
1136 break;
1137 case 'Z':
1138 ctype = "jbooleanArray";
1139 break;
1140 case '[':
1141 /* We have a nested array. */
1142 ++array_depth;
1143 if (! flag_jni)
1144 fputs ("JArray<", stream);
1145 goto array_loop;
1147 case 'L':
1148 /* We have to generate a reference to JArray here, so that
1149 our output matches what the compiler does. */
1150 ++signature;
1151 /* Space between `<' and `:' to avoid C++ digraphs. */
1152 if (! flag_jni)
1153 fputs ("JArray< ::", stream);
1154 while (signature < limit && *signature != ';')
1156 int ch = UTF8_GET (signature, limit);
1157 if (! flag_jni)
1159 if (ch == '/')
1160 fputs ("::", stream);
1161 else
1162 jcf_print_char (stream, ch);
1165 if (! flag_jni)
1166 fputs (" *> *", stream);
1167 *need_space = 0;
1168 ctype = NULL;
1169 break;
1170 default:
1171 /* Unparseable signature. */
1172 return NULL;
1175 /* If the previous iterations left us with something to print,
1176 print it. For JNI, we always print `jobjectArray' in the
1177 nested cases. */
1178 if (flag_jni && ctype == NULL)
1180 ctype = "jobjectArray";
1181 *need_space = 1;
1183 /* The `printit' case will advance SIGNATURE for us. If we
1184 don't go there, we must advance past the `;' ourselves. */
1185 if (ctype != NULL)
1186 goto printit;
1187 ++signature;
1188 break;
1190 case '(':
1191 case ')':
1192 /* This shouldn't happen. */
1193 return NULL;
1195 case 'B': ctype = "jbyte"; goto printit;
1196 case 'C': ctype = "jchar"; goto printit;
1197 case 'D': ctype = "jdouble"; goto printit;
1198 case 'F': ctype = "jfloat"; goto printit;
1199 case 'I': ctype = "jint"; goto printit;
1200 case 'J': ctype = "jlong"; goto printit;
1201 case 'S': ctype = "jshort"; goto printit;
1202 case 'Z': ctype = "jboolean"; goto printit;
1203 case 'V': ctype = "void"; goto printit;
1204 case 'L':
1205 if (flag_jni)
1207 /* We know about certain types and special-case their
1208 names.
1209 FIXME: something like java.lang.Exception should be
1210 printed as `jthrowable', because it is a subclass. This
1211 means that gcjh must read the entire hierarchy and
1212 comprehend it. */
1213 if (! strncmp (signature, "Ljava/lang/String;",
1214 sizeof ("Ljava/lang/String;") -1))
1215 ctype = "jstring";
1216 else if (! strncmp (signature, "Ljava/lang/Class;",
1217 sizeof ("Ljava/lang/Class;") - 1))
1218 ctype = "jclass";
1219 else if (! strncmp (signature, "Ljava/lang/Throwable;",
1220 sizeof ("Ljava/lang/Throwable;") - 1))
1221 ctype = "jthrowable";
1222 else if (! strncmp (signature, "Ljava/lang/ref/WeakReference;",
1223 sizeof ("Ljava/lang/ref/WeakReference;") - 1))
1224 ctype = "jweak";
1225 else
1226 ctype = "jobject";
1228 while (*signature && *signature != ';')
1229 ++signature;
1231 goto printit;
1233 /* Print a leading "::" so we look in the right namespace. */
1234 fputs ("::", stream);
1235 ++signature;
1236 while (*signature && *signature != ';')
1238 int ch = UTF8_GET (signature, limit);
1239 if (ch == '/')
1240 fputs ("::", stream);
1241 else
1242 jcf_print_char (stream, ch);
1244 fputs (" *", stream);
1245 if (*signature == ';')
1246 signature++;
1247 *need_space = 0;
1248 break;
1249 default:
1250 *need_space = 1;
1251 jni_print_char (stream, *signature++);
1252 break;
1253 printit:
1254 signature++;
1255 *need_space = 1;
1256 fputs (ctype, stream);
1257 break;
1260 if (! flag_jni)
1262 while (array_depth-- > 0)
1263 fputs ("> *", stream);
1266 return signature;
1269 static void
1270 DEFUN(print_c_decl, (stream, jcf, name_index, signature_index, is_init,
1271 name_override, flags),
1272 FILE* stream AND JCF* jcf
1273 AND int name_index AND int signature_index
1274 AND int is_init AND const char *name_override AND int flags)
1276 if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
1278 fprintf (stream, "<not a UTF8 constant>");
1279 found_error = 1;
1281 else
1283 int length = JPOOL_UTF_LENGTH (jcf, signature_index);
1284 const unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
1285 register const unsigned char *str = str0;
1286 const unsigned char *limit = str + length;
1287 int need_space = 0;
1288 int is_method = str[0] == '(';
1289 const unsigned char *next;
1291 /* If printing a method, skip to the return signature and print
1292 that first. However, there is no return value if this is a
1293 constructor. */
1294 if (is_method && ! is_init)
1296 while (str < limit)
1298 int ch = *str++;
1299 if (ch == ')')
1300 break;
1304 /* If printing a field or an ordinary method, then print the
1305 "return value" now. */
1306 if (! is_method || ! is_init)
1308 next = decode_signature_piece (stream, str, limit, &need_space);
1309 if (! next)
1311 fprintf (stderr, "unparseable signature: `%s'\n", str0);
1312 found_error = 1;
1313 return;
1317 /* Now print the name of the thing. */
1318 if (need_space)
1319 fputs (" ", stream);
1320 print_full_cxx_name (stream, jcf, name_index,
1321 signature_index, is_init, name_override,
1322 flags);
1326 /* Print the unqualified method name followed by the signature. */
1327 static void
1328 DEFUN(print_full_cxx_name, (stream, jcf, name_index, signature_index,
1329 is_init, name_override, flags),
1330 FILE* stream AND JCF* jcf
1331 AND int name_index AND int signature_index AND int is_init
1332 AND const char *name_override AND int flags)
1334 int length = JPOOL_UTF_LENGTH (jcf, signature_index);
1335 const unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
1336 register const unsigned char *str = str0;
1337 const unsigned char *limit = str + length;
1338 int need_space = 0;
1339 int is_method = str[0] == '(';
1340 const unsigned char *next;
1342 if (name_override)
1343 fputs (name_override, stream);
1344 else if (name_index)
1346 /* Declare constructors specially. */
1347 if (is_init)
1348 print_base_classname (stream, jcf, jcf->this_class);
1349 else
1350 print_name (stream, jcf, name_index);
1353 if (flag_jni)
1355 unsigned char *signature = JPOOL_UTF_DATA (jcf, signature_index);
1356 int sig_len = JPOOL_UTF_LENGTH (jcf, signature_index);
1357 if (overloaded_jni_method_exists_p (JPOOL_UTF_DATA (jcf, name_index),
1358 JPOOL_UTF_LENGTH (jcf, name_index),
1359 signature, sig_len))
1361 /* If this method is overloaded by another native method,
1362 then include the argument information in the mangled
1363 name. */
1364 unsigned char *limit = signature + sig_len;
1365 fputs ("__", stream);
1366 while (signature < limit)
1368 int ch = UTF8_GET (signature, limit);
1369 jni_print_char (stream, ch);
1370 if (ch == ')')
1372 /* Done. */
1373 break;
1379 if (is_method)
1381 /* Have a method or a constructor. Print signature pieces
1382 until done. */
1383 fputs (" (", stream);
1385 str = str0 + 1;
1387 /* In JNI mode, add extra arguments. */
1388 if (flag_jni)
1390 /* FIXME: it would be nice to know if we are printing a decl
1391 or a definition, and only print `env' for the latter. */
1392 fputs ("JNIEnv *env", stream);
1394 fputs ((flags & ACC_STATIC) ? ", jclass" : ", jobject", stream);
1396 if (*str != ')')
1397 fputs (", ", stream);
1400 while (str < limit && *str != ')')
1402 next = decode_signature_piece (stream, str, limit, &need_space);
1403 if (! next)
1405 fprintf (stderr, "unparseable signature: `%s'\n", str0);
1406 found_error = 1;
1407 return;
1410 if (next < limit && *next != ')')
1411 fputs (", ", stream);
1412 str = next;
1415 fputs (")", stream);
1419 /* This is a helper for print_stub_or_jni. */
1420 static void
1421 DEFUN (print_name_for_stub_or_jni, (stream, jcf, name_index, signature_index,
1422 is_init, name_override, flags),
1423 FILE *stream AND JCF *jcf
1424 AND int name_index AND int signature_index
1425 AND int is_init AND const char *name_override AND int flags)
1427 const char *const prefix = flag_jni ? "Java_" : "";
1428 print_cxx_classname (stream, prefix, jcf, jcf->this_class);
1429 fputs (flag_jni ? "_" : "::", stream);
1430 print_full_cxx_name (stream, jcf, name_index,
1431 signature_index, is_init, name_override,
1432 flags);
1435 static void
1436 DEFUN(print_stub_or_jni, (stream, jcf, name_index, signature_index, is_init,
1437 name_override, flags),
1438 FILE* stream AND JCF* jcf
1439 AND int name_index AND int signature_index
1440 AND int is_init AND const char *name_override AND int flags)
1442 if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
1444 fprintf (stream, "<not a UTF8 constant>");
1445 found_error = 1;
1447 else
1449 int length = JPOOL_UTF_LENGTH (jcf, signature_index);
1450 const unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
1451 register const unsigned char *str = str0;
1452 const unsigned char *limit = str + length;
1453 int need_space = 0;
1454 int is_method = str[0] == '(';
1455 const unsigned char *next;
1457 /* Don't print fields in the JNI case. */
1458 if (! is_method && flag_jni)
1459 return;
1461 if (flag_jni && ! stubs)
1462 fputs ("extern ", stream);
1464 /* If printing a method, skip to the return signature and print
1465 that first. However, there is no return value if this is a
1466 constructor. */
1467 if (is_method && ! is_init)
1469 while (str < limit)
1471 int ch = *str++;
1472 if (ch == ')')
1473 break;
1477 /* If printing a field or an ordinary method, then print the
1478 "return value" now. Note that a constructor can't be native,
1479 so we don't bother checking this in the JNI case. */
1480 if (! is_method || ! is_init)
1482 next = decode_signature_piece (stream, str, limit, &need_space);
1483 if (! next)
1485 fprintf (stderr, "unparseable signature: `%s'\n", str0);
1486 found_error = 1;
1487 return;
1491 /* When printing a JNI header we need to respect the space. In
1492 other cases we're just going to insert a newline anyway. */
1493 fputs (need_space && ! stubs ? " " : "\n", stream);
1495 /* Now print the name of the thing. */
1496 print_name_for_stub_or_jni (stream, jcf, name_index,
1497 signature_index, is_init, name_override,
1498 flags);
1500 /* Print the body. */
1501 if (stubs)
1503 if (flag_jni)
1504 fputs ("\n{\n (*env)->FatalError (\"", stream);
1505 else
1506 fputs ("\n{\n throw new ::java::lang::UnsupportedOperationException (JvNewStringLatin1 (\"", stream);
1507 print_name_for_stub_or_jni (stream, jcf, name_index,
1508 signature_index, is_init,
1509 name_override,
1510 flags);
1511 fprintf (stream, " not implemented\")%s;\n}\n\n",
1512 flag_jni ? "" : ")");
1517 static void
1518 DEFUN(print_mangled_classname, (stream, jcf, prefix, index),
1519 FILE *stream AND JCF *jcf AND const char *prefix AND int index)
1521 int name_index = JPOOL_USHORT1 (jcf, index);
1522 fputs (prefix, stream);
1523 jcf_print_utf8_replace (out,
1524 JPOOL_UTF_DATA (jcf, name_index),
1525 JPOOL_UTF_LENGTH (jcf, name_index),
1526 '/', '_');
1529 /* Print PREFIX, then a class name in C++ format. If the name refers
1530 to an array, ignore it and don't print PREFIX. Returns 1 if
1531 something was printed, 0 otherwise. */
1532 static int
1533 print_cxx_classname (stream, prefix, jcf, index)
1534 FILE *stream;
1535 const char *prefix;
1536 JCF *jcf;
1537 int index;
1539 int name_index = JPOOL_USHORT1 (jcf, index);
1540 int len, c;
1541 const unsigned char *s, *p, *limit;
1543 s = JPOOL_UTF_DATA (jcf, name_index);
1544 len = JPOOL_UTF_LENGTH (jcf, name_index);
1545 limit = s + len;
1547 /* Explicitly omit arrays here. */
1548 p = s;
1549 c = UTF8_GET (p, limit);
1550 if (c == '[')
1551 return 0;
1553 fputs (prefix, stream);
1555 /* Print a leading "::" so we look in the right namespace. */
1556 if (! flag_jni && ! stubs)
1557 fputs ("::", stream);
1559 while (s < limit)
1561 c = UTF8_GET (s, limit);
1562 if (c == '/')
1563 fputs (flag_jni ? "_" : "::", stream);
1564 else
1565 jni_print_char (stream, c);
1568 return 1;
1571 int written_class_count = 0;
1573 /* Return name of superclass. If LEN is not NULL, fill it with length
1574 of name. */
1575 static const unsigned char *
1576 super_class_name (derived_jcf, len)
1577 JCF *derived_jcf;
1578 int *len;
1580 int supername_index = JPOOL_USHORT1 (derived_jcf, derived_jcf->super_class);
1581 int supername_length = JPOOL_UTF_LENGTH (derived_jcf, supername_index);
1582 const unsigned char *supername =
1583 JPOOL_UTF_DATA (derived_jcf, supername_index);
1585 if (len)
1586 *len = supername_length;
1588 return supername;
1593 /* We keep track of all the `#include's we generate, so we can avoid
1594 duplicates. */
1595 struct include
1597 char *name;
1598 struct include *next;
1601 /* List of all includes. */
1602 static struct include *all_includes = NULL;
1604 /* Generate a #include. */
1605 static void
1606 print_include (out, utf8, len)
1607 FILE *out;
1608 const unsigned char *utf8;
1609 int len;
1611 struct include *incl;
1613 if (! out)
1614 return;
1616 if (len == -1)
1617 len = strlen (utf8);
1619 for (incl = all_includes; incl; incl = incl->next)
1621 /* We check the length because we might have a proper prefix. */
1622 if (len == (int) strlen (incl->name)
1623 && ! strncmp (incl->name, utf8, len))
1624 return;
1627 incl = (struct include *) xmalloc (sizeof (struct include));
1628 incl->name = xmalloc (len + 1);
1629 strncpy (incl->name, utf8, len);
1630 incl->name[len] = '\0';
1631 incl->next = all_includes;
1632 all_includes = incl;
1634 fputs ("#include <", out);
1635 jcf_print_utf8_replace (out, utf8, len,
1636 '/',
1637 flag_jni ? '_' : '/');
1638 fputs (".h>\n", out);
1643 /* This is used to represent part of a package or class name. */
1644 struct namelet
1646 /* The text of this part of the name. */
1647 char *name;
1648 /* True if this represents a class. */
1649 int is_class;
1650 /* Linked list of all classes and packages inside this one. */
1651 struct namelet *subnamelets;
1652 /* Pointer to next sibling. */
1653 struct namelet *next;
1656 static void add_namelet PARAMS ((const unsigned char *,
1657 const unsigned char *, struct namelet *));
1658 static void print_namelet PARAMS ((FILE *, struct namelet *, int));
1660 /* The special root namelet. */
1661 static struct namelet root =
1663 NULL,
1665 NULL,
1666 NULL
1669 /* This extracts the next name segment from the full UTF-8 encoded
1670 package or class name and links it into the tree. It does this
1671 recursively. */
1672 static void
1673 add_namelet (name, name_limit, parent)
1674 const unsigned char *name, *name_limit;
1675 struct namelet *parent;
1677 const unsigned char *p;
1678 struct namelet *n = NULL, *np;
1680 /* We want to skip the standard namespaces that we assume the
1681 runtime already knows about. We only do this at the top level,
1682 though, hence the check for `root'. */
1683 if (parent == &root)
1685 #define JAVALANG "java/lang/"
1686 #define JAVAIO "java/io/"
1687 #define JAVAUTIL "java/util/"
1688 if ((name_limit - name >= (int) sizeof (JAVALANG) - 1
1689 && ! strncmp (name, JAVALANG, sizeof (JAVALANG) - 1))
1690 || (name_limit - name >= (int) sizeof (JAVAUTIL) - 1
1691 && ! strncmp (name, JAVAUTIL, sizeof (JAVAUTIL) - 1))
1692 || (name_limit - name >= (int) sizeof (JAVAIO) - 1
1693 && ! strncmp (name, JAVAIO, sizeof (JAVAIO) - 1)))
1694 return;
1697 for (p = name; p < name_limit && *p != '/'; ++p)
1700 /* Search for this name beneath the PARENT node. */
1701 for (np = parent->subnamelets; np != NULL; np = np->next)
1703 /* We check the length because we might have a proper prefix. */
1704 if ((int) strlen (np->name) == p - name &&
1705 ! strncmp (name, np->name, p - name))
1707 n = np;
1708 break;
1712 if (n == NULL)
1714 n = (struct namelet *) xmalloc (sizeof (struct namelet));
1715 n->name = xmalloc (p - name + 1);
1716 strncpy (n->name, name, p - name);
1717 n->name[p - name] = '\0';
1718 n->is_class = (p == name_limit);
1719 n->subnamelets = NULL;
1720 n->next = parent->subnamelets;
1721 parent->subnamelets = n;
1724 /* We recurse if there is more text, and if the trailing piece does
1725 not represent an inner class. */
1726 if (p < name_limit)
1727 add_namelet (p + 1, name_limit, n);
1730 /* Print a single namelet. Destroys namelets while printing. */
1731 static void
1732 print_namelet (out, name, depth)
1733 FILE *out;
1734 struct namelet *name;
1735 int depth;
1737 int i, term = 0;
1738 struct namelet *c;
1740 if (name->name)
1742 for (i = 0; i < depth; ++i)
1743 fputc (' ', out);
1744 fprintf (out, "%s %s", name->is_class ? "class" : "namespace",
1745 name->name);
1746 if (name->is_class && name->subnamelets == NULL)
1747 fputs (";\n", out);
1748 else
1750 term = 1;
1751 fputs ("\n", out);
1752 for (i = 0; i < depth; ++i)
1753 fputc (' ', out);
1754 fputs ("{\n", out);
1758 c = name->subnamelets;
1759 while (c != NULL)
1761 struct namelet *next = c->next;
1762 print_namelet (out, c, depth + 2);
1763 c = next;
1765 name->subnamelets = NULL;
1767 if (name->name)
1769 if (term)
1771 for (i = 0; i < depth; ++i)
1772 fputc (' ', out);
1773 fputs ("}\n", out);
1774 /* Only print a `;' when printing a class. C++ is evil. */
1775 if (name->is_class)
1776 fputs (";", out);
1779 free (name->name);
1780 free (name);
1784 /* This is called to add some classes to the list of classes for which
1785 we need decls. The signature argument can be a function
1786 signature. */
1787 static void
1788 add_class_decl (out, jcf, signature)
1789 FILE *out;
1790 JCF *jcf;
1791 JCF_u2 signature;
1793 const unsigned char *s = JPOOL_UTF_DATA (jcf, signature);
1794 int len = JPOOL_UTF_LENGTH (jcf, signature);
1795 int i;
1797 for (i = 0; i < len; ++i)
1799 int start;
1801 /* If we see an array, then we include the array header. */
1802 if (s[i] == '[')
1804 print_include (out, "gcj/array", -1);
1805 continue;
1808 /* We're looking for `L<stuff>;' -- everything else is
1809 ignorable. */
1810 if (s[i] != 'L')
1811 continue;
1813 for (start = ++i; i < len && s[i] != ';'; ++i)
1816 add_namelet (&s[start], &s[i], &root);
1820 /* Print declarations for all classes required by this class. Any
1821 class or package in the `java' package is assumed to be handled
1822 statically in libjava; we don't generate declarations for these.
1823 This makes the generated headers a bit easier to read. */
1824 static void
1825 print_class_decls (out, jcf, self)
1826 FILE *out;
1827 JCF *jcf;
1828 int self;
1830 /* Make sure to always add the current class to the list of things
1831 that should be declared. */
1832 int name_index = JPOOL_USHORT1 (jcf, self);
1833 int len;
1834 const unsigned char *s;
1836 s = JPOOL_UTF_DATA (jcf, name_index);
1837 len = JPOOL_UTF_LENGTH (jcf, name_index);
1838 add_namelet (s, s + len, &root);
1840 if (root.subnamelets)
1842 fputs ("extern \"Java\"\n{\n", out);
1843 /* We use an initial offset of 0 because the root namelet
1844 doesn't cause anything to print. */
1845 print_namelet (out, &root, 0);
1846 fputs ("};\n\n", out);
1852 static void
1853 DEFUN(process_file, (jcf, out),
1854 JCF *jcf AND FILE *out)
1856 int code, i;
1857 uint32 field_start, method_end, method_start;
1859 current_jcf = jcf;
1861 last_access = -1;
1863 if (jcf_parse_preamble (jcf) != 0)
1865 fprintf (stderr, "Not a valid Java .class file.\n");
1866 found_error = 1;
1867 return;
1870 /* Parse and possibly print constant pool */
1871 code = jcf_parse_constant_pool (jcf);
1872 if (code != 0)
1874 fprintf (stderr, "error while parsing constant pool\n");
1875 found_error = 1;
1876 return;
1878 code = verify_constant_pool (jcf);
1879 if (code > 0)
1881 fprintf (stderr, "error in constant pool entry #%d\n", code);
1882 found_error = 1;
1883 return;
1886 jcf_parse_class (jcf);
1888 if (written_class_count++ == 0 && out)
1890 const char *cstart, *cstart2, *mode, *cend, *what, *jflag;
1891 if (flag_jni)
1893 cstart = "/*";
1894 cstart2 = " ";
1895 cend = " */";
1896 mode = "";
1897 what = "JNI";
1898 jflag = " -jni";
1900 else
1902 cstart = "//";
1903 cstart2 = "//";
1904 cend = "";
1905 mode = " -*- c++ -*-";
1906 what = "CNI";
1907 jflag = "";
1910 if (! stubs)
1911 fprintf (out, "%s DO NOT EDIT THIS FILE - it is machine generated%s%s\n\n",
1912 cstart, mode, cend);
1913 else
1915 fprintf (out, "%s This file was created by `gcjh -stubs%s'.%s\n\
1916 %s\n\
1917 %s This file is intended to give you a head start on implementing native\n\
1918 %s methods using %s.\n\
1919 %s Be aware: running `gcjh -stubs %s' once more for this class may\n\
1920 %s overwrite any edits you have made to this file.%s\n\n",
1921 cstart, jflag, mode,
1922 cstart2,
1923 cstart2,
1924 cstart2,
1925 what,
1926 cstart2,
1927 jflag,
1928 cstart2,
1929 cend);
1933 if (out)
1935 if (! stubs)
1937 print_mangled_classname (out, jcf, "#ifndef __", jcf->this_class);
1938 fprintf (out, "__\n");
1940 print_mangled_classname (out, jcf, "#define __", jcf->this_class);
1941 fprintf (out, "__\n\n");
1943 if (flag_jni)
1945 fprintf (out, "#include <jni.h>\n\n");
1946 fprintf (out, "#ifdef __cplusplus\n");
1947 fprintf (out, "extern \"C\"\n");
1948 fprintf (out, "{\n");
1949 fprintf (out, "#endif\n");
1951 else
1953 /* We do this to ensure that inline methods won't be
1954 `outlined' by g++. This works as long as method and
1955 fields are not added by the user. */
1956 fprintf (out, "#pragma interface\n");
1958 if (jcf->super_class)
1960 int super_length;
1961 const unsigned char *supername =
1962 super_class_name (jcf, &super_length);
1964 fputs ("\n", out);
1965 print_include (out, supername, super_length);
1969 else
1971 /* Strip off the ".class" portion of the name when printing
1972 the include file name. */
1973 char *name;
1974 int i, len = strlen (jcf->classname);
1975 if (len > 6 && ! strcmp (&jcf->classname[len - 6], ".class"))
1976 len -= 6;
1977 /* Turn the class name into a file name. */
1978 name = xmalloc (len + 1);
1979 for (i = 0; i < len; ++i)
1980 name[i] = jcf->classname[i] == '.' ? '/' : jcf->classname[i];
1981 name[i] = '\0';
1982 print_include (out, name, len);
1983 free (name);
1985 if (! flag_jni)
1987 print_include (out, "gcj/cni", -1);
1988 print_include (out, "java/lang/UnsupportedOperationException",
1989 -1);
1994 /* We want to parse the methods first. But we need to find where
1995 they start. So first we skip the fields, then parse the methods.
1996 Then we parse the fields and skip the methods. This is ugly, but
1997 not too bad since we need two full passes to get class decl
1998 information anyway. */
1999 field_pass = 0;
2000 field_start = JCF_TELL (jcf);
2001 jcf_parse_fields (jcf);
2003 method_start = JCF_TELL (jcf);
2004 method_pass = 0;
2005 jcf_parse_methods (jcf);
2007 if (out)
2008 fputs ("\n", out);
2010 if (out && ! flag_jni)
2012 if (! stubs)
2013 print_class_decls (out, jcf, jcf->this_class);
2015 for (i = 0; i < prepend_count; ++i)
2016 fprintf (out, "%s\n", prepend_specs[i]);
2017 if (prepend_count > 0)
2018 fputc ('\n', out);
2020 if (! stubs)
2022 if (! print_cxx_classname (out, "class ", jcf, jcf->this_class))
2024 fprintf (stderr, "class is of array type\n");
2025 found_error = 1;
2026 return;
2028 if (jcf->super_class)
2030 if (! print_cxx_classname (out, " : public ",
2031 jcf, jcf->super_class))
2033 fprintf (stderr, "base class is of array type\n");
2034 found_error = 1;
2035 return;
2039 fputs ("\n{\n", out);
2043 /* Now go back for second pass over methods and fields. */
2044 JCF_SEEK (jcf, method_start);
2045 method_pass = 1;
2046 jcf_parse_methods (jcf);
2047 method_end = JCF_TELL (jcf);
2049 field_pass = 1;
2050 JCF_SEEK (jcf, field_start);
2051 jcf_parse_fields (jcf);
2052 JCF_SEEK (jcf, method_end);
2054 jcf_parse_final_attributes (jcf);
2056 if (out && ! stubs)
2058 if (flag_jni)
2060 fprintf (out, "\n#ifdef __cplusplus\n");
2061 fprintf (out, "}\n");
2062 fprintf (out, "#endif\n");
2064 else
2066 /* Generate friend decl if we still must. */
2067 for (i = 0; i < friend_count; ++i)
2068 fprintf (out, " friend %s\n", friend_specs[i]);
2070 /* Generate extra declarations. */
2071 if (add_count > 0)
2072 fputc ('\n', out);
2073 for (i = 0; i < add_count; ++i)
2074 fprintf (out, " %s\n", add_specs[i]);
2076 /* Generate an entry for the class object. */
2077 generate_access (out, ACC_PUBLIC);
2078 fprintf (out, "\n static ::java::lang::Class class$;\n");
2080 fputs ("}", out);
2082 if (jcf->access_flags & ACC_INTERFACE)
2083 fputs (" __attribute__ ((java_interface))", out);
2085 fputs (";\n", out);
2087 if (append_count > 0)
2088 fputc ('\n', out);
2089 for (i = 0; i < append_count; ++i)
2090 fprintf (out, "%s\n", append_specs[i]);
2093 print_mangled_classname (out, jcf,
2094 "\n#endif /* __", jcf->this_class);
2095 fprintf (out, "__ */\n");
2101 /* This is used to mark options with no short value. */
2102 #define LONG_OPT(Num) ((Num) + 128)
2104 #define OPT_classpath LONG_OPT (0)
2105 #define OPT_CLASSPATH OPT_classpath
2106 #define OPT_bootclasspath LONG_OPT (1)
2107 #define OPT_HELP LONG_OPT (2)
2108 #define OPT_TEMP LONG_OPT (3)
2109 #define OPT_VERSION LONG_OPT (4)
2110 #define OPT_PREPEND LONG_OPT (5)
2111 #define OPT_FRIEND LONG_OPT (6)
2112 #define OPT_ADD LONG_OPT (7)
2113 #define OPT_APPEND LONG_OPT (8)
2114 #define OPT_M LONG_OPT (9)
2115 #define OPT_MM LONG_OPT (10)
2116 #define OPT_MG LONG_OPT (11)
2117 #define OPT_MD LONG_OPT (12)
2118 #define OPT_MMD LONG_OPT (13)
2120 static const struct option options[] =
2122 { "classpath", required_argument, NULL, OPT_classpath },
2123 { "bootclasspath", required_argument, NULL, OPT_bootclasspath },
2124 { "CLASSPATH", required_argument, NULL, OPT_CLASSPATH },
2125 { "help", no_argument, NULL, OPT_HELP },
2126 { "stubs", no_argument, &stubs, 1 },
2127 { "td", required_argument, NULL, OPT_TEMP },
2128 { "verbose", no_argument, NULL, 'v' },
2129 { "version", no_argument, NULL, OPT_VERSION },
2130 { "prepend", required_argument, NULL, OPT_PREPEND },
2131 { "friend", required_argument, NULL, OPT_FRIEND },
2132 { "add", required_argument, NULL, OPT_ADD },
2133 { "append", required_argument, NULL, OPT_APPEND },
2134 { "M", no_argument, NULL, OPT_M },
2135 { "MM", no_argument, NULL, OPT_MM },
2136 { "MG", no_argument, NULL, OPT_MG },
2137 { "MD", no_argument, NULL, OPT_MD },
2138 { "MMD", no_argument, NULL, OPT_MMD },
2139 { "jni", no_argument, &flag_jni, 1 },
2140 { NULL, no_argument, NULL, 0 }
2143 static void
2144 usage ()
2146 fprintf (stderr, "Try `gcjh --help' for more information.\n");
2147 exit (1);
2150 static void
2151 help ()
2153 printf ("Usage: gcjh [OPTION]... CLASS...\n\n");
2154 printf ("Generate C++ header files from .class files\n\n");
2155 printf (" -stubs Generate an implementation stub file\n");
2156 printf (" -jni Generate a JNI header or stub\n");
2157 printf ("\n");
2158 printf (" -add TEXT Insert TEXT into class body\n");
2159 printf (" -append TEXT Insert TEXT after class declaration\n");
2160 printf (" -friend TEXT Insert TEXT as `friend' declaration\n");
2161 printf (" -prepend TEXT Insert TEXT before start of class\n");
2162 printf ("\n");
2163 printf (" --classpath PATH Set path to find .class files\n");
2164 printf (" -IDIR Append directory to class path\n");
2165 printf (" --bootclasspath PATH Override built-in class path\n");
2166 printf (" -d DIRECTORY Set output directory name\n");
2167 printf (" -o FILE Set output file name\n");
2168 printf (" -td DIRECTORY Set temporary directory name\n");
2169 printf ("\n");
2170 printf (" --help Print this help, then exit\n");
2171 printf (" --version Print version number, then exit\n");
2172 printf (" -v, --verbose Print extra information while running\n");
2173 printf ("\n");
2174 printf (" -M Print all dependencies to stdout;\n");
2175 printf (" suppress ordinary output\n");
2176 printf (" -MM Print non-system dependencies to stdout;\n");
2177 printf (" suppress ordinary output\n");
2178 printf (" -MD Print all dependencies to stdout\n");
2179 printf (" -MMD Print non-system dependencies to stdout\n");
2180 /* We omit -MG until it is implemented. */
2181 printf ("\n");
2182 printf ("For bug reporting instructions, please see:\n");
2183 printf ("%s.\n", GCCBUGURL);
2184 exit (0);
2187 static void
2188 version ()
2190 printf ("gcjh (GCC) %s\n\n", version_string);
2191 printf ("Copyright (C) 2002 Free Software Foundation, Inc.\n");
2192 printf ("This is free software; see the source for copying conditions. There is NO\n");
2193 printf ("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
2194 exit (0);
2198 DEFUN(main, (argc, argv),
2199 int argc AND char** argv)
2201 JCF jcf;
2202 int argi;
2203 char *output_file = NULL;
2204 int emit_dependencies = 0, suppress_output = 0;
2205 int opt;
2207 if (argc <= 1)
2209 fprintf (stderr, "gcjh: no classes specified\n");
2210 usage ();
2213 jcf_path_init ();
2215 /* We use getopt_long_only to allow single `-' long options. For
2216 some of our options this is more natural. */
2217 while ((opt = getopt_long_only (argc, argv, "I:d:o:v", options, NULL)) != -1)
2219 switch (opt)
2221 case 0:
2222 /* Already handled. */
2223 break;
2225 case 'o':
2226 output_file = optarg;
2227 break;
2229 case 'd':
2230 output_directory = optarg;
2231 break;
2233 case 'I':
2234 jcf_path_include_arg (optarg);
2235 break;
2237 case 'v':
2238 verbose++;
2239 break;
2241 case OPT_classpath:
2242 jcf_path_classpath_arg (optarg);
2243 break;
2245 case OPT_bootclasspath:
2246 jcf_path_bootclasspath_arg (optarg);
2247 break;
2249 case OPT_HELP:
2250 help ();
2251 break;
2253 case OPT_TEMP:
2254 temp_directory = optarg;
2255 break;
2257 case OPT_VERSION:
2258 version ();
2259 break;
2261 case OPT_PREPEND:
2262 if (prepend_count == 0)
2263 prepend_specs = (char**) ALLOC (argc * sizeof (char*));
2264 prepend_specs[prepend_count++] = optarg;
2265 break;
2267 case OPT_FRIEND:
2268 if (friend_count == 0)
2269 friend_specs = (char**) ALLOC (argc * sizeof (char*));
2270 friend_specs[friend_count++] = optarg;
2271 break;
2273 case OPT_ADD:
2274 if (add_count == 0)
2275 add_specs = (char**) ALLOC (argc * sizeof (char*));
2276 add_specs[add_count++] = optarg;
2277 break;
2279 case OPT_APPEND:
2280 if (append_count == 0)
2281 append_specs = (char**) ALLOC (argc * sizeof (char*));
2282 append_specs[append_count++] = optarg;
2283 break;
2285 case OPT_M:
2286 emit_dependencies = 1;
2287 suppress_output = 1;
2288 jcf_dependency_init (1);
2289 break;
2291 case OPT_MM:
2292 emit_dependencies = 1;
2293 suppress_output = 1;
2294 jcf_dependency_init (0);
2295 break;
2297 case OPT_MG:
2298 fprintf (stderr, "gcjh: `-MG' option is unimplemented\n");
2299 exit (1);
2301 case OPT_MD:
2302 emit_dependencies = 1;
2303 jcf_dependency_init (1);
2304 break;
2306 case OPT_MMD:
2307 emit_dependencies = 1;
2308 jcf_dependency_init (0);
2309 break;
2311 default:
2312 usage ();
2313 break;
2317 if (optind == argc)
2319 fprintf (stderr, "gcjh: no classes specified\n");
2320 usage ();
2323 jcf_path_seal (verbose);
2325 if (output_file && emit_dependencies)
2327 fprintf (stderr, "gcjh: can't specify both -o and -MD\n");
2328 exit (1);
2331 for (argi = optind; argi < argc; argi++)
2333 char *classname = argv[argi];
2334 char *current_output_file;
2335 const char *classfile_name;
2337 if (verbose)
2338 fprintf (stderr, "Processing %s\n", classname);
2339 if (! output_file)
2340 jcf_dependency_reset ();
2341 classfile_name = find_class (classname, strlen (classname), &jcf, 0);
2342 if (classfile_name == NULL)
2344 fprintf (stderr, "%s: no such class\n", classname);
2345 exit (1);
2347 if (verbose)
2348 fprintf (stderr, "Found in %s\n", classfile_name);
2349 if (output_file)
2351 if (strcmp (output_file, "-") == 0)
2352 out = stdout;
2353 else if (out == NULL)
2355 out = fopen (output_file, "w");
2357 if (out == NULL)
2359 perror (output_file);
2360 exit (1);
2362 current_output_file = output_file;
2364 else
2366 int dir_len = strlen (output_directory);
2367 int i, classname_length = strlen (classname);
2368 current_output_file = (char*) ALLOC (dir_len + classname_length + 5);
2369 strcpy (current_output_file, output_directory);
2370 if (dir_len > 0 && output_directory[dir_len-1] != '/')
2371 current_output_file[dir_len++] = '/';
2372 for (i = 0; classname[i] != '\0'; i++)
2374 char ch = classname[i];
2375 if (ch == '.')
2376 ch = '/';
2377 if (flag_jni && ch == '/')
2378 ch = '_';
2379 current_output_file[dir_len++] = ch;
2381 if (emit_dependencies)
2383 if (suppress_output)
2385 jcf_dependency_set_dep_file ("-");
2386 out = NULL;
2388 else
2390 /* We use `.hd' and not `.d' to avoid clashes with
2391 dependency tracking from straight compilation. */
2392 strcpy (current_output_file + dir_len, ".hd");
2393 jcf_dependency_set_dep_file (current_output_file);
2396 strcpy (current_output_file + dir_len,
2397 stubs ? (flag_jni ? ".c" : ".cc") : ".h");
2398 jcf_dependency_set_target (current_output_file);
2399 if (! suppress_output)
2401 out = fopen (current_output_file, "w");
2402 if (out == NULL)
2404 perror (current_output_file);
2405 exit (1);
2409 process_file (&jcf, out);
2410 JCF_FINISH (&jcf);
2411 if (current_output_file != output_file)
2412 free (current_output_file);
2413 jcf_dependency_write ();
2416 if (out != NULL && out != stdout)
2417 fclose (out);
2419 return found_error;