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

📄 runparse.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
字号:
// -*- c-basic-offset: 4 -*-/* * runparse.cc -- unparse a tool router * Eddie Kohler * * Copyright (c) 1999-2000 Massachusetts Institute of Technology * Copyright (c) 2000 Mazu Networks, Inc. * Copyright (c) 2001-2003 International Computer Science Institute * * 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 "routert.hh"#include "eclasst.hh"#include <click/bitvector.hh>#include <click/confparse.hh>#include <click/straccum.hh>#include <click/variableenv.hh>#include <stdio.h>static voidadd_line_directive(StringAccum &sa, const String &landmark){    int colon = landmark.find_right(':');    // XXX protect filename    if (colon >= 0)	sa << "# " << landmark.substring(colon + 1) << " \""	   << landmark.substring(0, colon) << "\"\n";    else	sa << "# 0 \"" << landmark << "\"\n";}voidElementClassT::unparse_declaration(StringAccum &sa, const String &, UnparseKind uk, ElementClassT *){    if (uk == UNPARSE_OVERLOAD)	sa << " ...\n";}voidSynonymElementClassT::unparse_declaration(StringAccum &sa, const String &indent, UnparseKind uk, ElementClassT *){    if (uk == UNPARSE_OVERLOAD)	sa << " ...\n";    else if (uk == UNPARSE_NAMED)	sa << indent << "elementclass " << name() << " " << _eclass->name() << ";\n";}voidRouterT::unparse_declaration(StringAccum &sa, const String &indent, UnparseKind uk, ElementClassT *stop){    assert(!_circularity_flag && (name() || uk != UNPARSE_NAMED));    // stop early: scope control    if (stop == this) {	if (uk == UNPARSE_OVERLOAD)	    sa << " ...\n";	return;    }        _circularity_flag = true;    if (uk == UNPARSE_NAMED)	sa << indent << "elementclass " << name() << " {";    else if (uk == UNPARSE_ANONYMOUS)	sa << '{';    if (_overload_type) {	_overload_type->unparse_declaration(sa, indent, UNPARSE_OVERLOAD, stop);	sa << indent << "||";    }    // print formals    for (int i = 0; i < _formals.size(); i++) {	sa << (i ? ", " : " ");	if (_formal_types[i])	    sa << _formal_types[i] << ' ';	sa << _formals[i];    }    if (_formals.size())	sa << " |";    sa << "\n";    unparse(sa, indent + "  ");    if (uk == UNPARSE_NAMED)	sa << indent << "}\n";    else if (uk == UNPARSE_ANONYMOUS)	sa << indent << '}';    _circularity_flag = false;}voidRouterT::unparse_requirements(StringAccum &sa, const String &indent) const{    if (_requirements.size() > 0) {	sa << indent << "require(";	for (int i = 0; i < _requirements.size(); i++) {	    if (i) sa << ", ";	    sa << _requirements[i];	}	sa << ");\n\n";    }}#if 0RouterUnparserT::RouterUnparserT(ErrorHandler *errh)    : _tuid_map(-1), _relation(X_UNK), _errh(errh ? errh : ErrorHandler::silent_handler()){}int RouterUnparseT::relation_negater[X_NUM] = {    X_BAD, X_UNK, X_GT, X_GEQ, X_EQ, X_LEQ, X_LT};uint8_t RouterUnparseT::relation_combiner[X_NUM][X_NUM] = {    //X_BAD, X_UNK, X_LT,  X_LEQ, X_EQ,  X_GEQ, X_GT    { X_BAD, X_BAD, X_BAD, X_BAD, X_BAD, X_BAD, X_BAD }, // X_BAD    { X_BAD, X_UNK, X_LT,  X_LEQ, X_EQ,  X_GEQ, X_GT  }, // X_UNK    { X_BAD, X_LT,  X_LT,  X_LT,  X_BAD, X_BAD, X_BAD }, // X_LT    { X_BAD, X_LEQ, X_LT,  X_LEQ, X_EQ,  X_EQ,  X_BAD }, // X_LEQ    { X_BAD, X_EQ,  X_BAD, X_EQ,  X_EQ,  X_EQ,  X_BAD }, // X_EQ    { X_BAD, X_GEQ, X_BAD, X_EQ,  X_EQ,  X_GEQ, X_GT  }, // X_GEQ    { X_BAD, X_GT,  X_BAD, X_BAD, X_BAD, X_GT,  X_GT  }  // X_GT};intRouterUnparseT::apply_relation(ElementClassT *a, ElementClassT *b, int new_relation){    assert(new_relation >= X_LT && new_relation <= X_GT);    if (a->uid() > b->uid()) {	swap(a, b);	new_relation = relation_negater[new_relation];    }        int *relation = _relation.findp(make_pair(a, b));    int old_relation = *relation;    *relation = relation_combiner[old_relation][new_relation];    return (*relation != X_BAD || old_relation == X_BAD ? 0 : -1);}voidRouterUnparseT::collect_types(){    HashMap<int, ElementClassT *> class_map;    collect_types(class_map);    for (HashMap<int, ElementClassT *>::iterator i = class_map.begin(); i; i++) {	_tuid_map.insert(k.key(), _types.size());	_types.push_back(k.value());    }}voidRouterUnparseT::relate_types(){    // collect type relations    for (Vector<ElementClassT *>::iterator i = _types.begin(); i != _types.end(); i++)	if (RouterT *r = i->cast_router())	    if (r->previous() && apply_relation(c, c->previous(), X_GEQ))		_errh->lerror(c->landmark(), "circular type relationship involving '%s'", c->printable_name_c_str());}#elsevoidRouterT::unparse_declarations(StringAccum &sa, const String &indent) const{    int nelements = _elements.size();    int ntypes = _declared_types.size();    check();    // We may need to interleave element class declarations and element    // declarations because of scope issues.    // type_to_scope[] maps each type name to the latest scope in which it is    // good.    HashMap<ElementClassT *, int> type_to_scope(-2);    for (int i = 0; i < ntypes; i++) {	const ElementType &t = _declared_types[i];	type_to_scope.insert(t.type, _scope_cookie);	if (t.prev_name >= 0) {	    const ElementType &pt = _declared_types[t.prev_name];	    type_to_scope.insert(pt.type, pt.scope_cookie);	}    }    // XXX FIXME    //for (const_iterator e = begin_elements(); e; e++)    //    assert(e->tunnel() || type_to_scope[e->type()] >= -1);    // For each scope:    // First print the element class declarations with that scope,    // then print the elements whose classes are good only at that scope.    int print_state = 0;    for (int scope = -2; scope <= _scope_cookie; scope++) {	for (Vector<ElementType>::const_iterator t = _declared_types.begin(); t != _declared_types.end(); t++)	    if (t->scope_cookie == scope && t->name()		&& !t->type->primitive()) {		ElementClassT *stop_class = declared_type(t->name(), t->scope_cookie - 1);		if (print_state == 2)		    sa << "\n";		t->type->unparse_declaration(sa, indent, ElementClassT::UNPARSE_NAMED, stop_class);		print_state = 1;	    }	for (const_iterator e = begin_elements(); e; e++) {	    if (e->dead() || e->tunnel()		|| type_to_scope[e->type()] != scope)		continue;	    if (print_state == 1)		sa << "\n";	    add_line_directive(sa, e->landmark());	    sa << indent << e->name() << " :: ";	    if (e->type()->name())		sa << e->type()->name();	    else		e->type()->unparse_declaration(sa, indent, ElementClassT::UNPARSE_ANONYMOUS, 0);	    if (e->configuration())		sa << "(" << e->configuration() << ")";	    sa << ";\n";	    print_state = 2;	}    }        // print tunnel pairs    for (int i = 0; i < nelements; i++)	if (_elements[i]->tunnel() && _elements[i]->tunnel_output()) {	    add_line_directive(sa, _elements[i]->landmark());	    if (print_state > 0)		sa << "\n";	    sa << indent << "connectiontunnel " << _elements[i]->name()	       << " -> " << _elements[i]->tunnel_output()->name() << ";\n";	    print_state = 3;	}}#endifvoidRouterT::unparse_connections(StringAccum &sa, const String &indent) const{    // mark loser connections    int nc = _conn.size();    Bitvector used(nc, false);    for (int c = 0; c < nc; c++)	if (_conn[c].dead())	    used[c] = true;    // prepare hookup chains    Vector<int> next(nc, -1);    Bitvector startchain(nc, true);    for (int c = 0; c < nc; c++) {	const PortT &ht = _conn[c].to();	if (ht.port != 0 || used[c])	    continue;	int result = -1;	for (int d = 0; d < nc; d++)	    if (d != c && _conn[d].from() == ht && !used[d]) {		result = d;		if (_conn[d].to().port == 0)		    break;	    }	if (result >= 0) {	    next[c] = result;	    startchain[result] = false;	}    }    // count line numbers so we can give reasonable error messages    if (nc) {	int lineno = 1;	const char *s = sa.data();	int len = sa.length();	for (int i = 0; i < len; i++)	    if (s[i] == '\n')		lineno++;	sa << "# " << lineno + 1 << " \"\"\n";    }    // print hookup    bool done = false;    while (!done) {	// print chains	for (int c = 0; c < nc; c++) {	    const PortT &hf = _conn[c].from();	    if (used[c] || !startchain[c])		continue;	    	    sa << indent << hf.element->name();	    if (hf.port)		sa << " [" << hf.port << "]";	    int d = c;	    while (d >= 0 && !used[d]) {		if (d == c)		    sa << " -> ";		else		    sa << "\n" << indent << "    -> ";		const PortT &ht = _conn[d].to();		if (ht.port)		    sa << "[" << ht.port << "] ";		sa << ht.element->name();		used[d] = true;		d = next[d];	    }	    sa << ";\n";	}	// add new chains to include cycles	done = true;	for (int c = 0; c < nc && done; c++)	    if (!used[c])		startchain[c] = true, done = false;    }}voidRouterT::unparse(StringAccum &sa, const String &indent) const{    unparse_requirements(sa, indent);    unparse_declarations(sa, indent);    unparse_connections(sa, indent);}StringRouterT::configuration_string() const{    StringAccum sa;    unparse(sa);    return sa.take_string();}

⌨️ 快捷键说明

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