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 + -
显示快捷键?