?? click-combine.cc
字號:
// combine links link_id.clear(); for (int i = 0; i < links_from.size(); i++) link_id.push_back(i); bool done = false; while (!done) { done = true; for (int i = 1; i < links_from.size(); i++) for (int j = 0; j < i; j++) if ((links_from[i] == links_from[j] || links_to[i] == links_to[j]) && link_id[i] != link_id[j]) { link_id[i] = link_id[j]; done = false; } } return 0;}static voidmake_link(const Vector<RouterPortT> &from, const Vector<RouterPortT> &to, RouterT *combined){ static int linkno = 0; Vector<RouterPortT> all(from); for (int i = 0; i < to.size(); i++) all.push_back(to[i]); Vector<ElementT *> combes; Vector<String> words; for (int i = 0; i < all.size(); i++) { int r = all[i].port; ElementT *e = all[i].element; String name = router_names[r] + "/" + e->name(); combes.push_back(combined->element(name)); assert(combes.back()); words.push_back(router_names[r] + " " + e->name() + " " + e->type_name()); words.push_back(e->configuration()); } // add new element ElementClassT *link_type = ElementClassT::base_type("RouterLink"); ElementT *newe = combined->get_element ("link" + String(++linkno), link_type, cp_unargvec(words), "<click-combine>"); for (int i = 0; i < from.size(); i++) { combined->insert_before(PortT(newe, i), PortT(combes[i], 0)); combined->free_element(combes[i]); } for (int j = from.size(); j < combes.size(); j++) { combined->insert_after(PortT(newe, j - from.size()), PortT(combes[j], 0)); combined->free_element(combes[j]); }}static voidadd_links(RouterT *r){ Vector<int> done(link_id.size(), 0); for (int i = 0; i < links_from.size(); i++) if (!done[link_id[i]]) { // find all input & output ports Vector<RouterPortT> from, to; for (int j = 0; j < links_from.size(); j++) if (link_id[j] == link_id[i]) { if (links_from[j].index_in(from) < 0) from.push_back(links_from[j]); if (links_to[j].index_in(to) < 0) to.push_back(links_to[j]); } // add single link make_link(from, to, r); done[link_id[i]] = 1; }}intmain(int argc, char **argv){ click_static_initialize(); CLICK_DEFAULT_PROVIDES; ErrorHandler *errh = ErrorHandler::default_handler(); ErrorHandler *p_errh = new PrefixErrorHandler(errh, "click-combine: "); // 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 *output_file = 0; String next_name; int next_number = 1; Vector<String> link_texts; bool config_only = false; while (1) { int opt = Clp_Next(clp); switch (opt) { case HELP_OPT: usage(); exit(0); break; case VERSION_OPT: printf("click-combine (Click) %s\n", CLICK_VERSION); printf("Copyright (c) 2000 Massachusetts Institute of Technology\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 ROUTER_OPT: cc_read_router(String(), next_name, next_number, clp->arg, false, errh); break; case EXPRESSION_OPT: cc_read_router(String(), next_name, next_number, clp->arg, true, errh); break; case OUTPUT_OPT: if (output_file) { p_errh->error("output file specified twice"); goto bad_option; } output_file = clp->arg; break; case NAME_OPT: if (next_name) p_errh->warning("router name specified twice"); next_name = clp->arg; break; case LINK_OPT: link_texts.push_back(clp->arg); break; case CONFIG_OPT: config_only = true; break; case Clp_NotOption: if (const char *s = strchr(clp->arg, ':')) cc_read_router(String(clp->arg, s - clp->arg), next_name, next_number, s + 1, false, errh); else if (const char *eq = strchr(clp->arg, '=')) { const char *dot = strchr(clp->arg, '.'); if (!dot || dot > eq) cc_read_router(String(clp->arg, eq - clp->arg), next_name, next_number, eq + 1, false, errh); else link_texts.push_back(clp->arg); } else cc_read_router(String(), next_name, next_number, clp->arg, false, errh); break; bad_option: case Clp_BadOption: short_usage(); exit(1); break; case Clp_Done: goto done; } } done: // no routers is an error if (routers.size() == 0) p_errh->fatal("no routers specified"); // check that routers are named differently HashMap<String, int> name_map(-1); for (int i = 0; i < routers.size(); i++) { if (name_map[router_names[i]] >= 0) p_errh->fatal("two routers named '%s'", router_names[i].cc()); name_map.insert(router_names[i], i); } // define links for (int i = 0; i < link_texts.size(); i++) parse_link(link_texts[i], p_errh); // exit if there have been errors if (errh->nerrors() != 0) exit(1); // open output file FILE *outf = stdout; if (output_file && strcmp(output_file, "-") != 0) { outf = fopen(output_file, "w"); if (!outf) errh->fatal("%s: %s", output_file, strerror(errno)); } // combine routers RouterT *combined = new RouterT; VariableEnvironment empty_ve; for (int i = 0; i < routers.size(); i++) routers[i]->expand_into(combined, router_names[i], empty_ve, errh); // exit if there have been errors (again) if (errh->nerrors() != 0) exit(1); // nested combinations: change config strings of included RouterLinks ElementClassT *link_type = ElementClassT::base_type("RouterLink"); for (RouterT::type_iterator x = combined->begin_elements(link_type); x; x++) frob_nested_routerlink(x); // make links if (links_from.size() == 0) errh->warning("no links between routers"); if (combine_links(p_errh) < 0) exit(1); add_links(combined); combined->remove_tunnels(); // add elementmap to archive if (!config_only) { ElementMap em; if (link_id.size()) { ElementTraits t; t.name = "RouterLink"; t.processing_code = "l/h"; t.flow_code = "x/x"; t.flags = "S3"; em.add(t); } // add data from included elementmaps for (int i = 0; i < routers.size(); i++) if (routers[i]->archive_index("elementmap.xml") >= 0) { ArchiveElement &nae = routers[i]->archive("elementmap.xml"); em.parse(nae.data); } if (!em.empty()) { combined->add_archive(init_archive_element("elementmap.xml", 0600)); ArchiveElement &ae = combined->archive("elementmap.xml"); ae.data = em.unparse(); } } // add componentmap to archive if (!config_only) { combined->add_archive(init_archive_element("componentmap", 0600)); ArchiveElement &ae = combined->archive("componentmap"); StringAccum sa; for (int i = 0; i < routers.size(); i++) { sa << router_names[i] << '\n'; if (routers[i]->archive_index("componentmap") >= 0) { ArchiveElement &nae = routers[i]->archive("componentmap"); Vector<String> combines; cp_spacevec(nae.data, combines); for (int j = 0; j < combines.size(); j++) sa << router_names[i] << '/' << combines[j] << '\n'; } } ae.data = sa.take_string(); } write_router_file(combined, outf, errh); exit(0);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -