dstyle.cc
来自「Click is a modular router toolkit. To us」· CC 代码 · 共 2,157 行 · 第 1/4 页
CC
2,157 行
bool dcss_selector::match(crouter *cr, const delt *e, int *sensitivity) const{ bool answer = true; int senses = 0; if (e->root()) return false; if (_type && _type != e->type_name()) if (!_type_glob || !glob_match(e->type_name(), _type)) return false; if (_name && _name != e->name()) if (!_name_glob || !glob_match(e->name(), _name)) return false; const char *s; for (const String *k = _klasses.begin(); k != _klasses.end(); ++k) if (k->starts_with("in", 2) && k->length() > 2 && comparison_char((*k)[2])) { if (e->fake() || !int_match_string(k->begin() + 2, k->end(), e->ninputs())) return false; } else if (k->starts_with("out", 3) && k->length() > 3 && comparison_char((*k)[3])) { if (e->fake() || !int_match_string(k->begin() + 3, k->end(), e->noutputs())) return false; } else if (k->equals("primitive", 9)) { if (e->fake() || !e->primitive()) return false; } else if (k->equals("compound", 8)) { if (e->fake() || e->primitive()) return false; } else if (k->equals("passthrough", 11)) { if (e->fake() || e->primitive() || !e->passthrough()) return false; } else if (k->equals("anonymous", 9)) { const String &name = e->name(), &type_name = e->type_name(); if (name.length() < type_name.length() + 2 || name[type_name.length()] != '@' || memcmp(name.begin(), type_name.begin(), type_name.length())) return false; } else if (k->equals("live", 4)) { if (!cr->driver()) return false; } else if (k->starts_with("name*=", 6)) { if (e->name().find_left(k->substring(6)) < 0) return false; } else if (k->starts_with("downstream=", 11)) { if (e->fake()) return false; const crouter::reachable_t &ex = cr->downstream(k->substring(11)); if (!ex(e->parent()->flat_name(), e->eindex())) return false; } else if (k->starts_with("downstream!=", 12)) { if (e->fake()) return false; const crouter::reachable_t &ex = cr->downstream(k->substring(12)); if (ex(e->parent()->flat_name(), e->eindex())) return false; } else if (k->starts_with("upstream=", 9)) { if (e->fake()) return false; const crouter::reachable_t &ex = cr->upstream(k->substring(9)); if (!ex(e->parent()->flat_name(), e->eindex())) return false; } else if (k->starts_with("upstream!=", 10)) { if (e->fake()) return false; const crouter::reachable_t &ex = cr->upstream(k->substring(10)); if (ex(e->parent()->flat_name(), e->eindex())) return false; } else if (k->starts_with("reachable=", 10)) { if (e->fake()) return false; const crouter::reachable_t &ex1 = cr->downstream(k->substring(10)); const crouter::reachable_t &ex2 = cr->upstream(k->substring(10)); if (!ex1(e->parent()->flat_name(), e->eindex()) && !ex2(e->parent()->flat_name(), e->eindex())) return false; } else if (k->starts_with("reachable!=", 11)) { if (e->fake()) return false; const crouter::reachable_t &ex1 = cr->downstream(k->substring(11)); const crouter::reachable_t &ex2 = cr->upstream(k->substring(11)); if (ex1(e->parent()->flat_name(), e->eindex()) || ex2(e->parent()->flat_name(), e->eindex())) return false; } else if ((s = find(*k, '=')) != k->end()) { if (!cr->driver() || !e->flat_name() || !e->primitive()) return false; const char *hend = s; if (hend > k->begin() && hend[-1] == '!') --hend; handler_value *hv = cr->hvalues().find_placeholder(e->flat_name() + "." + k->substring(k->begin(), hend), hflag_notify_delt); if (!hv) return false; // XXX fix this if (!hv->have_hvalue()) { hv->refresh(cr); answer = false; } else if ((hv->hvalue() == k->substring(s + 1, k->end())) == (*hend == '!')) answer = false; senses |= dsense_handler; } else // generic class match would go here return false; if (_highlight_match) { senses |= dsense_highlight; if ((e->highlights() & _highlight_match) != _highlight) answer = false; } if (sensitivity) *sensitivity |= senses; return answer;}bool dcss_selector::match_port(bool isoutput, int port, int processing) const{ if (_type && !_type.equals("port", 4)) if (!_type_glob || !glob_match(_type, "port")) return false; for (const String *k = _klasses.begin(); k != _klasses.end(); ++k) if (k->equals("input", 5)) { if (isoutput) return false; } else if (k->equals("output", 6)) { if (!isoutput) return false; } else if (k->equals("push", 4)) { if ((processing & ProcessingT::ppush) == 0) return false; } else if (k->equals("pull", 4)) { if ((processing & ProcessingT::ppull) == 0) return false; } else if (k->equals("agnostic", 8)) { if ((processing & ProcessingT::pagnostic) == 0) return false; } else if (k->equals("error", 5)) { if ((processing & ProcessingT::perror) == 0) return false; } else return false; if (_name && port >= 0 && !int_match_string(_name.begin(), _name.end(), port, false)) return false; return true;}bool dcss_selector::match(const handler_value *hv) const{ if (!_type.equals("handler", 7)) return false; if (_name && _name != hv->handler_name()) if (!_name_glob || !glob_match(hv->handler_name(), _name)) return false; for (const String *k = _klasses.begin(); k != _klasses.end(); ++k) if (k->equals("read", 4)) { if (!hv->readable()) return false; } else if (k->equals("write", 5)) { if (!hv->writable()) return false; } else if (k->equals("param", 5)) { if (!hv->read_param()) return false; } else if (k->equals("calm", 4)) { if (!(hv->flags() & hflag_calm)) return false; } else if (k->equals("expensive", 9)) { if (!(hv->flags() & hflag_expensive)) return false; } else if (k->equals("deprecated", 10)) { if (!(hv->flags() & hflag_deprecated)) return false; } return true;}bool dcss_selector::type_glob_match(PermString str) const{ return glob_match(str, _type);}const char *dcss_selector::parse(const String &str, const char *s){ _type = _name = String(); _type_glob = _name_glob = _highlight = _highlight_match = 0; _klasses.clear(); StringAccum sa; char start = 1; const char *send = str.end(); while (s != send && *s != '>' && *s != '{' && *s != ',' && *s != '}' && !isspace((unsigned char) *s)) { const char *n = s; if (*n == '[') { s = ++n; const char *last = s; sa.clear(); int nest = 0, equals = 0; for (; s != send && *s != '\n' && *s != '\r' && *s != '\f' && (*s != ']' || nest); ++s) if (isspace((unsigned char) *s)) { sa.append(last, s); for (++s; s != send && isspace((unsigned char) *s); ++s) /* nada */; if (!sa || s == send) /* nada */; else if (*s == '=' && !equals) { sa << '='; ++equals; for (++s; s != send && isspace((unsigned char) *s); ++s) /* nada */; } else sa << ' '; last = s; --s; } else if (*s == '[') ++nest; else if (*s == ']') --nest; if (sa) { sa.append(last, s); _klasses.push_back(sa.take_string()); } else _klasses.push_back(str.substring(last, s)); if (s == send || *s != ']') break; ++s; start = 0; continue; } if (*n == '.' || *n == '#' || *n == ':') { start = *n; s = ++n; } else if (!start) break; int glob = 0; retry: while (s != send && !isspace((unsigned char) *s) && *s != '.' && *s != '>' && *s != '#' && *s != ':' && *s != ',' && *s != '{' && *s != '}' && *s != '[' && *s != ']' && (*s != '/' || s + 1 != send || (s[1] != '/' && s[1] != '*'))) { if (*s == '*' || *s == '?' || *s == '\\') glob = 1; if (*s == '\\' && s + 1 != send) ++s; ++s; } if (s == n && start == '#' && *s == '#' && !_name && !_type) { _type = String::make_stable("handler", 7); s = ++n; goto retry; } else if (s == n && start) { --s; break; } else if (s == n) break; if (n + 1 == s && *n == '*') { n = s; glob = 0; } if (start == '.') _klasses.push_back(str.substring(n, s)); else if (start == '#') { _name = str.substring(n, s); _name_glob = glob; } else if (start == ':') { String x = str.substring(n, s); if (x.equals("hover", 5)) _highlight |= (1<<dhlt_hover), _highlight_match |= (1<<dhlt_hover); else if (x.equals("active", 6)) _highlight |= (1<<dhlt_click), _highlight_match |= (1<<dhlt_click); else if (x.equals("pressed", 7)) _highlight |= (1<<dhlt_pressed), _highlight_match |= (1<<dhlt_pressed); else _klasses.push_back(x); } else { _type = str.substring(n, s); _type_glob = glob; } start = 0; } return s;}String dcss_selector::unparse() const{ StringAccum sa; if (_type) sa << _type; if (_name) sa << '#' << _name; for (const String *k = _klasses.begin(); k != _klasses.end(); ++k) sa << '.' << *k; if (_highlight & (1<<dhlt_click)) sa << ":active"; if (_highlight & (1<<dhlt_hover)) sa << ":hover"; if (!sa) sa << '*'; return sa.take_string();}/***** * */const dcss_property dcss_property::null_property("", "");const double dcss_property::transparent_color[4] = { 0, 0, 0, 0 };bool dcss_property::hard_change_type(int t) const{ if (_t == t_color) delete[] _v.dp; _t = t_none; if (!_vstr) return t == t_none; switch (t) { case t_numeric: if (cp_double(_vstr, &_v.d)) _t = t_numeric; break; case t_pixel: if (cp_pixel(_vstr, &_v.d)) _t = t_pixel; break; case t_relative: if (cp_relative(_vstr, &_v.d)) _t = t_relative; break; case t_seconds: if (cp_seconds(_vstr, &_v.d)) _t = t_seconds; break; case t_color: { double c[4]; if (cp_color(_vstr, &c[0], &c[1], &c[2], &c[3])) { _v.dp = new double[4]; memcpy(_v.dp, &c, sizeof(double) * 4); _t = t_color; } break; } case t_border_style: if (_vstr.equals("none", 4)) { _v.i = dborder_none; _t = t_border_style; } else if (_vstr.equals("solid", 5)) { _v.i = dborder_solid; _t = t_border_style; } else if (_vstr.equals("inset", 5)) { _v.i = dborder_inset; _t = t_border_style; } else if (_vstr.equals("dashed", 6)) { _v.i = dborder_dashed; _t = t_border_style; } else if (_vstr.equals("dotted", 6)) { _v.i = dborder_dotted; _t = t_border_style; } break; case t_shadow_style: if (_vstr.equals("none", 4)) { _v.i = dshadow_none; _t = t_shadow_style; } else if (_vstr.equals("drop", 4)) { _v.i = dshadow_drop; _t = t_shadow_style; } else if (_vstr.equals("outline", 7) || _vstr.equals("halo", 4)) { _v.i = dshadow_outline; _t = t_shadow_style; } else if (_vstr.equals("unscaled-outline", 16)) { _v.i = dshadow_unscaled_outline; _t = t_shadow_style; } break; } return _t == t;}bool dcss_property::hard_change_relative_pixel() const{ if (_t == t_color) delete[] _v.dp; _t = t_none; if (!_vstr) return false; if (_vstr.back() != '%' && !isalpha((unsigned char) _vstr[0])) if (cp_pixel(_vstr, &_v.d)) { _t = t_pixel; return true; } if (cp_relative(_vstr, &_v.d)) { _t = t_relative; return true; } else return false;}double dcss_property::vpixel(crouter *cr, PermString relative_to, const delt *e) const{ change_relative_pixel(); if (_t == t_pixel) return _v.d; else if (_t == t_relative) return _v.d * cr->ccss()->vpixel(relative_to, cr, e); else return 0;}/***** * */dcss::dcss() : _pflags(0), _sorted(false), _next(0){}static bool operator<(const dcss_property &a, const dcss_property &b){ return a.name() < b.name();}void dcss::sort() const{ std::sort(_de.begin(), _de.end()); _sorted = true;}const dcss_property *dcss::find(PermString name) const{ if (_sorted) { dcss_property *l = _de.begin(), *r = _de.end(); while (l < r) { dcss_property *m = l + (r - l) / 2; if (m->name() == name) return m; else if (m->name() < name) l = m + 1; else r = m; } } else for (dcss_property *p = _de.begin(); p != _de.end(); ++p) if (p->name() == name) return p; return 0;}void dcss::add(PermString name, const String &value){ if (dcss_property *dx = find(name)) *dx = dcss_property(name, value); else { _sorted = false; _pflags |= property_map[name]; _de.push_back(dcss_property(name, value)); }}bool dcss::hard_match_context(crouter *cr, const delt *e, int *sensitivity, bool strict) const{ if (!e) return _context.begin() == _context.end(); int sense = 0; const dcss_selector *sel_precise = _context.end(); const dcss_selector *sel_approx = _context.end(); if (strict && _context.begin() != _context.end()) { if (!_context.back().match(cr, e, sensitivity)) return false; --sel_precise; --sel_approx; } while (!e->root() && sel_approx != _context.begin()) { if (sel_precise != sel_approx && sel_precise != _context.begin() && sel_precise[-1].match(cr, e, 0)) --sel_precise; int ts = 0; bool m = sel_approx[-1].match(cr, e, &ts); if (m && sel_precise == sel_approx) --sel_precise; if (m || ts) --sel_approx; sense |= ts; e = e->parent(); } if (sel_approx == _context.begin() && sensitivity) *sensitivity |= sense; return sel_precise == _context.begin();}const char *dcss::parse(const String &str, const String &media, const char *s){ const char *send = str.end(); Vector<int> mediastk; while (1) { s = cp_skip_comment_space(s, send); const char *n = s; while (s != send && !isspace((unsigned char) *s)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?