📄 click-pretty.cc
字号:
add_item(pos1, "<span class='c-cmt'>", pos2, "</span>"); } void notify_error(const String &what, int pos1, int pos2) { add_item(pos1, "<span class='c-err' title='" + html_quote_attr(what) + "'>", pos2, "</span>"); } void notify_keyword(const String &, int pos1, int pos2) { add_item(pos1, "<span class='c-kw'>", pos2, "</span>"); } void notify_config_string(int pos1, int pos2) { add_item(pos1, "<span class='c-cfg'>", pos2, "</span>"); } void notify_class_declaration(ElementClassT *ec, bool anonymous, int decl_pos1, int name_pos1, int) { if (!anonymous) add_item(name_pos1, "<a name='" + link_class_decl(ec) + "'><span class='c-cd'>", name_pos1 + ec->name().length(), "</span></a>"); else add_item(decl_pos1, "<a name='" + link_class_decl(ec) + "'>", decl_pos1 + 1, "</a>"); add_class_href(ec, "#" + link_class_decl(ec)); } void notify_class_extension(ElementClassT *ec, int pos1, int pos2) { add_item(pos1, "{" + String(cid(ec)), pos2, ""); } void notify_class_reference(ElementClassT *ec, int pos1, int pos2) { add_item(pos1, "{" + String(cid(ec)), pos2, ""); } void notify_element_declaration(ElementT *e, int pos1, int pos2, int decl_pos2) { add_item(pos1, "<a name='" + link_element_decl(e) + "'>", pos2, "</a>"); add_item(pos1, "<span class='c-ed'>", decl_pos2, "</span>"); notify_element_reference(e, pos1, decl_pos2); } void notify_element_reference(ElementT *e, int pos1, int pos2) { add_item(pos1, "<span title='" + e->name() + " :: " + e->type_name() + "'>", pos2, "</span>"); }};voidshort_usage(){ fprintf(stderr, "Usage: %s [OPTION]... [ROUTERFILE]\n\Try '%s --help' for more information.\n", program_name, program_name);}static RouterT *pretty_read_router(const char *filename, bool file_is_expr, ErrorHandler *errh, String &config){ // This function is a paraphrase of read_router_file. // read file string int before_nerrors = errh->nerrors(); if (file_is_expr) config = filename; else config = file_string(filename, errh); if (!config && errh->nerrors() != before_nerrors) return 0; // set readable filename if (file_is_expr) filename = "<expr>"; else if (!filename || strcmp(filename, "-") == 0) filename = "<stdin>"; // check for archive Vector<ArchiveElement> archive; if (config.length() && config[0] == '!') { separate_ar_string(config, archive, errh); int found = -1; for (int i = 0; i < archive.size(); i++) if (archive[i].name == "config") found = i; if (found >= 0) config = archive[found].data; else { errh->error("%s: archive has no 'config' section", filename); config = String(); } } // clear list of items items.clear(); end_items.clear(); items_prepared = false; // read router if (!config.length()) errh->warning("%s: empty configuration", filename); LexerT lexer(ErrorHandler::silent_handler()); PrettyLexerTInfo pinfo; lexer.reset(config, filename); lexer.set_lexinfo(&pinfo); // add archive bits first if (lexer.router() && archive.size()) { for (int i = 0; i < archive.size(); i++) if (archive[i].live() && archive[i].name != "config") lexer.router()->add_archive(archive[i]); } // read statements while (lexer.ystatement()) /* nada */; // done return lexer.finish();}static voidactivate(OutputItem &item, int &first_active){ item.activate(true); int iitem = item.item_index(); if (iitem < first_active) first_active = iitem;}static voiddeactivate(OutputItem &item, int &first_active, int ipos){ item.activate(false); int iitem = item.item_index(); if (iitem == first_active) { for (first_active++; first_active < ipos && !items[first_active].active; first_active++) /* nada */; if (first_active >= ipos) first_active = items.size(); }}static voidoutput_config(String r_config, FILE *outf){ // create two sorted lists of objects // add sentinel item, sort item lists if (!items_prepared) prepare_items(r_config.length()); // loop over characters const char *data = r_config.cc(); int len = r_config.length(); int ipos = 0, eipos = 0; int first_active = items.size(); fputs("<pre>", outf); for (int pos = 0; pos < len; pos++) { while (items[ipos].pos <= pos || end_items[eipos].pos <= pos) if (end_items[eipos].pos <= items[ipos].pos) { if (end_items[eipos].active) fputs(end_items[eipos].text.cc(), outf); deactivate(end_items[eipos], first_active, ipos); eipos++; } else { fputs(items[ipos].text.cc(), outf); activate(items[ipos], first_active); ipos++; } switch (data[pos]) { case '\n': case '\r': for (int i = ipos - 1; i >= first_active; i--) if (items[i].active) fputs(items[i].other()->text.cc(), outf); fputc('\n', outf); if (data[pos] == '\r' && pos < len - 1 && data[pos+1] == '\n') pos++; for (int i = first_active; i < ipos; i++) if (items[i].active) { if (items[i].other()->pos <= pos + 1) items[i].activate(false); else fputs(items[i].text.cc(), outf); } break; case '<': fputs("<", outf); break; case '>': fputs(">", outf); break; case '&': fputs("&", outf); break; default: fputc(data[pos], outf); break; } } fputs("</pre>\n", outf);}static boolparse_columns(const String &s, int &which, int &count){ const char *slash = find(s, '/'); if (!cp_integer(s.substring(s.begin(), slash), &which) || !cp_integer(s.substring(slash + 1, s.end()), &count) || which <= 0 || which > count) { which = count = 1; return false; } else return true;}extern "C" {static const Vector<ConnectionT> *conn_compar_connvec;static bool conn_compar_from;static intconn_compar(const void *v1, const void *v2){ const int *i1 = (const int *)v1, *i2 = (const int *)v2; const ConnectionT &c1 = (*conn_compar_connvec)[*i1]; const ConnectionT &c2 = (*conn_compar_connvec)[*i2]; const PortT &p1 = (conn_compar_from ? c1.from() : c1.to()); const PortT &p2 = (conn_compar_from ? c2.from() : c2.to()); if (p1.element == p2.element) return p1.port - p2.port; else return click_strcmp(p1.element->name(), p2.element->name());}static intelement_name_compar(const void *v1, const void *v2){ const ElementT **e1 = (const ElementT **)v1, **e2 = (const ElementT **)v2; return click_strcmp((*e1)->name(), (*e2)->name());}}static voidsort_connections(RouterT *r, Vector<int> &conn, bool from){ conn_compar_connvec = &r->connections(); conn_compar_from = from; if (conn.size()) qsort(&conn[0], conn.size(), sizeof(int), conn_compar);}//// elements//static String type_landmark = "$fake_type$";class ElementsOutput { public: ElementsOutput(RouterT *, const ProcessingT &, const HashMap<String, String> &); ~ElementsOutput(); void run(ElementT *, FILE *); void run(FILE *); private: RouterT *_router; const ProcessingT &_processing; const HashMap<String, String> &_main_attrs; Vector<ElementT *> _entries; Vector<ElementT *> _elements; StringAccum _sa; String _sep; void run_template(String, ElementT *, int, bool); String expand(const String &, ElementT *, int, bool); };ElementsOutput::ElementsOutput(RouterT *r, const ProcessingT &processing, const HashMap<String, String> &main_attrs) : _router(r), _processing(processing), _main_attrs(main_attrs){ bool do_elements = main_attrs["entry"]; bool do_types = main_attrs["typeentry"]; // get list of elements and/or types HashMap<ElementClassT *, int> done_types(-1); for (RouterT::iterator x = r->begin_elements(); x; x++) { _elements.push_back(x); if (do_elements) _entries.push_back(x); if (do_types && done_types[x->type()] < 0) { ElementT *fake = new ElementT(x->type_name(), x->type(), "", type_landmark); _entries.push_back(fake); done_types.insert(x->type(), 1); } } // sort by name if (_elements.size()) qsort(&_elements[0], _elements.size(), sizeof(ElementT *), element_name_compar); if (_entries.size()) qsort(&_entries[0], _entries.size(), sizeof(ElementT *), element_name_compar);}ElementsOutput::~ElementsOutput(){ for (int i = 0; i < _entries.size(); i++) if (_entries[i]->landmark() == type_landmark) delete _entries[i];}voidElementsOutput::run_template(String templ_str, ElementT *e, int port, bool is_output){ ElementClassT *t = e->type(); bool is_type = (e->landmark() == type_landmark); String tag; HashMap<String, String> attrs; const char *templ = templ_str.cc(); while (templ) { templ = output_template_until_tag(templ, _sa, tag, attrs, true, &_sep); String next_sep; int pre_expansion_pos = _sa.length(); if (tag == "name") { String href, link = attrs["link"].lower(); if (link == "type" || (is_type && link)) href = class_href(t); else if (link) href = link_element_decl(e); if (href) _sa << _sep << "<a href='" << href << "'>" << e->name() << "</a>"; else _sa << _sep << e->name(); } else if (tag == "type") { String href = (attrs["link"] ? class_href(t) : String()); if (href) _sa << _sep << "<a href='" << href << "'>" << t->name() << "</a>"; else _sa << _sep << t->name(); } else if (tag == "config" && !is_type) { int limit = 0; if (attrs["limit"]) cp_integer(html_unquote(attrs["limit"]), &limit); String config = e->configuration(); if (limit && config.length() > limit) config = config.substring(0, limit) + "..."; if (config && attrs["parens"]) _sa << _sep << '(' << html_quote_text(config) << ')'; else if (config) _sa << _sep << html_quote_text(config); } else if (tag == "typerefs") { String subsep = attrs["sep"]; String text = attrs["entry"]; if (!text) text = _main_attrs["typeref"]; for (int i = 0; i < _elements.size(); i++) if (_elements[i]->type() == t) { run_template(text, _elements[i], -1, false); _sep = subsep; } } else if (tag == "configlink" && !is_type) { String text = attrs["text"]; if (!text) text = _main_attrs["configlink"]; if (text) { text = "<a href='#" + link_element_decl(e) + "'>" + text + "</a>"; run_template(text, e, port, is_output); next_sep = attrs["sep"]; } } else if (tag == "ninputs" && !is_type) { _sa << _sep << e->ninputs(); if (attrs["english"]) _sa << (e->ninputs() == 1 ? " input" : " inputs"); } else if (tag == "noutputs" && !is_type) { _sa << _sep << e->noutputs(); if (attrs["english"]) _sa << (e->noutputs() == 1 ? " output" : " outputs"); } else if (tag == "inputs" && !is_type) { if (e->ninputs() == 0) { String text = attrs["noentry"]; if (!text) text = _main_attrs["noinputentry"]; run_template(text, e, -1, false); } else { String subsep = attrs["sep"]; String text = attrs["entry"]; if (!text) text = _main_attrs["inputentry"]; for (int i = 0; i < e->ninputs(); i++) { run_template(text, e, i, false); _sep = subsep; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -