--- parser3/src/classes/op.C 2005/12/06 07:46:59 1.152.4.10 +++ parser3/src/classes/op.C 2005/08/09 08:14:48 1.155 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_OP_C="$Date: 2005/12/06 07:46:59 $"; +static const char * const IDENT_OP_C="$Date: 2005/08/09 08:14:48 $"; #include "classes.h" #include "pa_vmethod_frame.h" @@ -22,7 +22,7 @@ static const char * const IDENT_OP_C="$D // limits -#define MAX_LOOPS 20000 +#define MAX_LOOPS 10000 // defines @@ -76,7 +76,6 @@ public: ULN("optimized-xml", XML|String::L_OPTIMIZE_BIT); ULN("html", HTML); ULN("optimized-html", HTML|String::L_OPTIMIZE_BIT); - ULN("regex", REGEX); #undef ULN } } untaint_lang_name2enum; @@ -84,11 +83,14 @@ public: // methods static void _if(Request& r, MethodParams& params) { - bool condition=params.as_bool(0, "condition must be expression", r); + Value& condition_code=params.as_junction(0, "condition must be expression"); + + bool condition=r.process_to_value(condition_code, + false/*don't intercept string*/).as_bool(); if(condition) - r.write_pass_lang(r.process(*params.get(1))); + r.write_pass_lang(r.process(params.as_junction(1, "'then' parameter must be code"))); else if(params.count()>2) - r.write_pass_lang(r.process(*params.get(2))); + r.write_pass_lang(r.process(params.as_junction(2, "'else' parameter must be code"))); } static void _untaint(Request& r, MethodParams& params) { @@ -230,12 +232,10 @@ static void _rem(Request&, MethodParams& static void _while(Request& r, MethodParams& params) { Value& vcondition=params.as_junction(0, "condition must be expression"); - Value& body_code=params.as_junction(1, "body must be code"); - Value* delim_maybe_code=params.count()>2?¶ms[2]:0; + Value& body=params.as_junction(1, "body must be code"); // while... int endless_loop_count=0; - bool need_delim=false; while(true) { if(++endless_loop_count>=MAX_LOOPS) // endless loop? throw Exception("parser.runtime", @@ -247,14 +247,8 @@ static void _while(Request& r, MethodPar if(!condition) // ...condition is true break; - StringOrValue sv_processed=r.process(body_code); - const String* s_processed=sv_processed.get_string(); - if(delim_maybe_code && s_processed && s_processed->length()) { // delimiter set and we have body - if(need_delim) // need delim & iteration produced string? - r.write_pass_lang(r.process(*delim_maybe_code)); - need_delim=true; - } - r.write_pass_lang(sv_processed); + // write processed body + r.write_pass_lang(r.process(body)); } } @@ -279,7 +273,7 @@ static void _for(Request& r, MethodParam VInt* vint=new VInt(0); VMethodFrame& caller=*r.get_method_frame()->caller(); - caller.put_element(var_name, vint, false); + caller.put_element(caller, var_name, vint, false); for(int i=from; i<=to; i++) { vint->set_int(i); @@ -387,21 +381,19 @@ static void _case(Request& r, MethodPara int count=params.count(); Value& code=params.as_junction(--count, "case result must be code"); - Value& searching=data->searching; - bool we_are_searching_string=searching.is_string(); for(int i=0; i_default=&code; break; } bool matches; - if(we_are_searching_string) - matches=searching.as_string() == value.as_string(); + if(data->searching.is_string()) + matches=data->searching.as_string() == value.as_string(); else - matches=searching.as_double() == value.as_double(); + matches=data->searching.as_double() == value.as_double(); if(matches) { if(data->found) @@ -427,7 +419,7 @@ struct Try_catch_result { template static Try_catch_result try_catch(Request& r, StringOrValue body_code(Request&, I), I info, - Value* catch_code, bool could_be_handled_by_caller=false) + Value* catch_code) { Try_catch_result result; if(!catch_code) { @@ -448,23 +440,20 @@ static Try_catch_result try_catch(Reques Value* method_frame=junction->method_frame; Value* saved_exception_var_value=method_frame->get_element(exception_var_name, *method_frame, false); VMethodFrame& frame=*junction->method_frame; - frame.put_element(exception_var_name, &details.vhash, false); + frame.put_element(frame, exception_var_name, &details.vhash, false); result.processed_code=r.process(*catch_code); // retriving $exception.handled, restoring $exception var Value* vhandled=details.vhash.hash().get(exception_handled_part_name); - frame.put_element(exception_var_name, saved_exception_var_value, false); + frame.put_element(frame, exception_var_name, saved_exception_var_value, false); bool bhandled=false; if(vhandled) { if(vhandled->is_string()) { // not simple $exception.handled(1/0)? - if(could_be_handled_by_caller) { // and we can possibly handle it result.exception_should_be_handled=vhandled->get_string(); // considering 'recovered' and let the caller recover return result; } - bhandled=false; - } else bhandled=vhandled->as_bool(); } @@ -512,7 +501,7 @@ struct Locked_process_and_cache_put_acti static StringOrValue process_cache_body_code(Request& r, Value* body_code) { - return StringOrValue(&r.process_to_string(*body_code), 0); + return StringOrValue(r.process_to_string(*body_code)); } /* @todo maybe network order worth spending some effort? @@ -523,17 +512,19 @@ static void locked_process_and_cache_put Locked_process_and_cache_put_action_info& info= *static_cast(context); - - const String* body_from_disk=info.scope->body_from_disk; // body->process Try_catch_result result=try_catch(*info.r, process_cache_body_code, info.body_code, - info.catch_code, body_from_disk!=0 /*we have something old=we can handle=recover later*/); + info.catch_code); if(result.exception_should_be_handled) { if(*result.exception_should_be_handled==CACHE_EXCEPTION_HANDLED_CACHE_NAME) { - assert(body_from_disk); + if(const String* body_from_disk=info.scope->body_from_disk) // we have something old? info.processed_code=body_from_disk; + else + throw Exception(0, + new String("$"EXCEPTION_VAR_NAME"."EXCEPTION_HANDLED_PART_NAME"["CACHE_EXCEPTION_HANDLED_CACHE_NAME"]"), + "fallback failed - there is no old cached body"); } else throw Exception("parser.runtime", result.exception_should_be_handled, @@ -623,18 +614,6 @@ static const String& as_file_spec(Reques return r.absolute(params.as_string(index, "filespec must be string")); } static void _cache(Request& r, MethodParams& params) { - if(params.count()==0) - { - // return current expiration time - Cache_scope* scope=static_cast(r.classes_conf.get(cache_data_name)); - if(!scope) - throw Exception("parser.runtime", - 0, - "expire-time get without cache"); - r.write_no_lang(*new VDate(scope->expires)); - return; - } - time_t now=time(0); // ^cache[filename] ^cache(seconds) ^cache[expires date] @@ -838,8 +817,7 @@ VClassMAIN::VClassMAIN(): VClass() { // ^cache[file_spec](time){code}[{catch code}] time=0 no cache // ^cache[file_spec] delete cache - // ^cache[] get current expiration time - add_native_method("cache", Method::CT_ANY, _cache, 0, 4); + add_native_method("cache", Method::CT_ANY, _cache, 1, 4); // switch