Diff for /parser3/src/classes/op.C between versions 1.89 and 1.103

version 1.89, 2002/04/16 08:22:19 version 1.103, 2002/08/13 15:55:41
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) {
         // calculate pseudo file name of processed chars          Pool& pool=r.pool();
         // would be something like "/some/file(4) process"  
         char local_place[MAX_STRING];  
 #ifndef NO_STRING_ORIGIN  
         const Origin& origin=method_name.origin();  
         size_t place_size=snprintf(local_place, MAX_STRING, "%s(%d) %s",   
                 origin.file?origin.file:"unknown_file", 1+origin.line,  
                 method_name.cstr())+1;  
 #else  
         strncpy(local_place, method_name.cstr(), MAX_STRING-1); place[MAX_STRING-1]=0;  
         size_t place_size=strlen(local_place)+1;  
 #endif  
         char *heap_place=(char *)r.malloc(place_size);  
         memcpy(heap_place, local_place, place_size);  
   
   
         VStateless_class& self_class=*r.self->get_class();          VStateless_class& self_class=*r.self->get_class();
         const Method *main_method;          const Method *main_method;
         {          {
                 // 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);
                                   
                 // evaluate source to process                  // evaluate source to process
                 const String& source=r.process_to_string(params->as_junction(0, "body must be code"));                  const String& source=r.process_to_string(params->as_junction(0, "body must be code"));
                   // calculate pseudo file name of processed chars
                   // would be something like "/some/file(4) process"
                   char local_place[MAX_STRING];
   #ifndef NO_STRING_ORIGIN
                   const Origin& source_origin=source.origin();
                   const Origin& method_origin=method_name.origin();
                   size_t place_size;
                   if(source_origin.file==method_origin.file)
                           place_size=snprintf(local_place, MAX_STRING, "%s(%d) %s",  // same file
                                   source_origin.file?source_origin.file:"unknown_file", 1+source_origin.line, 
                                   method_name.cstr())+1;
                   else // different files ^process{external__file_text__or__sql}
                           place_size=snprintf(local_place, MAX_STRING, "%s", 
                                   source_origin.file?source_origin.file:"unknown_file")+1;
   #else
                   strncpy(local_place, method_name.cstr(), MAX_STRING-1); place[MAX_STRING-1]=0;
                   size_t place_size=strlen(local_place)+1;
   #endif
                   char *heap_place=(char *)r.malloc(place_size);
                   memcpy(heap_place, local_place, place_size);
   
                 // 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(
                         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 202  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, false);
         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 220  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 228  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 406  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 541  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 556  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 589  static void _try_operator(Request& r, co Line 594  static void _try_operator(Request& r, co
                 VHash& vhash=exception2vhash(pool, e);                  VHash& vhash=exception2vhash(pool, e);
   
                 Junction *junction=catch_code.get_junction();                  Junction *junction=catch_code.get_junction();
                 Value *saved_exception_var_value=junction->root->get_element(*exception_var_name);                  Value *root=junction->root;
                 junction->root->put_element(*exception_var_name, &vhash);                  Value *saved_exception_var_value=root->get_element(*exception_var_name, root, false);
                   junction->root->put_element(*exception_var_name, &vhash, false);
                 result=r.process(catch_code);                  result=r.process(catch_code);
                 bool handled=false;                  bool handled=false;
                 if(Value *value=static_cast<Value *>(vhash.hash(0).get(*exception_handled_part_name)))                  if(Value *value=static_cast<Value *>(vhash.hash(0).get(*exception_handled_part_name)))
                         handled=value->as_bool();                                         handled=value->as_bool();               
                 junction->root->put_element(*exception_var_name, saved_exception_var_value);                  junction->root->put_element(*exception_var_name, saved_exception_var_value, false);
   
                 if(!handled)                  if(!handled)
                         throw(e); // rethrow                          throw(e); // rethrow
Line 631  static void _throw_operator(Request& r, Line 637  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);
Line 709  void MOP::configure_user(Request& r) { Line 713  void MOP::configure_user(Request& r) {
         Pool& pool=r.pool();          Pool& pool=r.pool();
   
         // $MAIN:SQL.drivers          // $MAIN:SQL.drivers
         if(Value *sql=r.main_class->get_element(main_sql_name))          if(Value *sql=r.main_class->get_element(main_sql_name, r.main_class, false))
                 if(Value *element=sql->get_element(main_sql_drivers_name))                  if(Value *element=sql->get_element(main_sql_drivers_name, sql, false))
                         if(Table *protocol2library=element->get_table())                          if(Table *protocol2library=element->get_table())
                                 r.classes_conf.put(name(), protocol2library);                                  r.classes_conf.put(name(), protocol2library);
 }  }

Removed from v.1.89  
changed lines
  Added in v.1.103


E-mail: