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

📄 script.cc

📁 Click is a modular router toolkit. To use it you ll need to know how to compile and install the sof
💻 CC
📖 第 1 页 / 共 2 页
字号:
	    else if (_args[_insn_pos] == label_error)		last_insn = insn_error;	}    }#if CLICK_USERLEVEL    if (last_insn == INSN_END && _type == type_signal)	for (int i = 0; i < _signos.size(); i++)	    master()->add_signal_handler(_signos[i], router(), name() + ".run");#endif    if (retval) {	int x;	*retval = String();	if (last_insn == INSN_RETURN || last_insn == insn_returnq) {	    if ((x = find_variable(String::make_stable("_", 1), false)) < _vars.size())		*retval = _vars[x + 1];	} else if (last_insn == INSN_END && _type == type_push)	    *retval = String::make_stable("0", 1);    }    if (last_insn == insn_error || last_insn == insn_errorq)	return -1;    else if (last_insn == INSN_STOP)	return 1;    else	return 0;}voidScript::run_timer(Timer *){    // called when a timer expires    assert(_insns[_insn_pos] == INSN_WAIT_TIME || _insns[_insn_pos] == INSN_INITIAL);    ErrorHandler *errh = ErrorHandler::default_handler();    ContextErrorHandler cerrh(errh, "While executing %<%{element}%>:", this);    step(1, STEP_TIMER, 0, &cerrh);    complete_step(0);}voidScript::push(int port, Packet *p){    ErrorHandler *errh = ErrorHandler::default_handler();    ContextErrorHandler cerrh(errh, "While executing %<%{element}%>:", this);    // This is slow, but it probably doesn't need to be fast.    int i = find_variable(String::make_stable("input", 5), true);    _vars[i + 1] = String(port);    _insn_pos = 0;    step(0, STEP_JUMP, 0, &cerrh);    String out;    complete_step(&out);    port = -1;    (void) cp_integer(out, &port);    checked_output_push(port, p);}boolScript::Expander::expand(const String &vname, int vartype, int quote, StringAccum &sa) const{    int x = script->find_variable(vname, false);    if (x < script->_vars.size()) {	sa << cp_expand_in_quotes(script->_vars[x + 1], quote);	return true;    }    if (vname.length() == 1 && vname[0] == '?') {	sa << script->_write_status;	return true;    }    if (vname.equals("args", 4)) {	sa << cp_expand_in_quotes(script->_run_args, quote);	return true;    }    if (vname.length() == 1 && vname[0] == '0') {	sa << script->_run_handler_name;	return true;    }    if (vname.length() > 0 && vname[0] >= '1' && vname[0] <= '9'	&& cp_integer(vname, &x)) {	String arg, run_args = script->_run_args;	for (; x > 0; --x)	    arg = cp_shift_spacevec(run_args);	sa << cp_expand_in_quotes(arg, quote);	return true;    }    if (vname.length() == 1 && vname[0] == '#') {	String run_args = script->_run_args;	for (x = 0; cp_shift_spacevec(run_args); )	    ++x;	sa << cp_expand_in_quotes(String(x), quote);	return true;    }    if (vname.equals("write", 5)) {	sa << cp_unparse_bool(script->_run_op & Handler::OP_WRITE);	return true;    }    if (vartype == '(') {	HandlerCall hc(vname);	if (hc.initialize_read(script, errh) >= 0) {	    sa << cp_expand_in_quotes(hc.call_read(errh), quote);	    return true;	}    }    return false;}intScript::step_handler(int op, String &str, Element *e, const Handler *h, ErrorHandler *errh){    Script *scr = (Script *) e;    String data = cp_uncomment(str);    int nsteps, steptype;    int what = (uintptr_t) h->user_data1();    scr->_run_handler_name = h->name();    scr->_run_args = String();    scr->_run_op = op;    if (what == ST_GOTO) {	int step = scr->find_label(cp_uncomment(data));	if (step >= scr->_insns.size() || step < 0)	    return errh->error("jump to nonexistent label");	for (int i = step; i < scr->_insns.size(); i++)	    if (scr->_insns[i] == INSN_WAIT_STEP)		scr->_args2[i] = 0;	scr->_insn_pos = step;	nsteps = 0, steptype = STEP_JUMP;    } else if (what == ST_RUN) {	scr->_insn_pos = 0;	scr->_run_args = str;	nsteps = 0, steptype = STEP_JUMP;    } else {	if (data == "router")	    nsteps = 1, steptype = STEP_ROUTER;	else if (!data)	    nsteps = 1, steptype = STEP_NORMAL;	else if (cp_integer(data, &nsteps))	    steptype = STEP_NORMAL;	else	    return errh->error("syntax error");    }    if (!scr->_cur_steps) {	int cur_steps = nsteps, njumps = 0;	scr->_cur_steps = &cur_steps;	while ((nsteps = cur_steps) >= 0) {	    cur_steps = -1;	    njumps = scr->step(nsteps, steptype, njumps, errh);	    steptype = ST_STEP;	}	scr->_cur_steps = 0;    } else if (what == ST_STEP)	*scr->_cur_steps += nsteps;    return scr->complete_step(&str);}#if HAVE_INT64_TYPES# define click_intmax_t int64_t# define click_uintmax_t uint64_t# define CLICK_INTMAX_CVT "ll"#else# define click_intmax_t int32_t# define click_uintmax_t uint32_t# define CLICK_INTMAX_CVT 'l'#endifintScript::arithmetic_handler(int, String &str, Element *e, const Handler *h, ErrorHandler *errh){    int what = (uintptr_t) h->user_data1();    switch (what) {    case AR_FIRST:	str = cp_shift_spacevec(str);	return 0;    case AR_ADD:    case AR_SUB:    case AR_MUL:    case AR_DIV:    case AR_IDIV: {	click_intmax_t accum = (what == AR_ADD || what == AR_SUB ? 0 : 1), arg;	bool first = true;#if CLICK_USERLEVEL	double daccum = (what == AR_ADD || what == AR_SUB ? 0 : 1), darg;	bool use_daccum = (what == AR_DIV || what == AR_IDIV);#endif	while (1) {	    String word = cp_shift_spacevec(str);	    if (!word && cp_is_space(str))		break;#if CLICK_USERLEVEL	    if (!use_daccum && !cp_integer(word, &arg)) {		use_daccum = true;		daccum = accum;	    }	    if (use_daccum && !cp_double(word, &darg))		return errh->error("expected list of numbers");	    if (use_daccum) {		if (first)		    daccum = darg;		else if (what == AR_ADD)		    daccum += darg;		else if (what == AR_SUB)		    daccum -= darg;		else if (what == AR_MUL)		    daccum *= darg;		else		    daccum /= darg;		goto set_first;	    }#else	    if (!cp_integer(word, &arg))		return errh->error("expected list of numbers");#endif	    if (first)		accum = arg;	    else if (what == AR_ADD)		accum += arg;	    else if (what == AR_SUB)		accum -= arg;	    else if (what == AR_MUL)		accum *= arg;	    else {#if CLICK_USERLEVEL || !HAVE_INT64_TYPES		accum /= arg;#else		// no int64 divide in the kernel		if (accum > 0x7FFFFFFF || arg > 0x7FFFFFFF)		    errh->warning("int64 divide truncated");		accum = (int32_t) accum / (int32_t) arg;#endif	    }#if CLICK_USERLEVEL	set_first:#endif	    first = false;	}#if CLICK_USERLEVEL	if (what == AR_IDIV) {	    use_daccum = false;	    accum = (click_intmax_t) daccum;	}	str = (use_daccum ? String(daccum) : String(accum));#else	str = String(accum);#endif	return 0;    }    case ar_mod:    case ar_rem: {	String astr = cp_shift_spacevec(str), bstr = cp_shift_spacevec(str);	click_intmax_t a, b;	if (str || !astr || !bstr)	    goto expected_two_numbers;	if (!cp_integer(astr, &a) || !cp_integer(bstr, &b)) {#if CLICK_USERLEVEL	    double da, db;	    if (what == ar_mod || !cp_double(astr, &da) || !cp_double(bstr, &db))		goto expected_two_numbers;	    str = String(fmod(da, db));	    return 0;#else	    goto expected_two_numbers;#endif	} else {#if CLICK_LINUXMODULE	    if ((int32_t) a != a || (int32_t) b != b)		errh->warning("int64 divide truncated");	    a = (int32_t) a % (int32_t) b;#else	    a %= b;#endif	    str = String(a);	    return 0;	}    }    case AR_LT:    case AR_EQ:    case AR_GT:    case AR_LE:    case AR_NE:    case AR_GE: {	String astr = cp_shift_spacevec(str), bstr = cp_shift_spacevec(str);	click_intmax_t a, b;	int comparison;	if (str || !astr || !bstr)	    goto expected_two_numbers;#if CLICK_USERLEVEL	if (!cp_integer(astr, &a) || !cp_integer(bstr, &b)) {	    double da, db;	    if (!cp_double(astr, &da) || !cp_double(bstr, &db))		goto compare_strings;	    comparison = (da < db ? AR_LT : (da == db ? AR_EQ : AR_GT));	    goto compare_return;	}#else	if (!cp_integer(astr, &a) || !cp_integer(bstr, &b))	    goto compare_strings;#endif	comparison = (a < b ? AR_LT : (a == b ? AR_EQ : AR_GT));    compare_return:	str = cp_unparse_bool(what == comparison			      || (what >= AR_GE && what != comparison + 3));	return 0;    compare_strings:	a = String::compare(cp_unquote(astr), cp_unquote(bstr));	comparison = (a < 0 ? AR_LT : (a == 0 ? AR_EQ : AR_GT));	goto compare_return;    }    case AR_NOT: {	bool x;	if (!cp_bool(str, &x))	    return errh->error("syntax error");	str = cp_unparse_bool(!x);	return 0;    }    case ar_and:    case ar_or: {	bool zero = (what == ar_and), current_value = zero;	while (current_value == zero && str) {	    bool x;	    if (!cp_bool(cp_shift_spacevec(str), &x))		return errh->error("syntax error");	    current_value = (what == ar_and ? current_value && x : current_value || x);	}	str = cp_unparse_bool(current_value);	return 0;    }    case ar_if: {	bool x;	if (!cp_bool(cp_shift_spacevec(str), &x))	    return errh->error("syntax error");	if (x)	    str = cp_shift_spacevec(str);	else {	    (void) cp_shift_spacevec(str);	    str = cp_shift_spacevec(str);	}	return 0;    }    case ar_now:	str = Timestamp::now().unparse();	return 0;    case AR_SPRINTF: {	String format = cp_unquote(cp_shift_spacevec(str));	const char *s = format.begin(), *pct, *end = format.end();	StringAccum result;	while ((pct = find(s, end, '%')) < end) {	    result << format.substring(s, pct);	    StringAccum pf;	    // flags	    do {		pf << *pct++;	    } while (pct < end && (*pct == '0' || *pct == '#'				|| *pct == '-' || *pct == ' ' || *pct == '+'));	    // field width	    int fw;	    if (pct < end && *pct == '*') {		if (!cp_integer(cp_shift_spacevec(str), &fw))		    return errh->error("syntax error");		pf << fw;	    } else		while (pct < end && *pct >= '0' && *pct <= '9')		    pf << *pct++;	    // precision	    if (pct < end && *pct == '.') {		pct++;		if (pct < end && *pct == '*') {		    if (!cp_integer(cp_shift_spacevec(str), &fw) || fw < 0)			return errh->error("syntax error");		    pf << '.' << fw;		} else if (pct < end && *pct >= '0' && *pct <= '9') {		    pf << '.';		    while (pct < end && *pct >= '0' && *pct <= '9')			pf << *pct++;		}	    }	    // width	    int width_flag = 0;	    while (1) {		if (pct < end && *pct == 'h')		    width_flag = 'h', pct++;		else if (pct < end && *pct == 'l')		    width_flag = (width_flag == 'l' ? 'q' : 'l'), pct++;		else if (pct < end && (*pct == 'L' || *pct == 'q'))		    width_flag = 'q', pct++;		else		    break;	    }	    // conversion	    if (pct < end && (*pct == 'o' || *pct == 'x' || *pct == 'X' || *pct == 'u')) {		click_uintmax_t ival;		String x = cp_shift_spacevec(str);		if (!cp_integer(x, &ival))		    return errh->error("syntax error");		if (width_flag == 'h')		    ival = (unsigned short) ival;		else if (width_flag == 0 || width_flag == 'l')		    ival = (unsigned long) ival;		pf << CLICK_INTMAX_CVT << *pct;		result << ErrorHandler::xformat(pf.c_str(), ival);	    } else if (pct < end && (*pct == 'd' || *pct == 'i')) {		click_intmax_t ival;		if (!cp_integer(cp_shift_spacevec(str), &ival))		    return errh->error("syntax error");		if (width_flag == 'h')		    ival = (short) ival;		else if (width_flag == 0 || width_flag == 'l')		    ival = (long) ival;		pf << CLICK_INTMAX_CVT << *pct;		result << ErrorHandler::xformat(pf.c_str(), ival);	    } else if (pct < end && *pct == '%') {		pf << '%';		result << ErrorHandler::xformat(pf.c_str());	    } else if (pct < end && *pct == 's') {		String s;		if (!cp_string(cp_shift_spacevec(str), &s))		    return errh->error("syntax error");		pf << *pct;		result << ErrorHandler::xformat(pf.c_str(), s.c_str());	    } else		return errh->error("syntax error");	    s = pct + 1;	}	if (str)	    return errh->error("syntax error");	result << format.substring(s, pct);	str = result.take_string();	return 0;    }    case ar_random: {	if (!str)	    str = String(click_random());	else {	    uint32_t n1, n2;	    bool have_n2 = false;	    if (cp_va_space_kparse(str, e, errh,				   "N1", cpkP+cpkM, cpUnsigned, &n1,				   "N2", cpkP+cpkM+cpkC, &have_n2, cpUnsigned, &n2,				   cpEnd) < 0)		return -1;	    if ((have_n2 && n2 < n1) || (!have_n2 && n1 == 0))		return errh->error("bad N");	    if (have_n2)		str = String(click_random(n1, n2));	    else		str = String(click_random(0, n1 - 1));	}	return 0;    }#if CLICK_USERLEVEL    case ar_cat: {	String filename;	if (!cp_filename(str, &filename))	    return errh->error("bad FILE");	int nerrors = errh->nerrors();	str = file_string(filename, errh);	return (errh->nerrors() == nerrors ? 0 : -errno);    }#endif    case ar_readable:    case ar_writable: {	Element *el;	const Handler *h;	int f = (what == ar_readable ? Handler::OP_READ : Handler::OP_WRITE);	while (String hname = cp_shift_spacevec(str))	    if (!cp_handler(hname, f, &el, &h, e)) {		str = String(false);		return 0;	    }	str = String(true);	return 0;    }    expected_two_numbers:	return errh->error("expected two numbers");    }    return -1;}intScript::star_write_handler(const String &str, Element *e, void *, ErrorHandler *){    Script *s = static_cast<Script *>(e);    s->set_handler(str, Handler::OP_READ | Handler::READ_PARAM | Handler::OP_WRITE, step_handler, ST_RUN, 0);    return Router::hindex(s, str);}voidScript::add_handlers(){    set_handler("step", Handler::OP_WRITE, step_handler, ST_STEP, 0);    set_handler("goto", Handler::OP_WRITE, step_handler, ST_GOTO, 0);    set_handler("run", Handler::OP_READ | Handler::READ_PARAM | Handler::OP_WRITE, step_handler, ST_RUN, 0);    set_handler("add", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, AR_ADD, 0);    set_handler("sub", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, AR_SUB, 0);    set_handler("mul", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, AR_MUL, 0);    set_handler("div", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, AR_DIV, 0);    set_handler("idiv", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, AR_IDIV, 0);    set_handler("mod", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, ar_mod, 0);    set_handler("rem", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, ar_rem, 0);    set_handler("eq", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, AR_EQ, 0);    set_handler("ne", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, AR_NE, 0);    set_handler("gt", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, AR_GT, 0);    set_handler("ge", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, AR_GE, 0);    set_handler("lt", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, AR_LT, 0);    set_handler("le", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, AR_LE, 0);    set_handler("not", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, AR_NOT, 0);    set_handler("sprintf", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, AR_SPRINTF, 0);    set_handler("first", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, AR_FIRST, 0);    set_handler("random", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, ar_random, 0);    set_handler("and", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, ar_and, 0);    set_handler("or", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, ar_or, 0);    set_handler("if", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, ar_if, 0);    set_handler("in", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, ar_in, 0);    set_handler("now", Handler::OP_READ, arithmetic_handler, ar_now, 0);    set_handler("readable", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, ar_readable, 0);    set_handler("writable", Handler::OP_READ | Handler::READ_PARAM, arithmetic_handler, ar_writable, 0);#if CLICK_USERLEVEL    set_handler("cat", Handler::OP_READ | Handler::READ_PARAM | Handler::READ_PRIVATE, arithmetic_handler, ar_cat, 0);#endif    if (_type == type_proxy)	add_write_handler("*", star_write_handler, 0);}EXPORT_ELEMENT(Script)CLICK_ENDDECLS

⌨️ 快捷键说明

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