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

📄 click-mkmindriver.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
📖 第 1 页 / 共 2 页
字号:
// -*- c-basic-offset: 4 -*-/* * click-mkmindriver.cc -- produce a minimum Click driver Makefile setup * Eddie Kohler * * Copyright (c) 2001 Massachusetts Institute of Technology * Copyright (c) 2001 International Computer Science Institute * Copyright (c) 2004 Regents of the University of California * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */#include <click/config.h>#include <click/pathvars.h>#include <click/error.hh>#include <click/confparse.hh>#include <click/straccum.hh>#include <click/driver.hh>#include "lexert.hh"#include "routert.hh"#include "toolutils.hh"#include "elementmap.hh"#include <click/clp.h>#include <stdio.h>#include <ctype.h>#include <time.h>#define HELP_OPT		300#define VERSION_OPT		301#define CLICKPATH_OPT		302#define ROUTER_OPT		303#define EXPRESSION_OPT		304#define PACKAGE_OPT		306#define DIRECTORY_OPT		307#define KERNEL_OPT		308#define USERLEVEL_OPT		309#define ELEMENT_OPT		310#define ALIGN_OPT		311#define ALL_OPT			312#define CHECK_OPT		313#define VERBOSE_OPT		314static Clp_Option options[] = {  { "align", 'A', ALIGN_OPT, 0, 0 },  { "all", 'a', ALL_OPT, 0, Clp_Negate },  { "check", 0, CHECK_OPT, 0, Clp_Negate },  { "clickpath", 'C', CLICKPATH_OPT, Clp_ArgString, 0 },  { "directory", 'd', DIRECTORY_OPT, Clp_ArgString, 0 },  { "elements", 'E', ELEMENT_OPT, Clp_ArgString, 0 },  { "expression", 'e', EXPRESSION_OPT, Clp_ArgString, 0 },  { "file", 'f', ROUTER_OPT, Clp_ArgString, Clp_Negate },  { "help", 0, HELP_OPT, 0, 0 },  { "kernel", 'k', KERNEL_OPT, 0, 0 },  { "linuxmodule", 0, KERNEL_OPT, 0, 0 },  { "package", 'p', PACKAGE_OPT, Clp_ArgString, 0 },  { "userlevel", 'u', USERLEVEL_OPT, 0, 0 },  { "verbose", 'V', VERBOSE_OPT, 0, Clp_Negate }};static const char *program_name;static String::Initializer string_initializer;static int driver = -1;static HashMap<String, int> initial_requirements(-1);static bool verbose = false;voidshort_usage(){  fprintf(stderr, "Usage: %s -p PKGNAME [OPTION]... [ROUTERFILE]...\n\Try '%s --help' for more information.\n",	  program_name, program_name);}voidusage(){  printf("\'Click-mkmindriver' produces a Makefile that builds a minimum Click driver\n\for a set of router configurations. This driver contains just the elements\n\those configurations require. Run 'click-mkmindriver' in the relevant driver's\n\build directory and supply a package name with the '-p PKG' option. The\n\resulting Makefile is called 'Makefile.PKG'; it will build either a 'PKGclick'\n\user-level driver or a 'PKGclick.o' kernel module.\n\\n\Usage: %s -p PKG [OPTION]... [ROUTERFILE]...\n\\n\Options:\n\  -p, --package PKG        Name of package is PKG.\n\  -f, --file FILE          Read a router configuration from FILE.\n\  -e, --expression EXPR    Use EXPR as a router configuration.\n\  -a, --all                Add all element classes from following configs,\n\                           even those in unused compound elements.\n\  -k, --linuxmodule        Build Makefile for Linux kernel module driver.\n\  -u, --userlevel          Build Makefile for user-level driver (default).\n\  -d, --directory DIR      Put files in DIR. DIR must contain a 'Makefile'\n\                           for the relevant driver. Default is '.'.\n\  -E, --elements ELTS      Include element classes ELTS.\n\  -A, --align              Include element classes required by click-align.\n\      --no-file            Don't read a configuration from standard input.\n\      --no-check           Don't check the directory for a driver Makefile.\n\  -V, --verbose            Print progress information.\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);}class Mindriver { public:    Mindriver();    void provide(const String&, ErrorHandler*);    void require(const String&, ErrorHandler*);    void add_source_file(const String&, ErrorHandler*);        void add_router_requirements(RouterT*, const ElementMap&, ErrorHandler*);    bool add_traits(const Traits&, const ElementMap&, ErrorHandler*);    bool resolve_requirement(const String& requirement, const ElementMap& emap, ErrorHandler* errh, bool complain = true);    void print_elements_conf(FILE*, String package, const ElementMap&);        HashMap<String, int> _provisions;    HashMap<String, int> _requirements;    HashMap<String, int> _source_files;    };Mindriver::Mindriver()    : _provisions(-1), _requirements(-1), _source_files(-1){}voidMindriver::provide(const String& req, ErrorHandler* errh){    if (verbose && _provisions[req] < 0)	errh->message("providing '%s'", req.c_str());    _provisions.insert(req, 1);}voidMindriver::require(const String& req, ErrorHandler* errh){    if (_provisions[req] < 0) {	if (verbose && _requirements[req] < 0)	    errh->message("requiring '%s'", req.c_str());	_requirements.insert(req, 1);    }}voidMindriver::add_source_file(const String& fn, ErrorHandler* errh){    if (verbose && _source_files[fn] < 0)	errh->message("adding source file '%s'", fn.c_str());    _source_files.insert(fn, 1);}voidMindriver::add_router_requirements(RouterT* router, const ElementMap& default_map, ErrorHandler* errh){    // find and parse elementmap    ElementMap emap(default_map);    emap.parse_requirement_files(router, CLICK_SHAREDIR, errh);    // check whether suitable for driver    if (!emap.driver_compatible(router, driver)) {	errh->error("not compatible with %s driver; ignored", Driver::name(driver));	return;    }    emap.set_driver(driver);    StringAccum missing_sa;    int nmissing = 0;    HashMap<ElementClassT*, int> primitives(-1);    router->collect_types(primitives);    for (HashMap<ElementClassT*, int>::iterator i = primitives.begin(); i; i++) {	if (!i.key()->primitive())	    continue;	String tname = i.key()->name();	if (!emap.has_traits(tname))	    missing_sa << (nmissing++ ? ", " : "") << tname;	else if (emap.package(tname))	    /* do nothing; element was defined in a package */;	else	    require(tname, errh);    }    if (nmissing == 1)	errh->fatal("cannot locate required element class '%s'\n(This may be due to a missing or out-of-date 'elementmap.xml'.)", missing_sa.c_str());    else if (nmissing > 1)	errh->fatal("cannot locate these required element classes:\n  %s\n(This may be due to a missing or out-of-date 'elementmap.xml'.)", missing_sa.c_str());}static voidhandle_router(Mindriver& md, String filename_in, const ElementMap &default_map, ErrorHandler *errh){    // decide if 'filename' should be flattened    bool flattenable = (filename_in[0] != 'a');    bool file_is_expr = (filename_in[1] == 'e');    const char *filename = filename_in.c_str() + 2;    // read file    int before = errh->nerrors();    RouterT *router = read_router(filename, file_is_expr, errh);    if (file_is_expr)	filename = "<expr>";    else if (!filename || strcmp(filename, "-") == 0)	filename = "<stdin>";    LandmarkErrorHandler lerrh(errh, filename);    if (router && flattenable)	router->flatten(&lerrh);    if (router && errh->nerrors() == before)	md.add_router_requirements(router, default_map, &lerrh);    delete router;}boolMindriver::add_traits(const Traits& t, const ElementMap&, ErrorHandler* errh){    if (t.source_file)	add_source_file(t.source_file, errh);    if (t.name)	provide(t.name, errh);    if (t.provisions) {	Vector<String> args;	cp_spacevec(t.provisions, args);	for (String* s = args.begin(); s < args.end(); s++)	    if (Driver::driver(*s) < 0)		provide(*s, errh);    }    if (t.requirements) {	Vector<String> args;	cp_spacevec(t.requirements, args);	for (String* s = args.begin(); s < args.end(); s++)	    require(*s, errh);    }    return true;}boolMindriver::resolve_requirement(const String& requirement, const ElementMap& emap, ErrorHandler* errh, bool complain){    LandmarkErrorHandler lerrh(errh, "resolving " + requirement);        if (_provisions[requirement] > 0)	return true;    int try_name_emapi = emap.traits_index(requirement);    if (try_name_emapi > 0) {	add_traits(emap.traits_at(try_name_emapi), emap, &lerrh);	return true;    }      for (int i = 1; i < emap.size(); i++)	if (emap.traits_at(i).provides(requirement)) {	    add_traits(emap.traits_at(i), emap, &lerrh);	    return true;	}    // check for '|' requirements    const char *begin = requirement.begin(), *bar;    while ((bar = find(begin, requirement.end(), '|')) < requirement.end()) {	if (resolve_requirement(requirement.substring(begin, bar), emap, errh, false))	    return true;	begin = bar + 1;    }    if (complain)	errh->error("cannot satisfy requirement '%s'", requirement.c_str());    return false;}voidMindriver::print_elements_conf(FILE *f, String package, const ElementMap &emap){    Vector<String> sourcevec;    for (HashMap<String, int>::iterator iter = _source_files.begin();	 iter;	 iter++) {	iter.value() = sourcevec.size();	sourcevec.push_back(iter.key());    }

⌨️ 快捷键说明

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