--- parser3/src/classes/op.C 2001/09/05 09:02:52 1.40 +++ parser3/src/classes/op.C 2001/10/10 12:52:13 1.52 @@ -2,10 +2,10 @@ Parser: parser @b operators. Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) - Author: Alexander Petrosyan (http://design.ru/paf) + + $Id: op.C,v 1.52 2001/10/10 12:52:13 parser Exp $ */ -static const char *RCSId="$Id: op.C,v 1.40 2001/09/05 09:02:52 parser Exp $"; #include "classes.h" #include "pa_config_includes.h" @@ -39,21 +39,21 @@ private: // methods static void _if(Request& r, const String&, MethodParams *params) { - Value& condition_code=params->get(0); + Value& condition_code=params->as_junction(0, "condition must be expression"); bool condition=r.process(condition_code, 0/*no name*/, false/*don't intercept string*/).as_bool(); if(condition) r.write_pass_lang(r.process(params->as_junction(1, "'then' parameter must be code"))); - else if(params->size()==3) + else if(params->size()>2) r.write_pass_lang(r.process(params->as_junction(2, "'else' parameter must be code"))); } static void _untaint(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); - const String& lang_name=r.process(params->get(0)).as_string(); + const String& lang_name=params->as_string(0, "lang must be string"); String::Untaint_lang lang=static_cast( untaint_lang_name2enum->get_int(lang_name)); if(!lang) @@ -76,8 +76,7 @@ static void _taint(Request& r, const Str if(params->size()==1) lang=String::UL_TAINTED; // mark as simply 'tainted'. useful in table:set else { - const String& lang_name= - r.process(params->get(0)).as_string(); + const String& lang_name=params->as_string(0, "lang must be string"); lang=static_cast( untaint_lang_name2enum->get_int(lang_name)); if(!lang) @@ -119,7 +118,7 @@ static void _process(Request& r, const S // evaluate source to process const String& source= - r.process(params->get(0)).as_string(); + r.process(params->as_no_junction(0, "body must be string")).as_string(); // process source code, append processed methods to 'self' class // maybe-define new @main @@ -171,11 +170,11 @@ static void _use(Request& r, const Strin static void _for(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); - const String& var_name=r.process(params->get(0)).as_string(); - int from=r.process(params->get(1)).as_int(); - int to=r.process(params->get(2)).as_int(); + const String& var_name=params->as_string(0, "var name must be string"); + int from=params->as_int(1, "from must be int", r); + int to=params->as_int(2, "to must be int", r); Value& body_code=params->as_junction(3, "body must be code"); - Value *delim_code=params->size()==3+1+1?¶ms->get(3+1):0; + Value *delim_maybe_code=params->size()>4?¶ms->get(4):0; bool need_delim=false; VInt *vint=new(pool) VInt(pool, 0); @@ -186,13 +185,13 @@ static void _for(Request& r, const Strin &method_name, "endless loop detected"); vint->set_int(i); - r.root->put_element(var_name, vint); + r.self/*root*/->put_element(var_name, vint); Value& processed_body=r.process(body_code); - if(delim_code) { // delimiter set? + if(delim_maybe_code) { // delimiter set? const String *string=processed_body.get_string(); if(need_delim && string && string->size()) // need delim & iteration produced string? - r.write_pass_lang(r.process(*delim_code)); + r.write_pass_lang(r.process(*delim_maybe_code)); need_delim=true; } r.write_pass_lang(processed_body); @@ -205,7 +204,7 @@ static void _eval(Request& r, const Stri Value *result=r.process(expr, 0/*no name YET*/, true/*don't intercept string*/).as_expr_result(); - if(params->size()==2) { + if(params->size()>1) { Value& fmt=params->as_no_junction(1, "fmt must not be code"); Pool& pool=r.pool(); @@ -217,8 +216,17 @@ static void _eval(Request& r, const Stri r.write_no_lang(*result); } +static void _error(Request& r, const String& method_name, MethodParams *params) { + Pool& pool=r.pool(); + + const String& serror=params->as_string(0, "message must be string"); + PTHROW(0, 0, + &method_name, + "%s", serror.cstr()); +} -static void _connect(Request& r, const String&, MethodParams *params) { + +static void _connect(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); Value& url=params->as_no_junction(0, "url must not be code"); @@ -229,7 +237,7 @@ static void _connect(Request& r, const S // connect SQL_Connection& connection=SQL_driver_manager->get_connection( - url.as_string(), protocol2driver_and_client); + url.as_string(), method_name, protocol2driver_and_client); Exception rethrow_me; // remember/set current connection @@ -267,12 +275,13 @@ static void _connect(Request& r, const S rethrow_me.comment()); } +#ifndef DOXYGEN struct Switch_data { Value *searching; Value *found; Value *_default; }; - +#endif static void _switch(Request& r, const String&, MethodParams *params) { void *backup=r.classes_conf.get(*switch_data_name); Switch_data data={&r.process(params->get(0))}; @@ -340,7 +349,7 @@ MOP::MOP(Pool& apool) : Methoded(apool), add_native_method("process", Method::CT_ANY, _process, 1, 1); // ^rem{code} - add_native_method("rem", Method::CT_ANY, _rem, 1, 1000); + add_native_method("rem", Method::CT_ANY, _rem, 1, 10000); // ^while(condition){code} add_native_method("while", Method::CT_ANY, _while, 2, 2); @@ -355,6 +364,9 @@ MOP::MOP(Pool& apool) : Methoded(apool), // ^eval(expr)[format] add_native_method("eval", Method::CT_ANY, _eval, 1, 2); + // ^error[msg] + add_native_method("error", Method::CT_ANY, _error, 1, 1); + // ^connect[protocol://user:pass@host[:port]/database]{code with ^sql-s} add_native_method("connect", Method::CT_ANY, _connect, 2, 2); @@ -365,7 +377,7 @@ MOP::MOP(Pool& apool) : Methoded(apool), add_native_method("switch", Method::CT_ANY, _switch, 2, 2); // ^case[value]{code} - add_native_method("case", Method::CT_ANY, _case, 2, 1000); + add_native_method("case", Method::CT_ANY, _case, 2, 10000); } // constructor & configurator @@ -374,7 +386,6 @@ Methoded *MOP_create(Pool& pool) { return new(pool) MOP(pool); } - void MOP::configure_user(Request& r) { Pool& pool=r.pool();