📄 etraits.cc
字号:
// -*- c-basic-offset: 4 -*-/* * etraits.{cc,hh} -- class records element traits * Eddie Kohler * * Copyright (c) 1999-2000 Massachusetts Institute of Technology * Copyright (c) 2000 Mazu Networks, Inc. * Copyright (c) 2001 International Computer Science Institute * Copyright (c) 2008 Meraki, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */#include <click/config.h>#include <click/straccum.hh>#include <click/bitvector.hh>#include "routert.hh"#include "lexert.hh"#include "etraits.hh"#include "toolutils.hh"#include <click/confparse.hh>ElementTraits ElementTraits::the_null_traits;static const char * const driver_names[] = { "userlevel", "linuxmodule", "bsdmodule", "ns", "multithread"};static const char * const driver_multithread_names[] = { "umultithread", "smpclick", "??", "??"};const char *Driver::name(int d){ static_assert(USERLEVEL == 0 && LINUXMODULE == 1 && BSDMODULE == 2 && NSMODULE == 3); if (d >= 0 && d <= COUNT) return driver_names[d]; else return "??";}const char *Driver::multithread_name(int d){ if (d >= 0 && d < COUNT) return driver_multithread_names[d]; else return "??";}const char *Driver::requirement(int d){ if (d >= 0 && d <= COUNT) return driver_names[d]; else return "";}intDriver::driver(const String& name){ for (int d = 0; d < COUNT; d++) if (name == driver_names[d]) return d; return -1;}intDriver::driver_mask(const String& name){ int d = driver(name); if (d >= 0) return 1 << d; int m = 0; const char* s = name.begin(), *end = name.end(); while (s != end) { const char *word = s; while (s != end && *s != '|' && !isspace((unsigned char) *s)) ++s; if ((d = driver(name.substring(word, s))) >= 0) m |= 1 << d; if (s != end) ++s; } return m;}static boolrequirement_contains(const String &req, const String &n){ assert(n.length()); int pos = 0; while ((pos = req.find_left(n, pos)) >= 0) { int rpos = pos + n.length(); // XXX should be more careful about '|' bars if ((pos == 0 || isspace((unsigned char) req[pos - 1]) || req[pos - 1] == '|') && (rpos == req.length() || isspace((unsigned char) req[rpos]) || req[rpos] == '|')) return true; pos = rpos; } return false;}boolElementTraits::requires(const String &n) const{ if (!requirements) return false; else return requirement_contains(requirements, n);}boolElementTraits::provides(const String &n) const{ if (n == name) return true; else if (!provisions) return false; else return requirement_contains(provisions, n);}intElementTraits::flag_value(int flag) const{ const unsigned char *data = reinterpret_cast<const unsigned char *>(flags.data()); int len = flags.length(); for (int i = 0; i < len; i++) { if (data[i] == flag) { if (i < len - 1 && isdigit(data[i+1])) { int value = 0; for (i++; i < len && isdigit(data[i]); i++) value = 10*value + data[i] - '0'; return value; } else return 1; } else while (i < len && !isspace((unsigned char) data[i])) i++; } return -1;}voidElementTraits::calculate_driver_mask(){ driver_mask = 0; if (requirement_contains(requirements, "userlevel")) driver_mask |= 1 << Driver::USERLEVEL; if (requirement_contains(requirements, "linuxmodule")) driver_mask |= 1 << Driver::LINUXMODULE; if (requirement_contains(requirements, "bsdmodule")) driver_mask |= 1 << Driver::BSDMODULE; if (requirement_contains(requirements, "ns")) driver_mask |= 1 << Driver::NSMODULE; if (driver_mask == 0) driver_mask = Driver::ALLMASK; if (requirement_contains(requirements, "multithread")) driver_mask |= 1 << Driver::MULTITHREAD;}String *ElementTraits::component(int what){ switch (what) { case D_CLASS: return &name; case D_CXX_CLASS: return &cxx; case D_HEADER_FILE: return &header_file; case D_SOURCE_FILE: return &source_file; case D_PORT_COUNT: return &port_count_code; case D_PROCESSING: return &processing_code; case D_FLOW_CODE: return &flow_code; case D_FLAGS: return &flags; case D_METHODS: return &methods; case D_REQUIREMENTS: return &requirements; case D_PROVISIONS: return &provisions; case D_LIBS: return &libs; case D_DOC_NAME: return &documentation_name; default: return 0; }}static HashTable<String, int> components(ElementTraits::D_NONE);static bool components_initialized = false;intElementTraits::parse_component(const String &s){ if (!components_initialized) { components.set("name", D_CLASS); components.set("cxxclass", D_CXX_CLASS); components.set("headerfile", D_HEADER_FILE); components.set("sourcefile", D_SOURCE_FILE); components.set("portcount", D_PORT_COUNT); components.set("processing", D_PROCESSING); components.set("flowcode", D_FLOW_CODE); components.set("methods", D_METHODS); components.set("requires", D_REQUIREMENTS); components.set("provides", D_PROVISIONS); components.set("libs", D_LIBS); components.set("docname", D_DOC_NAME); components.set("flags", D_FLAGS); // for compatibility components.set("class", D_CLASS); components.set("cxx_class", D_CXX_CLASS); components.set("header_file", D_HEADER_FILE); components.set("source_file", D_SOURCE_FILE); components.set("requirements", D_REQUIREMENTS); components.set("provisions", D_PROVISIONS); components.set("doc_name", D_DOC_NAME); } return components.get(s);}ElementTraitsElementTraits::make(int component, ...){ va_list val; va_start(val, component); ElementTraits t; while (component != D_NONE) { const char *x = va_arg(val, const char *); if (String *c = t.component(component)) *c = x; component = va_arg(val, int); } va_end(val); return t;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -