📄 gjavah.c
字号:
} free (name->name); free (name); }}/* This is called to add some classes to the list of classes for which we need decls. The signature argument can be a function signature. */static voidadd_class_decl (out, jcf, signature) FILE *out; JCF *jcf; JCF_u2 signature;{ unsigned char *s = JPOOL_UTF_DATA (jcf, signature); int len = JPOOL_UTF_LENGTH (jcf, signature); int i; /* Name of class we are processing. */ int name_index = JPOOL_USHORT1 (jcf, jcf->this_class); int tlen = JPOOL_UTF_LENGTH (jcf, name_index); char *tname = JPOOL_UTF_DATA (jcf, name_index); for (i = 0; i < len; ++i) { int start, saw_dollar; /* If we see an array, then we include the array header. */ if (s[i] == '[') { print_include (out, "java-array", -1); continue; } /* We're looking for `L<stuff>;' -- everything else is ignorable. */ if (s[i] != 'L') continue; saw_dollar = 0; for (start = ++i; i < len && s[i] != ';'; ++i) { if (! saw_dollar && s[i] == '$' && out) { saw_dollar = 1; /* If this class represents an inner class, then generate a `#include' for the outer class. However, don't generate the include if the outer class is the class we are processing. */ if (i - start < tlen || strncmp (&s[start], tname, i - start)) print_include (out, &s[start], i - start); break; } } /* If we saw an inner class, then the generated #include will declare the class. So in this case we needn't bother. */ if (! saw_dollar) add_namelet (&s[start], &s[i], &root); }}/* Print declarations for all classes required by this class. Any class or package in the `java' package is assumed to be handled statically in libjava; we don't generate declarations for these. This makes the generated headers a bit easier to read. */static voidprint_class_decls (out, jcf, self) FILE *out; JCF *jcf; int self;{ /* Make sure to always add the current class to the list of things that should be declared. */ int name_index = JPOOL_USHORT1 (jcf, self); int len; unsigned char *s; s = JPOOL_UTF_DATA (jcf, name_index); len = JPOOL_UTF_LENGTH (jcf, name_index); add_namelet (s, s + len, &root); if (root.subnamelets) { fputs ("extern \"Java\"\n{\n", out); /* We use an initial offset of 0 because the root namelet doesn't cause anything to print. */ print_namelet (out, &root, 0); fputs ("};\n\n", out); }}static voidDEFUN(process_file, (jcf, out), JCF *jcf AND FILE *out){ int code, i; uint32 field_start, method_end, method_start; current_jcf = jcf; last_access = -1; if (jcf_parse_preamble (jcf) != 0) { fprintf (stderr, "Not a valid Java .class file.\n"); found_error = 1; return; } /* Parse and possibly print constant pool */ code = jcf_parse_constant_pool (jcf); if (code != 0) { fprintf (stderr, "error while parsing constant pool\n"); found_error = 1; return; } code = verify_constant_pool (jcf); if (code > 0) { fprintf (stderr, "error in constant pool entry #%d\n", code); found_error = 1; return; } jcf_parse_class (jcf); if (written_class_count++ == 0 && out) fputs ("// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-\n\n", out); if (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 && out) { int super_length; unsigned char *supername = super_class_name (jcf, &super_length); fputs ("\n", out); print_include (out, supername, super_length); } /* We want to parse the methods first. But we need to find where they start. So first we skip the fields, then parse the methods. Then we parse the fields and skip the methods. This is ugly, but not too bad since we need two full passes to get class decl information anyway. */ field_pass = 0; field_start = JCF_TELL (jcf); jcf_parse_fields (jcf); method_start = JCF_TELL (jcf); method_pass = 0; jcf_parse_methods (jcf); if (out) { fputs ("\n", out); print_class_decls (out, jcf, jcf->this_class); for (i = 0; i < prepend_count; ++i) fprintf (out, "%s\n", prepend_specs[i]); if (prepend_count > 0) fputc ('\n', out); } if (out && ! print_cxx_classname (out, "class ", jcf, jcf->this_class)) { fprintf (stderr, "class is of array type\n"); found_error = 1; return; } if (out && jcf->super_class) { if (! print_cxx_classname (out, " : public ", jcf, jcf->super_class)) { fprintf (stderr, "base class is of array type\n"); found_error = 1; return; } } if (out) fputs ("\n{\n", out); /* Now go back for second pass over methods and fields. */ JCF_SEEK (jcf, method_start); method_pass = 1; jcf_parse_methods (jcf); method_end = JCF_TELL (jcf); field_pass = 1; JCF_SEEK (jcf, field_start); jcf_parse_fields (jcf); JCF_SEEK (jcf, method_end); jcf_parse_final_attributes (jcf); if (out) { /* 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]); 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"); }}static voidusage (){ fprintf (stderr, "gcjh: no classes specified\n"); exit (1);}static voidhelp (){ printf ("Usage: gcjh [OPTION]... CLASS...\n\n"); printf ("Generate C++ header files from .class files\n\n"); printf (" --classpath PATH Set path to find .class files\n"); printf (" --CLASSPATH PATH Set path to find .class files\n"); printf (" -IDIR Append directory to class path\n"); printf (" -d DIRECTORY Set output directory name\n"); printf (" --help Print this help, then exit\n"); printf (" -o FILE Set output file name\n"); printf (" -td DIRECTORY Set temporary directory name\n"); printf (" -v, --verbose Print extra information while running\n"); printf (" --version Print version number, then exit\n"); /* FIXME: print bug-report information. */ exit (0);}static voidjava_no_argument (opt) char *opt;{ fprintf (stderr, "gcjh: no argument given for option `%s'\n", opt); exit (1);}static voidversion (){ /* FIXME: use version.c? */ printf ("gcjh (GNU gcc) 0.0\n\n"); printf ("Copyright (C) 1998 Free Software Foundation, Inc.\n"); printf ("This is free software; see the source for copying conditions. There is NO\n"); printf ("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); exit (0);}intDEFUN(main, (argc, argv), int argc AND char** argv){ JCF jcf; int argi; char *output_file = NULL; int emit_dependencies = 0, suppress_output = 0; if (argc <= 1) usage (); jcf_path_init (); for (argi = 1; argi < argc; argi++) { char *arg = argv[argi]; if (arg[0] != '-' || ! strcmp (arg, "--")) break; /* Just let all arguments be given in either "-" or "--" form. */ if (arg[1] == '-') ++arg; if (strcmp (arg, "-o") == 0) { if (argi + 1 < argc) output_file = argv[++argi]; else java_no_argument (argv[argi]); } else if (strcmp (arg, "-d") == 0) { if (argi + 1 < argc) output_directory = argv[++argi]; else java_no_argument (argv[argi]); } else if (strcmp (arg, "-td") == 0) { if (argi + 1 < argc) temp_directory = argv[++argi]; else java_no_argument (argv[argi]); } else if (strcmp (arg, "-prepend") == 0) { if (argi + 1 < argc) { if (prepend_count == 0) prepend_specs = (char**) ALLOC ((argc-argi) * sizeof (char*)); prepend_specs[prepend_count++] = argv[++argi]; } else java_no_argument (argv[argi]); } else if (strcmp (arg, "-friend") == 0) { if (argi + 1 < argc) { if (friend_count == 0) friend_specs = (char**) ALLOC ((argc-argi) * sizeof (char*)); friend_specs[friend_count++] = argv[++argi]; } else java_no_argument (argv[argi]); } else if (strcmp (arg, "-add") == 0) { if (argi + 1 < argc) { if (add_count == 0) add_specs = (char**) ALLOC ((argc-argi) * sizeof (char*)); add_specs[add_count++] = argv[++argi]; } else java_no_argument (argv[argi]); } else if (strcmp (arg, "-append") == 0) { if (argi + 1 < argc) { if (append_count == 0) append_specs = (char**) ALLOC ((argc-argi) * sizeof (char*)); append_specs[append_count++] = argv[++argi]; } else java_no_argument (argv[argi]); } else if (strcmp (arg, "-classpath") == 0) { if (argi + 1 < argc) jcf_path_classpath_arg (argv[++argi]); else java_no_argument (argv[argi]); } else if (strcmp (arg, "-CLASSPATH") == 0) { if (argi + 1 < argc) jcf_path_CLASSPATH_arg (argv[++argi]); else java_no_argument (argv[argi]); } else if (strncmp (arg, "-I", 2) == 0) jcf_path_include_arg (arg + 2); else if (strcmp (arg, "-verbose") == 0 || strcmp (arg, "-v") == 0) verbose++; else if (strcmp (arg, "-stubs") == 0) stubs++; else if (strcmp (arg, "-help") == 0) help (); else if (strcmp (arg, "-version") == 0) version (); else if (strcmp (arg, "-M") == 0) { emit_dependencies = 1; suppress_output = 1; jcf_dependency_init (1); } else if (strcmp (arg, "-MM") == 0) { emit_dependencies = 1; suppress_output = 1; jcf_dependency_init (0); } else if (strcmp (arg, "-MG") == 0) { fprintf (stderr, "gcjh: `%s' option is unimplemented\n", argv[argi]); exit (1); } else if (strcmp (arg, "-MD") == 0) { emit_dependencies = 1; jcf_dependency_init (1); } else if (strcmp (arg, "-MMD") == 0) { emit_dependencies = 1; jcf_dependency_init (0); } else { fprintf (stderr, "%s: illegal argument\n", argv[argi]); exit (1); } } if (argi == argc) usage (); jcf_path_seal (); if (output_file && emit_dependencies) { fprintf (stderr, "gcjh: can't specify both -o and -MD\n"); exit (1); } for (; argi < argc; argi++) { char *classname = argv[argi]; char *classfile_name, *current_output_file; if (verbose) fprintf (stderr, "Processing %s\n", classname); if (! output_file) jcf_dependency_reset (); classfile_name = find_class (classname, strlen (classname), &jcf, 0); if (classfile_name == NULL) { fprintf (stderr, "%s: no such class\n", classname); exit (1); } if (verbose) fprintf (stderr, "Found in %s\n", classfile_name); if (output_file) { if (strcmp (output_file, "-") == 0) out = stdout; else if (out == NULL) { out = fopen (output_file, "w"); } if (out == NULL) { perror (output_file); exit (1); } current_output_file = output_file; } else { int dir_len = strlen (output_directory); int i, classname_length = strlen (classname); current_output_file = (char*) ALLOC (dir_len + classname_length + 4); strcpy (current_output_file, output_directory); if (dir_len > 0 && output_directory[dir_len-1] != '/') current_output_file[dir_len++] = '/'; for (i = 0; classname[i] != '\0'; i++) { char ch = classname[i]; if (ch == '.') ch = '/'; current_output_file[dir_len++] = ch; } if (emit_dependencies) { if (suppress_output) { jcf_dependency_set_dep_file ("-"); out = NULL; } else { /* We use `.hd' and not `.d' to avoid clashes with dependency tracking from straight compilation. */ strcpy (current_output_file + dir_len, ".hd"); jcf_dependency_set_dep_file (current_output_file); } } strcpy (current_output_file + dir_len, ".h"); jcf_dependency_set_target (current_output_file); if (! suppress_output) { out = fopen (current_output_file, "w"); if (out == NULL) { perror (current_output_file); exit (1); } } } process_file (&jcf, out); JCF_FINISH (&jcf); if (current_output_file != output_file) free (current_output_file); jcf_dependency_write (); } if (out != NULL && out != stdout) fclose (out); return found_error;}/* TODO: * Do whatever the javah -stubs flag does. * Emit "structure forward declarations" when needed. * Generate C headers, like javah */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -