📄 elementmap.cc
字号:
} // skip to '>' while (s < ends && *s != '>') s++; }}voidElementMap::parse(const String &str, const String &package_name, ErrorHandler *errh){ if (str.length() && str[0] == '<') { parse_xml(str, package_name, errh); return; } int def_index = 0; if (package_name != _def[0].package) { def_index = _def.size(); _def.push_back(Globals()); _def.back().package = package_name; } // set up default data Vector<int> data; for (int i = Traits::D_FIRST_DEFAULT; i <= Traits::D_LAST_DEFAULT; i++) data.push_back(i); // loop over the lines const char *begin = str.begin(); const char *end = str.end(); while (begin < end) { // read a line String line = str.substring(begin, find(begin, end, '\n')); begin = line.end() + 1; // break into words Vector<String> words; cp_spacevec(line, words); // skip blank lines & comments if (words.size() == 0 || words[0][0] == '#') continue; // check for $sourcedir if (words[0] == "$sourcedir") { if (words.size() == 2) { def_index = _def.size(); _def.push_back(Globals()); _def.back() = _def[def_index - 1]; _def.back().srcdir = cp_unquote(words[1]); } } else if (words[0] == "$webdoc") { if (words.size() == 2) { def_index = _def.size(); _def.push_back(Globals()); _def.back() = _def[def_index - 1]; _def.back().dochref = cp_unquote(words[1]); } } else if (words[0] == "$provides") { for (int i = 1; i < words.size(); i++) _e[0].provisions += " " + cp_unquote(words[i]); } else if (words[0] == "$data") { data.clear(); for (int i = 1; i < words.size(); i++) data.push_back(Traits::parse_component(cp_unquote(words[i]))); } else if (words[0][0] != '$') { // an actual line Traits elt; for (int i = 0; i < data.size() && i < words.size(); i++) if (String *sp = elt.component(data[i])) *sp = cp_unquote(words[i]); if (elt.provisions || elt.name) { elt.def_index = def_index; (void) add(elt); } } }}voidElementMap::parse(const String &str, ErrorHandler *errh){ parse(str, String(), errh);}StringElementMap::unparse(const String &package) const{ StringAccum sa; sa << "<?xml version=\"1.0\" standalone=\"yes\"?>\n\<elementmap xmlns=\"http://www.lcdf.org/click/xml/\""; if (package) sa << " package=\"" << xml_quote(package) << "\""; sa << ">\n"; for (int i = 1; i < _e.size(); i++) { const Traits &e = _e[i]; if (!e.name && !e.cxx) continue; sa << " <entry"; if (e.name) sa << " name=\"" << xml_quote(e.name) << "\""; if (e.cxx) sa << " cxxclass=\"" << xml_quote(e.cxx) << "\""; if (e.documentation_name) sa << " docname=\"" << xml_quote(e.documentation_name) << "\""; if (e.header_file) sa << " headerfile=\"" << xml_quote(e.header_file) << "\""; if (e.source_file) sa << " sourcefile=\"" << xml_quote(e.source_file) << "\""; sa << " processing=\"" << xml_quote(e.processing_code) << "\" flowcode=\"" << xml_quote(e.flow_code) << "\""; if (e.flags) sa << " flags=\"" << xml_quote(e.flags) << "\""; if (e.requirements) sa << " requires=\"" << xml_quote(e.requirements) << "\""; if (e.provisions) sa << " provides=\"" << xml_quote(e.provisions) << "\""; sa << " />\n"; } sa << "</elementmap>\n"; return sa.take_string();}StringElementMap::unparse_nonxml() const{ StringAccum sa; sa << "$data\tname\tcxxclass\tdocname\theaderfile\tprocessing\tflowcode\tflags\trequires\tprovides\n"; for (int i = 1; i < _e.size(); i++) { const Traits &e = _e[i]; if (!e.name && !e.cxx) continue; sa << cp_quote(e.name) << '\t' << cp_quote(e.cxx) << '\t' << cp_quote(e.documentation_name) << '\t' << cp_quote(e.header_file) << '\t' << cp_quote(e.processing_code) << '\t' << cp_quote(e.flow_code) << '\t' << cp_quote(e.flags) << '\t' << cp_quote(e.requirements) << '\t' << cp_quote(e.provisions) << '\n'; } return sa.take_string();}voidElementMap::collect_indexes(const RouterT *router, Vector<int> &indexes, ErrorHandler *errh) const{ indexes.clear(); HashMap<ElementClassT *, int> types(-1); router->collect_types(types); for (HashMap<ElementClassT *, int>::iterator i = types.begin(); i; i++) if (i.key()->primitive()) { int t = _name_map[i.key()->name()]; if (t > 0) indexes.push_back(t); else if (errh) errh->error("unknown element class '%s'", i.key()->printable_name_c_str()); }}intElementMap::check_completeness(const RouterT *r, ErrorHandler *errh) const{ if (!errh) errh = ErrorHandler::silent_handler(); int before = errh->nerrors(); Vector<int> indexes; collect_indexes(r, indexes, errh); return (errh->nerrors() == before ? 0 : -1);}boolElementMap::driver_indifferent(const RouterT *r, int driver_mask, ErrorHandler *errh) const{ Vector<int> indexes; collect_indexes(r, indexes, errh); for (int i = 0; i < indexes.size(); i++) { int idx = indexes[i]; if (idx > 0 && (_e[idx].driver_mask & driver_mask) != driver_mask) return false; } return true;}boolElementMap::driver_compatible(const RouterT *r, int driver, ErrorHandler *errh) const{ Vector<int> indexes; collect_indexes(r, indexes, errh); int mask = 1 << driver; for (int i = 0; i < indexes.size(); i++) { int idx = indexes[i]; if (idx > 0 && !(_e[idx].driver_mask & mask)) { while (idx > 0) { if (_e[idx].driver_mask & mask) goto found; idx = _e[idx].name_next; } return false; } found: ; } return true;}voidElementMap::set_driver_mask(int driver_mask){ if (_driver_mask != driver_mask) incr_version(); _driver_mask = driver_mask;}boolElementMap::parse_default_file(const String &default_path, ErrorHandler *errh){ String default_fn = clickpath_find_file("elementmap.xml", "share", default_path); if (!default_fn) default_fn = clickpath_find_file("elementmap", "share", default_path); if (default_fn) { String text = file_string(default_fn, errh); parse(text); return true; } else { errh->warning("cannot find default elementmap"); return false; }}boolElementMap::parse_requirement_files(RouterT *r, const String &default_path, ErrorHandler *errh, String *not_found_store){ String not_found; // try elementmap in archive int defaultmap_aei = r->archive_index("elementmap.xml"); if (defaultmap_aei < 0) defaultmap_aei = r->archive_index("elementmap"); if (defaultmap_aei >= 0) parse(r->archive(defaultmap_aei).data, "<archive>"); // parse elementmaps for requirements in required order const Vector<String> &requirements = r->requirements(); for (int i = 0; i < requirements.size(); i++) { String req = requirements[i]; String mapname = "elementmap-" + req + ".xml"; String mapname2 = "elementmap." + req; // look for elementmap in archive int map_aei = r->archive_index(mapname); if (map_aei < 0) map_aei = r->archive_index(mapname2); if (map_aei >= 0) { parse(r->archive(map_aei).data, req); continue; } String fn = clickpath_find_file(mapname, "share", default_path); if (!fn) fn = clickpath_find_file(mapname2, "share", default_path); if (fn) { String text = file_string(fn, errh); parse(text, req); } else { if (not_found) not_found += ", "; not_found += "'" + req + "'"; } } if (not_found_store) *not_found_store = not_found; if (not_found) { errh->warning("cannot find package-specific elementmaps:\n %s", not_found.cc()); return false; } else return true;}boolElementMap::parse_all_files(RouterT *r, const String &default_path, ErrorHandler *errh){ bool found_default = parse_default_file(default_path, errh); bool found_other = parse_requirement_files(r, default_path, errh); if (found_default && found_other) return true; else { report_file_not_found(default_path, found_default, errh); return false; }}voidElementMap::report_file_not_found(String default_path, bool found_default, ErrorHandler *errh){ if (!found_default) errh->message("(You may get unknown element class errors.\nTry 'make install' or set the CLICKPATH evironment variable."); else errh->message("(You may get unknown element class errors."); const char *path = clickpath(); bool allows_default = path_allows_default_path(path); if (!allows_default) errh->message("Searched in CLICKPATH '%s'.)", path); else if (!path) errh->message("Searched in install directory '%s'.)", default_path.cc()); else errh->message("Searched in CLICKPATH and '%s'.)", default_path.cc());}// TraitsIteratorElementMap::TraitsIterator::TraitsIterator(const ElementMap *emap, bool elements_only) : _emap(emap), _index(0), _elements_only(elements_only){ (*this)++;}voidElementMap::TraitsIterator::operator++(int){ _index++; while (_index < _emap->size()) { const ElementTraits &t = _emap->traits_at(_index); if ((t.driver_mask & _emap->driver_mask()) && (t.name || t.cxx) && (t.name || !_elements_only)) break; _index++; }}// template instance#include <click/vector.cc>template class Vector<ElementMap::Globals>;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -