Diff for /parser3/src/classes/string.C between versions 1.71 and 1.87

version 1.71, 2001/08/28 09:27:42 version 1.87, 2001/10/31 14:01:44
Line 2 Line 2
         Parser: @b string parser class.          Parser: @b string parser class.
   
         Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
   
         Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)          Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
   
           $Id$
 */  */
 static const char *RCSId="$Id$";   
   
 #include "classes.h"  #include "classes.h"
 #include "pa_request.h"  #include "pa_request.h"
Line 39  static void _length(Request& r, const St Line 39  static void _length(Request& r, const St
         r.write_no_lang(result);          r.write_no_lang(result);
 }  }
   
 static void _int(Request& r, const String& method_name, MethodParams *) {  static void _int(Request& r, const String& method_name, MethodParams *params) {
         Pool& pool=r.pool();          Pool& pool=r.pool();
         Value& result=*new(pool) VInt(pool, r.self->as_int());          int converted;
           Value *default_code=params->size()>0?
                   default_code=&params->as_junction(0, "default must be int"):0; // (default)
           try {
                   converted=r.self->as_int();
           } catch(...) { // convert problem
                   if(!default_code) // we have a problem when no default
                           /*re*/throw;
                   else
                           converted=r.process(*default_code).as_int();
           }
   
           Value& result=*new(pool) VInt(pool, converted);
         result.set_name(method_name);          result.set_name(method_name);
         r.write_no_lang(result);          r.write_no_lang(result);
 }  }
   
 static void _double(Request& r, const String& method_name, MethodParams *) {  static void _double(Request& r, const String& method_name, MethodParams *params) {
         Pool& pool=r.pool();          Pool& pool=r.pool();
         Value& result=*new(pool) VDouble(pool, r.self->as_double());          double converted;
           Value *default_code=params->size()>0?
                   default_code=&params->as_junction(0, "default must be double"):0; // (default)
           try {
                   converted=r.self->as_double();
           } catch(...) { // convert problem
                   if(!default_code) // we have a problem when no default
                           /*re*/throw;  
                   else
                           converted=r.process(*default_code).as_double();
           }
   
           Value& result=*new(pool) VDouble(pool, converted);
         result.set_name(method_name);          result.set_name(method_name);
         r.write_no_lang(result);          r.write_no_lang(result);
 }  }
Line 59  static void _double(Request& r, const St Line 83  static void _double(Request& r, const St
         Value& fmt=params->as_junction(0, "fmt must be code");          Value& fmt=params->as_junction(0, "fmt must be code");
   
         Temp_lang temp_lang(r, String::UL_PASS_APPENDED);          Temp_lang temp_lang(r, String::UL_PASS_APPENDED);
         char *buf=format(pool, r.self->as_double(), r.process(fmt).as_string().cstr());          char *buf=format(pool, r.self->as_double(), 
                   r.process(fmt).as_string().cstr(String::UL_UNSPECIFIED));
   
         String result(pool);          String result(pool);
         result.APPEND_CLEAN(buf, 0,           result.APPEND_CLEAN(buf, 0, 
Line 71  static void _double(Request& r, const St Line 96  static void _double(Request& r, const St
 static void _left(Request& r, const String&, MethodParams *params) {  static void _left(Request& r, const String&, MethodParams *params) {
         Pool& pool=r.pool();          Pool& pool=r.pool();
   
         size_t n=(size_t)r.process(params->get(0)).as_double();          size_t n=(size_t)params->as_int(0, "n must be int", r);
                   
         const String& string=*static_cast<VString *>(r.self)->get_string();          const String& string=*static_cast<VString *>(r.self)->get_string();
         r.write_assign_lang(*new(pool) VString(string.mid(0, n)));          r.write_assign_lang(*new(pool) VString(string.mid(0, n)));
Line 80  static void _left(Request& r, const Stri Line 105  static void _left(Request& r, const Stri
 static void _right(Request& r, const String&, MethodParams *params) {  static void _right(Request& r, const String&, MethodParams *params) {
         Pool& pool=r.pool();          Pool& pool=r.pool();
   
         size_t n=(size_t)r.process(params->get(0)).as_double();          size_t n=(size_t)params->as_int(0, "n must be int", r);
                   
         const String& string=*static_cast<VString *>(r.self)->get_string();          const String& string=*static_cast<VString *>(r.self)->get_string();
         r.write_assign_lang(*new(pool) VString(string.mid(string.size()-n, string.size())));          r.write_assign_lang(*new(pool) VString(string.mid(string.size()-n, string.size())));
Line 89  static void _right(Request& r, const Str Line 114  static void _right(Request& r, const Str
 static void _mid(Request& r, const String&, MethodParams *params) {  static void _mid(Request& r, const String&, MethodParams *params) {
         Pool& pool=r.pool();          Pool& pool=r.pool();
   
         size_t p=(size_t)r.process(params->get(0)).as_double();  
         size_t n=(size_t)r.process(params->get(1)).as_double();  
           
         const String& string=*static_cast<VString *>(r.self)->get_string();          const String& string=*static_cast<VString *>(r.self)->get_string();
   
           size_t p=(size_t)params->as_int(0, "p must be int", r);
           size_t n=params->size()>1?
                   (size_t)params->as_int(1, "n must be int", r):string.size();
           
         r.write_assign_lang(*new(pool) VString(string.mid(p, p+n)));          r.write_assign_lang(*new(pool) VString(string.mid(p, p+n)));
 }  }
   
Line 160  static void search_action(Table& table, Line 187  static void search_action(Table& table,
                 table+=row;                  table+=row;
 }  }
   
 /// used by string: _match / replace_action  #ifndef DOXYGEN
 struct Replace_action_info {  struct Replace_action_info {
         Request *request;  const String *origin;          Request *request;  const String *origin;
         const String *src;  String *dest;          const String *src;  String *dest;
         Value *replacement_code;          Value *replacement_code;
         const String *post_match;          const String *post_match;
 };  };
   #endif
 static void replace_action(Table& table, Array *row, int start, int finish,   static void replace_action(Table& table, Array *row, int start, int finish, 
                                                            void *info) {                                                             void *info) {
         Replace_action_info& ai=*static_cast<Replace_action_info *>(info);          Replace_action_info& ai=*static_cast<Replace_action_info *>(info);
Line 217  static void _match(Request& r, const Str Line 245  static void _match(Request& r, const Str
         Table *table;          Table *table;
         if(params->size()<3) { // search          if(params->size()<3) { // search
                 bool was_global;                  bool was_global;
                 bool matched=src.match(r.pcre_tables,                  bool matched=src.match(r.pcre_tables(),
                         &method_name,                           &method_name, 
                         regexp.as_string(), options,                          regexp.as_string(), options,
                         &table,                          &table,
Line 239  static void _match(Request& r, const Str Line 267  static void _match(Request& r, const Str
                         &replacement_code,                          &replacement_code,
                         &src                          &src
                 };                  };
                 src.match(r.pcre_tables,                  src.match(r.pcre_tables(),
                         &method_name,                           &method_name, 
                         r.process(regexp).as_string(), options,                          r.process(regexp).as_string(), options,
                         &table,                          &table,
Line 255  static void change_case(Request& r, cons Line 283  static void change_case(Request& r, cons
         Pool& pool=r.pool();          Pool& pool=r.pool();
         const String& src=*static_cast<VString *>(r.self)->get_string();          const String& src=*static_cast<VString *>(r.self)->get_string();
   
         r.write_assign_lang(*new(pool) VString(src.change_case(pool, r.pcre_tables,          r.write_assign_lang(*new(pool) VString(src.change_case(pool, r.pcre_tables(),
                 kind)));                  kind)));
 }  }
 static void _upper(Request& r, const String& method_name, MethodParams *params) {  static void _upper(Request& r, const String& method_name, MethodParams *params) {
Line 279  public: Line 307  public:
   
         void add_column(void *ptr, size_t size) {          void add_column(void *ptr, size_t size) {
                 if(got_column)                  if(got_column)
                         PTHROW(0, 0,                          throw Exception(0, 0,
                                 &statement_string,                                  &statement_string,
                                 "result must contain exactly one column");                                  "result must contain exactly one column");
                 got_column=true;                  got_column=true;
Line 288  public: Line 316  public:
         void add_row() { /* ignore */ }          void add_row() { /* ignore */ }
         void add_row_cell(void *ptr, size_t size) {          void add_row_cell(void *ptr, size_t size) {
                 if(got_cell)                  if(got_cell)
                         PTHROW(0, 0,                          throw Exception(0, 0,
                                 &statement_string,                                  &statement_string,
                                 "result must not contain more then one row");                                  "result must not contain more then one row");
                 got_cell=true;                  got_cell=true;
Line 306  public: Line 334  public:
 };  };
 #endif  #endif
 const String* sql_result_string(Request& r, const String& method_name, MethodParams *params,  const String* sql_result_string(Request& r, const String& method_name, MethodParams *params,
                                                                 Hash *&options) {                                                                  Hash *& options, Value *& default_code) {
         Pool& pool=r.pool();          Pool& pool=r.pool();
   
         if(!r.connection)          if(!r.connection)
                 PTHROW(0, 0,                  throw Exception(0, 0,
                         &method_name,                          &method_name,
                         "without connect");                          "without connect");
   
Line 318  const String* sql_result_string(Request& Line 346  const String* sql_result_string(Request&
   
         ulong limit=0;          ulong limit=0;
         ulong offset=0;          ulong offset=0;
           default_code=0;
         if(params->size()>1) {          if(params->size()>1) {
                 Value& options_param=params->as_no_junction(1, "options must be hash, not code");                  Value& voptions=params->as_no_junction(1, "options must be hash, not code");
                 if(options=options_param.get_hash()) {                  if(voptions.is_defined())
                         if(Value *vlimit=(Value *)options->get(*sql_limit_name))                          if(options=voptions.get_hash(&method_name)) {
                                 limit=(ulong)r.process(*vlimit).as_double();                                  if(Value *vlimit=(Value *)options->get(*sql_limit_name))
                         if(Value *voffset=(Value *)options->get(*sql_offset_name))                                          limit=(ulong)r.process(*vlimit).as_double();
                                 offset=(ulong)r.process(*voffset).as_double();                                  if(Value *voffset=(Value *)options->get(*sql_offset_name))
                 } else                                          offset=(ulong)r.process(*voffset).as_double();
                         PTHROW(0, 0,                                  if(default_code=(Value *)options->get(*sql_default_name)) {
                                 &method_name,                                          if(!default_code->get_junction())
                                 "options must be hash");                                                  throw Exception(0, 0,
                                                           &method_name,
                                                           "default option must be code");
                                   }
                           } else
                                   throw Exception(0, 0,
                                           &method_name,
                                           "options must be hash");
         } else          } else
                 options=0;                  options=0;
   
Line 337  const String* sql_result_string(Request& Line 373  const String* sql_result_string(Request&
         const char *statement_cstr=          const char *statement_cstr=
                 statement_string.cstr(String::UL_UNSPECIFIED, r.connection);                  statement_string.cstr(String::UL_UNSPECIFIED, r.connection);
         String_sql_event_handlers handlers(pool, statement_string, statement_cstr);          String_sql_event_handlers handlers(pool, statement_string, statement_cstr);
         bool need_rethrow=false; Exception rethrow_me;          try {
         PTRY {  
                 r.connection->query(                  r.connection->query(
                         statement_cstr, offset, limit,                           statement_cstr, offset, limit, 
                         handlers);                          handlers);
           } catch(const Exception& e) { // query problem
                   // give more specific source [were url]
                   throw Exception(e.type(), e.code(),
                           &statement_string, 
                           "%s", e.comment());
         }          }
         PCATCH(e) { // query problem  
                 rethrow_me=e;  need_rethrow=true;  
         }  
         PEND_CATCH  
         if(need_rethrow)  
                 PTHROW(rethrow_me.type(), rethrow_me.code(),  
                         &statement_string, // setting more specific source [were url]  
                         rethrow_me.comment());  
                   
         if(!handlers.got_cell)          if(!handlers.got_cell)
                 return 0; // no lines, caller should return second param[default value]                  return 0; // no lines, caller should return second param[default value]
Line 362  static void _sql(Request& r, const Strin Line 394  static void _sql(Request& r, const Strin
         Pool& pool=r.pool();          Pool& pool=r.pool();
   
         Hash *options;          Hash *options;
         const String *string=sql_result_string(r, method_name, params, options);          Value *default_code;
           const String *string=sql_result_string(r, method_name, params, options, default_code);
         if(!string) {          if(!string) {
                 if(options) {                  if(default_code) {
                         if(Value *vdefault=(Value *)options->get(*sql_default_name)) {                          string=r.process(*default_code).get_string();
                                 if(!vdefault->get_junction())                          if(!string)
                                         PTHROW(0, 0,                                  string=new(pool) String(pool);
                                                 &method_name,  
                                                 "default option must be code");  
                                 string=r.process(*vdefault).get_string();  
                                 if(!string)  
                                         string=empty_string;  
                         } else  
                                 PTHROW(0, 0,  
                                         &method_name,  
                                         "produced no result, but no default option specified");  
                 } else                  } else
                         PTHROW(0, 0,                          throw Exception(0, 0,
                                 &method_name,                                  &method_name,
                                 "produced no result, but no options (no default) specified");                                  "produced no result, but no default option specified");
         }          }
         VString& result=*new(pool) VString(*string);          VString& result=*new(pool) VString(*string);
         result.set_name(method_name);          result.set_name(method_name);
Line 393  static void _replace(Request& r, const S Line 417  static void _replace(Request& r, const S
   
         Table *table=params->as_no_junction(0, "parameter must not be code").get_table();          Table *table=params->as_no_junction(0, "parameter must not be code").get_table();
         if(!table)          if(!table)
                 PTHROW(0, 0,                  throw Exception(0, 0,
                         &method_name,                          &method_name,
                         "parameter must be table");                          "parameter must be table");
   
         Dictionary dict(*table);          Dictionary dict(*table);
         r.write_assign_lang(*new(pool) VString(src.replace(pool, dict)));          r.write_assign_lang(*new(pool) VString(src.replace(pool, dict)));
 }  }
   
   static void _save(Request& r, const String& method_name, MethodParams *params) {
           Pool& pool=r.pool();
           const String& file_name=params->as_string(params->size()-1, 
                   "file name must be string");
   
           const String& src=*static_cast<VString *>(r.self)->get_string();
   
           bool do_append=false;
           if(params->size()>1) {
                   const String& mode=params->as_string(0, "mode must be string");
                   if(mode=="append")
                           do_append=true;
                   else
                           throw Exception(0, 0,
                                   &mode,
                                   "unknown mode, must be 'append'");
           }               
   
           // write
           file_write(pool, r.absolute(file_name), 
                   src.cstr(), src.size(), true, do_append);
   }
   
 // constructor  // constructor
   
 MString::MString(Pool& apool) : Methoded(apool) {  MString::MString(Pool& apool) : Methoded(apool) {
Line 410  MString::MString(Pool& apool) : Methoded Line 458  MString::MString(Pool& apool) : Methoded
         add_native_method("length", Method::CT_DYNAMIC, _length, 0, 0);          add_native_method("length", Method::CT_DYNAMIC, _length, 0, 0);
                   
         // ^string.int[]          // ^string.int[]
         add_native_method("int", Method::CT_DYNAMIC, _int, 0, 0);          // ^string.int(default)
                   add_native_method("int", Method::CT_DYNAMIC, _int, 0, 1);
         // ^string.double[]          // ^string.double[]
         add_native_method("double", Method::CT_DYNAMIC, _double, 0, 0);          // ^string.double(default)
           add_native_method("double", Method::CT_DYNAMIC, _double, 0, 1);
   
         // ^string.format{format}          // ^string.format{format}
         add_native_method("format", Method::CT_DYNAMIC, _string_format, 1, 1);          add_native_method("format", Method::CT_DYNAMIC, _string_format, 1, 1);
Line 423  MString::MString(Pool& apool) : Methoded Line 472  MString::MString(Pool& apool) : Methoded
         // ^string.right(n)          // ^string.right(n)
         add_native_method("right", Method::CT_DYNAMIC, _right, 1, 1);          add_native_method("right", Method::CT_DYNAMIC, _right, 1, 1);
         // ^string.mid(p;n)          // ^string.mid(p;n)
         add_native_method("mid", Method::CT_DYNAMIC, _mid, 2, 2);          add_native_method("mid", Method::CT_DYNAMIC, _mid, 1, 2);
   
         // ^string.pos[substr]          // ^string.pos[substr]
         add_native_method("pos", Method::CT_DYNAMIC, _pos, 1, 1);          add_native_method("pos", Method::CT_DYNAMIC, _pos, 1, 1);
Line 448  MString::MString(Pool& apool) : Methoded Line 497  MString::MString(Pool& apool) : Methoded
   
         // ^string.replace[table]          // ^string.replace[table]
         add_native_method("replace", Method::CT_DYNAMIC, _replace, 1, 1);          add_native_method("replace", Method::CT_DYNAMIC, _replace, 1, 1);
   
           // ^string.save[file]  
           add_native_method("save", Method::CT_DYNAMIC, _save, 1, 2);
 }         }       
   
 // global variable  // global variable

Removed from v.1.71  
changed lines
  Added in v.1.87


E-mail: