|
|
| version 1.127.2.15, 2003/02/21 08:23:09 | version 1.127.2.22.2.3, 2003/03/19 13:16:55 |
|---|---|
| Line 16 static const char* IDENT_OP_C="$Date$"; | Line 16 static const char* IDENT_OP_C="$Date$"; |
| #include "pa_sql_connection.h" | #include "pa_sql_connection.h" |
| #include "pa_vdate.h" | #include "pa_vdate.h" |
| #include "pa_vmethod_frame.h" | #include "pa_vmethod_frame.h" |
| #include "pa_vclass.h" | |
| // limits | // limits |
| Line 30 static const char* IDENT_OP_C="$Date$"; | Line 31 static const char* IDENT_OP_C="$Date$"; |
| class VClassMAIN: public VClass { | class VClassMAIN: public VClass { |
| public: | public: |
| VClassMAIN(); | VClassMAIN(); |
| override ~VClassMAIN() {} | |
| }; | }; |
| // defines for statics | // defines for statics |
| Line 45 public: | Line 47 public: |
| // statics | // statics |
| //^switch ^case | //^switch ^case |
| static StringPtr switch_data_name(new String(SWITCH_DATA_NAME)); | static const String& switch_data_name(new String(SWITCH_DATA_NAME)); |
| //^cache | //^cache |
| static StringPtr cache_data_name(new String(CACHE_DATA_NAME)); | static const String& cache_data_name(new String(CACHE_DATA_NAME)); |
| static StringPtr exception_var_name(new String(EXCEPTION_VAR_NAME)); | |
| static StringPtr exception_type_part_name(new String(EXCEPTION_TYPE_PART_NAME)); | |
| static StringPtr exception_source_part_name(new String(EXCEPTION_SOURCE_PART_NAME)); | |
| static StringPtr exception_comment_part_name(new String(EXCEPTION_COMMENT_PART_NAME)); | |
| static StringPtr exception_handled_part_name(new String(EXCEPTION_HANDLED_PART_NAME)); | |
| static const String& exception_var_name(new String(EXCEPTION_VAR_NAME)); | |
| static const String& exception_type_part_name(new String(EXCEPTION_TYPE_PART_NAME)); | |
| static const String& exception_source_part_name(new String(EXCEPTION_SOURCE_PART_NAME)); | |
| static const String& exception_comment_part_name(new String(EXCEPTION_COMMENT_PART_NAME)); | |
| static const String& exception_handled_part_name(new String(EXCEPTION_HANDLED_PART_NAME)); | |
| // helpers | // helpers |
| class Untaint_lang_name2enum: public Hash<StringPtr, int> { | class Untaint_lang_name2enum: public Hash<String* , int> { |
| public: | public: |
| Untaint_lang_name2enum() { | Untaint_lang_name2enum() { |
| #define ULN(name, LANG) \ | #define ULN(name, LANG) \ |
| put(StringPtr(new String(name)), (value_type)String::UL_##LANG); | put(String* (new String(name)), (value_type)String::UL_##LANG); |
| ULN("as-is", AS_IS); | ULN("as-is", AS_IS); |
| ULN("optimized-as-is", AS_IS|String::UL_OPTIMIZE_BIT); | ULN("optimized-as-is", AS_IS|String::UL_OPTIMIZE_BIT); |
| ULN("file-spec", FILE_SPEC); | ULN("file-spec", FILE_SPEC); |
| Line 82 public: | Line 83 public: |
| // methods | // methods |
| static void _if(Request& r, StringPtr /*method_name*/, MethodParams* params) { | static void _if(Request& r, const String& /*method_name*/, MethodParams* params) { |
| ValuePtr condition_code=params->as_junction(0, "condition must be expression"); | ValuePtr condition_code=params->as_junction(0, "condition must be expression"); |
| bool condition=r.process_to_value(condition_code, | bool condition=r.process_to_value(condition_code, |
| Line 94 static void _if(Request& r, StringPtr /* | Line 95 static void _if(Request& r, StringPtr /* |
| r.write_pass_lang(r.process(params->as_junction(2, "'else' parameter must be code"))); | r.write_pass_lang(r.process(params->as_junction(2, "'else' parameter must be code"))); |
| } | } |
| static void _untaint(Request& r, StringPtr method_name, MethodParams* params) { | static void _untaint(Request& r, const String& method_name, MethodParams* params) { |
| Pool& pool=r.pool(); | |
| uchar lang; | String_UL lang; |
| if(params->count()==1) | if(params->count()==1) |
| lang=String::UL_AS_IS; // mark as simply 'tainted'. useful in html from sql | lang=String::UL_AS_IS; // mark as simply 'tainted'. useful in html from sql |
| else { | else { |
| StringPtr lang_name=params->as_string(0, "lang must be string"); | const String& lang_name=params->as_string(0, "lang must be string"); |
| lang=untaint_lang_name2enum.get(lang_name); | lang=untaint_lang_name2enum.get(lang_name); |
| if(!lang) | if(!lang) |
| throw Exception(0, | throw Exception(0, |
| Line 117 static void _untaint(Request& r, StringP | Line 117 static void _untaint(Request& r, StringP |
| } | } |
| } | } |
| static void _taint(Request& r, StringPtr /*method_name*/, MethodParams* params) { | static void _taint(Request& r, const String& /*method_name*/, MethodParams* params) { |
| Pool& pool=r.pool(); | |
| uchar lang; | String_UL lang; |
| if(params->count()==1) | if(params->count()==1) |
| lang=String::UL_TAINTED; // mark as simply 'tainted'. useful in table:set | lang=String::UL_TAINTED; // mark as simply 'tainted'. useful in table:set |
| else { | else { |
| StringPtr lang_name=params->as_string(0, "lang must be string"); | const String& lang_name=params->as_string(0, "lang must be string"); |
| lang=untaint_lang_name2enum.get(lang_name); | lang=untaint_lang_name2enum.get(lang_name); |
| if(!lang) | if(!lang) |
| throw Exception(0, | throw Exception(0, |
| Line 143 static void _taint(Request& r, StringPtr | Line 142 static void _taint(Request& r, StringPtr |
| } | } |
| } | } |
| static void _process(Request& r, StringPtr method_name, MethodParams* params) { | static void _process(Request& r, const String& method_name, MethodParams* params) { |
| Pool& pool=r.pool(); | const String* source; // must be declared here to prevent premature destruction |
| StringPtr source; // must be declared here to prevent premature destruction | |
| MethodPtr main_method; | MethodPtr main_method; |
| ValuePtr target_self=params->count()>1? | ValuePtr target_self=params->count()>1? |
| params->as_no_junction(0, "target must not be code") | params->as_no_junction(0, "target must not be code") |
| Line 192 static void _process(Request& r, StringP | Line 190 static void _process(Request& r, StringP |
| // process source code, append processed methods to 'self' class | // process source code, append processed methods to 'self' class |
| // maybe-define new @main | // maybe-define new @main |
| r.use_buf(*target_class, | r.use_buf(*target_class, |
| source->cstr(pool, String::UL_UNSPECIFIED, r.connection(StringPtr(0))), | source->cstr(pool, String::UL_UNSPECIFIED, r.connection(0)), |
| StringPtr(new String(heap_place, place_size, true /*tainted*/)), | String* (new String(heap_place, place_size, true /*tainted*/)), |
| heap_place); | heap_place); |
| // main_method | // main_method |
| Line 209 static void _process(Request& r, StringP | Line 207 static void _process(Request& r, StringP |
| } | } |
| } | } |
| static void _rem(Request& r, StringPtr /*method_name*/, MethodParams* params) { | static void _rem(Request& r, const String& /*method_name*/, MethodParams* params) { |
| params->as_junction(0, "body must be code"); | params->as_junction(0, "body must be code"); |
| } | } |
| static void _while(Request& r, StringPtr method_name, MethodParams* params) { | static void _while(Request& r, const String& method_name, MethodParams* params) { |
| Pool& pool=r.pool(); | |
| ValuePtr vcondition=params->as_junction(0, "condition must be expression"); | ValuePtr vcondition=params->as_junction(0, "condition must be expression"); |
| ValuePtr body=params->as_junction(1, "body must be code"); | ValuePtr body=params->as_junction(1, "body must be code"); |
| Line 238 static void _while(Request& r, StringPtr | Line 235 static void _while(Request& r, StringPtr |
| } | } |
| } | } |
| static void _use(Request& r, StringPtr method_name, MethodParams* params) { | static void _use(Request& r, const String& method_name, MethodParams* params) { |
| Pool& pool=r.pool(); | |
| ValuePtr vfile=params->as_no_junction(0, "file name must not be code"); | ValuePtr vfile=params->as_no_junction(0, "file name must not be code"); |
| r.use_file(*r.main_class, vfile->as_string(&pool)); | r.use_file(*r.main_class, vfile->as_string(&pool)); |
| } | } |
| static void _for(Request& r, StringPtr method_name, MethodParams* params) { | static void _for(Request& r, const String& method_name, MethodParams* params) { |
| Pool& pool=r.pool(); | const String& var_name=params->as_string(0, "var name must be string"); |
| StringPtr var_name=params->as_string(0, "var name must be string"); | |
| int from=params->as_int(1, "from must be int", r); | int from=params->as_int(1, "from must be int", r); |
| int to=params->as_int(2, "to must be int", r); | int to=params->as_int(2, "to must be int", r); |
| ValuePtr body_code=params->as_junction(3, "body must be code"); | ValuePtr body_code=params->as_junction(3, "body must be code"); |
| Line 264 static void _for(Request& r, StringPtr m | Line 259 static void _for(Request& r, StringPtr m |
| vint->set_int(i); | vint->set_int(i); |
| StringOrValue sv_processed=r.process(body_code); | StringOrValue sv_processed=r.process(body_code); |
| StringPtr s_processed=sv_processed.get_string(); | const String& s_processed=sv_processed.get_string(); |
| if(delim_maybe_code && s_processed && s_processed->size()) { // delimiter set and we have body | if(delim_maybe_code && s_processed && s_processed->size()) { // delimiter set and we have body |
| if(need_delim) // need delim & iteration produced string? | if(need_delim) // need delim & iteration produced string? |
| r.write_pass_lang(r.process(delim_maybe_code)); | r.write_pass_lang(r.process(delim_maybe_code)); |
| Line 274 static void _for(Request& r, StringPtr m | Line 269 static void _for(Request& r, StringPtr m |
| } | } |
| } | } |
| static void _eval(Request& r, StringPtr method_name, MethodParams* params) { | static void _eval(Request& r, const String& method_name, MethodParams* params) { |
| ValuePtr expr=params->as_junction(0, "need expression"); | ValuePtr expr=params->as_junction(0, "need expression"); |
| // evaluate expresion | // evaluate expresion |
| ValuePtr value_result=r.process_to_value(expr, | ValuePtr value_result=r.process_to_value(expr, |
| Line 282 static void _eval(Request& r, StringPtr | Line 277 static void _eval(Request& r, StringPtr |
| true/*don't intercept string*/)->as_expr_result(); | true/*don't intercept string*/)->as_expr_result(); |
| if(params->count()>1) { | if(params->count()>1) { |
| ValuePtr fmt=params->as_no_junction(1, "fmt must not be code"); | ValuePtr fmt=params->as_no_junction(1, "fmt must not be code"); |
| Pool& pool=r.pool(); | |
| String string; | String string; |
| string.APPEND_CONST( | string.APPEND_CONST( |
| format(pool, value_result->as_double(), fmt->as_string(&pool)->cstr())); | format(pool, value_result->as_double(), fmt->as_string(&pool)->cstr())); |
| Line 292 static void _eval(Request& r, StringPtr | Line 285 static void _eval(Request& r, StringPtr |
| r.write_no_lang(value_result); | r.write_no_lang(value_result); |
| } | } |
| static void _connect(Request& r, StringPtr method_name, MethodParams* params) { | static void _connect(Request& r, const String& method_name, MethodParams* params) { |
| Pool& pool=r.pool(); | |
| #ifdef RESOURCES_DEBUG | #ifdef RESOURCES_DEBUG |
| struct timeval mt[2]; | struct timeval mt[2]; |
| #endif | #endif |
| Line 301 struct timeval mt[2]; | Line 293 struct timeval mt[2]; |
| ValuePtr body_code=params->as_junction(1, "body must be code"); | ValuePtr body_code=params->as_junction(1, "body must be code"); |
| Table* protocol2driver_and_client=0; | Table* protocol2driver_and_client=0; |
| if(ValuePtr sql=r.main_class->get_element(StringPtr(new String(MAIN_SQL_NAME)), *r.main_class, false)) { | if(ValuePtr sql=r.main_class->get_element(String* (new String(MAIN_SQL_NAME)), *r.main_class, false)) { |
| if(ValuePtr element=sql->get_element(StringPtr(new String(MAIN_SQL_DRIVERS_NAME)), *sql, false)) { | if(ValuePtr element=sql->get_element(String* (new String(MAIN_SQL_DRIVERS_NAME)), *sql, false)) { |
| protocol2driver_and_client=element->get_table(); | protocol2driver_and_client=element->get_table(); |
| } | } |
| } | } |
| Line 348 public: | Line 340 public: |
| }; | }; |
| DECLARE_OBJECT_PTR(Switch_data); | DECLARE_OBJECT_PTR(Switch_data); |
| #endif | #endif |
| static void _switch(Request& r, StringPtr /*method_name*/, MethodParams* params) { | static void _switch(Request& r, const String& /*method_name*/, MethodParams* params) { |
| Switch_dataPtr data(new Switch_data(r, r.process_to_value(params->get(0)))); | Switch_dataPtr data(new Switch_data(r, r.process_to_value(params->get(0)))); |
| Temp_hash_value<StringPtr, PA_ObjectPtr> | Temp_hash_value<String* , PA_Object* > |
| switch_data_setter(r.classes_conf, switch_data_name, data); | switch_data_setter(r.classes_conf, switch_data_name, data); |
| ValuePtr cases_code=params->as_junction(1, "switch cases must be code"); | ValuePtr cases_code=params->as_junction(1, "switch cases must be code"); |
| Line 364 static void _switch(Request& r, StringPt | Line 356 static void _switch(Request& r, StringPt |
| } | } |
| } | } |
| static void _case(Request& r, StringPtr method_name, MethodParams* params) { | static void _case(Request& r, const String& method_name, MethodParams* params) { |
| Pool& pool=r.pool(); | |
| Switch_data* data=static_cast<Switch_data*>(r.classes_conf.get(switch_data_name).get()); | Switch_data* data=static_cast<Switch_data*>(r.classes_conf.get(switch_data_name).get()); |
| if(!data) | if(!data) |
| Line 410 static void _case(Request& r, StringPtr | Line 401 static void _case(Request& r, StringPtr |
| // consts | // consts |
| const int DATA_STRING_SERIALIZED_VERSION=0x0003; | const int DATA_STRING_SERIALIZED_VERSION=0x0004; |
| // helper types | // helper types |
| Line 421 struct Data_string_serialized_prolog { | Line 412 struct Data_string_serialized_prolog { |
| }; | }; |
| #endif | #endif |
| void cache_delete(StringPtr file_spec) { | void cache_delete(const String& file_spec) { |
| file_delete(file_spec, false/*fail_on_read_problem*/); | file_delete(file_spec, false/*fail_on_read_problem*/); |
| } | } |
| Line 434 DECLARE_OBJECT_PTR(Cache_data); | Line 425 DECLARE_OBJECT_PTR(Cache_data); |
| struct Locked_process_and_cache_put_action_info { | struct Locked_process_and_cache_put_action_info { |
| Request *r; | Request *r; |
| Cache_data *data; | Cache_data *data; |
| ValuePtr body_code; StringPtr evaluated_body; | ValuePtr body_code; const String& evaluated_body; |
| }; | }; |
| #endif | #endif |
| /* @todo maybe network order worth spending some effort? | /* @todo maybe network order worth spending some effort? |
| Line 445 static void locked_process_and_cache_put | Line 436 static void locked_process_and_cache_put |
| Locked_process_and_cache_put_action_info& info= | Locked_process_and_cache_put_action_info& info= |
| *static_cast<Locked_process_and_cache_put_action_info *>(context); | *static_cast<Locked_process_and_cache_put_action_info *>(context); |
| Pool& pool=info.r->pool(); | =info.r->pool(); |
| // body->process | // body->process |
| info.evaluated_body=info.r->process_to_string(info.body_code); | info.evaluated_body=info.r->process_to_string(info.body_code); |
| Line 467 static void locked_process_and_cache_put | Line 458 static void locked_process_and_cache_put |
| } else // expired! | } else // expired! |
| info.data->expires=0; // flag it so that could be easily checked by caller | info.data->expires=0; // flag it so that could be easily checked by caller |
| } | } |
| StringPtr locked_process_and_cache_put(Request& r, | const String& locked_process_and_cache_put(Request& r, |
| ValuePtr body_code, | ValuePtr body_code, |
| Cache_data& data, | Cache_data& data, |
| StringPtr file_spec) { | const String& file_spec) { |
| Locked_process_and_cache_put_action_info info; | Locked_process_and_cache_put_action_info info; |
| info.r=&r; | info.r=&r; |
| info.data=&data; | info.data=&data; |
| info.body_code=body_code; | info.body_code=body_code; |
| StringPtr result=file_write_action_under_lock( | const String& result=file_write_action_under_lock( |
| file_spec, | file_spec, |
| "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*/, | false/*block*/, |
| false/*fail on lock problem*/) ? info.evaluated_body: StringPtr(0); | false/*fail on lock problem*/) ? info.evaluated_body: 0; |
| time_t now=time(0); | time_t now=time(0); |
| if(data.expires<=now) | if(data.expires<=now) |
| cache_delete(file_spec); | cache_delete(file_spec); |
| return result; | return result; |
| } | } |
| StringPtr cache_get(Pool& pool, Charset& charset, StringPtr file_spec, time_t now) { | const String& cache_getCharset& charset, const String& file_spec, time_t now) { |
| File_read_result file=file_read(pool, charset, file_spec, | File_read_result file=file_read(pool, charset, file_spec, |
| false/*as_text*/, | false/*as_text*/, |
| 0, //no params | 0, //no params |
| Line 499 StringPtr cache_get(Pool& pool, Charset& | Line 490 StringPtr cache_get(Pool& pool, Charset& |
| Data_string_serialized_prolog& prolog= | Data_string_serialized_prolog& prolog= |
| *reinterpret_cast<Data_string_serialized_prolog *>(file.data); | *reinterpret_cast<Data_string_serialized_prolog *>(file.data); |
| StringPtr result(new String); | const String& result(new String); |
| if( | if( |
| file.size>=sizeof(Data_string_serialized_prolog) | file.size>=sizeof(Data_string_serialized_prolog) |
| && prolog.version==DATA_STRING_SERIALIZED_VERSION | && prolog.version==DATA_STRING_SERIALIZED_VERSION |
| && prolog.expires > now | && prolog.expires > now |
| && result->deserialize( | && result->deserialize( |
| sizeof(Data_string_serialized_prolog), file.data, file.size, file_spec->cstr(pool))) | sizeof(Data_string_serialized_prolog), file.data, file.size, file_spec->cstr())) |
| return result; | return result; |
| } | } |
| return 0; | return 0; |
| } | } |
| static time_t as_expires(Request& r, StringPtr method_name, MethodParams* params, | static time_t as_expires(Request& r, const String& method_name, MethodParams* params, |
| int index, time_t now) { | int index, time_t now) { |
| time_t result; | time_t result; |
| if(Value* vdate=(*params)[index]->as(VDATE_TYPE, false)) | if(Value* vdate=(*params)[index]->as(VDATE_TYPE, false)) |
| Line 521 static time_t as_expires(Request& r, Str | Line 512 static time_t as_expires(Request& r, Str |
| return result; | return result; |
| } | } |
| static StringPtr as_file_spec(Request& r, MethodParams* params, int index) { | static const String& as_file_spec(Request& r, MethodParams* params, int index) { |
| return r.absolute(params->as_string(index, "filespec must be string")); | return r.absolute(params->as_string(index, "filespec must be string")); |
| } | } |
| static void _cache(Request& r, StringPtr method_name, MethodParams* params) { | static void _cache(Request& r, const String& method_name, MethodParams* params) { |
| Pool& pool=r.pool(); | |
| time_t now=time(0); | time_t now=time(0); |
| // ^cache[filename] ^cache(seconds) ^cache[expires date] | // ^cache[filename] ^cache(seconds) ^cache[expires date] |
| Line 550 static void _cache(Request& r, StringPtr | Line 540 static void _cache(Request& r, StringPtr |
| } | } |
| // file_spec, expires, body code | // file_spec, expires, body code |
| StringPtr file_spec=r.absolute(params->as_string(0, "filespec must be string")); | const String& file_spec=r.absolute(params->as_string(0, "filespec must be string")); |
| Cache_dataPtr data(new Cache_data); | Cache_dataPtr data(new Cache_data); |
| Temp_hash_value<StringPtr, PA_ObjectPtr> | Temp_hash_value<String* , PA_Object* > |
| cache_data_setter(r.classes_conf, cache_data_name, data); | cache_data_setter(r.classes_conf, cache_data_name, data); |
| data->expires=as_expires(r, method_name, params, 1, now); | data->expires=as_expires(r, method_name, params, 1, now); |
| ValuePtr body_code=params->as_junction(2, "body must be code"); | ValuePtr body_code=params->as_junction(2, "body must be code"); |
| Line 576 static void _cache(Request& r, StringPtr | Line 566 static void _cache(Request& r, StringPtr |
| // |lockSH succeeds; ... | // |lockSH succeeds; ... |
| for(int retry=0; retry<2; retry++) { | for(int retry=0; retry<2; retry++) { |
| if(StringPtr cached_body=cache_get(pool, r.charsets.source(), file_spec, now)) { // have cached copy? | if(const String& cached_body=cache_get(pool, r.charsets.source(), file_spec, now)) { // have cached copy? |
| // write it out | // write it out |
| r.write_assign_lang(*cached_body); | r.write_assign_lang(*cached_body); |
| // happy with it | // happy with it |
| Line 584 static void _cache(Request& r, StringPtr | Line 574 static void _cache(Request& r, StringPtr |
| } | } |
| // non-blocked lock; process; cache it | // non-blocked lock; process; cache it |
| if(StringPtr processed_body= | if(const String& processed_body= |
| locked_process_and_cache_put(r, body_code, *data, file_spec)) { | locked_process_and_cache_put(r, body_code, *data, file_spec)) { |
| // write it out | // write it out |
| r.write_assign_lang(*processed_body); | r.write_assign_lang(*processed_body); |
| Line 602 static void _cache(Request& r, StringPtr | Line 592 static void _cache(Request& r, StringPtr |
| // instructed not to cache; forget cached copy | // instructed not to cache; forget cached copy |
| cache_delete(file_spec); | cache_delete(file_spec); |
| // process | // process |
| StringPtr processed_body=r.process_to_string(body_code); | const String& processed_body=r.process_to_string(body_code); |
| // write it out | // write it out |
| r.write_assign_lang(*processed_body); | r.write_assign_lang(*processed_body); |
| // happy with it | // happy with it |
| Line 612 static void _cache(Request& r, StringPtr | Line 602 static void _cache(Request& r, StringPtr |
| } | } |
| // also used in pa_request.C to pass param to @unhandled_exception | // also used in pa_request.C to pass param to @unhandled_exception |
| VHashPtr exception2vhash(Pool& pool, const Exception& e) { | VHashPtr exception2vhashconst Exception& e) { |
| VHashPtr result(new VHash); | VHashPtr result(new VHash); |
| HashStringValue& hash=result->hash(Exception::undefined_source); | HashStringValue& hash=result->hash(Exception::undefined_source); |
| if(const char* type=e.type(true)) | if(const char* type=e.type(true)) |
| hash.put(exception_type_part_name, ValuePtr(new VString(StringPtr(new String(type))))); | hash.put(exception_type_part_name, ValuePtr(new VString(String* (new String(type))))); |
| if(StringPtr asource=e.problem_source()) { | if(const String& asource=e.problem_source()) { |
| StringPtr source(new String); | const String* source(new String); |
| source->append(*asource, String::UL_TAINTED, true/*forced*/); | source->append(*asource, String::UL_TAINTED, true/*forced*/); |
| hash.put(exception_source_part_name, ValuePtr(new VString(source))); | hash.put(exception_source_part_name, ValuePtr(new VString(source))); |
| #ifndef NO_STRING_ORIGIN | #ifndef NO_STRING_ORIGIN |
| const String_fragment::Origin& origin=source->origin(); | const String_fragment::Origin& origin=source->origin(); |
| hash.put(StringPtr(new String("file", 0, true)), | hash.put(String* (new String("file", 0, true)), |
| ValuePtr(new VString(StringPtr(new String(origin.file))))); | ValuePtr(new VString(String* (new String(origin.file))))); |
| hash.put(StringPtr(new String("lineno")), | hash.put(String* (new String("lineno")), |
| ValuePtr(new VInt(1+origin.line))); | ValuePtr(new VInt(1+origin.line))); |
| #endif | #endif |
| } | } |
| if(const char* ecomment=e.comment(true)) { | if(const char* ecomment=e.comment(true)) { |
| char *pcomment=pool.copy(ecomment); | char *pcomment=pool.copy(ecomment); |
| hash.put(exception_comment_part_name, | hash.put(exception_comment_part_name, |
| ValuePtr(new VString(StringPtr(new String(pcomment, 0, true/*tainted*/))))); | ValuePtr(new VString(String* (new String(pcomment, 0, true/*tainted*/))))); |
| } | } |
| hash.put(exception_handled_part_name, | hash.put(exception_handled_part_name, |
| ValuePtr(new VBool(false))); | ValuePtr(new VBool(false))); |
| Line 641 VHashPtr exception2vhash(Pool& pool, con | Line 631 VHashPtr exception2vhash(Pool& pool, con |
| return result; | return result; |
| } | } |
| static void _try_operator(Request& r, StringPtr method_name, MethodParams* params) { | static void _try_operator(Request& r, const String& method_name, MethodParams* params) { |
| Pool& pool=r.pool(); | |
| ValuePtr body_code=params->as_junction(0, "body_code must be code"); | ValuePtr body_code=params->as_junction(0, "body_code must be code"); |
| ValuePtr catch_code=params->as_junction(1, "catch_code must be code"); | ValuePtr catch_code=params->as_junction(1, "catch_code must be code"); |
| Line 678 static void _try_operator(Request& r, St | Line 667 static void _try_operator(Request& r, St |
| r.write_pass_lang(result); | r.write_pass_lang(result); |
| } | } |
| static void _throw_operator(Request& r, StringPtr method_name, MethodParams* params) { | static void _throw_operator(Request& r, const String& method_name, MethodParams* params) { |
| Pool& pool=r.pool(); | |
| if(params->count()==1) { | if(params->count()==1) { |
| ValuePtr param0=(*params)[0]; | ValuePtr param0=(*params)[0]; |
| Line 687 static void _throw_operator(Request& r, | Line 675 static void _throw_operator(Request& r, |
| const char* type=0; | const char* type=0; |
| if(ValuePtr value=hash->get(exception_type_part_name)) | if(ValuePtr value=hash->get(exception_type_part_name)) |
| type=value->as_string(&pool)->cstr(); | type=value->as_string(&pool)->cstr(); |
| StringPtr source(0); | const String* source; |
| if(ValuePtr value=hash->get(exception_source_part_name)) | if(ValuePtr value=hash->get(exception_source_part_name)) |
| source=value->as_string(&pool); | source=value->as_string(&pool); |
| CharPtr comment(0); | const char* comment; |
| if(ValuePtr value=hash->get(exception_comment_part_name)) | if(ValuePtr value=hash->get(exception_comment_part_name)) |
| comment=value->as_string(&pool)->cstr(); | comment=value->as_string(&pool)->cstr(); |
| throw Exception(type, | throw Exception(type, |
| source?source:method_name, | source?source:method_name, |
| comment); | "%s", comment?comment.get():""); |
| } else | } else |
| throw Exception("parser.runtime", | throw Exception("parser.runtime", |
| method_name, | method_name, |
| "one-param version has hash param"); | "one-param version has hash param"); |
| } else { | } else { |
| const char* type=params->as_string(0, "type must be string")->cstr(pool); | const char* type=params->as_string(0, "type must be string")->cstr(); |
| StringPtr source=params->as_string(1, "source must be string"); | const String* source=params->as_string(1, "source must be string"); |
| CharPtr comment=params->count()>2? params->as_string(2, "comment must be string")->cstr() | const char* comment=params->count()>2? params->as_string(2, "comment must be string")->cstr() |
| :CharPtr(0); | :CharPtr(0); |
| throw Exception(type, source, "%s", comment?comment:""); | throw Exception(type, source, "%s", comment?comment.get():""); |
| } | } |
| } | } |
| #if defined(WIN32) && defined(_DEBUG) | |
| # define PA_BPT | |
| static void _bpt(Request& r, const String& method_name, MethodParams* params) { | |
| _asm int 3; | |
| } | |
| #endif | |
| // constructor | // constructor |
| VClassMAIN::VClassMAIN(): VClass() { | VClassMAIN::VClassMAIN(): VClass() { |
| set_name(StringPtr(new String(MAIN_CLASS_NAME))); | set_name(String* (new String(MAIN_CLASS_NAME))); |
| #ifdef PA_BPT | |
| // ^bpt[] | |
| add_native_method("bpt", Method::CT_ANY, _bpt, 0, 0); | |
| #endif | |
| // ^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} |