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, 2003
5 Free Software Foundation, Inc.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.
24 Java and all Java-based marks are trademarks or registered trademarks
25 of Sun Microsystems, Inc. in the United States and other countries.
26 The Free Software Foundation is independent of Sun Microsystems, Inc. */
28 /* Written by Per Bothner <bothner@cygnus.com>, February 1996. */
32 #include "coretypes.h"
39 #include "java-tree.h"
40 #include "java-opcodes.h"
48 /* The output file. */
51 /* Nonzero on failure. */
52 static int found_error = 0;
54 /* Nonzero if we're generating JNI output. */
55 static int flag_jni = 0;
57 /* When nonzero, warn when source file is newer than matching class
61 /* Directory to place resulting files in. Set by -d option. */
62 const char *output_directory = "";
64 /* Directory to place temporary file. Set by -td option. Currently unused. */
65 const char *temp_directory = "/tmp";
67 /* Number of friend functions we have to declare. */
68 static int friend_count;
70 /* A class can optionally have a `friend' function declared. If
71 non-NULL, this is that function. */
72 static char **friend_specs = NULL;
74 /* Number of lines we are prepending before the class. */
75 static int prepend_count;
77 /* We can prepend extra lines before the class's start. */
78 static char **prepend_specs = NULL;
80 /* Number of lines we are appending at the end of the class. */
83 /* We can append extra lines just before the class's end. */
84 static char **add_specs = NULL;
86 /* Number of lines we are appending after the class. */
87 static int append_count;
89 /* We can append extra lines after the class's end. */
90 static char **append_specs = NULL;
96 struct JCF *current_jcf;
98 /* This holds access information for the last field we examined. They
99 let us generate "private:", "public:", and "protected:" properly.
100 If 0 then we haven't previously examined any field. */
101 static JCF_u2 last_access;
103 /* Pass this macro the flags for a class and for a method. It will
104 return true if the method should be considered `final'. */
105 #define METHOD_IS_FINAL(Class, Method) \
106 (((Class) & ACC_FINAL) || ((Method) & (ACC_FINAL | ACC_PRIVATE)))
108 /* Pass this macro the flags for a method. It will return true if the
110 #define METHOD_IS_NATIVE(Method) \
111 ((Method) & ACC_NATIVE)
113 /* We keep a linked list of all method names we have seen. This lets
114 us determine if a method name and a field name are in conflict. */
119 unsigned char *signature;
121 struct method_name *next;
124 /* List of method names we've seen. */
125 static struct method_name *method_name_list;
127 static void print_field_info (FILE*, JCF*, int, int, JCF_u2);
128 static void print_mangled_classname (FILE*, JCF*, const char*, int);
129 static int print_cxx_classname (FILE*, const char*, JCF*, int, int);
130 static void print_method_info (FILE*, JCF*, int, int, JCF_u2);
131 static void print_c_decl (FILE*, JCF*, int, int, int, const char *, int);
132 static void print_stub_or_jni (FILE*, JCF*, int, int, int, const char *, int);
133 static void print_full_cxx_name (FILE*, JCF*, int, int, int, const char *, int);
134 static void decompile_method (FILE*, JCF*, int);
135 static void add_class_decl (FILE*, JCF*, JCF_u2);
137 static int java_float_finite (jfloat);
138 static int java_double_finite (jdouble);
139 static void print_name (FILE *, JCF *, int);
140 static void print_base_classname (FILE *, JCF *, int);
141 static int utf8_cmp (const unsigned char *, int, const char *);
142 static char *cxx_keyword_subst (const unsigned char *, int);
143 static void generate_access (FILE *, JCF_u2);
144 static int name_is_method_p (const unsigned char *, int);
145 static char *get_field_name (JCF *, int, JCF_u2);
146 static void print_field_name (FILE *, JCF *, int, JCF_u2);
147 static const unsigned char *super_class_name (JCF *, int *);
148 static void print_include (FILE *, const unsigned char *, int);
149 static int gcjh_streq (const void *p1, const void *p2);
150 static int throwable_p (const unsigned char *signature);
151 static const unsigned char *
152 decode_signature_piece (FILE *, const unsigned char *,
153 const unsigned char *, int *);
154 static void print_class_decls (FILE *, JCF *, int);
155 static void usage (void) ATTRIBUTE_NORETURN;
156 static void help (void) ATTRIBUTE_NORETURN;
157 static void version (void) ATTRIBUTE_NORETURN;
158 static int overloaded_jni_method_exists_p (const unsigned char *, int,
160 static void jni_print_char (FILE *, int);
161 static void decompile_return_statement (FILE *, JCF *, int, int, int);
163 JCF_u2 current_field_name;
164 JCF_u2 current_field_value;
165 JCF_u2 current_field_signature;
166 JCF_u2 current_field_flags;
168 #define HANDLE_START_FIELD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
169 ( current_field_name = (NAME), current_field_signature = (SIGNATURE), \
170 current_field_flags = (ACCESS_FLAGS), current_field_value = 0)
172 /* We pass over fields twice. The first time we just note the types
173 of the fields and then the start of the methods. Then we go back
174 and parse the fields for real. This is ugly. */
175 static int field_pass;
176 /* Likewise we pass over methods twice. The first time we generate
177 class decl information; the second time we generate actual method
179 static int method_pass;
181 #define HANDLE_END_FIELD() \
184 if (out && ! stubs && ! flag_jni) \
185 print_field_info (out, jcf, current_field_name, \
186 current_field_signature, \
187 current_field_flags); \
189 else if (! stubs && ! flag_jni) \
190 add_class_decl (out, jcf, current_field_signature);
192 #define HANDLE_CONSTANTVALUE(VALUEINDEX) current_field_value = (VALUEINDEX)
194 static int method_declared = 0;
195 static int method_access = 0;
196 static int method_printed = 0;
197 static int method_synthetic = 0;
198 static int method_signature = 0;
200 /* Set to 1 while the very first data member of a class is being handled. */
201 static int is_first_data_member = 0;
203 #define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
205 method_synthetic = 0; \
206 method_printed = 0; \
208 method_signature = SIGNATURE; \
209 if (ATTRIBUTE_COUNT) \
210 method_synthetic = peek_attribute (jcf, ATTRIBUTE_COUNT, \
211 (const char *)"Synthetic", 9); \
212 /* If a synthetic methods have been declared, its attribute aren't \
213 worth reading (and triggering side-effects). We skip them an \
214 set ATTRIBUTE_COUNT to zero so that they'll be skipped in \
215 jcf_parse_one_method. */ \
216 if (method_synthetic) \
218 skip_attribute (jcf, ATTRIBUTE_COUNT); \
219 ATTRIBUTE_COUNT = 0; \
221 if (method_pass && !method_synthetic) \
224 print_method_info (out, jcf, NAME, SIGNATURE, \
227 else if (!method_synthetic) \
229 print_method_info (NULL, jcf, NAME, SIGNATURE, \
231 if (! stubs && ! flag_jni) \
232 add_class_decl (out, jcf, SIGNATURE); \
236 #define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
237 if (out && method_declared) decompile_method (out, jcf, CODE_LENGTH);
239 static int decompiled = 0;
240 #define HANDLE_END_METHOD() \
241 if (out && method_printed && !method_synthetic) \
242 fputs (decompiled || stubs ? "\n" : ";\n", out);
244 /* We're going to need {peek,skip}_attribute, enable their definition. */
245 #define NEED_PEEK_ATTRIBUTE
246 #define NEED_SKIP_ATTRIBUTE
248 #include "jcf-reader.c"
250 /* Some useful constants. */
251 #define F_NAN_MASK 0x7f800000
252 #if (1 == HOST_FLOAT_WORDS_BIG_ENDIAN) && ! defined (HOST_WORDS_BIG_ENDIAN)
253 #define D_NAN_MASK 0x000000007ff00000LL
255 #define D_NAN_MASK 0x7ff0000000000000LL
258 /* Return 1 if F is not Inf or NaN. */
260 java_float_finite (jfloat f)
265 /* We happen to know that F_NAN_MASK will match all NaN values, and
266 also positive and negative infinity. That's why we only need one
267 test here. See The Java Language Specification, section 20.9. */
268 return (u.i & F_NAN_MASK) != F_NAN_MASK;
271 /* Return 1 if D is not Inf or NaN. */
273 java_double_finite (jdouble d)
278 /* Now check for all NaNs. */
279 return (u.l & D_NAN_MASK) != D_NAN_MASK;
282 /* Print a character, appropriately mangled for JNI. */
285 jni_print_char (FILE *stream, int ch)
288 jcf_print_char (stream, ch);
289 else if (ch == '(' || ch == ')')
294 fputs ("_1", stream);
296 fputs ("_2", stream);
298 fputs ("_3", stream);
301 else if (ISALNUM (ch))
305 /* "Unicode" character. */
306 fprintf (stream, "_0%04x", ch);
310 /* Print a name from the class data. If the index does not point to a
311 string, an error results. */
314 print_name (FILE* stream, JCF* jcf, int name_index)
316 if (JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
318 fprintf (stream, "<not a UTF8 constant>");
322 jcf_print_utf8 (stream, JPOOL_UTF_DATA (jcf, name_index),
323 JPOOL_UTF_LENGTH (jcf, name_index));
326 /* For JNI we must correctly quote each character. */
327 const unsigned char *str = JPOOL_UTF_DATA (jcf, name_index);
328 int length = JPOOL_UTF_LENGTH (jcf, name_index);
329 const unsigned char *limit = str + length;
332 int ch = UTF8_GET (str, limit);
335 fprintf (stream, "\\<invalid>");
338 jni_print_char (stream, ch);
343 /* Print base name of class. The base name is everything after the
347 print_base_classname (FILE *stream, JCF *jcf, int index)
349 int name_index = JPOOL_USHORT1 (jcf, index);
351 const unsigned char *s, *p, *limit;
353 s = JPOOL_UTF_DATA (jcf, name_index);
354 len = JPOOL_UTF_LENGTH (jcf, name_index);
359 int c = UTF8_GET (s, limit);
366 int ch = UTF8_GET (p, limit);
368 fputs ("::", stream);
370 jcf_print_char (stream, ch);
374 /* Return 0 if NAME is equal to STR, -1 if STR is "less" than NAME,
375 and 1 if STR is "greater" than NAME. */
378 utf8_cmp (const unsigned char *str, int length, const char *name)
380 const unsigned char *limit = str + length;
383 for (i = 0; name[i]; ++i)
385 int ch = UTF8_GET (str, limit);
390 return str == limit ? 0 : 1;
393 /* This is a sorted list of all C++ keywords. */
395 static const char *const cxx_keywords[] =
504 /* If NAME is the name of a C++ keyword, then return an override name.
505 This is a name that can be used in place of the keyword.
506 Otherwise, return NULL. The return value is malloc()d. */
509 cxx_keyword_subst (const unsigned char *str, int length)
511 int last = ARRAY_SIZE (cxx_keywords);
513 int mid = (last + first) / 2;
516 for (mid = (last + first) / 2;
518 old = mid, mid = (last + first) / 2)
520 int kwl = strlen (cxx_keywords[mid]);
521 int min_length = kwl > length ? length : kwl;
522 int r = utf8_cmp (str, min_length, cxx_keywords[mid]);
528 /* Skip all trailing `$'. */
529 for (i = min_length; i < length && str[i] == '$'; ++i)
531 /* We've only found a match if all the remaining characters
535 char *dup = xmalloc (2 + length - min_length + kwl);
536 strcpy (dup, cxx_keywords[mid]);
537 for (i = kwl; i < length + 1; ++i)
553 /* Generate an access control keyword based on FLAGS. */
556 generate_access (FILE *stream, JCF_u2 flags)
558 if ((flags & ACC_VISIBILITY) == last_access)
560 last_access = (flags & ACC_VISIBILITY);
565 fputs ("public: // actually package-private\n", stream);
568 fputs ("public:\n", stream);
571 fputs ("private:\n", stream);
574 fputs ("public: // actually protected\n", stream);
578 fprintf (stream, "#error unrecognized visibility %d\n",
579 (flags & ACC_VISIBILITY));
584 /* See if NAME is already the name of a method. */
586 name_is_method_p (const unsigned char *name, int length)
588 struct method_name *p;
590 for (p = method_name_list; p != NULL; p = p->next)
592 if (p->length == length && ! memcmp (p->name, name, length))
598 /* If there is already a method named NAME, whose signature is not
599 SIGNATURE, then return true. Otherwise return false. */
601 overloaded_jni_method_exists_p (const unsigned char *name, int length,
602 const char *signature, int sig_length)
604 struct method_name *p;
606 for (p = method_name_list; p != NULL; p = p->next)
608 if (p->length == length
609 && ! memcmp (p->name, name, length)
610 && (p->sig_length != sig_length
611 || memcmp (p->signature, signature, sig_length)))
617 /* Get name of a field. This handles renamings due to C++ clash. */
619 get_field_name (JCF *jcf, int name_index, JCF_u2 flags)
621 unsigned char *name = JPOOL_UTF_DATA (jcf, name_index);
622 int length = JPOOL_UTF_LENGTH (jcf, name_index);
625 if (name_is_method_p (name, length))
627 /* This field name matches a method. So override the name with
628 a dummy name. This is yucky, but it isn't clear what else to
629 do. FIXME: if the field is static, then we'll be in real
631 if ((flags & ACC_STATIC))
633 fprintf (stderr, "static field has same name as method\n");
638 override = xmalloc (length + 3);
639 memcpy (override, name, length);
640 strcpy (override + length, "__");
643 override = cxx_keyword_subst (name, length);
648 /* Print a field name. Convenience function for use with
651 print_field_name (FILE *stream, JCF *jcf, int name_index, JCF_u2 flags)
653 char *override = get_field_name (jcf, name_index, flags);
657 fputs (override, stream);
661 jcf_print_utf8 (stream, JPOOL_UTF_DATA (jcf, name_index),
662 JPOOL_UTF_LENGTH (jcf, name_index));
666 print_field_info (FILE *stream, JCF* jcf, int name_index, int sig_index,
669 char *override = NULL;
671 generate_access (stream, flags);
672 if (JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
674 fprintf (stream, "<not a UTF8 constant>");
680 if ((flags & ACC_STATIC))
681 fputs ("static ", out);
683 if ((flags & ACC_FINAL))
685 if (current_field_value > 0)
690 switch (JPOOL_TAG (jcf, current_field_value))
692 case CONSTANT_Integer:
695 int most_negative = 0;
696 fputs ("const jint ", out);
697 print_field_name (out, jcf, name_index, 0);
699 num = JPOOL_INT (jcf, current_field_value);
700 /* We single out the most negative number to print
701 specially. This avoids later warnings from g++. */
702 if (num == (jint) 0x80000000)
707 format_int (buffer, (jlong) num, 10);
708 fprintf (out, "%sL%s;\n", buffer, most_negative ? " - 1" : "");
714 int most_negative = 0;
715 fputs ("const jlong ", out);
716 print_field_name (out, jcf, name_index, 0);
718 num = JPOOL_LONG (jcf, current_field_value);
719 /* We single out the most negative number to print
720 specially.. This avoids later warnings from g++. */
721 if (num == (jlong) 0x8000000000000000LL)
726 format_int (buffer, num, 10);
727 fprintf (out, "%sLL%s;\n", buffer, most_negative ? " - 1" :"");
732 jfloat fnum = JPOOL_FLOAT (jcf, current_field_value);
733 fputs ("const jfloat ", out);
734 print_field_name (out, jcf, name_index, 0);
735 if (! java_float_finite (fnum))
738 fprintf (out, " = %.10g;\n", fnum);
741 case CONSTANT_Double:
743 jdouble dnum = JPOOL_DOUBLE (jcf, current_field_value);
744 fputs ("const jdouble ", out);
745 print_field_name (out, jcf, name_index, 0);
746 if (! java_double_finite (dnum))
749 fprintf (out, " = %.17g;\n", dnum);
753 /* We can't print this as a constant, but we can still
754 print something sensible. */
764 override = get_field_name (jcf, name_index, flags);
765 print_c_decl (out, jcf, name_index, sig_index, 0, override, flags);
774 print_method_info (FILE *stream, JCF* jcf, int name_index, int sig_index,
777 const unsigned char *str;
778 int length, is_init = 0;
779 char *override = NULL;
782 method_access = flags;
783 if (stream && JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
784 fprintf (stream, "<not a UTF8 constant>");
785 str = JPOOL_UTF_DATA (jcf, name_index);
786 length = JPOOL_UTF_LENGTH (jcf, name_index);
790 /* Ignore the internally generated method <clinit>. However,
791 treat <init> as a constructor. */
792 if (! utf8_cmp (str, length, "<init>"))
794 else if (! METHOD_IS_FINAL (jcf->access_flags, flags)
795 && ! (flags & ACC_STATIC))
797 /* FIXME: i18n bug here. Order of prints should not be
799 fprintf (stderr, "ignored method `");
800 jcf_print_utf8 (stderr, str, length);
801 fprintf (stderr, "' marked virtual\n");
809 /* During the first method pass, build a list of method names. This will
810 be used to determine if field names conflict with method names. */
813 struct method_name *nn;
815 nn = xmalloc (sizeof (struct method_name));
816 nn->name = xmalloc (length);
817 memcpy (nn->name, str, length);
819 nn->next = method_name_list;
820 nn->sig_length = JPOOL_UTF_LENGTH (jcf, sig_index);
821 nn->signature = xmalloc (nn->sig_length);
822 memcpy (nn->signature, JPOOL_UTF_DATA (jcf, sig_index),
824 method_name_list = nn;
826 /* The rest of this function doesn't matter. */
830 /* We don't worry about overrides in JNI mode. */
833 /* We can't generate a method whose name is a C++ reserved word.
834 We can't just ignore the function, because that will cause
835 incorrect code to be generated if the function is virtual
836 (not only for calls to this function for for other functions
837 after it in the vtbl). So we give it a dummy name instead. */
838 override = cxx_keyword_subst (str, length);
841 if (! stubs && ! flag_jni)
845 generate_access (stream, flags);
848 if ((flags & ACC_STATIC))
849 fputs ("static ", out);
850 else if (! METHOD_IS_FINAL (jcf->access_flags, flags))
852 /* Don't print `virtual' if we have a constructor. */
854 fputs ("virtual ", out);
856 print_c_decl (out, jcf, name_index, sig_index, is_init, override, flags);
858 if ((flags & ACC_ABSTRACT))
865 if (METHOD_IS_NATIVE (flags))
868 print_stub_or_jni (out, jcf, name_index, sig_index,
869 is_init, override, flags);
877 /* A helper for the decompiler which prints a `return' statement where
878 the type is a reference type. If METHODTYPE and OBJECTTYPE are not
879 identical, we emit a cast. We do this because the C++ compiler
880 doesn't know that a reference can be cast to the type of an
881 interface it implements. METHODTYPE is the index of the method's
882 signature. NAMEINDEX is the index of the field name; -1 for
883 `this'. OBJECTTYPE is the index of the object's type. */
885 decompile_return_statement (FILE *out, JCF *jcf, int methodtype,
886 int nameindex, int objecttype)
889 int obj_name_len, method_name_len;
890 const unsigned char *obj_data, *method_data;
892 obj_name_len = JPOOL_UTF_LENGTH (jcf, objecttype);
893 obj_data = JPOOL_UTF_DATA (jcf, objecttype);
895 method_name_len = JPOOL_UTF_LENGTH (jcf, methodtype);
896 method_data = JPOOL_UTF_DATA (jcf, methodtype);
898 /* Skip forward to return type part of method. */
899 while (*method_data != ')')
908 /* If we see an `L', skip it and the trailing `;'. */
909 if (method_data[0] == 'L' && method_data[method_name_len - 1] == ';')
912 method_name_len -= 2;
914 if (obj_data[0] == 'L' && obj_data[obj_name_len - 1] == ';')
920 /* FIXME: if METHODTYPE is a superclass of OBJECTTYPE then we don't
921 need a cast. Right now there is no way to determine if this is
923 if (method_name_len != obj_name_len)
928 for (i = 0; i < method_name_len; ++i)
930 if (method_data[i] != obj_data[i])
938 fputs (" { return ", out);
943 const unsigned char *limit;
945 fputs ("reinterpret_cast<", out);
947 while (*method_data == '[')
952 fputs ("JArray<", out);
955 /* Leading space to avoid C++ digraphs. */
958 /* If we see an `L', skip it and the trailing `;'. Only do this
959 if we've seen an array specification. If we don't have an
960 array then the `L' was stripped earlier. */
961 if (array_depth && method_data[0] == 'L'
962 && method_data[method_name_len - 1] == ';')
965 method_name_len -= 2;
968 limit = method_data + method_name_len;
969 while (method_data < limit)
971 int ch = UTF8_GET (method_data, limit);
975 jcf_print_char (out, ch);
979 /* Close each array. */
980 while (array_depth > 0)
986 /* Close the cast. */
993 print_field_name (out, jcf, nameindex, 0);
1002 /* Try to decompile a method body. Right now we just try to handle a
1003 simple case that we can do. Expand as desired. */
1005 decompile_method (FILE *out, JCF *jcf, int code_len)
1007 const unsigned char *codes = jcf->read_ptr;
1009 uint16 name_and_type, name;
1011 /* If the method is synchronized, don't touch it. */
1012 if ((method_access & ACC_SYNCHRONIZED))
1016 && codes[0] == OPCODE_aload_0
1017 && codes[1] == OPCODE_getfield
1018 && (codes[4] == OPCODE_areturn
1019 || codes[4] == OPCODE_dreturn
1020 || codes[4] == OPCODE_freturn
1021 || codes[4] == OPCODE_ireturn
1022 || codes[4] == OPCODE_lreturn))
1024 /* Found code like `return FIELD'. */
1025 index = (codes[2] << 8) | codes[3];
1026 /* FIXME: ensure that tag is CONSTANT_Fieldref. */
1027 name_and_type = JPOOL_USHORT2 (jcf, index);
1028 /* FIXME: ensure that tag is CONSTANT_NameAndType. */
1029 name = JPOOL_USHORT1 (jcf, name_and_type);
1030 if (codes[4] == OPCODE_areturn)
1031 decompile_return_statement (out, jcf, method_signature,
1032 name, JPOOL_USHORT2 (jcf, name_and_type));
1035 fputs (" { return ", out);
1037 print_field_name (out, jcf, name, 0);
1042 else if (code_len == 2
1043 && codes[0] == OPCODE_aload_0
1044 && codes[1] == OPCODE_areturn
1045 /* We're going to generate `return this'. This only makes
1046 sense for non-static methods. */
1047 && ! (method_access & ACC_STATIC))
1049 decompile_return_statement (out, jcf, method_signature, -1,
1050 JPOOL_USHORT1 (jcf, jcf->this_class));
1053 else if (code_len == 1 && codes[0] == OPCODE_return)
1055 /* Found plain `return'. */
1056 fputs (" { }", out);
1059 else if (code_len == 2
1060 && codes[0] == OPCODE_aconst_null
1061 && codes[1] == OPCODE_areturn)
1063 /* Found `return null'. We don't want to depend on NULL being
1065 fputs (" { return 0; }", out);
1070 /* Like strcmp, but invert the return result for the hash table. This
1071 should probably be in hashtab.c to complement the existing string
1074 gcjh_streq (const void *p1, const void *p2)
1076 return ! strcmp ((char *) p1, (char *) p2);
1079 /* Return 1 if the initial part of CLNAME names a subclass of throwable,
1080 or 0 if not. CLNAME may be extracted from a signature, and can be
1081 terminated with either `;' or NULL. */
1083 throwable_p (const unsigned char *clname)
1086 unsigned char *current;
1090 /* We keep two hash tables of class names. In one we list all the
1091 classes which are subclasses of Throwable. In the other we will
1092 all other classes. We keep two tables to make the code a bit
1093 simpler; we don't have to have a structure mapping class name to
1094 a `throwable?' bit. */
1095 static htab_t throw_hash;
1096 static htab_t non_throw_hash;
1097 static int init_done = 0;
1104 /* Self-initializing. The cost of this really doesn't matter.
1105 We also don't care about freeing these, either. */
1106 throw_hash = htab_create (10, htab_hash_string, gcjh_streq,
1108 non_throw_hash = htab_create (10, htab_hash_string, gcjh_streq,
1111 /* Make sure the root classes show up in the tables. */
1112 str = xstrdup ("java.lang.Throwable");
1113 slot = htab_find_slot (throw_hash, str, INSERT);
1116 str = xstrdup ("java.lang.Object");
1117 slot = htab_find_slot (non_throw_hash, str, INSERT);
1123 for (length = 0; clname[length] != ';' && clname[length] != '\0'; ++length)
1125 current = ALLOC (length + 1);
1126 for (i = 0; i < length; ++i)
1127 current[i] = clname[i] == '/' ? '.' : clname[i];
1128 current[length] = '\0';
1130 /* We don't compute the hash slot here because the table might be
1131 modified by the recursion. In that case the slot could be
1133 if (htab_find (throw_hash, current))
1135 else if (htab_find (non_throw_hash, current))
1141 unsigned char *super, *tmp;
1142 int super_length = -1;
1143 const char *classfile_name = find_class (current, strlen (current),
1146 if (! classfile_name)
1148 fprintf (stderr, "couldn't find class %s\n", current);
1152 if (jcf_parse_preamble (&jcf) != 0
1153 || jcf_parse_constant_pool (&jcf) != 0
1154 || verify_constant_pool (&jcf) > 0)
1156 fprintf (stderr, "parse error while reading %s\n", classfile_name);
1160 jcf_parse_class (&jcf);
1162 tmp = (unsigned char *) super_class_name (&jcf, &super_length);
1163 super = ALLOC (super_length + 1);
1164 memcpy (super, tmp, super_length);
1165 super[super_length] = '\0';
1167 result = throwable_p (super);
1168 slot = htab_find_slot (result ? throw_hash : non_throw_hash,
1179 /* Print one piece of a signature. Returns pointer to next parseable
1180 character on success, NULL on error. */
1181 static const unsigned char *
1182 decode_signature_piece (FILE *stream, const unsigned char *signature,
1183 const unsigned char *limit, int *need_space)
1186 int array_depth = 0;
1188 switch (signature[0])
1191 /* More spaghetti. */
1194 for (signature++; (signature < limit
1195 && ISDIGIT (*signature)); signature++)
1200 ctype = "jbyteArray";
1203 ctype = "jcharArray";
1206 ctype = "jdoubleArray";
1209 ctype = "jfloatArray";
1212 ctype = "jintArray";
1215 ctype = "jshortArray";
1218 ctype = "jlongArray";
1221 ctype = "jbooleanArray";
1224 /* We have a nested array. */
1227 fputs ("JArray<", stream);
1231 /* We have to generate a reference to JArray here, so that
1232 our output matches what the compiler does. */
1234 /* Space between `<' and `:' to avoid C++ digraphs. */
1236 fputs ("JArray< ::", stream);
1237 while (signature < limit && *signature != ';')
1239 int ch = UTF8_GET (signature, limit);
1243 fputs ("::", stream);
1245 jcf_print_char (stream, ch);
1249 fputs (" *> *", stream);
1254 /* Unparseable signature. */
1258 /* If the previous iterations left us with something to print,
1259 print it. For JNI, we always print `jobjectArray' in the
1261 if (flag_jni && (ctype == NULL || array_depth > 0))
1263 ctype = "jobjectArray";
1266 /* The `printit' case will advance SIGNATURE for us. If we
1267 don't go there, we must advance past the `;' ourselves. */
1275 /* This shouldn't happen. */
1278 case 'B': ctype = "jbyte"; goto printit;
1279 case 'C': ctype = "jchar"; goto printit;
1280 case 'D': ctype = "jdouble"; goto printit;
1281 case 'F': ctype = "jfloat"; goto printit;
1282 case 'I': ctype = "jint"; goto printit;
1283 case 'J': ctype = "jlong"; goto printit;
1284 case 'S': ctype = "jshort"; goto printit;
1285 case 'Z': ctype = "jboolean"; goto printit;
1286 case 'V': ctype = "void"; goto printit;
1290 /* We know about certain types and special-case their names. */
1291 if (! strncmp (signature, "Ljava/lang/String;",
1292 sizeof ("Ljava/lang/String;") -1))
1294 else if (! strncmp (signature, "Ljava/lang/Class;",
1295 sizeof ("Ljava/lang/Class;") - 1))
1297 /* Skip leading 'L' for throwable_p call. */
1298 else if (throwable_p (signature + 1))
1299 ctype = "jthrowable";
1303 while (*signature && *signature != ';')
1308 /* Print a leading "::" so we look in the right namespace. */
1309 fputs ("::", stream);
1311 while (*signature && *signature != ';')
1313 int ch = UTF8_GET (signature, limit);
1315 fputs ("::", stream);
1317 jcf_print_char (stream, ch);
1319 fputs (" *", stream);
1320 if (*signature == ';')
1326 jni_print_char (stream, *signature++);
1331 fputs (ctype, stream);
1337 while (array_depth-- > 0)
1338 fputs ("> *", stream);
1345 print_c_decl (FILE* stream, JCF* jcf, int name_index, int signature_index,
1346 int is_init, const char *name_override, int flags)
1348 if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
1350 fprintf (stream, "<not a UTF8 constant>");
1355 int length = JPOOL_UTF_LENGTH (jcf, signature_index);
1356 const unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
1357 register const unsigned char *str = str0;
1358 const unsigned char *limit = str + length;
1360 int is_method = str[0] == '(';
1361 const unsigned char *next;
1363 /* If printing a method, skip to the return signature and print
1364 that first. However, there is no return value if this is a
1366 if (is_method && ! is_init)
1376 /* If printing a field or an ordinary method, then print the
1377 "return value" now. */
1378 if (! is_method || ! is_init)
1380 next = decode_signature_piece (stream, str, limit, &need_space);
1383 fprintf (stderr, "unparseable signature: `%s'\n", str0);
1389 /* Force the alignment of the first data member. This is
1390 because the "new" C++ ABI changed the alignemnt of non-POD
1391 classes. gcj, however, still uses the "old" alignment. */
1392 if (is_first_data_member && ! (flags & ACC_STATIC) && ! is_method)
1394 is_first_data_member = 0;
1395 print_cxx_classname (out, " __attribute__((aligned(__alignof__( ",
1396 jcf, jcf->super_class, 1);
1397 fputs (" )))) ", stream);
1400 /* Now print the name of the thing. */
1402 fputs (" ", stream);
1403 print_full_cxx_name (stream, jcf, name_index,
1404 signature_index, is_init, name_override,
1409 /* Print the unqualified method name followed by the signature. */
1411 print_full_cxx_name (FILE* stream, JCF* jcf, int name_index,
1412 int signature_index, int is_init,
1413 const char *name_override, int flags)
1415 int length = JPOOL_UTF_LENGTH (jcf, signature_index);
1416 const unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
1417 register const unsigned char *str = str0;
1418 const unsigned char *limit = str + length;
1420 int is_method = str[0] == '(';
1421 const unsigned char *next;
1424 fputs (name_override, stream);
1425 else if (name_index)
1427 /* Declare constructors specially. */
1429 print_base_classname (stream, jcf, jcf->this_class);
1431 print_name (stream, jcf, name_index);
1436 unsigned char *signature = JPOOL_UTF_DATA (jcf, signature_index);
1437 int sig_len = JPOOL_UTF_LENGTH (jcf, signature_index);
1438 if (overloaded_jni_method_exists_p (JPOOL_UTF_DATA (jcf, name_index),
1439 JPOOL_UTF_LENGTH (jcf, name_index),
1440 signature, sig_len))
1442 /* If this method is overloaded by another native method,
1443 then include the argument information in the mangled
1445 unsigned char *limit = signature + sig_len;
1446 fputs ("__", stream);
1447 while (signature < limit)
1449 int ch = UTF8_GET (signature, limit);
1450 jni_print_char (stream, ch);
1462 /* Have a method or a constructor. Print signature pieces
1464 fputs (" (", stream);
1468 /* In JNI mode, add extra arguments. */
1471 /* FIXME: it would be nice to know if we are printing a decl
1472 or a definition, and only print `env' for the latter. */
1473 fputs ("JNIEnv *env", stream);
1475 fputs ((flags & ACC_STATIC) ? ", jclass" : ", jobject", stream);
1478 fputs (", ", stream);
1481 while (str < limit && *str != ')')
1483 next = decode_signature_piece (stream, str, limit, &need_space);
1486 fprintf (stderr, "unparseable signature: `%s'\n", str0);
1491 if (next < limit && *next != ')')
1492 fputs (", ", stream);
1496 fputs (")", stream);
1500 /* This is a helper for print_stub_or_jni. */
1502 print_name_for_stub_or_jni (FILE *stream, JCF *jcf, int name_index,
1503 int signature_index, int is_init,
1504 const char *name_override, int flags)
1506 const char *const prefix = flag_jni ? "Java_" : "";
1507 print_cxx_classname (stream, prefix, jcf, jcf->this_class, 1);
1508 fputs (flag_jni ? "_" : "::", stream);
1509 print_full_cxx_name (stream, jcf, name_index,
1510 signature_index, is_init, name_override,
1515 print_stub_or_jni (FILE* stream, JCF* jcf, int name_index,
1516 int signature_index, int is_init,
1517 const char *name_override, int flags)
1519 if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
1521 fprintf (stream, "<not a UTF8 constant>");
1526 int length = JPOOL_UTF_LENGTH (jcf, signature_index);
1527 const unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
1528 register const unsigned char *str = str0;
1529 const unsigned char *limit = str + length;
1531 int is_method = str[0] == '(';
1532 const unsigned char *next;
1534 /* Don't print fields in the JNI case. */
1535 if (! is_method && flag_jni)
1538 if (flag_jni && ! stubs)
1539 fputs ("extern JNIEXPORT ", stream);
1541 /* If printing a method, skip to the return signature and print
1542 that first. However, there is no return value if this is a
1544 if (is_method && ! is_init)
1554 /* If printing a field or an ordinary method, then print the
1555 "return value" now. Note that a constructor can't be native,
1556 so we don't bother checking this in the JNI case. */
1557 if (! is_method || ! is_init)
1559 next = decode_signature_piece (stream, str, limit, &need_space);
1562 fprintf (stderr, "unparseable signature: `%s'\n", str0);
1568 /* When printing a JNI header we need to respect the space. In
1569 other cases we're just going to insert a newline anyway. */
1570 fputs (need_space && ! stubs ? " " : "\n", stream);
1572 if (flag_jni && ! stubs)
1573 fputs ("JNICALL ", stream);
1575 /* Now print the name of the thing. */
1576 print_name_for_stub_or_jni (stream, jcf, name_index,
1577 signature_index, is_init, name_override,
1580 /* Print the body. */
1584 fputs ("\n{\n (*env)->FatalError (\"", stream);
1586 fputs ("\n{\n throw new ::java::lang::UnsupportedOperationException (JvNewStringLatin1 (\"", stream);
1587 print_name_for_stub_or_jni (stream, jcf, name_index,
1588 signature_index, is_init,
1591 fprintf (stream, " not implemented\")%s;\n}\n\n",
1592 flag_jni ? "" : ")");
1598 print_mangled_classname (FILE *stream, JCF *jcf, const char *prefix, int index)
1600 int name_index = JPOOL_USHORT1 (jcf, index);
1601 fputs (prefix, stream);
1602 jcf_print_utf8_replace (out,
1603 JPOOL_UTF_DATA (jcf, name_index),
1604 JPOOL_UTF_LENGTH (jcf, name_index),
1608 /* Print PREFIX, then a class name in C++ format. If the name refers
1609 to an array, ignore it and don't print PREFIX. Returns 1 if
1610 something was printed, 0 otherwise. */
1612 print_cxx_classname (FILE *stream, const char *prefix,
1613 JCF *jcf, int index, int add_scope)
1615 int name_index = JPOOL_USHORT1 (jcf, index);
1617 const unsigned char *s, *p, *limit;
1619 s = JPOOL_UTF_DATA (jcf, name_index);
1620 len = JPOOL_UTF_LENGTH (jcf, name_index);
1623 /* Explicitly omit arrays here. */
1625 c = UTF8_GET (p, limit);
1629 fputs (prefix, stream);
1631 /* Print a leading "::" so we look in the right namespace. */
1632 if (! flag_jni && ! stubs && add_scope)
1633 fputs ("::", stream);
1637 c = UTF8_GET (s, limit);
1639 fputs (flag_jni ? "_" : "::", stream);
1641 jni_print_char (stream, c);
1647 int written_class_count = 0;
1649 /* Return name of superclass. If LEN is not NULL, fill it with length
1651 static const unsigned char *
1652 super_class_name (JCF *derived_jcf, int *len)
1654 int supername_index = JPOOL_USHORT1 (derived_jcf, derived_jcf->super_class);
1655 int supername_length = JPOOL_UTF_LENGTH (derived_jcf, supername_index);
1656 const unsigned char *supername =
1657 JPOOL_UTF_DATA (derived_jcf, supername_index);
1660 *len = supername_length;
1667 /* We keep track of all the `#include's we generate, so we can avoid
1672 struct include *next;
1675 /* List of all includes. */
1676 static struct include *all_includes = NULL;
1678 /* Generate a #include. */
1680 print_include (FILE *out, const unsigned char *utf8, int len)
1682 struct include *incl;
1688 len = strlen (utf8);
1690 for (incl = all_includes; incl; incl = incl->next)
1692 /* We check the length because we might have a proper prefix. */
1693 if (len == (int) strlen (incl->name)
1694 && ! strncmp (incl->name, utf8, len))
1698 incl = xmalloc (sizeof (struct include));
1699 incl->name = xmalloc (len + 1);
1700 strncpy (incl->name, utf8, len);
1701 incl->name[len] = '\0';
1702 incl->next = all_includes;
1703 all_includes = incl;
1705 fputs ("#include <", out);
1706 jcf_print_utf8_replace (out, utf8, len,
1708 flag_jni ? '_' : '/');
1709 fputs (".h>\n", out);
1714 /* This is used to represent part of a package or class name. */
1717 /* The text of this part of the name. */
1719 /* True if this represents a class. */
1721 /* Linked list of all classes and packages inside this one. */
1722 struct namelet *subnamelets;
1723 /* Pointer to next sibling. */
1724 struct namelet *next;
1727 static void add_namelet (const unsigned char *, const unsigned char *,
1729 static void print_namelet (FILE *, struct namelet *, int);
1731 /* The special root namelet. */
1732 static struct namelet root =
1740 /* This extracts the next name segment from the full UTF-8 encoded
1741 package or class name and links it into the tree. It does this
1744 add_namelet (const unsigned char *name, const unsigned char *name_limit,
1745 struct namelet *parent)
1747 const unsigned char *p;
1748 struct namelet *n = NULL, *np;
1750 /* We want to skip the standard namespaces that we assume the
1751 runtime already knows about. We only do this at the top level,
1752 though, hence the check for `root'. */
1753 if (parent == &root)
1755 #define JAVALANG "java/lang/"
1756 #define JAVAIO "java/io/"
1757 #define JAVAUTIL "java/util/"
1758 if ((name_limit - name >= (int) sizeof (JAVALANG) - 1
1759 && ! strncmp (name, JAVALANG, sizeof (JAVALANG) - 1))
1760 || (name_limit - name >= (int) sizeof (JAVAUTIL) - 1
1761 && ! strncmp (name, JAVAUTIL, sizeof (JAVAUTIL) - 1))
1762 || (name_limit - name >= (int) sizeof (JAVAIO) - 1
1763 && ! strncmp (name, JAVAIO, sizeof (JAVAIO) - 1)))
1767 for (p = name; p < name_limit && *p != '/'; ++p)
1770 /* Search for this name beneath the PARENT node. */
1771 for (np = parent->subnamelets; np != NULL; np = np->next)
1773 /* We check the length because we might have a proper prefix. */
1774 if ((int) strlen (np->name) == p - name &&
1775 ! strncmp (name, np->name, p - name))
1784 n = xmalloc (sizeof (struct namelet));
1785 n->name = xmalloc (p - name + 1);
1786 strncpy (n->name, name, p - name);
1787 n->name[p - name] = '\0';
1788 n->is_class = (p == name_limit);
1789 n->subnamelets = NULL;
1790 n->next = parent->subnamelets;
1791 parent->subnamelets = n;
1794 /* We recurse if there is more text, and if the trailing piece does
1795 not represent an inner class. */
1797 add_namelet (p + 1, name_limit, n);
1800 /* Print a single namelet. Destroys namelets while printing. */
1802 print_namelet (FILE *out, struct namelet *name, int depth)
1809 for (i = 0; i < depth; ++i)
1811 fprintf (out, "%s %s", name->is_class ? "class" : "namespace",
1813 if (name->is_class && name->subnamelets == NULL)
1819 for (i = 0; i < depth; ++i)
1825 c = name->subnamelets;
1828 struct namelet *next = c->next;
1829 print_namelet (out, c, depth + 2);
1832 name->subnamelets = NULL;
1838 for (i = 0; i < depth; ++i)
1841 /* Only print a `;' when printing a class. C++ is evil. */
1851 /* This is called to add some classes to the list of classes for which
1852 we need decls. The signature argument can be a function
1855 add_class_decl (FILE *out, JCF *jcf, JCF_u2 signature)
1857 const unsigned char *s = JPOOL_UTF_DATA (jcf, signature);
1858 int len = JPOOL_UTF_LENGTH (jcf, signature);
1861 for (i = 0; i < len; ++i)
1865 /* If we see an array, then we include the array header. */
1868 print_include (out, "gcj/array", -1);
1872 /* We're looking for `L<stuff>;' -- everything else is
1877 for (start = ++i; i < len && s[i] != ';'; ++i)
1880 add_namelet (&s[start], &s[i], &root);
1884 /* Print declarations for all classes required by this class. Any
1885 class or package in the `java' package is assumed to be handled
1886 statically in libjava; we don't generate declarations for these.
1887 This makes the generated headers a bit easier to read. */
1889 print_class_decls (FILE *out, JCF *jcf, int self)
1891 /* Make sure to always add the current class to the list of things
1892 that should be declared. */
1893 int name_index = JPOOL_USHORT1 (jcf, self);
1895 const unsigned char *s;
1897 s = JPOOL_UTF_DATA (jcf, name_index);
1898 len = JPOOL_UTF_LENGTH (jcf, name_index);
1899 add_namelet (s, s + len, &root);
1901 if (root.subnamelets)
1903 fputs ("extern \"Java\"\n{\n", out);
1904 /* We use an initial offset of 0 because the root namelet
1905 doesn't cause anything to print. */
1906 print_namelet (out, &root, 0);
1907 fputs ("}\n\n", out);
1914 process_file (JCF *jcf, FILE *out)
1917 uint32 field_start, method_end, method_start;
1923 if (jcf_parse_preamble (jcf) != 0)
1925 fprintf (stderr, "Not a valid Java .class file.\n");
1930 /* Parse and possibly print constant pool */
1931 code = jcf_parse_constant_pool (jcf);
1934 fprintf (stderr, "error while parsing constant pool\n");
1938 code = verify_constant_pool (jcf);
1941 fprintf (stderr, "error in constant pool entry #%d\n", code);
1946 jcf_parse_class (jcf);
1948 if (written_class_count++ == 0 && out)
1950 const char *cstart, *cstart2, *mode, *cend, *what, *jflag;
1965 mode = " -*- c++ -*-";
1971 fprintf (out, "%s DO NOT EDIT THIS FILE - it is machine generated%s%s\n\n",
1972 cstart, mode, cend);
1975 fprintf (out, "%s This file was created by `gcjh -stubs%s'.%s\n\
1977 %s This file is intended to give you a head start on implementing native\n\
1978 %s methods using %s.\n\
1979 %s Be aware: running `gcjh -stubs %s' once more for this class may\n\
1980 %s overwrite any edits you have made to this file.%s\n\n",
1981 cstart, jflag, mode,
1997 print_mangled_classname (out, jcf, "#ifndef __", jcf->this_class);
1998 fprintf (out, "__\n");
2000 print_mangled_classname (out, jcf, "#define __", jcf->this_class);
2001 fprintf (out, "__\n\n");
2005 fprintf (out, "#include <jni.h>\n\n");
2006 fprintf (out, "#ifdef __cplusplus\n");
2007 fprintf (out, "extern \"C\"\n");
2008 fprintf (out, "{\n");
2009 fprintf (out, "#endif\n");
2013 /* We do this to ensure that inline methods won't be
2014 `outlined' by g++. This works as long as method and
2015 fields are not added by the user. */
2016 fprintf (out, "#pragma interface\n");
2018 if (jcf->super_class)
2021 const unsigned char *supername =
2022 super_class_name (jcf, &super_length);
2025 print_include (out, supername, super_length);
2031 /* Strip off the ".class" portion of the name when printing
2032 the include file name. */
2034 int i, len = strlen (jcf->classname);
2035 if (len > 6 && ! strcmp (&jcf->classname[len - 6], ".class"))
2037 /* Turn the class name into a file name. */
2038 name = xmalloc (len + 1);
2039 for (i = 0; i < len; ++i)
2040 name[i] = jcf->classname[i] == '.' ? '/' : jcf->classname[i];
2042 print_include (out, name, len);
2047 print_include (out, "gcj/cni", -1);
2048 print_include (out, "java/lang/UnsupportedOperationException",
2054 /* We want to parse the methods first. But we need to find where
2055 they start. So first we skip the fields, then parse the methods.
2056 Then we parse the fields and skip the methods. This is ugly, but
2057 not too bad since we need two full passes to get class decl
2058 information anyway. */
2060 field_start = JCF_TELL (jcf);
2061 jcf_parse_fields (jcf);
2063 method_start = JCF_TELL (jcf);
2065 jcf_parse_methods (jcf);
2070 if (out && ! flag_jni)
2073 print_class_decls (out, jcf, jcf->this_class);
2075 for (i = 0; i < prepend_count; ++i)
2076 fprintf (out, "%s\n", prepend_specs[i]);
2077 if (prepend_count > 0)
2082 if (! print_cxx_classname (out, "class ", jcf,
2083 jcf->this_class, 0))
2085 fprintf (stderr, "class is of array type\n");
2089 if (jcf->super_class)
2091 if (! print_cxx_classname (out, " : public ",
2092 jcf, jcf->super_class, 1))
2094 fprintf (stderr, "base class is of array type\n");
2100 fputs ("\n{\n", out);
2104 /* Now go back for second pass over methods and fields. */
2105 is_first_data_member = 1;
2107 JCF_SEEK (jcf, method_start);
2109 jcf_parse_methods (jcf);
2110 method_end = JCF_TELL (jcf);
2113 JCF_SEEK (jcf, field_start);
2114 jcf_parse_fields (jcf);
2115 JCF_SEEK (jcf, method_end);
2117 jcf_parse_final_attributes (jcf);
2123 fprintf (out, "\n#ifdef __cplusplus\n");
2124 fprintf (out, "}\n");
2125 fprintf (out, "#endif\n");
2129 /* Generate friend decl if we still must. */
2130 for (i = 0; i < friend_count; ++i)
2131 fprintf (out, " friend %s\n", friend_specs[i]);
2133 /* Generate extra declarations. */
2136 for (i = 0; i < add_count; ++i)
2137 fprintf (out, " %s\n", add_specs[i]);
2139 /* Generate an entry for the class object. */
2140 generate_access (out, ACC_PUBLIC);
2141 fprintf (out, "\n static ::java::lang::Class class$;\n");
2145 if (jcf->access_flags & ACC_INTERFACE)
2146 fputs (" __attribute__ ((java_interface))", out);
2150 if (append_count > 0)
2152 for (i = 0; i < append_count; ++i)
2153 fprintf (out, "%s\n", append_specs[i]);
2156 print_mangled_classname (out, jcf,
2157 "\n#endif /* __", jcf->this_class);
2158 fprintf (out, "__ */\n");
2164 /* This is used to mark options with no short value. */
2165 #define LONG_OPT(Num) ((Num) + 128)
2167 #define OPT_classpath LONG_OPT (0)
2168 #define OPT_CLASSPATH OPT_classpath
2169 #define OPT_bootclasspath LONG_OPT (1)
2170 #define OPT_extdirs LONG_OPT (2)
2171 #define OPT_HELP LONG_OPT (3)
2172 #define OPT_TEMP LONG_OPT (4)
2173 #define OPT_VERSION LONG_OPT (5)
2174 #define OPT_PREPEND LONG_OPT (6)
2175 #define OPT_FRIEND LONG_OPT (7)
2176 #define OPT_ADD LONG_OPT (8)
2177 #define OPT_APPEND LONG_OPT (9)
2178 #define OPT_M LONG_OPT (10)
2179 #define OPT_MM LONG_OPT (11)
2180 #define OPT_MG LONG_OPT (12)
2181 #define OPT_MD LONG_OPT (13)
2182 #define OPT_MMD LONG_OPT (14)
2184 static const struct option options[] =
2186 { "classpath", required_argument, NULL, OPT_classpath },
2187 { "bootclasspath", required_argument, NULL, OPT_bootclasspath },
2188 { "extdirs", required_argument, NULL, OPT_extdirs },
2189 { "CLASSPATH", required_argument, NULL, OPT_CLASSPATH },
2190 { "help", no_argument, NULL, OPT_HELP },
2191 { "stubs", no_argument, &stubs, 1 },
2192 { "td", required_argument, NULL, OPT_TEMP },
2193 { "verbose", no_argument, NULL, 'v' },
2194 { "version", no_argument, NULL, OPT_VERSION },
2195 { "prepend", required_argument, NULL, OPT_PREPEND },
2196 { "friend", required_argument, NULL, OPT_FRIEND },
2197 { "add", required_argument, NULL, OPT_ADD },
2198 { "append", required_argument, NULL, OPT_APPEND },
2199 { "M", no_argument, NULL, OPT_M },
2200 { "MM", no_argument, NULL, OPT_MM },
2201 { "MG", no_argument, NULL, OPT_MG },
2202 { "MD", no_argument, NULL, OPT_MD },
2203 { "MMD", no_argument, NULL, OPT_MMD },
2204 { "jni", no_argument, &flag_jni, 1 },
2205 { NULL, no_argument, NULL, 0 }
2211 fprintf (stderr, "Try `gcjh --help' for more information.\n");
2218 printf ("Usage: gcjh [OPTION]... CLASS...\n\n");
2219 printf ("Generate C++ header files from .class files\n\n");
2220 printf (" -stubs Generate an implementation stub file\n");
2221 printf (" -jni Generate a JNI header or stub\n");
2223 printf (" -add TEXT Insert TEXT into class body\n");
2224 printf (" -append TEXT Insert TEXT after class declaration\n");
2225 printf (" -friend TEXT Insert TEXT as `friend' declaration\n");
2226 printf (" -prepend TEXT Insert TEXT before start of class\n");
2228 printf (" --classpath PATH Set path to find .class files\n");
2229 printf (" -IDIR Append directory to class path\n");
2230 printf (" --bootclasspath PATH Override built-in class path\n");
2231 printf (" --extdirs PATH Set extensions directory path\n");
2232 printf (" -d DIRECTORY Set output directory name\n");
2233 printf (" -o FILE Set output file name\n");
2234 printf (" -td DIRECTORY Set temporary directory name\n");
2236 printf (" --help Print this help, then exit\n");
2237 printf (" --version Print version number, then exit\n");
2238 printf (" -v, --verbose Print extra information while running\n");
2240 printf (" -M Print all dependencies to stdout;\n");
2241 printf (" suppress ordinary output\n");
2242 printf (" -MM Print non-system dependencies to stdout;\n");
2243 printf (" suppress ordinary output\n");
2244 printf (" -MD Print all dependencies to stdout\n");
2245 printf (" -MMD Print non-system dependencies to stdout\n");
2246 /* We omit -MG until it is implemented. */
2248 printf ("For bug reporting instructions, please see:\n");
2249 printf ("%s.\n", bug_report_url);
2256 printf ("gcjh (GCC) %s\n\n", version_string);
2257 printf ("Copyright (C) 2002 Free Software Foundation, Inc.\n");
2258 printf ("This is free software; see the source for copying conditions. There is NO\n");
2259 printf ("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
2264 main (int argc, char** argv)
2268 char *output_file = NULL;
2269 int emit_dependencies = 0, suppress_output = 0;
2274 fprintf (stderr, "gcjh: no classes specified\n");
2280 /* We use getopt_long_only to allow single `-' long options. For
2281 some of our options this is more natural. */
2282 while ((opt = getopt_long_only (argc, argv, "I:d:o:v", options, NULL)) != -1)
2287 /* Already handled. */
2291 output_file = optarg;
2295 output_directory = optarg;
2299 jcf_path_include_arg (optarg);
2307 jcf_path_classpath_arg (optarg);
2310 case OPT_bootclasspath:
2311 jcf_path_bootclasspath_arg (optarg);
2315 jcf_path_extdirs_arg (optarg);
2323 temp_directory = optarg;
2331 if (prepend_count == 0)
2332 prepend_specs = ALLOC (argc * sizeof (char*));
2333 prepend_specs[prepend_count++] = optarg;
2337 if (friend_count == 0)
2338 friend_specs = ALLOC (argc * sizeof (char*));
2339 friend_specs[friend_count++] = optarg;
2344 add_specs = ALLOC (argc * sizeof (char*));
2345 add_specs[add_count++] = optarg;
2349 if (append_count == 0)
2350 append_specs = ALLOC (argc * sizeof (char*));
2351 append_specs[append_count++] = optarg;
2355 emit_dependencies = 1;
2356 suppress_output = 1;
2357 jcf_dependency_init (1);
2361 emit_dependencies = 1;
2362 suppress_output = 1;
2363 jcf_dependency_init (0);
2367 fprintf (stderr, "gcjh: `-MG' option is unimplemented\n");
2371 emit_dependencies = 1;
2372 jcf_dependency_init (1);
2376 emit_dependencies = 1;
2377 jcf_dependency_init (0);
2388 fprintf (stderr, "gcjh: no classes specified\n");
2392 jcf_path_seal (verbose);
2394 if (output_file && emit_dependencies)
2396 fprintf (stderr, "gcjh: can't specify both -o and -MD\n");
2400 for (argi = optind; argi < argc; argi++)
2402 char *classname = argv[argi];
2403 char *current_output_file;
2404 const char *classfile_name;
2407 fprintf (stderr, "Processing %s\n", classname);
2409 jcf_dependency_reset ();
2410 classfile_name = find_class (classname, strlen (classname), &jcf, 0);
2411 if (classfile_name == NULL)
2413 fprintf (stderr, "%s: no such class\n", classname);
2417 fprintf (stderr, "Found in %s\n", classfile_name);
2420 if (strcmp (output_file, "-") == 0)
2422 else if (out == NULL)
2424 out = fopen (output_file, "w");
2428 perror (output_file);
2431 current_output_file = output_file;
2435 int dir_len = strlen (output_directory);
2436 int i, classname_length = strlen (classname);
2437 current_output_file = ALLOC (dir_len + classname_length + 5);
2438 strcpy (current_output_file, output_directory);
2439 if (dir_len > 0 && output_directory[dir_len-1] != '/')
2440 current_output_file[dir_len++] = '/';
2441 for (i = 0; classname[i] != '\0'; i++)
2443 char ch = classname[i];
2446 if (flag_jni && ch == '/')
2448 current_output_file[dir_len++] = ch;
2450 if (emit_dependencies)
2452 if (suppress_output)
2454 jcf_dependency_set_dep_file ("-");
2459 /* We use `.hd' and not `.d' to avoid clashes with
2460 dependency tracking from straight compilation. */
2461 strcpy (current_output_file + dir_len, ".hd");
2462 jcf_dependency_set_dep_file (current_output_file);
2465 strcpy (current_output_file + dir_len,
2466 stubs ? (flag_jni ? ".c" : ".cc") : ".h");
2467 jcf_dependency_set_target (current_output_file);
2468 if (! suppress_output)
2470 out = fopen (current_output_file, "w");
2473 perror (current_output_file);
2478 process_file (&jcf, out);
2480 if (current_output_file != output_file)
2481 free (current_output_file);
2482 jcf_dependency_write ();
2485 if (out != NULL && out != stdout)