⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 click-pretty.cc

📁 Click is a modular router toolkit. To use it you ll need to know how to compile and install the sof
💻 CC
📖 第 1 页 / 共 3 页
字号:
    String result(_sa.data() + pos, _sa.length() - pos);    _sa.pop_back(_sa.length() - pos);    return result;}voidElementsOutput::run(ElementT *e, FILE *f){    bool is_type = e->landmark() == type_landmark;    String templ = _main_attrs[is_type ? "typeentry" : "entry"];    run_template(templ, e, -1, false);    fputs(_sa.c_str(), f);    _sa.clear();    _sep = _main_attrs["sep"];}voidElementsOutput::run(FILE *f){    // divide into columns    int which_col, ncol;    parse_columns(_main_attrs["column"], which_col, ncol);    int per_col = ((_entries.size() - 1) / ncol) + 1;    int first = (which_col - 1) * per_col;    int last = which_col * per_col;    if (which_col == ncol || last > _entries.size())	last = _entries.size();    // actually do output    for (int i = first; i < last; i++)	run(_entries[i], f);}//// main loop//static voidrun_template(const char *templ, RouterT *r, const String &r_config,	     const ElementMap &emap, const ProcessingT &processing, FILE *outf){    String tag;    HashTable<String, String> attrs;    while (templ) {	templ = output_template_until_tag(templ, outf, tag, attrs, false);	if (tag == "config")	    output_config(r_config, outf);	else if (tag == "elements") {	    ElementsOutput eo(r, processing, attrs);	    eo.run(outf);	} else if (String text = definitions.get(tag))	    run_template(text.c_str(), r, r_config, emap, processing, outf);    }}static FILE *open_output_file(const char *outfile, ErrorHandler *errh){    FILE *outf = stdout;    if (outfile && strcmp(outfile, "-") != 0) {	outf = fopen(outfile, "w");	if (!outf)	    errh->error("%s: %s", outfile, strerror(errno));    }    return outf;}static voidpretty_process(const char *infile, bool file_is_expr, const char *outfile,	       const char *templ, ErrorHandler *errh){    String r_config;    RouterT *r = pretty_read_router(infile, file_is_expr, errh, r_config);    if (!r)	return;    // open output file    FILE *outf = open_output_file(outfile, errh);    if (!outf) {	delete r;	return;    }    // get element map and processing    ElementMap emap;    emap.parse_all_files(r, CLICK_DATADIR, errh);    emap.set_driver(emap.pick_driver(specified_driver, r, errh));    ProcessingT processing(r, &emap, errh);    processing.check_types(errh);    ElementMap::push_default(&emap);    // process template    run_template(templ, r, r_config, emap, processing, outf);    ElementMap::pop_default();    // close files, return    if (outf != stdout)	fclose(outf);    delete r;}// This algorithm based on the original click-viz script,// donated by Jose Vasconcellos <jvasco@bellatlantic.net>static voidpretty_process_dot(const char *infile, bool file_is_expr, const char *outfile,		   ErrorHandler *errh){    RouterT *r = read_router(infile, file_is_expr, errh);    if (!r)	return;    // open output file    FILE *outf = open_output_file(outfile, errh);    if (!outf) {	delete r;	return;    }    // write dot configuration    fprintf(outf, "digraph clickrouter {\n\  node [shape=record,height=.1]\n\  edge [arrowhead=normal,arrowtail=none,tailclip=false]\n");    // print all nodes    for (RouterT::const_iterator n = r->begin_elements(); n != r->end_elements(); n++) {#if 1	fprintf(outf, "  \"%s\" [label=\"", n->name_c_str());	if (n->ninputs() || n->noutputs())	    fprintf(outf, "{");	if (n->ninputs()) {	    fprintf(outf, "{");	    for (int i = 0; i < n->ninputs(); i++)		fprintf(outf, (i ? "|<i%d>" : "<i%d>"), i);	    fprintf(outf, "}|");	}	fputs(n->type_name_c_str(), outf);	if (n->noutputs()) {	    fprintf(outf, "|{");	    for (int i = 0; i < n->noutputs(); i++)		fprintf(outf, (i ? "|<o%d>" : "<o%d>"), i);	    fprintf(outf, "}");	}	if (n->ninputs() || n->noutputs())	    fprintf(outf, "}");	fprintf(outf, "\"];\n");#else	if (!n->ninputs() && !n->noutputs())	    fprintf(outf, "  \"%s\" [label=\"%s\"];\n",		    n->name_c_str(), n->type_name_c_str());	else {	    fprintf(outf, "  \"%s\" [label=< <TABLE BORDER=\"0\">", n->name_c_str());	    if (n->ninputs() > 0) {		fprintf(outf, "<TR><TD><TABLE BORDER=\"0\"><TR>");		for (int i = 0; i < n->ninputs(); i++)		    fprintf(outf, "<TD PORT=\"i%d\">X</TD>", i);		fprintf(outf, "</TR></TABLE></TD></TR>");	    }	    fprintf(outf, "<TR><TD>%s</TD></TR>", n->type_name_c_str());	    if (n->noutputs() > 0) {		fprintf(outf, "<TR><TD><TABLE BORDER=\"0\"><TR>");		for (int i = 0; i < n->noutputs(); i++)		    fprintf(outf, "<TD PORT=\"o%d\">X</TD>", i);		fprintf(outf, "</TR></TABLE></TD></TR>");	    }	    fprintf(outf, "</TABLE> >];\n");	}#endif    }    // print all connections    const Vector<ConnectionT> &conns = r->connections();    for (const ConnectionT *c = conns.begin(); c != conns.end(); c++)	fprintf(outf, "  \"%s\":o%d -> \"%s\":i%d;\n",		c->from_element()->name_c_str(), c->from_port(),		c->to_element()->name_c_str(), c->to_port());    fprintf(outf, "}\n");    // close files, return    if (outf != stdout)	fclose(outf);    delete r;}static voidpretty_process_gml(const char *infile, bool file_is_expr, const char *outfile,		   ErrorHandler *errh){    RouterT *r = read_router(infile, file_is_expr, errh);    if (!r)	return;    // open output file    FILE *outf = open_output_file(outfile, errh);    if (!outf) {	delete r;	return;    }    // write dot configuration    fprintf(outf, "Creator \"click-pretty\"\n\graph\n[ hierarchic 1\n\  directed 1\n");    // print all nodes    for (RouterT::const_iterator n = r->begin_elements(); n != r->end_elements(); n++)	fprintf(outf, "  node\n  [ id %d\n    label \"%s\"\n  ]\n", n->eindex(), n->name().c_str());    // print all connections    const Vector<ConnectionT> &conns = r->connections();    for (const ConnectionT *c = conns.begin(); c != conns.end(); c++) {	fprintf(outf, "  edge\n  [ source %d\n    target %d\n", c->from_eindex(), c->to_eindex());	double amt_from = 1. / c->from_element()->noutputs();	double first_from = -(c->from_element()->noutputs() - 1.) * amt_from;	double amt_to = 1. / c->to_element()->ninputs();	double first_to = -(c->to_element()->ninputs() - 1.) * amt_to;	fprintf(outf, "    edgeAnchor\n    [ xSource %f\n      xTarget %f\n      ySource 1\n      yTarget -1\n    ]\n", first_from + c->from_port() * amt_from, first_to + c->to_port() * amt_to);	fprintf(outf, "  ]\n");    }    fprintf(outf, "]\n");    // close files, return    if (outf != stdout)	fclose(outf);    delete r;}static voidpretty_process_graphml(const char *infile, bool file_is_expr, const char *outfile,		       ErrorHandler *errh){    RouterT *r = read_router(infile, file_is_expr, errh);    if (!r)	return;    // get element map and processing    ElementMap emap;    emap.parse_all_files(r, CLICK_DATADIR, errh);    emap.set_driver(emap.pick_driver(specified_driver, r, errh));    ProcessingT processing(r, &emap, errh);    processing.check_types(errh);    // open output file    FILE *outf = open_output_file(outfile, errh);    if (!outf) {	delete r;	return;    }    // write dot configuration    fprintf(outf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\">\n\<key id=\"kn\" for=\"node\" attr.name=\"name\" attr.type=\"string\" />\n\<key id=\"kc\" for=\"node\" attr.name=\"class\" attr.type=\"string\" />\n\<key id=\"kp\" for=\"port\" attr.name=\"processing\" attr.type=\"string\">\n\  <default>a</default>\n\</key>\n\<graph id=\"G\" edgedefault=\"directed\">\n");    // print all nodes    int nodeid = 0;    for (RouterT::iterator n = r->begin_elements(); n != r->end_elements(); n++) {	fprintf(outf, "  <node id=\"n%d\" parse.indegree=\"%d\" parse.outdegree=\"%d\">\n\    <data key=\"kn\">%s</data> <data key=\"kc\">%s</data>\n",		nodeid++, n->ninputs(), n->noutputs(), n->name().c_str(),		n->type_name().c_str());	for (int i = 0; i < n->ninputs(); i++)	    fprintf(outf, "    <port name=\"i%d\"> <data key=\"kp\">%c</data> </port>\n", i, processing.decorated_input_processing_letter(PortT(n.operator->(), i)));	for (int i = 0; i < n->noutputs(); i++)	    fprintf(outf, "    <port name=\"o%d\"> <data key=\"kp\">%c</data> </port>\n", i, processing.decorated_output_processing_letter(PortT(n.operator->(), i)));	fprintf(outf, "  </node>\n");    }    // print all connections    int edgeid = 0;    const Vector<ConnectionT> &conns = r->connections();    for (const ConnectionT *c = conns.begin(); c != conns.end(); c++)	fprintf(outf, "  <edge id=\"e%d\" source=\"n%d\" target=\"n%d\" sourceport=\"o%d\" targetport=\"i%d\" />\n",		edgeid++, c->from_eindex(), c->to_eindex(), c->from_port(), c->to_port());    fprintf(outf, "</graph>\n</graphml>\n");    // close files, return    if (outf != stdout)	fclose(outf);    delete r;}voidusage(){    printf("\'Click-pretty' reads a Click router configuration and outputs an HTML file,\n\based on a template, showing that configuration with syntax highlighting.\n\\n\Usage: %s [OPTION]... [ROUTERFILE]\n\\n\Options:\n\  -f, --file FILE             Read router configuration from FILE.\n\  -e, --expression EXPR       Use EXPR as router configuration.\n\  -o, --output FILE           Write HTML output to FILE.\n\  -t, --template FILE         Use FILE as the template instead of default.\n\  -d, --define NAME=TEXT      Define a new tag, NAME, that expands to TEXT.\n\  -u, --class-docs URL        Link primitive element classes to URL.\n\      --package-docs PKG=URL  Link element classes in package PKG to URL.\n\  -l, --linuxmodule           Prefer Linux kernel module elements.\n\  -b, --bsdmodule             Prefer FreeBSD kernel module elements.\n\      --userlevel             Prefer user-level driver elements.\n\      --write-template        Write template as is, without including router.\n\      --dot                   Output a 'dot' graph definition.\n\      --gml                   Output a GML graph definition.\n\      --graphml               Output a GraphML XML graph definition.\n\  -C, --clickpath PATH        Use PATH for CLICKPATH.\n\      --help                  Print this message and exit.\n\  -v, --version               Print version number and exit.\n\\n\Report bugs to <click@pdos.lcs.mit.edu>.\n", program_name);}intmain(int argc, char **argv){    click_static_initialize();    CLICK_DEFAULT_PROVIDES;    ErrorHandler *errh = ErrorHandler::default_handler();    ErrorHandler *p_errh = new PrefixErrorHandler(errh, "click-pretty: ");    // read command line arguments    Clp_Parser *clp =	Clp_NewParser(argc, argv, sizeof(options)/sizeof(options[0]), options);    Clp_SetOptionChar(clp, '+', Clp_ShortNegated);    program_name = Clp_ProgramName(clp);    const char *router_file = 0;    bool file_is_expr = false;    const char *output_file = 0;    String html_template = default_template;    int action = 0;    while (1) {	int opt = Clp_Next(clp);	switch (opt) {	  case HELP_OPT:	    usage();	    exit(0);	    break;	  case VERSION_OPT:	    printf("click-pretty (Click) %s\n", CLICK_VERSION);	    printf("Copyright (c) 2001-2002 International Computer Science Institute\n\Copyright (c) 2007 Regents of the University of California\n\This is free software; see the source for copying conditions.\n\There is NO warranty, not even for merchantability or fitness for a\n\particular purpose.\n");	    exit(0);	    break;	  case CLICKPATH_OPT:	    set_clickpath(clp->vstr);	    break;	  case CLASS_URLS_OPT:	    package_hrefs.set("x", clp->vstr);	    break;	  case PACKAGE_URLS_OPT: {	      String s = clp->vstr;	      const char *equals = find(s, '=');	      if (equals == s.end()) {		  p_errh->error("'--package-urls' option must contain an equals sign");		  goto bad_option;	      }	      package_hrefs.set("x" + s.substring(s.begin(), equals), s.substring(equals + 1, s.end()));	      break;	  }	  case TEMPLATE_OPT:	    html_template = file_string(clp->vstr, p_errh);	    break;	  case DEFINE_OPT: {	      String s = clp->vstr;	      const char *equals = find(s, '=');	      if (equals < s.end())		  definitions.set(s.substring(s.begin(), equals), s.substring(equals + 1, s.end()));	      else		  definitions.set(s, "");	      break;	  }	  case ROUTER_OPT:	  case EXPRESSION_OPT:	  router_file:	    if (router_file) {		p_errh->error("router configuration specified twice");		goto bad_option;	    }	    router_file = clp->vstr;	    file_is_expr = (opt == EXPRESSION_OPT);	    break;	  case Clp_NotOption:	    if (!click_maybe_define(clp->vstr, p_errh))		goto router_file;	    break;	  case OUTPUT_OPT:	    if (output_file) {		p_errh->error("output file specified twice");		goto bad_option;	    }	    output_file = clp->vstr;	    break;	  case USERLEVEL_OPT:	  case LINUXMODULE_OPT:	  case BSDMODULE_OPT:	    if (specified_driver >= 0) {		p_errh->error("driver specified twice");		goto bad_option;	    }	    specified_driver = opt - FIRST_DRIVER_OPT;	    break;	  case WRITE_TEMPLATE_OPT:	  case DOT_OPT:	  case GML_OPT:	  case GRAPHML_OPT:	    if (action) {		p_errh->error("action specified twice");		goto bad_option;	    }	    action = opt;	    break;	  bad_option:	  case Clp_BadOption:	    short_usage();	    exit(1);	    break;	  case Clp_Done:	    goto done;	}    }  done:    if (action == WRITE_TEMPLATE_OPT) {	if (FILE *f = open_output_file(output_file, errh)) {	    fputs(html_template.c_str(), f);	    fclose(f);	}    } else if (action == DOT_OPT)	pretty_process_dot(router_file, file_is_expr, output_file, errh);    else if (action == GML_OPT)	pretty_process_gml(router_file, file_is_expr, output_file, errh);    else if (action == GRAPHML_OPT)	pretty_process_graphml(router_file, file_is_expr, output_file, errh);    else	pretty_process(router_file, file_is_expr, output_file, html_template.c_str(), errh);    exit(errh->nerrors() > 0 ? 1 : 0);}

⌨️ 快捷键说明

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