mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-21 15:39:58 +08:00
gjavah.c (options): Added `jni' entry.
* gjavah.c (options): Added `jni' entry. (help): Document -jni. (flag_jni): New global. (process_file): Handle JNI output. Don't print text from -prepend, -add, etc, when generating stubs. Only remove `.class' suffix if it actually exists. (main): Create a `.c' file when run with `--jni --stubs'. Create correct output file name with `--jni'. (print_include): Mangle header name differently in JNI case. (HANDLE_METHOD): In JNI mode, call print_method_info to generate method list. (print_method_info): Handle JNI case. Put signature info into method name. Handle case when STREAM is NULL. (print_name_for_stub_or_jni): New function. (print_stub_or_jni): Renamed from `print_stub'. Handle JNI. (print_cxx_classname): Handle JNI. (print_full_cxx_name): Likewise. (decode_signature_piece): Likewise. (overloaded_jni_method_exists_p): New function. (struct method_name): Added `signature' and `sig_length' fields. (HANDLE_END_FIELD): Do nothing in JNI mode. From-SVN: r31767
This commit is contained in:
parent
cf8e13bbc8
commit
de3807234a
@ -1,3 +1,27 @@
|
||||
2000-02-02 Tom Tromey <tromey@cygnus.com>
|
||||
|
||||
* gjavah.c (options): Added `jni' entry.
|
||||
(help): Document -jni.
|
||||
(flag_jni): New global.
|
||||
(process_file): Handle JNI output. Don't print text from
|
||||
-prepend, -add, etc, when generating stubs. Only remove `.class'
|
||||
suffix if it actually exists.
|
||||
(main): Create a `.c' file when run with `--jni --stubs'. Create
|
||||
correct output file name with `--jni'.
|
||||
(print_include): Mangle header name differently in JNI case.
|
||||
(HANDLE_METHOD): In JNI mode, call print_method_info to generate
|
||||
method list.
|
||||
(print_method_info): Handle JNI case. Put signature info into
|
||||
method name. Handle case when STREAM is NULL.
|
||||
(print_name_for_stub_or_jni): New function.
|
||||
(print_stub_or_jni): Renamed from `print_stub'. Handle JNI.
|
||||
(print_cxx_classname): Handle JNI.
|
||||
(print_full_cxx_name): Likewise.
|
||||
(decode_signature_piece): Likewise.
|
||||
(overloaded_jni_method_exists_p): New function.
|
||||
(struct method_name): Added `signature' and `sig_length' fields.
|
||||
(HANDLE_END_FIELD): Do nothing in JNI mode.
|
||||
|
||||
2000-02-02 Tom Tromey <tromey@cygnus.com>
|
||||
|
||||
* jv-scan.c: Include version.c, <getopt.h>.
|
||||
|
@ -45,6 +45,9 @@ FILE *out = NULL;
|
||||
/* Nonzero on failure. */
|
||||
static int found_error = 0;
|
||||
|
||||
/* Nonzero if we're generating JNI output. */
|
||||
static int flag_jni = 0;
|
||||
|
||||
/* Directory to place resulting files in. Set by -d option. */
|
||||
const char *output_directory = "";
|
||||
|
||||
@ -105,6 +108,8 @@ struct method_name
|
||||
{
|
||||
unsigned char *name;
|
||||
int length;
|
||||
unsigned char *signature;
|
||||
int sig_length;
|
||||
struct method_name *next;
|
||||
};
|
||||
|
||||
@ -115,9 +120,12 @@ static void print_field_info PARAMS ((FILE*, JCF*, int, int, JCF_u2));
|
||||
static void print_mangled_classname PARAMS ((FILE*, JCF*, const char*, int));
|
||||
static int print_cxx_classname PARAMS ((FILE*, const char*, JCF*, int));
|
||||
static void print_method_info PARAMS ((FILE*, JCF*, int, int, JCF_u2));
|
||||
static void print_c_decl PARAMS ((FILE*, JCF*, int, int, int, const char *));
|
||||
static void print_stub PARAMS ((FILE*, JCF*, int, int, int, const char *));
|
||||
static void print_full_cxx_name PARAMS ((FILE*, JCF*, int, int, int, const char *));
|
||||
static void print_c_decl PARAMS ((FILE*, JCF*, int, int, int, const char *,
|
||||
int));
|
||||
static void print_stub_or_jni PARAMS ((FILE*, JCF*, int, int, int,
|
||||
const char *, int));
|
||||
static void print_full_cxx_name PARAMS ((FILE*, JCF*, int, int, int,
|
||||
const char *, int));
|
||||
static void decompile_method PARAMS ((FILE*, JCF*, int));
|
||||
static void add_class_decl PARAMS ((FILE*, JCF*, JCF_u2));
|
||||
|
||||
@ -161,13 +169,13 @@ static int method_pass;
|
||||
#define HANDLE_END_FIELD() \
|
||||
if (field_pass) \
|
||||
{ \
|
||||
if (out && ! stubs) \
|
||||
if (out && ! stubs && ! flag_jni) \
|
||||
print_field_info (out, jcf, current_field_name, \
|
||||
current_field_signature, \
|
||||
current_field_flags); \
|
||||
} \
|
||||
else \
|
||||
if (! stubs) add_class_decl (out, jcf, current_field_signature);
|
||||
else if (! stubs && ! flag_jni) \
|
||||
add_class_decl (out, jcf, current_field_signature);
|
||||
|
||||
#define HANDLE_CONSTANTVALUE(VALUEINDEX) current_field_value = (VALUEINDEX)
|
||||
|
||||
@ -181,8 +189,9 @@ static int method_printed = 0;
|
||||
if (out) \
|
||||
print_method_info (out, jcf, NAME, SIGNATURE, ACCESS_FLAGS); \
|
||||
} \
|
||||
else \
|
||||
if (! stubs) add_class_decl (out, jcf, SIGNATURE);
|
||||
else if (flag_jni) \
|
||||
print_method_info (NULL, jcf, NAME, SIGNATURE, ACCESS_FLAGS); \
|
||||
else if (! stubs) add_class_decl (out, jcf, SIGNATURE);
|
||||
|
||||
#define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
|
||||
if (out && method_declared) decompile_method (out, jcf, CODE_LENGTH);
|
||||
@ -312,8 +321,7 @@ cxx_keyword_subst (str, length)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Generate an access control keyword based on FLAGS. Returns 0 if
|
||||
FLAGS matches the saved access information, nonzero otherwise. */
|
||||
/* Generate an access control keyword based on FLAGS. */
|
||||
|
||||
static void
|
||||
generate_access (stream, flags)
|
||||
@ -362,6 +370,28 @@ name_is_method_p (name, length)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If there is already a method named NAME, whose signature is not
|
||||
SIGNATURE, then return true. Otherwise return false. */
|
||||
static int
|
||||
overloaded_jni_method_exists_p (name, length, signature, sig_length)
|
||||
const unsigned char *name;
|
||||
int length;
|
||||
const char *signature;
|
||||
int sig_length;
|
||||
{
|
||||
struct method_name *p;
|
||||
|
||||
for (p = method_name_list; p != NULL; p = p->next)
|
||||
{
|
||||
if (p->length == length
|
||||
&& ! memcmp (p->name, name, length)
|
||||
&& (p->sig_length != sig_length
|
||||
|| memcmp (p->signature, signature, sig_length)))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get name of a field. This handles renamings due to C++ clash. */
|
||||
static char *
|
||||
get_field_name (jcf, name_index, flags)
|
||||
@ -525,7 +555,7 @@ DEFUN(print_field_info, (stream, jcf, name_index, sig_index, flags),
|
||||
}
|
||||
|
||||
override = get_field_name (jcf, name_index, flags);
|
||||
print_c_decl (out, jcf, name_index, sig_index, 0, override);
|
||||
print_c_decl (out, jcf, name_index, sig_index, 0, override, flags);
|
||||
fputs (";\n", out);
|
||||
|
||||
if (override)
|
||||
@ -543,7 +573,7 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
|
||||
|
||||
method_declared = 0;
|
||||
method_access = flags;
|
||||
if (JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
|
||||
if (stream && JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
|
||||
fprintf (stream, "<not a UTF8 constant>");
|
||||
str = JPOOL_UTF_DATA (jcf, name_index);
|
||||
length = JPOOL_UTF_LENGTH (jcf, name_index);
|
||||
@ -576,9 +606,19 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
|
||||
memcpy (nn->name, str, length);
|
||||
nn->length = length;
|
||||
nn->next = method_name_list;
|
||||
nn->sig_length = JPOOL_UTF_LENGTH (jcf, sig_index);
|
||||
nn->signature = (char *) xmalloc (nn->sig_length);
|
||||
memcpy (nn->signature, JPOOL_UTF_DATA (jcf, sig_index),
|
||||
nn->sig_length);
|
||||
method_name_list = nn;
|
||||
}
|
||||
|
||||
/* If we're not printing, then the rest of this function doesn't
|
||||
matter. This happens during the first method pass in JNI mode.
|
||||
Eww. */
|
||||
if (! stream)
|
||||
return;
|
||||
|
||||
/* We can't generate a method whose name is a C++ reserved word. We
|
||||
can't just ignore the function, because that will cause incorrect
|
||||
code to be generated if the function is virtual (not only for
|
||||
@ -595,7 +635,7 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
|
||||
return;
|
||||
}
|
||||
|
||||
if (! stubs)
|
||||
if (! stubs && ! flag_jni)
|
||||
{
|
||||
method_printed = 1;
|
||||
|
||||
@ -610,7 +650,7 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
|
||||
if (! is_init)
|
||||
fputs ("virtual ", out);
|
||||
}
|
||||
print_c_decl (out, jcf, name_index, sig_index, is_init, override);
|
||||
print_c_decl (out, jcf, name_index, sig_index, is_init, override, flags);
|
||||
|
||||
if ((flags & ACC_ABSTRACT))
|
||||
fputs (" = 0", out);
|
||||
@ -619,10 +659,11 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
|
||||
}
|
||||
else
|
||||
{
|
||||
if (METHOD_IS_NATIVE(flags))
|
||||
if (METHOD_IS_NATIVE (flags))
|
||||
{
|
||||
method_printed = 1;
|
||||
print_stub (out, jcf, name_index, sig_index, is_init, override);
|
||||
print_stub_or_jni (out, jcf, name_index, sig_index,
|
||||
is_init, override, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -704,6 +745,7 @@ decode_signature_piece (stream, signature, limit, need_space)
|
||||
{
|
||||
case '[':
|
||||
/* More spaghetti. */
|
||||
|
||||
array_loop:
|
||||
for (signature++; (signature < limit
|
||||
&& *signature >= '0'
|
||||
@ -711,18 +753,35 @@ decode_signature_piece (stream, signature, limit, need_space)
|
||||
;
|
||||
switch (*signature)
|
||||
{
|
||||
case 'B': ctype = "jbyteArray"; goto printit;
|
||||
case 'C': ctype = "jcharArray"; goto printit;
|
||||
case 'D': ctype = "jdoubleArray"; goto printit;
|
||||
case 'F': ctype = "jfloatArray"; goto printit;
|
||||
case 'I': ctype = "jintArray"; goto printit;
|
||||
case 'S': ctype = "jshortArray"; goto printit;
|
||||
case 'J': ctype = "jlongArray"; goto printit;
|
||||
case 'Z': ctype = "jbooleanArray"; goto printit;
|
||||
case 'B':
|
||||
ctype = "jbyteArray";
|
||||
break;
|
||||
case 'C':
|
||||
ctype = "jcharArray";
|
||||
break;
|
||||
case 'D':
|
||||
ctype = "jdoubleArray";
|
||||
break;
|
||||
case 'F':
|
||||
ctype = "jfloatArray";
|
||||
break;
|
||||
case 'I':
|
||||
ctype = "jintArray";
|
||||
break;
|
||||
case 'S':
|
||||
ctype = "jshortArray";
|
||||
break;
|
||||
case 'J':
|
||||
ctype = "jlongArray";
|
||||
break;
|
||||
case 'Z':
|
||||
ctype = "jbooleanArray";
|
||||
break;
|
||||
case '[':
|
||||
/* We have a nested array. */
|
||||
++array_depth;
|
||||
fputs ("JArray<", stream);
|
||||
if (! flag_jni)
|
||||
fputs ("JArray<", stream);
|
||||
goto array_loop;
|
||||
|
||||
case 'L':
|
||||
@ -730,23 +789,42 @@ decode_signature_piece (stream, signature, limit, need_space)
|
||||
our output matches what the compiler does. */
|
||||
++signature;
|
||||
/* Space between `<' and `:' to avoid C++ digraphs. */
|
||||
fputs ("JArray< ::", stream);
|
||||
if (! flag_jni)
|
||||
fputs ("JArray< ::", stream);
|
||||
while (signature < limit && *signature != ';')
|
||||
{
|
||||
int ch = UTF8_GET (signature, limit);
|
||||
if (ch == '/')
|
||||
fputs ("::", stream);
|
||||
else
|
||||
jcf_print_char (stream, ch);
|
||||
if (! flag_jni)
|
||||
{
|
||||
if (ch == '/')
|
||||
fputs ("::", stream);
|
||||
else
|
||||
jcf_print_char (stream, ch);
|
||||
}
|
||||
}
|
||||
fputs (" *> *", stream);
|
||||
if (! flag_jni)
|
||||
fputs (" *> *", stream);
|
||||
*need_space = 0;
|
||||
++signature;
|
||||
ctype = NULL;
|
||||
break;
|
||||
default:
|
||||
/* Unparseable signature. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If the previous iterations left us with something to print,
|
||||
print it. For JNI, we always print `jobjectArray' in the
|
||||
nested cases. */
|
||||
if (flag_jni && ctype == NULL)
|
||||
{
|
||||
ctype = "jobjectArray";
|
||||
*need_space = 1;
|
||||
}
|
||||
/* The `printit' case will advance SIGNATURE for us. If we
|
||||
don't go there, we must advance past the `;' ourselves. */
|
||||
if (ctype != NULL)
|
||||
goto printit;
|
||||
++signature;
|
||||
break;
|
||||
|
||||
case '(':
|
||||
@ -764,6 +842,34 @@ decode_signature_piece (stream, signature, limit, need_space)
|
||||
case 'Z': ctype = "jboolean"; goto printit;
|
||||
case 'V': ctype = "void"; goto printit;
|
||||
case 'L':
|
||||
if (flag_jni)
|
||||
{
|
||||
/* We know about certain types and special-case their
|
||||
names.
|
||||
FIXME: something like java.lang.Exception should be
|
||||
printed as `jthrowable', because it is a subclass. This
|
||||
means that gcjh must read the entire hierarchy and
|
||||
comprehend it. */
|
||||
if (! strncmp (signature, "Ljava/lang/String;",
|
||||
sizeof ("Ljava/lang/String;") -1))
|
||||
ctype = "jstring";
|
||||
else if (! strncmp (signature, "Ljava/lang/Class;",
|
||||
sizeof ("Ljava/lang/Class;") - 1))
|
||||
ctype = "jclass";
|
||||
else if (! strncmp (signature, "Ljava/lang/Throwable;",
|
||||
sizeof ("Ljava/lang/Throwable;") - 1))
|
||||
ctype = "jthrowable";
|
||||
else if (! strncmp (signature, "Ljava/lang/ref/WeakReference;",
|
||||
sizeof ("Ljava/lang/ref/WeakReference;") - 1))
|
||||
ctype = "jweak";
|
||||
else
|
||||
ctype = "jobject";
|
||||
|
||||
while (*signature && *signature != ';')
|
||||
++signature;
|
||||
|
||||
goto printit;
|
||||
}
|
||||
/* Print a leading "::" so we look in the right namespace. */
|
||||
fputs ("::", stream);
|
||||
++signature;
|
||||
@ -792,18 +898,21 @@ decode_signature_piece (stream, signature, limit, need_space)
|
||||
break;
|
||||
}
|
||||
|
||||
while (array_depth-- > 0)
|
||||
fputs ("> *", stream);
|
||||
if (! flag_jni)
|
||||
{
|
||||
while (array_depth-- > 0)
|
||||
fputs ("> *", stream);
|
||||
}
|
||||
|
||||
return signature;
|
||||
}
|
||||
|
||||
static void
|
||||
DEFUN(print_c_decl, (stream, jcf, name_index, signature_index, is_init,
|
||||
name_override),
|
||||
name_override, flags),
|
||||
FILE* stream AND JCF* jcf
|
||||
AND int name_index AND int signature_index
|
||||
AND int is_init AND const char *name_override)
|
||||
AND int is_init AND const char *name_override AND int flags)
|
||||
{
|
||||
if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
|
||||
{
|
||||
@ -850,16 +959,18 @@ DEFUN(print_c_decl, (stream, jcf, name_index, signature_index, is_init,
|
||||
if (need_space)
|
||||
fputs (" ", stream);
|
||||
print_full_cxx_name (stream, jcf, name_index,
|
||||
signature_index, is_init, name_override);
|
||||
signature_index, is_init, name_override,
|
||||
flags);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print the unqualified method name followed by the signature. */
|
||||
static void
|
||||
DEFUN(print_full_cxx_name, (stream, jcf, name_index, signature_index, is_init, name_override),
|
||||
DEFUN(print_full_cxx_name, (stream, jcf, name_index, signature_index,
|
||||
is_init, name_override, flags),
|
||||
FILE* stream AND JCF* jcf
|
||||
AND int name_index AND int signature_index AND int is_init
|
||||
AND const char *name_override)
|
||||
AND const char *name_override AND int flags)
|
||||
{
|
||||
int length = JPOOL_UTF_LENGTH (jcf, signature_index);
|
||||
const unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
|
||||
@ -879,13 +990,75 @@ DEFUN(print_full_cxx_name, (stream, jcf, name_index, signature_index, is_init, n
|
||||
else
|
||||
print_name (stream, jcf, name_index);
|
||||
}
|
||||
|
||||
|
||||
if (flag_jni)
|
||||
{
|
||||
unsigned char *signature = JPOOL_UTF_DATA (jcf, signature_index);
|
||||
int sig_len = JPOOL_UTF_LENGTH (jcf, signature_index);
|
||||
if (overloaded_jni_method_exists_p (JPOOL_UTF_DATA (jcf, name_index),
|
||||
JPOOL_UTF_LENGTH (jcf, name_index),
|
||||
signature, sig_len))
|
||||
{
|
||||
/* If this method is overloaded by another native method,
|
||||
then include the argument information in the mangled
|
||||
name. */
|
||||
unsigned char *limit = signature + sig_len;
|
||||
fputs ("__", stream);
|
||||
while (signature < limit)
|
||||
{
|
||||
int ch = UTF8_GET (signature, limit);
|
||||
if (ch == '(')
|
||||
{
|
||||
/* Ignore. */
|
||||
}
|
||||
else if (ch == ')')
|
||||
{
|
||||
/* Done. */
|
||||
break;
|
||||
}
|
||||
else if (ch == '_')
|
||||
fputs ("_1", stream);
|
||||
else if (ch == ';')
|
||||
fputs ("_2", stream);
|
||||
else if (ch == '[')
|
||||
fputs ("_3", stream);
|
||||
else if (ch == '/')
|
||||
fputs ("_", stream);
|
||||
else if ((ch >= '0' && ch <= '9')
|
||||
|| (ch >= 'a' && ch <= 'z')
|
||||
|| (ch >= 'A' && ch <= 'Z'))
|
||||
fputc (ch, stream);
|
||||
else
|
||||
{
|
||||
/* "Unicode" character. FIXME: upper or lower case
|
||||
letters? */
|
||||
fprintf (stream, "_0%04x", ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_method)
|
||||
{
|
||||
/* Have a method or a constructor. Print signature pieces
|
||||
until done. */
|
||||
fputs (" (", stream);
|
||||
|
||||
str = str0 + 1;
|
||||
|
||||
/* In JNI mode, add extra arguments. */
|
||||
if (flag_jni)
|
||||
{
|
||||
/* FIXME: it would be nice to know if we are printing a decl
|
||||
or a definition, and only print `env' for the latter. */
|
||||
fputs ("JNIEnv *env", stream);
|
||||
|
||||
fputs ((flags & ACC_STATIC) ? ", jclass" : ", jobject", stream);
|
||||
|
||||
if (*str != ')')
|
||||
fputs (", ", stream);
|
||||
}
|
||||
|
||||
while (str < limit && *str != ')')
|
||||
{
|
||||
next = decode_signature_piece (stream, str, limit, &need_space);
|
||||
@ -905,12 +1078,28 @@ DEFUN(print_full_cxx_name, (stream, jcf, name_index, signature_index, is_init, n
|
||||
}
|
||||
}
|
||||
|
||||
/* This is a helper for print_stub_or_jni. */
|
||||
static void
|
||||
DEFUN(print_stub, (stream, jcf, name_index, signature_index, is_init,
|
||||
name_override),
|
||||
DEFUN (print_name_for_stub_or_jni, (stream, jcf, name_index, signature_index,
|
||||
is_init, name_override, flags),
|
||||
FILE *stream AND JCF *jcf
|
||||
AND int name_index AND int signature_index
|
||||
AND int is_init AND const char *name_override AND int flags)
|
||||
{
|
||||
char *prefix = flag_jni ? "Java_" : "\n";
|
||||
print_cxx_classname (stream, prefix, jcf, jcf->this_class);
|
||||
fputs (flag_jni ? "_" : "::", stream);
|
||||
print_full_cxx_name (stream, jcf, name_index,
|
||||
signature_index, is_init, name_override,
|
||||
flags);
|
||||
}
|
||||
|
||||
static void
|
||||
DEFUN(print_stub_or_jni, (stream, jcf, name_index, signature_index, is_init,
|
||||
name_override, flags),
|
||||
FILE* stream AND JCF* jcf
|
||||
AND int name_index AND int signature_index
|
||||
AND int is_init AND const char *name_override)
|
||||
AND int is_init AND const char *name_override AND int flags)
|
||||
{
|
||||
if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
|
||||
{
|
||||
@ -927,6 +1116,13 @@ DEFUN(print_stub, (stream, jcf, name_index, signature_index, is_init,
|
||||
int is_method = str[0] == '(';
|
||||
const unsigned char *next;
|
||||
|
||||
/* Don't print fields in the JNI case. */
|
||||
if (! is_method && flag_jni)
|
||||
return;
|
||||
|
||||
if (flag_jni && ! stubs)
|
||||
fputs ("extern ", stream);
|
||||
|
||||
/* If printing a method, skip to the return signature and print
|
||||
that first. However, there is no return value if this is a
|
||||
constructor. */
|
||||
@ -941,7 +1137,8 @@ DEFUN(print_stub, (stream, jcf, name_index, signature_index, is_init,
|
||||
}
|
||||
|
||||
/* If printing a field or an ordinary method, then print the
|
||||
"return value" now. */
|
||||
"return value" now. Note that a constructor can't be native,
|
||||
so we don't bother checking this in the JNI case. */
|
||||
if (! is_method || ! is_init)
|
||||
{
|
||||
next = decode_signature_piece (stream, str, limit, &need_space);
|
||||
@ -953,17 +1150,29 @@ DEFUN(print_stub, (stream, jcf, name_index, signature_index, is_init,
|
||||
}
|
||||
}
|
||||
|
||||
/* When printing a JNI header we need to respect the space. In
|
||||
other cases we're just going to insert a newline anyway. */
|
||||
if (flag_jni)
|
||||
fputs (need_space && ! stubs ? " " : "\n", stream);
|
||||
|
||||
/* Now print the name of the thing. */
|
||||
print_cxx_classname (stream, "\n", jcf, jcf->this_class);
|
||||
fputs ("::", stream);
|
||||
print_full_cxx_name (stream, jcf, name_index,
|
||||
signature_index, is_init, name_override);
|
||||
fputs ("\n{\n JvFail (\"", stream);
|
||||
print_cxx_classname (stream, "", jcf, jcf->this_class);
|
||||
fputs ("::", stream);
|
||||
print_full_cxx_name (stream, jcf, name_index,
|
||||
signature_index, is_init, name_override);
|
||||
fputs (" not implemented\");\n}\n\n", stream);
|
||||
print_name_for_stub_or_jni (stream, jcf, name_index,
|
||||
signature_index, is_init, name_override,
|
||||
flags);
|
||||
|
||||
/* Print the body. */
|
||||
if (stubs)
|
||||
{
|
||||
if (flag_jni)
|
||||
fputs ("\n{\n (*env)->FatalError (\"", stream);
|
||||
else
|
||||
fputs ("\n{\n JvFail (\"", stream);
|
||||
print_name_for_stub_or_jni (stream, jcf, name_index,
|
||||
signature_index, is_init,
|
||||
name_override,
|
||||
flags);
|
||||
fputs (" not implemented\");\n}\n\n", stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1006,13 +1215,14 @@ print_cxx_classname (stream, prefix, jcf, index)
|
||||
fputs (prefix, stream);
|
||||
|
||||
/* Print a leading "::" so we look in the right namespace. */
|
||||
fputs ("::", stream);
|
||||
if (! flag_jni)
|
||||
fputs ("::", stream);
|
||||
|
||||
while (s < limit)
|
||||
{
|
||||
c = UTF8_GET (s, limit);
|
||||
if (c == '/')
|
||||
fputs ("::", stream);
|
||||
fputs (flag_jni ? "_" : "::", stream);
|
||||
else
|
||||
jcf_print_char (stream, c);
|
||||
}
|
||||
@ -1084,7 +1294,9 @@ print_include (out, utf8, len)
|
||||
all_includes = incl;
|
||||
|
||||
fputs ("#include <", out);
|
||||
jcf_print_utf8 (out, utf8, len);
|
||||
jcf_print_utf8_replace (out, utf8, len,
|
||||
'/',
|
||||
flag_jni ? '_' : '/');
|
||||
fputs (".h>\n", out);
|
||||
}
|
||||
|
||||
@ -1356,17 +1568,46 @@ DEFUN(process_file, (jcf, out),
|
||||
|
||||
if (written_class_count++ == 0 && out)
|
||||
{
|
||||
if (! stubs)
|
||||
fputs ("// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-\n\n",
|
||||
out);
|
||||
char *cstart, *cstart2, *mode, *cend, *what, *jflag;
|
||||
if (flag_jni)
|
||||
{
|
||||
cstart = "/*";
|
||||
cstart2 = " ";
|
||||
cend = " */";
|
||||
mode = "";
|
||||
what = "JNI";
|
||||
jflag = " -jni";
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs ("// This file was created by `gcjh -stubs'. It is -*- c++ -*-.\n\
|
||||
//\n\
|
||||
// This file is intended to give you a head start on implementing native\n\
|
||||
// methods using CNI.\n\
|
||||
// Be aware: running `gcjh -stubs' once more for this class may overwrite any\n\
|
||||
// edits you have made to this file.\n\n", out);
|
||||
cstart = "//";
|
||||
cstart2 = "//";
|
||||
cend = "";
|
||||
mode = " -*- c++ -*-";
|
||||
what = "CNI";
|
||||
jflag = "";
|
||||
}
|
||||
|
||||
if (! stubs)
|
||||
fprintf (out, "%s DO NOT EDIT THIS FILE - it is machine generated%s%s\n\n",
|
||||
cstart, mode, cend);
|
||||
else
|
||||
{
|
||||
fprintf (out, "%s This file was created by `gcjh -stubs%s'.%s\n\
|
||||
%s\n\
|
||||
%s This file is intended to give you a head start on implementing native\n\
|
||||
%s methods using %s.\n\
|
||||
%s Be aware: running `gcjh -stubs %s' once more for this class may\n\
|
||||
%s overwrite any edits you have made to this file.%s\n\n",
|
||||
cstart, jflag, mode,
|
||||
cstart2,
|
||||
cstart2,
|
||||
cstart2,
|
||||
what,
|
||||
cstart2,
|
||||
jflag,
|
||||
cstart2,
|
||||
cend);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1376,30 +1617,44 @@ DEFUN(process_file, (jcf, out),
|
||||
{
|
||||
print_mangled_classname (out, jcf, "#ifndef __", jcf->this_class);
|
||||
fprintf (out, "__\n");
|
||||
|
||||
|
||||
print_mangled_classname (out, jcf, "#define __", jcf->this_class);
|
||||
fprintf (out, "__\n\n");
|
||||
|
||||
/* We do this to ensure that inline methods won't be `outlined'
|
||||
by g++. This works as long as method and fields are not
|
||||
added by the user. */
|
||||
fprintf (out, "#pragma interface\n");
|
||||
|
||||
if (jcf->super_class)
|
||||
|
||||
if (flag_jni)
|
||||
{
|
||||
int super_length;
|
||||
const unsigned char *supername =
|
||||
super_class_name (jcf, &super_length);
|
||||
|
||||
fputs ("\n", out);
|
||||
print_include (out, supername, super_length);
|
||||
fprintf (out, "#include <jni.h>\n\n");
|
||||
fprintf (out, "#ifdef __cplusplus\n");
|
||||
fprintf (out, "extern \"C\"\n");
|
||||
fprintf (out, "{\n");
|
||||
fprintf (out, "#endif\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We do this to ensure that inline methods won't be
|
||||
`outlined' by g++. This works as long as method and
|
||||
fields are not added by the user. */
|
||||
fprintf (out, "#pragma interface\n");
|
||||
|
||||
if (jcf->super_class)
|
||||
{
|
||||
int super_length;
|
||||
const unsigned char *supername =
|
||||
super_class_name (jcf, &super_length);
|
||||
|
||||
fputs ("\n", out);
|
||||
print_include (out, supername, super_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Strip off the ".class" portion of the name when printing
|
||||
the include file name. */
|
||||
print_include (out, jcf->classname, strlen (jcf->classname) - 6);
|
||||
int len = strlen (jcf->classname);
|
||||
if (len > 6 && ! strcmp (&jcf->classname[len - 6], ".class"))
|
||||
len -= 6;
|
||||
print_include (out, jcf->classname, len);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1417,9 +1672,10 @@ DEFUN(process_file, (jcf, out),
|
||||
jcf_parse_methods (jcf);
|
||||
|
||||
if (out)
|
||||
{
|
||||
fputs ("\n", out);
|
||||
fputs ("\n", out);
|
||||
|
||||
if (out && ! flag_jni)
|
||||
{
|
||||
if (! stubs)
|
||||
print_class_decls (out, jcf, jcf->this_class);
|
||||
|
||||
@ -1427,7 +1683,7 @@ DEFUN(process_file, (jcf, out),
|
||||
fprintf (out, "%s\n", prepend_specs[i]);
|
||||
if (prepend_count > 0)
|
||||
fputc ('\n', out);
|
||||
|
||||
|
||||
if (! stubs)
|
||||
{
|
||||
if (! print_cxx_classname (out, "class ", jcf, jcf->this_class))
|
||||
@ -1464,32 +1720,38 @@ DEFUN(process_file, (jcf, out),
|
||||
|
||||
jcf_parse_final_attributes (jcf);
|
||||
|
||||
if (out)
|
||||
if (out && ! stubs)
|
||||
{
|
||||
/* Generate friend decl if we still must. */
|
||||
for (i = 0; i < friend_count; ++i)
|
||||
fprintf (out, " friend %s\n", friend_specs[i]);
|
||||
|
||||
/* Generate extra declarations. */
|
||||
if (add_count > 0)
|
||||
fputc ('\n', out);
|
||||
for (i = 0; i < add_count; ++i)
|
||||
fprintf (out, " %s\n", add_specs[i]);
|
||||
|
||||
if (! stubs)
|
||||
fputs ("};\n", out);
|
||||
|
||||
if (append_count > 0)
|
||||
fputc ('\n', out);
|
||||
for (i = 0; i < append_count; ++i)
|
||||
fprintf (out, "%s\n", append_specs[i]);
|
||||
|
||||
if (!stubs)
|
||||
if (flag_jni)
|
||||
{
|
||||
print_mangled_classname (out, jcf,
|
||||
"\n#endif /* __", jcf->this_class);
|
||||
fprintf (out, "__ */\n");
|
||||
fprintf (out, "\n#ifdef __cplusplus\n");
|
||||
fprintf (out, "}\n");
|
||||
fprintf (out, "#endif\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Generate friend decl if we still must. */
|
||||
for (i = 0; i < friend_count; ++i)
|
||||
fprintf (out, " friend %s\n", friend_specs[i]);
|
||||
|
||||
/* Generate extra declarations. */
|
||||
if (add_count > 0)
|
||||
fputc ('\n', out);
|
||||
for (i = 0; i < add_count; ++i)
|
||||
fprintf (out, " %s\n", add_specs[i]);
|
||||
|
||||
if (! stubs)
|
||||
fputs ("};\n", out);
|
||||
|
||||
if (append_count > 0)
|
||||
fputc ('\n', out);
|
||||
for (i = 0; i < append_count; ++i)
|
||||
fprintf (out, "%s\n", append_specs[i]);
|
||||
}
|
||||
|
||||
print_mangled_classname (out, jcf,
|
||||
"\n#endif /* __", jcf->this_class);
|
||||
fprintf (out, "__ */\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1531,6 +1793,7 @@ static struct option options[] =
|
||||
{ "MG", no_argument, NULL, OPT_MG },
|
||||
{ "MD", no_argument, NULL, OPT_MD },
|
||||
{ "MMD", no_argument, NULL, OPT_MMD },
|
||||
{ "jni", no_argument, &flag_jni, 1 },
|
||||
{ NULL, no_argument, NULL, 0 }
|
||||
};
|
||||
|
||||
@ -1547,6 +1810,7 @@ help ()
|
||||
printf ("Usage: gcjh [OPTION]... CLASS...\n\n");
|
||||
printf ("Generate C++ header files from .class files\n\n");
|
||||
printf (" -stubs Generate an implementation stub file\n");
|
||||
printf (" -jni Generate a JNI header or stub\n");
|
||||
printf ("\n");
|
||||
printf (" -add TEXT Insert TEXT into class body\n");
|
||||
printf (" -append TEXT Insert TEXT after class declaration\n");
|
||||
@ -1767,6 +2031,8 @@ DEFUN(main, (argc, argv),
|
||||
char ch = classname[i];
|
||||
if (ch == '.')
|
||||
ch = '/';
|
||||
if (flag_jni && ch == '/')
|
||||
ch = '_';
|
||||
current_output_file[dir_len++] = ch;
|
||||
}
|
||||
if (emit_dependencies)
|
||||
@ -1785,7 +2051,7 @@ DEFUN(main, (argc, argv),
|
||||
}
|
||||
}
|
||||
strcpy (current_output_file + dir_len,
|
||||
stubs ? ".cc" : ".h");
|
||||
stubs ? (flag_jni ? ".c" : ".cc") : ".h");
|
||||
jcf_dependency_set_target (current_output_file);
|
||||
if (! suppress_output)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user