📄 elementmap.cc
字号:
} 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(); HashTable<ElementClassT *, int> types(-1); router->collect_types(types); for (HashTable<ElementClassT *, int>::iterator i = types.begin(); i.live(); 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{ LocalErrorHandler lerrh(errh); Vector<int> indexes; collect_indexes(r, indexes, &lerrh); return (lerrh.nerrors() ? -1 : 0);}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;}intElementMap::compatible_driver_mask(const RouterT *r, ErrorHandler *errh) const{ Vector<int> indexes; collect_indexes(r, indexes, errh); int mask = Driver::ALLMASK; for (int i = 0; i < indexes.size(); i++) { int idx = indexes[i]; int elt_mask = 0; while (idx > 0) { int idx_mask = _e[idx].driver_mask; if (idx_mask & (1 << Driver::MULTITHREAD)) for (int d = 0; d < Driver::COUNT; ++d) if ((idx_mask & (1 << d)) && !provides_global(Driver::multithread_name(d))) idx_mask &= ~(1 << d); elt_mask |= idx_mask; idx = _e[idx].name_next; } mask &= elt_mask; } return mask;}boolElementMap::driver_compatible(const RouterT *r, int driver, ErrorHandler *errh) const{ return compatible_driver_mask(r, errh) & (1 << driver);}voidElementMap::set_driver_mask(int driver_mask){ if (_driver_mask != driver_mask) incr_version(); _driver_mask = driver_mask;}intElementMap::pick_driver(int wanted_driver, const RouterT* router, ErrorHandler* errh) const{ LocalErrorHandler lerrh(errh); int driver_mask = compatible_driver_mask(router, &lerrh); if (driver_mask == 0) { lerrh.warning("configuration not compatible with any driver"); return Driver::USERLEVEL; } if ((driver_mask & _provided_driver_mask) == 0) { lerrh.warning("configuration not compatible with installed drivers"); driver_mask = _provided_driver_mask; } if (wanted_driver >= 0) { if (!(driver_mask & (1 << wanted_driver))) lerrh.warning("configuration not compatible with %s driver", Driver::name(wanted_driver)); return wanted_driver; } for (int d = Driver::COUNT - 1; d >= 0; d--) if (driver_mask & (1 << d)) wanted_driver = d; // don't complain if only a single driver works if ((driver_mask & (driver_mask - 1)) != 0 && !driver_indifferent(router, driver_mask, errh)) lerrh.warning("configuration not indifferent to driver, picking %s\n(You might want to specify a driver explicitly.)", Driver::name(wanted_driver)); return wanted_driver;}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("default elementmap missing"); 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("package-specific elementmaps missing:\n %s", not_found.c_str()); 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("(The %<elementmap.xml%> file stores information about available elements,\nand is required for correct operation. %<make install%> should install it."); 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.c_str()); else errh->message("Searched in CLICKPATH and %<%s%>.)", default_path.c_str());}// 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++; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -