--- parser3/src/classes/op.C 2008/01/28 16:01:43 1.173 +++ parser3/src/classes/op.C 2008/05/26 14:23:46 1.178 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_OP_C="$Date: 2008/01/28 16:01:43 $"; +static const char * const IDENT_OP_C="$Date: 2008/05/26 14:23:46 $"; #include "classes.h" #include "pa_vmethod_frame.h" @@ -102,19 +102,22 @@ static void _if(Request& r, MethodParams r.write_pass_lang(r.process(*params.get(2))); } -static void _untaint(Request& r, MethodParams& params) { +static String::Language get_untaint_lang(MethodParams& params, int index){ + const String& lang_name=params.as_string(index, "lang must be string"); + String::Language lang=untaint_lang_name2enum.get(lang_name); + if(!lang) + throw Exception(0, + &lang_name, + "invalid taint language"); + return lang; +} +static void _untaint(Request& r, MethodParams& params) { String::Language lang; if(params.count()==1) - lang=String::L_AS_IS; // mark as simply 'tainted'. useful in html from sql - else { - const String& lang_name=params.as_string(0, "lang must be string"); - lang=untaint_lang_name2enum.get(lang_name); - if(!lang) - throw Exception(0, - &lang_name, - "invalid taint language"); - } + lang=String::L_AS_IS; // mark as simply 'as-is'. useful in html from sql + else + lang=get_untaint_lang(params, 0); { Value& vbody=params.as_junction(params.count()-1, "body must be code"); @@ -127,15 +130,9 @@ static void _untaint(Request& r, MethodP static void _taint(Request& r, MethodParams& params) { String::Language lang; if(params.count()==1) - lang=String::L_TAINTED; // mark as simply 'tainted'. useful in table:set - else { - const String& lang_name=params.as_string(0, "lang must be string"); - lang=untaint_lang_name2enum.get(lang_name); - if(!lang) - throw Exception(0, - &lang_name, - "invalid taint language"); - } + lang=String::L_TAINTED; // mark as simply 'tainted'. useful in table:create + else + lang=get_untaint_lang(params, 0); { Value& vbody=params.as_no_junction(params.count()-1, "body must not be code"); @@ -268,7 +265,8 @@ static void _while(Request& r, MethodPar 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; + else + need_delim=true; } r.write_pass_lang(sv_processed); @@ -329,7 +327,8 @@ static void _for(Request& r, MethodParam 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; + else + need_delim=true; } r.write_pass_lang(sv_processed); @@ -344,8 +343,12 @@ static void _eval(Request& r, MethodPara Value& value_result=r.process_to_value(expr, false/*don't intercept string*/).as_expr_result(); if(params.count()>1) { - Value& fmt=params.as_no_junction(1, "fmt must not be code"); - r.write_no_lang(String(format(value_result.as_double(), fmt.as_string().cstrm()))); + const String& fmt=params.as_string(1, "fmt must be string").trim(); + if(fmt.is_empty()){ + r.write_no_lang(value_result); + } else { + r.write_no_lang(String(format(value_result.as_double(), fmt.cstrm()))); + } } else r.write_no_lang(value_result); } @@ -723,10 +726,10 @@ static void _cache(Request& r, MethodPar Cache_get_result cached=cache_get(r.charsets, file_spec, now); if(cached.body) { // have cached copy - if(cached.expired) { - scope.body_from_disk=cached.body; // storing for user to retrive it with ^cache[] - } else { - // and it's not expired yet write it out + if(cached.expired) { + scope.body_from_disk=cached.body; // storing for user to retrive it with ^cache[] + } else { + // and it's not expired yet write it out r.write_assign_lang(*cached.body); // happy with it return; @@ -736,15 +739,15 @@ static void _cache(Request& r, MethodPar // no cached info or it's already expired // trying to process it under lock and store result in file - const String* processed_body=locked_process_and_cache_put(r, body_code, catch_code, scope, file_spec); + const String* processed_body=locked_process_and_cache_put(r, body_code, catch_code, scope, file_spec); if(processed_body){ - // write it out - r.write_assign_lang(*processed_body); - // happy with it - return; + // write it out + r.write_assign_lang(*processed_body); + // happy with it + return; } else { // we fail while get exclusive lock. nvm, we just execute body_code a bit later - } + } } else { // instructed not to cache; forget cached copy cache_delete(file_spec); @@ -777,7 +780,7 @@ static void _try_operator(Request& r, Me } static void _throw_operator(Request&, MethodParams& params) { - if(params.count()==1) { + if(params.count()==1 && !params[0].is_string()) { if(HashStringValue *hash=params[0].get_hash()) { const char* type=0; if(Value* value=hash->get(exception_type_part_name)) @@ -795,13 +798,12 @@ static void _throw_operator(Request&, Me } else throw Exception(PARSER_RUNTIME, 0, - "one-param version has hash param"); + "one-param version has hash or string param"); } else { const char* type=params.as_string(0, "type must be string").cstr(); - const String& source=params.as_string(1, "source must be string"); - const char* comment=params.count()>2? params.as_string(2, "comment must be string").cstr() - :0; - throw Exception(type, &source, "%s", comment?comment:""); + const String* source=params.count()>1? ¶ms.as_string(1, "source must be string"):0; + const char* comment=params.count()>2? params.as_string(2, "comment must be string").cstr():0; + throw Exception(type, source, "%s", comment?comment:""); } }