📄 click-mkmindriver.cc
字号:
Vector<String> sourcevec; for (HashTable<String, int>::iterator iter = _source_files.begin(); iter.live(); iter++) { iter.value() = sourcevec.size(); sourcevec.push_back(iter.key()); } Vector<String> headervec(sourcevec.size(), String()); Vector<String> classvec(sourcevec.size(), String()); HashTable<String, int> statichash(0); // collect header file and C++ element class definitions from emap for (int i = 1; i < emap.size(); i++) { const Traits &elt = emap.traits_at(i); int sourcei = _source_files.get(elt.source_file); if (sourcei >= 0) { // track ELEMENT_LIBS // ah, if only I had regular expressions if (!headervec[sourcei] && elt.libs) { StringAccum sa; sa << " -!lib"; for (const char *x = elt.libs.begin(); x != elt.libs.end(); x++) if (isspace((unsigned char) *x)) { sa << ';'; skipspace: while (x + 1 != elt.libs.end() && isspace((unsigned char) x[1])) x++; } else if (x + 1 != elt.libs.end() && *x == '-' && x[1] == 'L') { sa << '-' << 'L'; x++; goto skipspace; } else sa << *x; classvec[sourcei] += sa.take_string(); } // remember header file headervec[sourcei] = elt.header_file; // remember name if (elt.name) classvec[sourcei] += " " + elt.cxx + "-" + elt.name; // remember static methods if (elt.methods && !statichash[elt.cxx]) { statichash[elt.cxx] = 1; Vector<String> ms; cp_spacevec(elt.methods, ms); for (String *m = ms.begin(); m != ms.end(); m++) if (*m == "static_initialize") classvec[sourcei] += " " + elt.cxx + "-!si"; else if (*m == "static_cleanup") classvec[sourcei] += " " + elt.cxx + "-!sc"; } } } // output data time_t now = time(0); const char *date_str = ctime(&now); fprintf(f, "# Generated by 'click-mkmindriver -p %s' on %s", package.c_str(), date_str); for (int i = 0; i < sourcevec.size(); i++) if (headervec[i]) { String classstr(classvec[i].begin() + 1, classvec[i].end()); if (headervec[i][0] != '\"' && headervec[i][0] != '<') fprintf(f, "%s%s\t\"%s%s\"\t%s\n", top_srcdir.c_str(), sourcevec[i].c_str(), top_srcdir.c_str(), headervec[i].c_str(), classstr.c_str()); else fprintf(f, "%s%s\t%s\t%s\n", top_srcdir.c_str(), sourcevec[i].c_str(), headervec[i].c_str(), classstr.c_str()); }}static Stringanalyze_makefile(const String &directory, ErrorHandler *errh){ int before = errh->nerrors(); String fn = directory + "Makefile"; String text = file_string(fn, errh); if (before != errh->nerrors()) return String(); String expectation = String("\n## Click ") + Driver::requirement(driver) + " driver Makefile ##\n"; if (text.find_left(expectation) < 0) { errh->error("%s lacks magic string\n(Does this directory have a Makefile for Click's %s driver?)", fn.c_str(), Driver::name(driver)); return String(); } int top_srcdir_pos = text.find_left("\ntop_srcdir := "); if (top_srcdir_pos < 0) { errh->error("%s lacks top_srcdir variable", fn.c_str()); return String(); } int top_srcdir_end = text.find_left('\n', top_srcdir_pos + 1); String top_srcdir = text.substring(top_srcdir_pos + 15, top_srcdir_end - (top_srcdir_pos + 15)); if (top_srcdir.back() != '/') top_srcdir += '/'; return top_srcdir;}intmain(int argc, char **argv){ click_static_initialize(); CLICK_DEFAULT_PROVIDES; ErrorHandler *errh = ErrorHandler::default_handler(); LandmarkErrorHandler arg_lerrh(errh, "argument requirements"); // read command line arguments Clp_Parser *clp = Clp_NewParser(argc, argv, sizeof(options) / sizeof(options[0]), options); Clp_SetOptionChar(clp, '+', Clp_ShortNegated); program_name = Clp_ProgramName(clp); Vector<String> router_filenames; String specifier = "x"; const char *package_name = 0; String directory; bool check = true; bool extras = true; Mindriver md; while (1) { int opt = Clp_Next(clp); switch (opt) { case HELP_OPT: usage(); exit(0); break; case VERSION_OPT: printf("click-mkmindriver (Click) %s\n", CLICK_VERSION); printf("Copyright (c) 2001 Massachusetts Institute of Technology\n\Copyright (c) 2001 International Computer Science Institute\n\Copyright (c) 2004-2007 Regents of the University of California\n\This is free software; see the source for copying conditions.\n\There is NO warranty, not even for merchantability or fitness for a\n\particular purpose.\n"); exit(0); break; case CLICKPATH_OPT: set_clickpath(clp->vstr); break; case KERNEL_OPT: driver = Driver::LINUXMODULE; break; case USERLEVEL_OPT: driver = Driver::USERLEVEL; break; case PACKAGE_OPT: package_name = clp->vstr; break; case DIRECTORY_OPT: directory = clp->vstr; if (directory.length() && directory.back() != '/') directory += "/"; break; case ALL_OPT: specifier = (clp->negated ? "x" : "a"); break; case CHECK_OPT: check = !clp->negated; break; case ELEMENT_OPT: { Vector<String> elements; cp_spacevec(clp->vstr, elements); for (String *e = elements.begin(); e < elements.end(); e++) md.require(*e, &arg_lerrh); break; } case ALIGN_OPT: break; case EXTRAS_OPT: extras = !clp->negated; break; case VERBOSE_OPT: verbose = !clp->negated; break; case ROUTER_OPT: router_file: router_filenames.push_back(specifier + String("f") + clp->vstr); break; case Clp_NotOption: if (!click_maybe_define(clp->vstr, &arg_lerrh)) goto router_file; break; case EXPRESSION_OPT: router_filenames.push_back(specifier + String("e") + clp->vstr); break; case Clp_BadOption: short_usage(); exit(1); break; case Clp_Done: goto done; } } done: if (driver < 0) driver = Driver::USERLEVEL; if (!package_name) errh->fatal("fatal error: no package name specified\nPlease supply the '-p PKG' option."); if (extras) { md.require("Align", errh); md.require("IPNameInfo", errh); } ElementMap default_emap; if (!default_emap.parse_default_file(CLICK_DATADIR, errh)) default_emap.report_file_not_found(CLICK_DATADIR, false, errh); for (int i = 0; i < router_filenames.size(); i++) handle_router(md, router_filenames[i], default_emap, errh); if (md._nrequirements == 0) errh->fatal("no elements required"); // add types that are always required { LandmarkErrorHandler lerrh(errh, "default requirements"); md.require("AddressInfo", &lerrh); md.require("AlignmentInfo", &lerrh); md.require("Error", &lerrh); md.require("PortInfo", &lerrh); md.require("ScheduleInfo", &lerrh); if (driver == Driver::USERLEVEL) md.require("ControlSocket", &lerrh); } // add initial provisions default_emap.set_driver(driver); md.provide(Driver::requirement(driver), errh); // all default provisions are stored in elementmap index 0 md.add_traits(default_emap.traits_at(0), default_emap, errh); // now, loop over requirements until closure while (1) { HashTable<String, int> old_reqs(-1); old_reqs.swap(md._requirements); for (HashTable<String, int>::iterator iter = old_reqs.begin(); iter.live(); iter++) md.resolve_requirement(iter.key(), default_emap, errh); if (!md._requirements.size()) break; } if (errh->nerrors() > 0) exit(1); // Print elements_PKG.conf String top_srcdir = analyze_makefile(directory, (check ? errh : ErrorHandler::silent_handler())); if (errh->nerrors() == 0) { String fn = directory + String("elements_") + package_name + ".conf"; errh->message("Creating %s...", fn.c_str()); FILE *f = fopen(fn.c_str(), "w"); if (!f) errh->fatal("%s: %s", fn.c_str(), strerror(errno)); md.print_elements_conf(f, package_name, default_emap, top_srcdir); fclose(f); } // Final message if (errh->nerrors() == 0) { if (driver == Driver::USERLEVEL) errh->message("Build '%sclick' with 'make MINDRIVER=%s'.", package_name, package_name); else errh->message("Build '%sclick.ko' with 'make MINDRIVER=%s'.", package_name, package_name); return 0; } else exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -