Diff for /parser3/src/classes/op.C between versions 1.107 and 1.127.2.4

version 1.107, 2002/09/10 14:56:33 version 1.127.2.4, 2003/01/31 12:10:41
Line 1 Line 1
 /** @file  /** @file
         Parser: parser @b operators.          Parser: parser @b operators.
   
         Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001, 2003 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)
 */  */
   
Line 25  static const char* IDENT_OP_C="$Date$"; Line 25  static const char* IDENT_OP_C="$Date$";
   
 // class  // class
   
 class MOP : public Methoded {  class VClassMAIN: public VClass {
 public:  public:
         MOP(Pool& pool);          VClassMAIN(Pool& apool);
 public: // Methoded  
         bool used_directly() { return true; }  
         void configure_user(Request& r);  
   
 private:  
         String main_sql_name;  
         String main_sql_drivers_name;  
 };  };
   
   // helpers
   
   Hash<StringPtr, int> Hash untaint_lang_name2enum;
   
 // methods  // methods
   
 static void _if(Request& r, const String&, MethodParams *params) {  static void _if(Request& r, const String&, MethodParams *params) {
Line 102  static void _taint(Request& r, const Str Line 99  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();          Pool& pool=r.pool();
         VStateless_class& self_class=*r.self->get_class();  
         const Method *main_method;          const Method *main_method;
           Value& target_self=params->size()>1?
                   params->as_no_junction(0, "target must not be code")
                   :r.get_method_frame()->caller()->self();
         {          {
                   Value& vjunction=params->as_junction(params->size()-1, "body must be code");
   
                   VStateless_class *target_class=target_self.get_last_derived_class();
                   if(!target_class)
                           throw Exception("parser.runtime",
                                   &method_name,
                                   "no target class");
                   
                   // evaluate source to process
                   const String& source=r.process_to_string(vjunction);
   
                 // 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, r.main_method_name, 0);                  Temp_method temp_method_main(*target_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(*target_class, *auto_method_name, 0);
                                   
                 // evaluate source to process  
                 const String& source=r.process_to_string(params->as_junction(0, "body must be code"));  
                 // 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 137  static void _process(Request& r, const S Line 145  static void _process(Request& r, const S
   
                 // 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(                  r.use_buf(*target_class,
                         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*/),                          *new(pool) String(pool, heap_place, place_size, true /*tainted*/),
                         heap_place,                           heap_place);
                         &self_class);  
                                   
                 // main_method                  // main_method
                 main_method=self_class.get_method(r.main_method_name);                  main_method=target_class->get_method(r.main_method_name);
         }          }
         // after restoring current-request-lang          // after restoring current-request-lang
         // maybe-execute @main[]          // maybe-execute @main[]
         if(main_method) {          if(main_method) {
                   // temporarily set method_frame's self to target_self
                   Temp_method_frame_self tmfs(*r.get_method_frame(), target_self);
                 // execute!                       // execute!     
                 r.execute(*main_method->parser_code);                  r.execute(*main_method->parser_code);
         }          }
Line 185  static void _while(Request& r, const Str Line 194  static void _while(Request& r, const Str
   
 static void _use(Request& r, const String& method_name, MethodParams *params) {  static void _use(Request& r, const String& method_name, MethodParams *params) {
         Value& vfile=params->as_no_junction(0, "file name must not be code");          Value& vfile=params->as_no_junction(0, "file name must not be code");
         r.use_file(vfile.as_string());          r.use_file(r.main_class, vfile.as_string());
 }  }
   
 static void _for(Request& r, const String& method_name, MethodParams *params) {  static void _for(Request& r, const String& method_name, MethodParams *params) {
Line 203  static void _for(Request& r, const Strin Line 212  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.method_frame->put_element(var_name, vint, false);          r.get_method_frame()->caller()->put_element(var_name, vint, false);
         for(int i=from; i<=to; i++) {          for(int i=from; i<=to; i++) {
                 vint->set_int(i);                  vint->set_int(i);
   
                 StringOrValue processed_body=r.process(body_code);                  StringOrValue sv_processed=r.process(body_code);
                 if(delim_maybe_code) { // delimiter set?                  const String *s_processed=sv_processed.get_string();
                         const String *string=processed_body.get_string();                  if(delim_maybe_code && s_processed && s_processed->size()) { // delimiter set and we have body
                         if(need_delim && string && string->size()) // 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));
                         need_delim=true;                          need_delim=true;
                 }                  }
                 r.write_pass_lang(processed_body);                  r.write_pass_lang(sv_processed);
         }          }
 }  }
   
Line 243  struct timeval mt[2]; Line 252  struct timeval mt[2];
         Value& url=params->as_no_junction(0, "url must not be code");          Value& url=params->as_no_junction(0, "url must not be code");
         Value& body_code=params->as_junction(1, "body must be code");          Value& body_code=params->as_junction(1, "body must be code");
   
         Table *protocol2driver_and_client=          Table *protocol2driver_and_client=0;
                 static_cast<Table *>(r.classes_conf.get(r.OP.name()));          if(Value *sql=r.main_class.get_element(*new(pool) String(pool, MAIN_SQL_NAME), r.main_class, false)) {
                   if(Value *element=sql->get_element(*new(pool) String(pool, MAIN_SQL_DRIVERS_NAME), *sql, false)) {
                           protocol2driver_and_client=element->get_table();
                   }
           }
   
 #ifdef RESOURCES_DEBUG  #ifdef RESOURCES_DEBUG
 //measure:before  //measure:before
Line 343  static void _case(Request& r, const Stri Line 356  static void _case(Request& r, const Stri
   
 // consts  // consts
   
 const int DATA_STRING_SERIALIZED_VERSION=0x0002;  const int DATA_STRING_SERIALIZED_VERSION=0x0003;
   
 // helper types  // helper types
   
Line 368  struct Locked_process_and_cache_put_acti Line 381  struct Locked_process_and_cache_put_acti
         Value *body_code; const String *evaluated_body;          Value *body_code; const String *evaluated_body;
 };  };
 #endif  #endif
   /* @todo maybe network order worth spending some effort?
           don't bothering myself with network byte order,
           am not planning to be able to move resulting file across platforms
   */
 static void locked_process_and_cache_put_action(int f, void *context) {  static void locked_process_and_cache_put_action(int f, void *context) {
         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);
Line 419  String *cache_get(Pool& pool, const Stri Line 436  String *cache_get(Pool& pool, const Stri
         if(file_read(pool, file_spec,           if(file_read(pool, file_spec, 
                            data, data_size,                              data, data_size, 
                            false/*as_text*/,                              false/*as_text*/, 
                              0, 0, //no params&out_fields
                            false/*fail_on_read_problem*/)                             false/*fail_on_read_problem*/)
             && data_size/* ignore reads which are empty due to               && data_size/* ignore reads which are empty due to 
                         non-unary open+lockEX conflict with lockSH */) {                          non-unary open+lockEX conflict with lockSH */) {
Line 577  static void _try_operator(Request& r, co Line 595  static void _try_operator(Request& r, co
         Value& catch_code=params->as_junction(1, "catch_code must be code");          Value& catch_code=params->as_junction(1, "catch_code must be code");
   
         StringOrValue result;          StringOrValue result;
           // taking snapshot of try-context
         // taking snapshot of request processing status          Request_context_saver try_context(r);
         //int ssexception_trace=r.exception_trace.top_index();  
         int sstack=r.stack.top_index();  
         Value *sself=r.self;  
         VMethodFrame *smethod_frame=r.method_frame;  
         Value *srcontext=r.rcontext;    
         WContext *swcontext=r.wcontext;   
         try {          try {
                 result=r.process(body_code);                  result=r.process(body_code);
         } catch(const Exception& e) {          } catch(const Exception& e) {
                 // restoring request processing status                  Request_context_saver throw_context(r); // taking snapshot of throw-context [stack trace contains error]
                 //r.exception_trace.top_index(ssexception_trace);                  try_context.restore(); // restoring try-context to perform catch-code
                 r.stack.top_index(sstack);  
                 r.self=sself; r.method_frame=smethod_frame, r.rcontext=srcontext; r.wcontext=swcontext;  
                   
                   
                 VHash& vhash=exception2vhash(pool, e);                  VHash& vhash=exception2vhash(pool, e);
   
                 Junction *junction=catch_code.get_junction();                  Junction *junction=catch_code.get_junction();
                 Value *method_frame=junction->method_frame;                  Value *method_frame=junction->method_frame;
                 Value *saved_exception_var_value=method_frame->get_element(*exception_var_name, method_frame, false);                  Value *saved_exception_var_value=method_frame->get_element(*exception_var_name, *method_frame, false);
                 junction->method_frame->put_element(*exception_var_name, &vhash, false);                  junction->method_frame->put_element(*exception_var_name, &vhash, false);
                 result=r.process(catch_code);                  result=r.process(catch_code);
                 bool handled=false;                  bool handled=false;
Line 606  static void _try_operator(Request& r, co Line 615  static void _try_operator(Request& r, co
                         handled=value->as_bool();                                         handled=value->as_bool();               
                 junction->method_frame->put_element(*exception_var_name, saved_exception_var_value, false);                  junction->method_frame->put_element(*exception_var_name, saved_exception_var_value, false);
   
                 if(!handled)                  if(!handled) {
                           throw_context.restore(); // restoring throw-context [exception were not handled]
                         throw(e); // rethrow                          throw(e); // rethrow
                   }
         }          }
         // write it out           // write out result
         r.write_pass_lang(result);          r.write_pass_lang(result);
 }  }
   
Line 647  static void _throw_operator(Request& r, Line 658  static void _throw_operator(Request& r,
                   
 // constructor  // constructor
   
 MOP::MOP(Pool& apool) : Methoded(apool, "OP"),  VClassMAIN::VClassMAIN(Pool& apool): VClass(apool) {
         main_sql_name(apool, MAIN_SQL_NAME),          set_name(*NEW String(pool(), MAIN_CLASS_NAME));
         main_sql_drivers_name(apool, MAIN_SQL_DRIVERS_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);
Line 662  MOP::MOP(Pool& apool) : Methoded(apool, Line 672  MOP::MOP(Pool& apool) : Methoded(apool,
         add_native_method("taint", Method::CT_ANY, _taint, 1, 2);          add_native_method("taint", Method::CT_ANY, _taint, 1, 2);
   
         // ^process[code]          // ^process[code]
         add_native_method("process", Method::CT_ANY, _process, 1, 1);          add_native_method("process", Method::CT_ANY, _process, 1, 2);
   
         // ^rem{code}          // ^rem{code}
         add_native_method("rem", Method::CT_ANY, _rem, 1, 10000);          add_native_method("rem", Method::CT_ANY, _rem, 1, 10000);
Line 708  MOP::MOP(Pool& apool) : Methoded(apool, Line 718  MOP::MOP(Pool& apool) : Methoded(apool,
   
 // constructor & configurator  // constructor & configurator
   
 Methoded *MOP_create(Pool& pool) {  VStateless_classPtr VClassMAIN_create() {
         return new(pool) MOP(pool);          #define ULN(name, LANG) \
 }                  untaint_lang_name2enum.put(StringPtr(new String(name)), (int)String::UL_##LANG);
           ULN("as-is", AS_IS);
 void MOP::configure_user(Request& r) {          ULN("optimized-as-is", AS_IS|String::UL_OPTIMIZE_BIT);
         Pool& pool=r.pool();          ULN("file-spec", FILE_SPEC);
           ULN("http-header", HTTP_HEADER);
         // $MAIN:SQL.drivers          ULN("mail-header", MAIL_HEADER);
         if(Value *sql=r.main_class->get_element(main_sql_name, r.main_class, false))          ULN("uri", URI);
                 if(Value *element=sql->get_element(main_sql_drivers_name, sql, false))          ULN("table", TABLE);
                         if(Table *protocol2library=element->get_table())          ULN("sql", SQL);
                                 r.classes_conf.put(name(), protocol2library);          ULN("js", JS);
           ULN("xml", XML);
           ULN("optimized-xml", XML|String::UL_OPTIMIZE_BIT);
           ULN("html", HTML);
           ULN("optimized-html", HTML|String::UL_OPTIMIZE_BIT);
           #undef ULN
           
           return VStateless_classPtr(new VClassMAIN);
 }  }

Removed from v.1.107  
changed lines
  Added in v.1.127.2.4


E-mail: