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

📄 xml2click.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
📖 第 1 页 / 共 2 页
字号:
// -*- c-basic-offset: 4 -*-/* * click2xml.cc -- translate Click configurations into and out of XML * Eddie Kohler * * Copyright (c) 2002 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 <click/pathvars.h>#include <expat.h>#include "routert.hh"#include "lexert.hh"#include "lexertinfo.hh"#include <click/error.hh>#include <click/driver.hh>#include <click/straccum.hh>#include <click/confparse.hh>#include <click/clp.h>#include "toolutils.hh"#include "processingt.hh"#include "elementmap.hh"#include "xml2click.hh"#define HELP_OPT		300#define VERSION_OPT		301#define CLICKPATH_OPT		302#define ROUTER_OPT		303#define EXPRESSION_OPT		304#define OUTPUT_OPT		305#define FLATTEN_OPT		306static Clp_Option options[] = {    { "clickpath", 'C', CLICKPATH_OPT, Clp_ArgString, 0 },    { "expression", 'e', EXPRESSION_OPT, Clp_ArgString, 0 },    { "file", 'f', ROUTER_OPT, Clp_ArgString, 0 },    { "flatten", 'F', FLATTEN_OPT, 0, Clp_Negate },    { "help", 0, HELP_OPT, 0, 0 },    { "output", 'o', OUTPUT_OPT, Clp_ArgString, 0 },    { "version", 'v', VERSION_OPT, 0, 0 },};static String::Initializer string_initializer;static const char *program_name;static ErrorHandler *xml_errh;static String xml_file;static bool flatten = false;static inline Stringxml_landmark(XML_Parser parser){    return xml_file + ":" + String(XML_GetCurrentLineNumber(parser));}static intxml_error(XML_Parser parser, const char *format, ...){    va_list val;    va_start(val, format);    xml_errh->verror(ErrorHandler::ERR_ERROR, xml_landmark(parser), format, val);    va_end(val);    return -EINVAL;}CxConfig::CxConfig(CxConfig *enclosing, const String &xml_landmark)    : _enclosing(enclosing), _depth(enclosing ? enclosing->_depth + 1 : 0),      _filled(false),      _xml_landmark(xml_landmark),      _decl_ninputs(-1), _decl_noutputs(-1), _decl_nformals(-1),      _type(0), _router(0), _completing(false){}CxConfig::~CxConfig(){    if (_type)	_type->unuse();    if (_router)	_router->unuse();}StringCxConfig::readable_name() const{    return (_name ? _name : String("<anonymous>"));}enum CxState { CX_NONE, CX_CONFIGURATION, CX_ELEMENTCLASS, CX_COMPOUND,	       CX_IN_EMPTY, CX_ERROR };static Vector<CxState> xstates;static Vector<CxConfig *> xstack;static HashMap<String, int> class_id_map(-1);static Vector<CxConfig *> classes;static CxStatedo_element(XML_Parser parser, const XML_Char **attrs, ErrorHandler *errh){    String landmark = xml_landmark(parser);        if (xstates.back() != CX_CONFIGURATION && xstates.back() != CX_COMPOUND) {	if (xstates.back() != CX_ERROR)	    errh->lerror(landmark, "<element> tag outside of <configuration>");	return CX_ERROR;    }        CxElement e;    e.xml_landmark = landmark;    bool ok = true;        String file, line;    for (const XML_Char **a = attrs; *a; a += 2)	if (strcmp(a[0], "name") == 0) {	    if (!cp_is_click_id(a[1]))		errh->lerror(landmark, "'name' attribute not a Click identifier");	    e.name = a[1];	} else if (strcmp(a[0], "classname") == 0) {	    if (!cp_is_click_id(a[1]))		errh->lerror(landmark, "'classname' attribute not a Click identifier");	    e.class_name = a[1];	} else if (strcmp(a[0], "classid") == 0)	    e.class_id = a[1];	else if (strcmp(a[0], "config") == 0)	    e.config = a[1];	else if (strcmp(a[0], "file") == 0)	    file = a[1];	else if (strcmp(a[0], "line") == 0)	    line = a[1];	else if (strcmp(a[0], "ninputs") == 0) {	    if (!cp_integer(a[1], &e.ninputs))		errh->lerror(landmark, "'ninputs' attribute must be an integer");	} else if (strcmp(a[0], "noutputs") == 0) {	    if (!cp_integer(a[1], &e.noutputs))		errh->lerror(landmark, "'noutputs' attribute must be an integer");	}        if (file && line)	e.landmark = file + ":" + line;    else if (file)	e.landmark = file;    else if (line)	e.landmark = "line " + line;    if (e.class_name && e.class_id) {	errh->lerror(landmark, "conflicting attributes 'classname' and 'classid'");	e.class_name = String();    } else if (!e.class_name && !e.class_id) {	errh->lerror(landmark, "element declared without a class");	ok = false;    }    if (!e.name) {	errh->lerror(landmark, "element declared without a name");	ok = false;    }    if (ok)	xstack.back()->_elements.push_back(e);    return CX_IN_EMPTY;}static CxStatedo_connection(XML_Parser parser, const XML_Char **attrs, ErrorHandler *errh){    String landmark = xml_landmark(parser);        if (xstates.back() != CX_CONFIGURATION && xstates.back() != CX_COMPOUND) {	if (xstates.back() != CX_ERROR)	    errh->lerror(landmark, "<connection> tag meaningless outside of <configuration>");	return CX_ERROR;    }        CxConnection e;    e.xml_landmark = landmark;    bool ok = true;        for (const XML_Char **a = attrs; *a; a += 2)	if (strcmp(a[0], "from") == 0)	    e.from = a[1];	else if (strcmp(a[0], "to") == 0)	    e.to = a[1];	else if (strcmp(a[0], "fromport") == 0) {	    if (!cp_integer(a[1], &e.fromport) && e.fromport >= 0)		errh->lerror(landmark, "'fromport' should be port number");	} else if (strcmp(a[0], "toport") == 0) {	    if (!cp_integer(a[1], &e.toport) && e.toport >= 0)		errh->lerror(landmark, "'toport' should be port number");	}    if (!e.from || !e.to) {	errh->lerror(landmark, "connection lacks 'from' or 'to' attribute");	ok = false;    }        if (ok)	xstack.back()->_connections.push_back(e);    return CX_IN_EMPTY;}static CxStatedo_start_elementclass(XML_Parser parser, const XML_Char **attrs, ErrorHandler *errh){    String landmark = xml_landmark(parser);    if (xstates.back() != CX_CONFIGURATION && xstates.back() != CX_COMPOUND) {	if (xstates.back() != CX_ERROR)	    errh->lerror(landmark, "<elementclass> tag outside of <configuration>");	return CX_ERROR;    }    CxConfig *nc = new CxConfig(xstack.back(), landmark);        String file, line;    for (const XML_Char **a = attrs; *a; a += 2)	if (strcmp(a[0], "classname") == 0) {	    if (!cp_is_click_id(a[1]))		errh->lerror(landmark, "'classname' attribute not a valid Click identifier");	    nc->_name = a[1];	} else if (strcmp(a[0], "classid") == 0)	    nc->_id = a[1];	else if (strcmp(a[0], "file") == 0)	    file = a[1];	else if (strcmp(a[0], "line") == 0)	    line = a[1];    if (file && line)	nc->_landmark = file + ":" + line;    else if (file)	nc->_landmark = file;    else if (line)	nc->_landmark = "line " + line;    if (!nc->_id)	errh->lerror(landmark, "element class declared without an ID");    else	class_id_map.insert(nc->_id, classes.size());    classes.push_back(nc);        xstack.push_back(nc);    return CX_ELEMENTCLASS;}static CxStatedo_synonym(XML_Parser parser, const XML_Char **attrs, ErrorHandler *errh){    String landmark = xml_landmark(parser);        if (xstates.back() != CX_ELEMENTCLASS) {	if (xstates.back() != CX_ERROR)	    errh->lerror(landmark, "<synonym> tag outside of <elementclass>");	return CX_ERROR;    } else if (xstack.back()->_filled) {	errh->lerror(landmark, "element class already defined");	return CX_ERROR;    }    CxConfig *cx = xstack.back();    for (const XML_Char **a = attrs; *a; a += 2)	if (strcmp(a[0], "classname") == 0) {	    if (!cp_is_click_id(a[1]))		errh->lerror(landmark, "'classname' attribute not a Click identifier");	    cx->_prev_class_name = a[1];	} else if (strcmp(a[0], "classid") == 0)	    cx->_prev_class_id = a[1];    if (cx->_prev_class_name && cx->_prev_class_id) {	errh->lerror(landmark, "conflicting attributes 'classname' and 'classid'");	cx->_prev_class_name = String();    } else if (!cx->_prev_class_name && !cx->_prev_class_id)	errh->lerror(landmark, "synonym refers to no other class");        cx->_filled = true;    cx->_is_synonym = true;    return CX_IN_EMPTY;}static CxStatedo_start_compound(XML_Parser parser, const XML_Char **attrs, ErrorHandler *errh){    String landmark = xml_landmark(parser);        if (xstates.back() != CX_ELEMENTCLASS) {	if (xstates.back() != CX_ERROR)	    errh->lerror(landmark, "<compound> tag outside of <elementclass>");	return CX_ERROR;    } else if (xstack.back()->_filled) {	errh->lerror(landmark, "element class already defined");	return CX_ERROR;    }    CxConfig *cx = xstack.back();    for (const XML_Char **a = attrs; *a; a += 2)	if (strcmp(a[0], "overloadclassname") == 0) {	    if (!cp_is_click_id(a[1]))		errh->lerror(landmark, "'overloadclassname' attribute not a valid Click identifier");	    cx->_prev_class_name = a[1];	} else if (strcmp(a[0], "overloadclassid") == 0)	    cx->_prev_class_id = a[1];	else if (strcmp(a[0], "ninputs") == 0) {	    if (!cp_integer(a[1], &cx->_decl_ninputs))		errh->lerror(landmark, "'ninputs' attribute must be an integer");	} else if (strcmp(a[0], "noutputs") == 0) {	    if (!cp_integer(a[1], &cx->_decl_noutputs))		errh->lerror(landmark, "'noutputs' attribute must be an integer");	} else if (strcmp(a[0], "nformals") == 0) {	    if (!cp_integer(a[1], &cx->_decl_nformals))		errh->lerror(landmark, "'noutputs' attribute must be an integer");	}    // XXX nformals etc.    if (cx->_prev_class_name && cx->_prev_class_id) {	errh->lerror(landmark, "conflicting attributes 'classname' and 'classid'");	cx->_prev_class_name = String();    }    cx->_filled = true;    cx->_is_synonym = false;    return CX_COMPOUND;}static CxStatedo_formal(XML_Parser parser, const XML_Char **attrs, ErrorHandler *errh){    String landmark = xml_landmark(parser);        if (xstates.back() != CX_COMPOUND) {	if (xstates.back() != CX_ERROR)	    errh->lerror(landmark, "<formal> tag meaningless outside of <compound>");	return CX_ERROR;    }    int number = -1;    String name, key;    for (const XML_Char **a = attrs; *a; a += 2)	if (strcmp(a[0], "name") == 0) {	    name = a[1];	    if (!cp_is_word(name))		errh->lerror(landmark, "'name' should be formal name");	} else if (strcmp(a[0], "number") == 0) {	    if (!cp_integer(a[1], &number) || number < 0)		errh->lerror(landmark, "'number' should be formal argument position");	} else if (strcmp(a[0], "key") == 0) {	    key = a[1];	    if (!cp_is_word(key))		errh->lerror(landmark, "'key' should be formal keyword");	}    while (xstack.back()->_formals.size() <= number) {	xstack.back()->_formals.push_back(String());	xstack.back()->_formal_types.push_back(String());    }    if (xstack.back()->_formals[number])	errh->lerror(landmark, "formal parameter %d already defined as '$%s'", number, xstack.back()->_formals[number].cc());    else {	xstack.back()->_formals[number] = name;	xstack.back()->_formal_types[number] = key;    }    return CX_IN_EMPTY;}extern "C" {static voidstart_element_handler(void *v, const XML_Char *name, const XML_Char **attrs){    XML_Parser parser = (XML_Parser)v;    CxState next_state = CX_ERROR;    // handle XML namespaces    if (strncmp(name, "http://www.lcdf.org/click/xml/|", 31) == 0)

⌨️ 快捷键说明

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