|
|
| version 1.89, 2002/04/16 08:22:19 | version 1.100, 2002/08/07 11:25:36 |
|---|---|
| Line 3 | Line 3 |
| Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) | Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) |
| Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) | Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) |
| $Id$ | |
| */ | */ |
| static const char* IDENT_OP_C="$Date$"; | |
| #include "classes.h" | #include "classes.h" |
| #include "pa_common.h" | #include "pa_common.h" |
| #include "pa_request.h" | #include "pa_request.h" |
| Line 20 | Line 20 |
| // defines | // defines |
| #define OP_CLASS_NAME "OP" | |
| #define CASE_DEFAULT_VALUE "DEFAULT" | #define CASE_DEFAULT_VALUE "DEFAULT" |
| // class | // class |
| Line 92 static void _taint(Request& r, const Str | Line 91 static void _taint(Request& r, const Str |
| { | { |
| Value& vbody=params->as_no_junction(params->size()-1, "body must not be code"); | Value& vbody=params->as_no_junction(params->size()-1, "body must not be code"); |
| String result(r.pool()); | String& result=*new(pool) String(pool); |
| result.append( | result.append( |
| vbody.as_string(), // process marking tainted with that lang | vbody.as_string(), // process marking tainted with that lang |
| lang, true); // force result language to specified | lang, true); // force result language to specified |
| Line 101 static void _taint(Request& r, const Str | Line 100 static void _taint(Request& r, const Str |
| } | } |
| static void _process(Request& r, const String& method_name, MethodParams *params) { | static void _process(Request& r, const String& method_name, MethodParams *params) { |
| Pool& pool=r.pool(); | |
| // calculate pseudo file name of processed chars | // calculate pseudo file name of processed chars |
| // would be something like "/some/file(4) process" | // would be something like "/some/file(4) process" |
| char local_place[MAX_STRING]; | char local_place[MAX_STRING]; |
| Line 123 static void _process(Request& r, const S | Line 123 static void _process(Request& r, const S |
| // temporary remove language change | // temporary remove language change |
| Temp_lang temp_lang(r, String::UL_PASS_APPENDED); | Temp_lang temp_lang(r, String::UL_PASS_APPENDED); |
| // temporary zero @main so to maybe-replace it in processed code | // temporary zero @main so to maybe-replace it in processed code |
| Temp_method temp_method_main(self_class, *main_method_name, 0); | Temp_method temp_method_main(self_class, r.main_method_name, 0); |
| // temporary zero @auto so it wouldn't be auto-called in Request::use_buf | // temporary zero @auto so it wouldn't be auto-called in Request::use_buf |
| Temp_method temp_method_auto(self_class, *auto_method_name, 0); | Temp_method temp_method_auto(self_class, *auto_method_name, 0); |
| Line 134 static void _process(Request& r, const S | Line 134 static void _process(Request& r, const S |
| // maybe-define new @main | // maybe-define new @main |
| r.use_buf( | r.use_buf( |
| source.cstr(String::UL_UNSPECIFIED, r.connection(0)), | source.cstr(String::UL_UNSPECIFIED, r.connection(0)), |
| *new(pool) String(pool, heap_place, place_size, true /*tainted*/), | |
| heap_place, | heap_place, |
| &self_class); | &self_class); |
| // main_method | // main_method |
| main_method=self_class.get_method(*main_method_name); | main_method=self_class.get_method(r.main_method_name); |
| } | } |
| // after restoring current-request-lang | // after restoring current-request-lang |
| // maybe-execute @main[] | // maybe-execute @main[] |
| Line 197 static void _for(Request& r, const Strin | Line 198 static void _for(Request& r, const Strin |
| bool need_delim=false; | bool need_delim=false; |
| VInt *vint=new(pool) VInt(pool, 0); | VInt *vint=new(pool) VInt(pool, 0); |
| r.root->put_element(var_name, vint); | |
| for(int i=from; i<=to; i++) { | for(int i=from; i<=to; i++) { |
| vint->set_int(i); | vint->set_int(i); |
| r.root->put_element(var_name, vint); | |
| StringOrValue processed_body=r.process(body_code); | StringOrValue processed_body=r.process(body_code); |
| if(delim_maybe_code) { // delimiter set? | if(delim_maybe_code) { // delimiter set? |
| Line 215 static void _for(Request& r, const Strin | Line 216 static void _for(Request& r, const Strin |
| static void _eval(Request& r, const String& method_name, MethodParams *params) { | static void _eval(Request& r, const String& method_name, MethodParams *params) { |
| Value& expr=params->as_junction(0, "need expression"); | Value& expr=params->as_junction(0, "need expression"); |
| // evaluate expresion | // evaluate expresion |
| Value *result=r.process_to_value(expr, | Value *value_result=r.process_to_value(expr, |
| /*0/*no name YET* /,*/ | /*0/*no name YET* /,*/ |
| true/*don't intercept string*/).as_expr_result(); | true/*don't intercept string*/).as_expr_result(); |
| if(params->size()>1) { | if(params->size()>1) { |
| Line 223 static void _eval(Request& r, const Stri | Line 224 static void _eval(Request& r, const Stri |
| Pool& pool=r.pool(); | Pool& pool=r.pool(); |
| String& string=*new(pool) String(pool); | String& string=*new(pool) String(pool); |
| string.APPEND_CONST(format(pool, result->as_double(), fmt.as_string().cstr())); | string.APPEND_CONST(format(pool, value_result->as_double(), fmt.as_string().cstr())); |
| result=new(pool) VString(string); | r.write_no_lang(string); |
| } | } else |
| result->set_name(method_name); | r.write_no_lang(*value_result); |
| r.write_no_lang(*result); | |
| } | } |
| static void _connect(Request& r, const String& method_name, MethodParams *params) { | static void _connect(Request& r, const String& method_name, MethodParams *params) { |
| Line 402 const String *locked_process_and_cache_p | Line 402 const String *locked_process_and_cache_p |
| "cache_put", locked_process_and_cache_put_action, &info, | "cache_put", locked_process_and_cache_put_action, &info, |
| false/*as_text*/, | false/*as_text*/, |
| false/*do_append*/, | false/*do_append*/, |
| false/*block*/) ? info.evaluated_body: 0; | false/*block*/, |
| if(data.expires==0) | false/*fail on lock problem*/) ? info.evaluated_body: 0; |
| time_t now=time(0); | |
| if(data.expires<=now) | |
| cache_delete(file_spec); | cache_delete(file_spec); |
| return result; | return result; |
| } | } |
| Line 535 static void _cache(Request& r, const Str | Line 537 static void _cache(Request& r, const Str |
| VHash& exception2vhash(Pool& pool, const Exception& e) { | VHash& exception2vhash(Pool& pool, const Exception& e) { |
| VHash& result=*new(pool) VHash(pool); | VHash& result=*new(pool) VHash(pool); |
| Hash& hash=result.hash(0); | Hash& hash=result.hash(0); |
| if(const char *type=e.type()) | if(const char *type=e.type(true)) |
| hash.put(*exception_type_part_name, new(pool) VString(*new(pool) String(pool, type))); | hash.put(*exception_type_part_name, new(pool) VString(*new(pool) String(pool, type))); |
| if(const String *asource=e.problem_source()) { | if(const String *asource=e.problem_source()) { |
| String& source=*new(pool) String(pool); | String& source=*new(pool) String(pool); |
| source.append(*asource, String::UL_TAINTED, true/*forced*/); | source.append(*asource, String::UL_TAINTED, true/*forced*/); |
| result.set_name(source); | |
| hash.put(*exception_source_part_name, new(pool) VString(source)); | hash.put(*exception_source_part_name, new(pool) VString(source)); |
| #ifndef NO_STRING_ORIGIN | #ifndef NO_STRING_ORIGIN |
| Line 551 VHash& exception2vhash(Pool& pool, const | Line 552 VHash& exception2vhash(Pool& pool, const |
| new(pool) VInt(pool, 1+origin.line)); | new(pool) VInt(pool, 1+origin.line)); |
| #endif | #endif |
| } | } |
| if(const char *ecomment=e.comment()) { | if(const char *ecomment=e.comment(true)) { |
| int comment_size=strlen(ecomment); | int comment_size=strlen(ecomment); |
| char *pcomment=(char *)pool.malloc(comment_size); | char *pcomment=(char *)pool.malloc(comment_size); |
| memcpy(pcomment, ecomment, comment_size); | memcpy(pcomment, ecomment, comment_size); |
| Line 631 static void _throw_operator(Request& r, | Line 632 static void _throw_operator(Request& r, |
| } else { | } else { |
| const char *type=params->as_string(0, "type must be string").cstr(); | const char *type=params->as_string(0, "type must be string").cstr(); |
| const String& source=params->as_string(1, "source must be string"); | const String& source=params->as_string(1, "source must be string"); |
| const char *comment=params->as_string(2, "comment must be string").cstr(); | const char *comment=params->size()>2?params->as_string(2, "comment must be string").cstr():0; |
| throw Exception(type, &source, comment); | throw Exception(type, &source, "%s", comment?comment:""); |
| } | } |
| } | } |
| // constructor | // constructor |
| MOP::MOP(Pool& apool) : Methoded(apool), | MOP::MOP(Pool& apool) : Methoded(apool, "OP"), |
| main_sql_name(apool, MAIN_SQL_NAME), | main_sql_name(apool, MAIN_SQL_NAME), |
| main_sql_drivers_name(apool, MAIN_SQL_DRIVERS_NAME) | main_sql_drivers_name(apool, MAIN_SQL_DRIVERS_NAME) |
| { | { |
| set_name(*NEW String(pool(), OP_CLASS_NAME)); | |
| // ^if(condition){code-when-true} | // ^if(condition){code-when-true} |
| // ^if(condition){code-when-true}{code-when-false} | // ^if(condition){code-when-true}{code-when-false} |
| add_native_method("if", Method::CT_ANY, _if, 2, 3); | add_native_method("if", Method::CT_ANY, _if, 2, 3); |