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