int main (int argc, char** argv) { JCF jcf[1]; int argi, opt; /* Unlock the stdio streams. */ unlock_std_streams (); gcc_init_libintl (); if (argc <= 1) { fprintf (stderr, _("jcf-dump: no classes specified\n")); usage (); } jcf_path_init (); /* We use getopt_long_only to allow single `-' long options. For some of our options this is more natural. */ while ((opt = getopt_long_only (argc, argv, "o:I:vc", options, NULL)) != -1) { switch (opt) { case 0: /* Already handled. */ break; case 'o': output_file = optarg; break; case 'I': jcf_path_include_arg (optarg); break; case 'v': verbose++; break; case 'c': flag_disassemble_methods = 1; break; case OPT_classpath: jcf_path_classpath_arg (optarg); break; case OPT_bootclasspath: jcf_path_bootclasspath_arg (optarg); break; case OPT_extdirs: jcf_path_extdirs_arg (optarg); break; case OPT_HELP: help (); break; case OPT_VERSION: version (); break; case OPT_JAVAP: flag_javap_compatible++; flag_print_constant_pool = 0; flag_print_attributes = 0; break; default: usage (); } } if (verbose && ! flag_javap_compatible) flag_print_constant_pool = 1; if (optind == argc) { fprintf (stderr, _("jcf-dump: no classes specified\n")); usage (); } jcf_path_seal (verbose); if (flag_print_main) { flag_print_fields = 0; flag_print_methods = 0; flag_print_constant_pool = 0; flag_print_attributes = 0; flag_print_class_info = 0; } if (output_file) { out = fopen (output_file, "w"); if (! out) { fprintf (stderr, _("Cannot open '%s' for output.\n"), output_file); return FATAL_EXIT_CODE; } } else out = stdout; if (optind >= argc) { fprintf (out, "Reading .class from <standard input>.\n"); open_class ("<stdio>", jcf, 0, NULL); process_class (jcf); } else { for (argi = optind; argi < argc; argi++) { char *arg = argv[argi]; const char *class_filename = find_class (arg, strlen (arg), jcf, 0); if (class_filename == NULL) class_filename = find_classfile (arg, jcf, NULL); if (class_filename == NULL) { perror ("Could not find class"); return FATAL_EXIT_CODE; } JCF_FILL (jcf, 4); if (GET_u4 (jcf->read_ptr) == ZIPMAGIC) { long compressed_size, member_size; int compression_method, filename_length, extra_length; int general_purpose_bits; const char *filename; int total_length; if (flag_print_class_info) fprintf (out, "Reading classes from archive %s.\n", class_filename); for (;;) { int skip = 0; jcf_filbuf_t save_filbuf = jcf->filbuf; long magic = JCF_readu4_le (jcf); if (magic == 0x02014b50 || magic == 0x06054b50) break; /* got to central directory */ if (magic != 0x04034b50) /* ZIPMAGIC (little-endian) */ { fprintf (stderr, _("bad format of .zip/.jar archive\n")); return FATAL_EXIT_CODE; } JCF_FILL (jcf, 26); JCF_SKIP (jcf, 2); general_purpose_bits = JCF_readu2_le (jcf); compression_method = JCF_readu2_le (jcf); JCF_SKIP (jcf, 8); compressed_size = JCF_readu4_le (jcf); member_size = JCF_readu4_le (jcf); filename_length = JCF_readu2_le (jcf); extra_length = JCF_readu2_le (jcf); total_length = filename_length + extra_length + compressed_size; if (jcf->read_end - jcf->read_ptr < total_length) jcf_trim_old_input (jcf); JCF_FILL (jcf, total_length); filename = (const char *) jcf->read_ptr; JCF_SKIP (jcf, filename_length); JCF_SKIP (jcf, extra_length); if (filename_length > 0 && filename[filename_length-1] == '/') { if (flag_print_class_info) fprintf (out, "[Skipping directory %.*s]\n", filename_length, filename); skip = 1; } else if (compression_method != 0) { if (flag_print_class_info) fprintf (out, "[Skipping compressed file %.*s]\n", filename_length, filename); skip = 1; } else if (member_size < 4 || GET_u4 (jcf->read_ptr) != 0xcafebabe) { if (flag_print_class_info) fprintf (out, "[Skipping non-.class member %.*s]\n", filename_length, filename); skip = 1; } else { if (flag_print_class_info) fprintf (out, "Reading class member: %.*s.\n", filename_length, filename); } if (skip) { JCF_SKIP (jcf, compressed_size); } else { unsigned char *save_end; jcf->filbuf = jcf_unexpected_eof; save_end = jcf->read_end; jcf->read_end = jcf->read_ptr + compressed_size; process_class (jcf); jcf->filbuf = save_filbuf; jcf->read_end = save_end; } } } else { if (flag_print_class_info) fprintf (out, "Reading .class from %s.\n", class_filename); process_class (jcf); } JCF_FINISH(jcf); } } return SUCCESS_EXIT_CODE; }
/* * process java-specific compiler command-line options * return 0, but do not complain if the option is not recognized. */ static int java_handle_option (size_t scode, const char *arg, int value) { enum opt_code code = (enum opt_code) scode; switch (code) { case OPT_I: jcf_path_include_arg (arg); break; case OPT_M: jcf_dependency_init (1); dependency_tracking |= DEPEND_ENABLE; break; case OPT_MD_: jcf_dependency_init (1); dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE; break; case OPT_MF: jcf_dependency_set_dep_file (arg); dependency_tracking |= DEPEND_FILE_ALREADY_SET; break; case OPT_MM: jcf_dependency_init (0); dependency_tracking |= DEPEND_ENABLE; break; case OPT_MMD_: jcf_dependency_init (0); dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE; break; case OPT_MP: jcf_dependency_print_dummies (); break; case OPT_MT: jcf_dependency_set_target (arg); dependency_tracking |= DEPEND_TARGET_SET; break; case OPT_Wall: flag_wall = value; /* When -Wall given, enable -Wunused. We do this because the C compiler does it, and people expect it. */ warn_unused = value; break; case OPT_fenable_assertions_: add_enable_assert (arg, value); break; case OPT_fenable_assertions: add_enable_assert ("", value); break; case OPT_fdisable_assertions_: add_enable_assert (arg, !value); break; case OPT_fdisable_assertions: add_enable_assert ("", !value); break; case OPT_fassume_compiled_: add_assume_compiled (arg, !value); break; case OPT_fassume_compiled: add_assume_compiled ("", !value); break; case OPT_fbootclasspath_: jcf_path_bootclasspath_arg (arg); break; case OPT_faux_classpath: case OPT_fclasspath_: case OPT_fCLASSPATH_: jcf_path_classpath_arg (arg); break; case OPT_fcompile_resource_: resource_name = arg; break; case OPT_fdump_: if (!dump_switch_p (arg)) return 0; break; case OPT_fencoding_: /* Nothing. */ break; case OPT_fextdirs_: jcf_path_extdirs_arg (arg); break; case OPT_foutput_class_dir_: /* FIXME: remove; this is handled by ecj1 now. */ break; case OPT_version: v_flag = 1; break; case OPT_fsource_filename_: java_read_sourcefilenames (arg); break; default: if (cl_options[code].flags & CL_Java) break; gcc_unreachable (); } return 1; }