📄 click-devirtualize.cc
字号:
config_only = !clp->negated; break; case KERNEL_OPT: compile_kernel = !clp->negated; break; case USERLEVEL_OPT: compile_user = !clp->negated; break; case DEVIRTUALIZE_OPT: specializing.insert(clp->arg, !clp->negated); break; case NO_DEVIRTUALIZE_OPT: specializing.insert(clp->arg, 0); break; case INSTRS_OPT: instruction_files.push_back(clp->arg); break; case REVERSE_OPT: reverse = !clp->negated; break; bad_option: case Clp_BadOption: short_usage(); exit(1); break; case Clp_Done: goto done; } } done: if (config_only) compile_kernel = compile_user = 0; // read router RouterT *router = read_router(router_file, file_is_expr, errh); if (router) router->flatten(errh); if (!router || errh->nerrors() > 0) exit(1); // open output file FILE *outf = stdout; if (output_file && strcmp(output_file, "-") != 0) { outf = fopen(output_file, "w"); if (!outf) errh->fatal("%s: %s", output_file, strerror(errno)); } // handle reversing case if (reverse) { reverse_transformation(router, errh); write_router_file(router, outf, errh); exit(0); } // find and parse elementmap ElementMap full_elementmap; full_elementmap.parse_all_files(router, CLICK_SHAREDIR, errh); // initialize signatures Signatures sigs(router); // follow instructions embedded in router definition ElementClassT *devirtualize_info_class = ElementClassT::base_type("DevirtualizeInfo"); for (RouterT::type_iterator x = router->begin_elements(devirtualize_info_class); x; x++) { Vector<String> args; cp_argvec(x->configuration(), args); for (int j = 0; j < args.size(); j++) parse_instruction(args[j], sigs, p_errh); } // follow instructions from command line { for (int i = 0; i < instruction_files.size(); i++) parse_instruction_file(instruction_files[i], sigs, errh); for (StringMap::iterator iter = specializing.begin(); iter; iter++) sigs.specialize_class(iter.key(), iter.value()); } // choose driver for output full_elementmap.check_completeness(router, p_errh); String suffix = ""; String driver_requirement = ""; if (!full_elementmap.driver_indifferent(router)) { bool linuxmodule_ok = full_elementmap.driver_compatible (router, Driver::LINUXMODULE); bool userlevel_ok = full_elementmap.driver_compatible (router, Driver::USERLEVEL); if (linuxmodule_ok && userlevel_ok && (compile_kernel > 0) == (compile_user > 0)) p_errh->fatal("kernel and user-level drivers require different code;\nyou must specify either '-k' or '-u'"); else if (!linuxmodule_ok && compile_kernel > 0) p_errh->fatal("configuration incompatible with kernel driver"); else if (!userlevel_ok && compile_user > 0) p_errh->fatal("configuration incompatible with user-level driver"); else if (compile_kernel > 0 || (linuxmodule_ok && compile_user <= 0)) { suffix = ".k"; driver_requirement = "linuxmodule "; full_elementmap.set_driver(Driver::LINUXMODULE); } else { suffix = ".u"; driver_requirement = "userlevel "; full_elementmap.set_driver(Driver::USERLEVEL); } } // analyze signatures to determine specialization sigs.analyze(full_elementmap); // initialize specializer Specializer specializer(router, full_elementmap); specializer.specialize(sigs, errh); // quit early if nothing was done if (specializer.nspecials() == 0) { if (source_only) errh->message("nothing to devirtualize"); else write_router_file(router, outf, errh); exit(0); } // find name of package String package_name = "devirtualize"; int uniqueifier = 1; while (1) { if (router->archive_index(package_name + suffix + ".cc") < 0) break; uniqueifier++; package_name = "devirtualize" + String(uniqueifier); } router->add_requirement(package_name); // output StringAccum header, source; source << "/** click-compile: -w -fno-access-control */\n"; header << "#ifndef CLICK_" << package_name << suffix << "_HH\n" << "#define CLICK_" << package_name << suffix << "_HH\n" << "#include <click/package.hh>\n#include <click/element.hh>\n"; specializer.output_package(package_name, source, errh); specializer.output(header, source); header << "#endif\n"; // output source code if required if (source_only) { fwrite(header.data(), 1, header.length(), outf); fwrite(source.data(), 1, source.length(), outf); fclose(outf); exit(0); } // create temporary directory String tmpdir; if (compile_user > 0 || compile_kernel > 0) { if (!(tmpdir = click_mktmpdir(errh))) exit(1); // find Click binaries String click_compile_prog = clickpath_find_file("click-compile", "bin", CLICK_BINDIR, errh); // write header file String hh_filename = package_name + suffix + ".hh"; FILE *f = fopen((tmpdir + hh_filename).c_str(), "w"); if (!f) errh->fatal("%s: %s", (tmpdir + hh_filename).c_str(), strerror(errno)); fwrite(header.data(), 1, header.length(), f); fclose(f); // write C++ file String cxx_filename = package_name + suffix + ".cc"; f = fopen((tmpdir + cxx_filename).c_str(), "w"); if (!f) errh->fatal("%s: %s", (tmpdir + cxx_filename).c_str(), strerror(errno)); fwrite(source.data(), 1, source.length(), f); fclose(f); // write any archived headers const Vector<ArchiveElement> &aelist = router->archive(); for (int i = 0; i < aelist.size(); i++) if (aelist[i].name.substring(-3) == ".hh") { String filename = tmpdir + aelist[i].name; f = fopen(filename.c_str(), "w"); if (!f) errh->warning("%s: %s", filename.c_str(), strerror(errno)); else { fwrite(aelist[i].data.data(), 1, aelist[i].data.length(), f); fclose(f); } } // compile kernel module if (compile_kernel > 0) { String compile_command = click_compile_prog + " --directory=" + tmpdir + " --driver=kernel --package=" + package_name + ".ko " + cxx_filename; int compile_retval = system(compile_command.cc()); if (compile_retval == 127) errh->fatal("could not run '%s'", compile_command.cc()); else if (compile_retval < 0) errh->fatal("could not run '%s': %s", compile_command.cc(), strerror(errno)); else if (compile_retval != 0) errh->fatal("'%s' failed", compile_command.cc()); } // compile userlevel if (compile_user > 0) { String compile_command = click_compile_prog + " --directory=" + tmpdir + " --driver=user --package=" + package_name + ".uo " + cxx_filename; int compile_retval = system(compile_command.cc()); if (compile_retval == 127) errh->fatal("could not run '%s'", compile_command.cc()); else if (compile_retval < 0) errh->fatal("could not run '%s': %s", compile_command.cc(), strerror(errno)); else if (compile_retval != 0) errh->fatal("'%s' failed", compile_command.cc()); } } // retype elements specializer.fix_elements(); // read .cc and .?o files, add them to archive { ArchiveElement ae = init_archive_element(package_name + suffix + ".cc", 0600); ae.data = source.take_string(); router->add_archive(ae); ae.name = package_name + suffix + ".hh"; ae.data = header.take_string(); router->add_archive(ae); if (compile_kernel > 0) { ae.name = package_name + ".ko"; ae.data = file_string(tmpdir + ae.name, errh); router->add_archive(ae); } if (compile_user > 0) { ae.name = package_name + ".uo"; ae.data = file_string(tmpdir + ae.name, errh); router->add_archive(ae); } } // add elementmap to archive { if (router->archive_index("elementmap-devirtualize.xml") < 0) router->add_archive(init_archive_element("elementmap-devirtualize.xml", 0600)); ArchiveElement &ae = router->archive("elementmap-devirtualize.xml"); ElementMap em(ae.data); specializer.output_new_elementmap(full_elementmap, em, package_name + suffix, driver_requirement); ae.data = em.unparse("devirtualize"); } // add devirtualize_info to archive { if (router->archive_index("devirtualize_info") < 0) router->add_archive(init_archive_element("devirtualize_info", 0600)); ArchiveElement &ae = router->archive("devirtualize_info"); StringAccum sa; for (int i = 0; i < specializer.nspecials(); i++) { const SpecializedClass &c = specializer.special(i); if (c.special()) sa << c.click_name << '\t' << c.old_click_name << '\n'; } ae.data += sa.take_string(); } // write configuration if (config_only) { String s = router->configuration_string(); fwrite(s.data(), 1, s.length(), outf); } else write_router_file(router, outf, errh); exit(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -