dstyle.cc

来自「Click is a modular router toolkit. To us」· CC 代码 · 共 2,157 行 · 第 1/4 页

CC
2,157
字号
	       && *s != ':' && *s != ';' && *s != '{' && *s != '}'	       && (*s != '/' || s + 1 == send || (s[1] != '/' && s[1] != '*')))	    ++s;	const char *n_end = s;	s = cp_skip_comment_space(s, send);	// check for media	if (n_end - n == 6 && memcmp(n, "@media", 6) == 0 && s > n_end) {	    const char *z = s;	    while (s != send && isalnum((unsigned char) *s))		++s;	    mediastk.push_back(media.equals(z, s - z));	    s = cp_skip_comment_space(s, send);	    if (s != send && *s == '{')		++s;	    continue;	}	if (s == send || *s == '{' || (*s == '}' && mediastk.size() == 0))	    break;	else if (*s == ';') {	    ++s;	    continue;	} else if (*s == '}') {	    mediastk.pop_back();	    ++s;	    continue;	}	// have n..n_end ':'	++s;			// skip ':'	s = cp_skip_comment_space(s, send);	const char *v = s;	const char *v_ew0 = s;	const char *v_ew1 = s;	for (; s != send; ++s)	    if (*s == '\'' || *s == '\"') {		int quote = *s;		for (++s; s != send; ++s)		    if (*s == '\\') {			if (s + 1 != send && s[1] == '\r')			    s += (s + 2 != send && s[2] == '\n' ? 2 : 1);			else			    ++s;		    } else if (*s == quote)			break;		    else if (*s == '\n' || *s == '\r' || *s == '\f')			goto unexpected_end_of_string;		v_ew0 = s + 1;	    } else if (*s == ';' || *s == '{' || *s == '}' || *s == ':')		break;	    else if (*s == '/' && s + 1 != send && (s[1] == '/' || s[1] == '*')) {		if (v_ew0 == s)		    v_ew1 = v_ew0;		s = cp_skip_comment_space(s, send) - 1;	    } else if (!isspace((unsigned char) *s))		v_ew0 = s + 1;	    else if (v_ew0 == s)		v_ew1 = v_ew0;	if (s != send && *s == ':')	    v_ew0 = v_ew1;	if (n == n_end || v == v_ew0 || (mediastk.size() && !mediastk.back()))	    /* do nothing */;	else if (n + 6 == n_end && memcmp(n, "border", 6) == 0)	    parse_border(str, v, v_ew0, "border");	else if (n + 11 == n_end && memcmp(n, "port-border", 11) == 0)	    parse_border(str, v, v_ew0, "port-border");	else if (n + 12 == n_end && memcmp(n, "queue-stripe", 12) == 0)	    parse_border(str, v, v_ew0, "queue-stripe");	else if (n + 6 == n_end && memcmp(n, "shadow", 6) == 0)	    parse_shadow(str, v, v_ew0);	else if (n + 10 == n_end && memcmp(n, "background", 10) == 0)	    parse_background(str, v, v_ew0);	else if (n + 6 == n_end && memcmp(n, "margin", 6) == 0)	    parse_box(str, v, v_ew0, "margin");	else if (n + 11 == n_end && memcmp(n, "port-margin", 11) == 0)	    parse_box(str, v, v_ew0, "port-margin");	else if (n + 7 == n_end && memcmp(n, "padding", 7) == 0)	    parse_box(str, v, v_ew0, "padding");	else if (n + 5 == n_end && memcmp(n, "split", 5) == 0)	    parse_split(str, v, v_ew0);	else	    add(str.substring(n, n_end), str.substring(v, v_ew0));	s = v_ew0;	if (s == send)	    break;      unexpected_end_of_string:	;    }    return s;}void dcss::parse_border(const String &str, const char *s, const char *send,			const String &prefix){    double d;    while (s != send) {	s = cp_skip_comment_space(s, send);	const char *n = s;	while (s != send && !isspace((unsigned char) *s)	       && (*s != '/' || s + 1 == send || (s[1] != '/' && s[1] != '*')))	    if (*s == '(') {		for (++s; s != send && *s != ')'; ++s)		    /* */;		if (s != send)		    ++s;	    } else		++s;	if ((n + 4 == s && memcmp(n, "none", 4) == 0)	    || (n + 5 == s && memcmp(n, "solid", 5) == 0)	    || (n + 5 == s && memcmp(n, "inset", 5) == 0)	    || (n + 6 == s && memcmp(n, "dashed", 6) == 0)	    || (n + 6 == s && memcmp(n, "dotted", 6) == 0))	    add(prefix + "-style", str.substring(n, s));	else if (n < s && (isdigit((unsigned char) *n) || *n == '+' || *n == '.')		 && cp_pixel(str.substring(n, s), &d))	    add(prefix + "-width", str.substring(n, s));	else if (cp_color(str.substring(n, s), &d, &d, &d, &d))	    add(prefix + "-color", str.substring(n, s));    }}void dcss::parse_shadow(const String &str, const char *s, const char *send){    double d;    while (s != send) {	s = cp_skip_comment_space(s, send);	const char *n = s;	while (s != send && !isspace((unsigned char) *s)	       && (*s != '/' || s + 1 == send || (s[1] != '/' && s[1] != '*')))	    if (*s == '(') {		for (++s; s != send && *s != ')'; ++s)		    /* */;		if (s != send)		    ++s;	    } else		++s;	if ((n + 4 == s && memcmp(n, "none", 4) == 0)	    || (n + 4 == s && memcmp(n, "drop", 4) == 0)	    || (n + 4 == s && memcmp(n, "halo", 4) == 0)	    || (n + 7 == s && memcmp(n, "outline", 7) == 0)	    || (n + 16 == s && memcmp(n, "unscaled-outline", 16) == 0))	    add("shadow-style", str.substring(n, s));	else if (n < s && (isdigit((unsigned char) *n) || *n == '+' || *n == '.')		 && cp_pixel(str.substring(n, s), &d))	    add("shadow-width", str.substring(n, s));	else if (cp_color(str.substring(n, s), &d, &d, &d, &d))	    add("shadow-color", str.substring(n, s));    }}void dcss::parse_background(const String &str, const char *s, const char *send){    double d;    while (s != send) {	s = cp_skip_comment_space(s, send);	const char *n = s;	while (s != send && !isspace((unsigned char) *s)	       && (*s != '/' || s + 1 == send || (s[1] != '/' && s[1] != '*')))	    if (*s == '(') {		for (++s; s != send && *s != ')'; ++s)		    /* */;		if (s != send)		    ++s;	    } else		++s;	if (cp_color(str.substring(n, s), &d, &d, &d, &d))	    add("background-color", str.substring(n, s));    }}void dcss::parse_split(const String &str, const char *s, const char *send){    while (s != send) {	s = cp_skip_comment_space(s, send);	const char *n = s;	while (s != send && !isspace((unsigned char) *s)	       && (*s != '/' || s + 1 == send || (s[1] != '/' && s[1] != '*')))	    if (*s == '(') {		for (++s; s != send && *s != ')'; ++s)		    /* */;		if (s != send)		    ++s;	    } else		++s;	if (s == n + 4 && memcmp(n, "none", 4) == 0) {	    add("port-split", str.substring(n, s));	    add("flow-split", str.substring(n, s));	} else if (s > n + 4 && memcmp(n, "flow(", 5) == 0)	    add("flow-split", str.substring(n, s));	else if ((s == n + 4 && memcmp(n, "both", 4) == 0)		 || (s == n + 6 && memcmp(n, "inputs", 6) == 0)		 || (s == n + 7 && memcmp(n, "outputs", 7) == 0))	    add("port-split", str.substring(n, s));    }}void dcss::parse_box(const String &str, const char *s, const char *send, const String &prefix){    double d;    String x[4];    int pos = 0;    while (s != send) {	s = cp_skip_comment_space(s, send);	const char *n = s;	while (s != send && !isspace((unsigned char) *s)	       && (*s != '/' || s + 1 == send || (s[1] != '/' && s[1] != '*')))	    ++s;	if (pos < 4 && (cp_pixel(str.substring(n, s), &d)			|| cp_relative(str.substring(n, s), &d)))	    x[pos++] = str.substring(n, s);	else	    break;    }    if (pos == 1)	x[1] = x[0], ++pos;    if (pos == 2)	x[2] = x[0], ++pos;    if (pos == 3)	x[3] = x[1], ++pos;    if (pos == 4) {	add(prefix + "-top", x[0]);	add(prefix + "-right", x[1]);	add(prefix + "-bottom", x[2]);	add(prefix + "-left", x[3]);    }}String dcss::unparse_selector() const{    if (!_context.size())	return _selector.unparse();    else {	StringAccum sa;	for (const dcss_selector *sp = _context.end(); sp != _context.begin(); )	    sa << (--sp)->unparse() << ' ';	sa << _selector.unparse();	return sa.take_string();    }}static bool dcsspp_compare(dcss *a, dcss *b){    return *b < *a;}static bool propmatchp_compare(dcss_propmatch *a, dcss_propmatch *b){    return a->name < b->name;}int dcss::assign(dcss_propmatch **begin, dcss_propmatch **end) const{    if (!_sorted)	sort();    int assigned = 0;    for (dcss_property *p = _de.begin(); p != _de.end() && begin != end; )	if (p->name() == (*begin)->name) {	    if (!(*begin)->property) {		(*begin)->property = p;		++assigned;	    }	    ++begin, ++p;	} else if (p->name() < (*begin)->name)	    ++p;	else {	    dcss_propmatch **l = begin, **r = end;	    while (l != r) {		dcss_propmatch **m = l + (r - l) / 2;		if (p->name() == (*m)->name)		    l = r = m;		else if (p->name() < (*m)->name)		    r = m;		else		    l = m + 1;	    }	    begin = l;	}    return assigned;}void dcss::assign_all(dcss_propmatch *props, dcss_propmatch **pp, int n,		      dcss **begin, dcss **end){    if (!*pp) {	for (int i = 0; i < n; ++i)	    pp[i] = props + i;	std::sort(pp, pp + n, propmatchp_compare);    }    for (int i = 0; i < n; ++i)	pp[i]->property = 0;    int done;    for (done = 0; begin != end && done != n; ++begin)	done += (*begin)->assign(pp, pp + n);    if (done != n)	for (int i = 0; i < n; ++i)	    if (!pp[i]->property)		pp[i]->property = &dcss_property::null_property;}/***** * */String dcss_set::expand_imports(const String &text, const String &filename,				ErrorHandler *errh){    LocalErrorHandler lerrh(errh);    const char *s = text.begin(), *send = text.end();    StringAccum expansion;    while (1) {	s = cp_skip_comment_space(s, send);	if (s == send || s + 7 >= send || memcmp(s, "@import", 7) != 0)	    break;	const char *fnbegin = cp_skip_comment_space(s + 7, send);	const char *fnend = s = ccss_skip_braces(fnbegin, send, true);	if (fnbegin == fnend || *fnbegin == '{') {	    lerrh.error("%s: bad @import rule", filename.c_str());	    break;	}	// get @media	String atmedia;	s = cp_skip_comment_space(s, send);	if (s != send && *s != ';') {	    const char *atmedia_start = s;	    while (s != send && *s != ';')		if (*s == '/' && s + 1 != send && (s[1] == '/' || s[1] == '*'))		    s = cp_skip_comment_space(s, send);		else		    ++s;	    atmedia = text.substring(atmedia_start, s);	}	// skip past ';'	if (s != send)	    ++s;	String fn;	if (!cp_filename(text.substring(fnbegin, fnend), &fn) || !fn) {	    lerrh.error("%s: bad @import rule", filename.c_str());	    break;	}	if (fn[0] != '/' && filename && filename[0] != '<') {	    String prefix = filename;	    while (prefix && prefix.back() != '/')		prefix = prefix.substring(0, prefix.length() - 1);	    fn = prefix + fn;	}	String text = file_string(fn, &lerrh);	if (atmedia)	    expansion << "@media " << atmedia << " {\n";	expansion << expand_imports(text, fn, &lerrh) << '\n';	if (atmedia)	    expansion << "}\n";    }    if (expansion) {	expansion << text.substring(s, text.end());	return expansion.take_string();    } else	return text.substring(s, text.end());}dcss_set::dcss_set(const String &text, const String &media)    : _text(), _media(media), _media_next(0), _below(0),      _selector_index(0), _frozen(false){    _s.push_back(0);    _s.push_back(0);    if (!property_map.size()) {	for (const dcss_propmatch *pm = port_pm; pm != port_pm + num_port_pm; ++pm)	    property_map[pm->name] |= pflag_port;	for (const dcss_propmatch *pm = elt_pm; pm != elt_pm + num_elt_pm; ++pm)	    property_map[pm->name] |= pflag_elt;	for (const dcss_propmatch *pm = elt_size_pm; pm != elt_size_pm + num_elt_size_pm; ++pm)	    property_map[pm->name] |= pflag_elt_size;	for (const dcss_propmatch *pm = handler_pm; pm != handler_pm + num_handler_pm; ++pm)	    property_map[pm->name] |= pflag_handler;	for (const dcss_propmatch *pm = fullness_pm; pm != fullness_pm + num_fullness_pm; ++pm)	    property_map[pm->name] |= pflag_fullness;	for (const dcss_propmatch *pm = activity_pm; pm != activity_pm + num_activity_pm; ++pm)	    property_map[pm->name] |= pflag_activity;    }    parse(text);}dcss_set::dcss_set(dcss_set *below)    : _text(), _media(below->media()), _media_next(0), _below(below),      _selector_index(below->_selector_index + 100000), _frozen(false){    _s.push_back(0);    _s.push_back(0);}dcss_set *dcss_set::remedia(const String &m){    dcss_set *p = this;    dcss_set **pprev = &p;    while (*pprev && (*pprev)->media() != m)	pprev = &(*pprev)->_media_next;    if (!*pprev) {	if (_below) {	    *pprev = new dcss_set(_below->remedia(m));	    (*pprev)->parse(_text);	} else	    *pprev = new dcss_set(_text, m);    }    return *pprev;}void dcss_set::mark_change(){    if (_frozen) {	_etable.clear();	_frozen = false;    }}dcss_set::~dcss_set(){    for (dcss **s = _s.begin(); s != _s.end(); ++s)	while (*s) {	    dcss *next = (*s)->_next;	    delete *s;	    *s = next;	}    if (_media_next)	delete _media_next;    mark_change();}void dcss_set::parse(const String &str){    const char *s = str.begin(), *send = str.end();    _text += str;    while (1) {	s = cp_skip_comment_space(s, send);	Vector<dcss *> cs;	if (s == send)	    return;	int nsel = 0;	while (s != send && *s != '{') {	    dcss_selector sel;	    const char *n = s;	    s = sel.parse(str, s);	    if (s == n)		goto skip_braces;	    if (nsel == 0 && s == n + 6 && memcmp(n, "@media", 6) == 0) {		s = cp_skip_comment_space(s, send);		bool right_media = send - s > _media.length()		    && memcmp(s, _media.data(), _media.length()) == 0		    && !isalnum((unsigned char) s[_media.length()]);		while (s != send && *s != '{')		    ++s;	// cp_skip_comment_space		if (s == send)		    goto skip_braces;		else if (!right_media) {		    ++s;		    goto skip_braces;		} else {		    s = cp_skip_comment_space(s + 1, send);		    continue;		}	    }	    if (nsel == 0)		cs.push_back(new dcss);	    else		cs.back()->_context.push_back(cs.back()->_selector);	    cs.back()->_selector = sel;	    ++nsel;	    s = cp_skip_comment_space(s, send);	    if (s != send && *s == ',') {		s = cp_skip_comment_space(s + 1, send);		nsel = 0;	    } else if (s != send && *s == '>')		s = cp_skip_comment_space(s + 1, send);	}	if (cs.size() && s != send && *s == '{') {	    const char *n = s + 1;	    s = cs[0]->parse(str, _media, n);	    if (cs[0]->_de.size()) {		for (dcss **cspp = cs.begin() + 1; cspp != cs.end(); ++cspp)		    (*cspp)->parse(str, _media, n);		for (dcss **cspp = cs.begin(); cspp != cs.end(); ++cspp)		    add(*cspp);		cs.clear();	    }	}      skip_braces:	s = ccss_skip_braces(s, send);	for (dcss **cspp = cs.begin(); cspp != cs.end(); ++cspp)	    delete *cspp;    }}void dcss_set::add(dcss *s){    s->_selector_index = _selector_index;    ++_selector_index;    int si;    if (!s->type() || s->type()[0] == '*' || s->type()[0] == '?'	|| s->type()[0] == '[' || s->type()[0] == '\\')	si = 0;    else	for (si = 2; si < _s.size(); ++si)	    if (_s[si]->type()[0] == s->type()[0])		break;    if (si == _s.size())	_s.push_back(0);    s->_next = _s[si];    _s[si] = s;    if (_frozen)	mark_change();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?