--- parser3/src/main/pa_string.C 2003/01/27 15:07:48 1.172.2.6 +++ parser3/src/main/pa_string.C 2003/03/18 11:54:56 1.172.2.21 @@ -1,18 +1,16 @@ /** @file Parser: string class. @see untasize_t.C. - Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char* IDENT_STRING_C="$Date: 2003/01/27 15:07:48 $"; +static const char* IDENT_STRING_C="$Date: 2003/03/18 11:54:56 $"; #include "pcre.h" -#include "pa_pool.h" #include "pa_string.h" #include "pa_exception.h" -#include "pa_array.h" #include "pa_table.h" #include "pa_dictionary.h" #include "pa_charset.h" @@ -23,28 +21,31 @@ static const char* IDENT_STRING_C="$Date const int MAX_MATCH_GROUPS=100; -class String_match_table_template_columns: public Array { +class String_match_table_template_columns: public ArrayString { Pool pool; public: String_match_table_template_columns() { - *this+=ConstStringPtr(new String("prematch")); - *this+=ConstStringPtr(new String("match")); - *this+=ConstStringPtr(new String("postmatch")); + *this+=StringPtr(new String("prematch")); + *this+=StringPtr(new String("match")); + *this+=StringPtr(new String("postmatch")); for(int i=0; i(1), fsize(0) { +String::String(const char* src, size_t src_size, bool tainted): Array(1), fsize(0) { if(src) if(tainted) APPEND_TAINTED(src, src_size, 0, 0); @@ -76,6 +77,8 @@ String& String::real_append(STRING_APPEN fragment->origin.line=line; #endif + fsize+=size; + return *this; } @@ -105,9 +108,12 @@ int String::cmp(int& partial, const Stri bool a_break; bool b_break; - while(!( - (a_break=(a_current==a_end)) - || (b_break=(b_current==b_end)))) { + while(true) { + a_break=(a_current==a_end); + b_break=(b_current==b_end); + if(a_break || b_break) + break; + if(pos+a_current->size > this_offset) { if(lang!=UL_UNSPECIFIED && a_current->lang>(String_UL)lang) return -1; // wrong lang -- bail out @@ -171,9 +177,10 @@ int String::cmp(int& partial, const char bool a_break; bool b_break=b_size==0; - while(!( - (a_break=(a_current==a_end)) - || b_break)) { + while(true) { + a_break=(a_current==a_end); + if(a_break || b_break) + break; if(pos+a_current->size > this_offset) { if(lang!=UL_UNSPECIFIED && a_current->lang>(String_UL)lang) return -1; // wrong lang -- bail out @@ -281,7 +288,7 @@ int String::pos(const String& substr, return -1; } -int String::pos(const char *substr, size_t substr_size, +int String::pos(const char* substr, size_t substr_size, int result, Untaint_lang lang) const { size_t self_size=size(); for(; size_t(result)& result, +void String::split(ArrayString& result, size_t* pos_after_ref, - const char *delim, size_t delim_size, - Untaint_lang lang, int limit) const { + const char* delim, size_t delim_size, + Untaint_lang lang, int limit) { size_t self_size=size(); if(delim_size) { size_t pos_after=pos_after_ref?*pos_after_ref:0; @@ -316,16 +323,16 @@ void String::split(Array if(pos_after_ref) *pos_after_ref=pos_after; } else { // empty delim - result+=ConstStringPtr(this); + result+=StringPtr(this); if(pos_after_ref) *pos_after_ref+=self_size; } } -void String::split(Array& result, +void String::split(ArrayString& result, size_t* pos_after_ref, const String& delim, Untaint_lang lang, - int limit) const { + int limit) { if(!delim.is_empty()) { size_t pos_after=pos_after_ref?*pos_after_ref:0; int pos_before; @@ -342,16 +349,16 @@ void String::split(Array if(pos_after_ref) *pos_after_ref=pos_after; } else { // empty delim - result+=ConstStringPtr(this); + result+=StringPtr(this); if(pos_after_ref) *pos_after_ref+=size(); } } -static void regex_options(ConstStringPtr options, int *result, bool& need_pre_post_match){ +static void regex_options(StringPtr options, int *result, bool& need_pre_post_match){ struct Regex_option { - const char *keyL; - const char *keyU; + const char* keyL; + const char* keyU; int clear, set; int *result; bool *flag; @@ -381,24 +388,22 @@ static void regex_options(ConstStringPtr } TablePtr String::match(Charset& source_charset, - ConstStringPtr aorigin, + StringPtr aorigin, const String& regexp, - ConstStringPtr options, + StringPtr options, Row_action row_action, void *info, - bool *was_global) const { - + bool& just_matched) const { if(regexp.is_empty()) throw Exception(0, aorigin, "regexp is empty"); CharPtr pattern=regexp.cstr(); - const char *errptr; + const char* errptr; int erroffset; bool need_pre_post_match=false; int option_bits[2]; regex_options(options, option_bits, need_pre_post_match); - if(was_global) - *was_global=option_bits[1]!=0; + bool global=option_bits[1]!=0; pcre *code=pcre_compile(pattern.get(), option_bits[0], &errptr, &erroffset, source_charset.pcre_tables); @@ -408,13 +413,13 @@ TablePtr String::match(Charset& source_c regexp.mid(erroffset, regexp.size()), "regular expression syntax error - %s", errptr); - int info_substrings=pcre_info(code, 0, 0); - if(info_substrings<0) { + int subpatterns=pcre_info(code, 0, 0); + if(subpatterns<0) { pcre_free(code); throw Exception(0, aorigin, "pcre_info error (%d)", - info_substrings); + subpatterns); } CharPtr subject=cstr(); @@ -423,7 +428,7 @@ TablePtr String::match(Charset& source_c int ovector[ovecsize]; // create table - TablePtr result(new Table(string_match_table_template)); + TablePtr table(new Table(string_match_table_template)); int exec_option_bits=0; int prestart=0; @@ -436,11 +441,12 @@ TablePtr String::match(Charset& source_c if(exec_substrings==PCRE_ERROR_NOMATCH) { pcre_free(code); - row_action(*result.get(), 0/*last time, no raw*/, 0, 0, poststart, postfinish, info); - if(option_bits[1]) - return result; // global=true+result - else - return TablePtr(0);// not global=no result + row_action(table, ArrayStringPtr(0)/*last time, no raw*/, 0, 0, poststart, postfinish, info); + if(global || subpatterns) + return table; // global or with subpatterns=true+result + else { + just_matched=false; return TablePtr(0); // not global=no result + } } if(exec_substrings<0) { @@ -453,15 +459,15 @@ TablePtr String::match(Charset& source_c int prefinish=ovector[0]; poststart=ovector[1]; - object_ptr > row; + object_ptr row(new ArrayString); if(need_pre_post_match) { *row+=mid(0, prefinish); // .prematch column value *row+=mid(prefinish, poststart); // .match *row+=mid(poststart, postfinish); // .postmatch } else { - *row+=ConstStringPtrZero; // .prematch column value - *row+=ConstStringPtrZero; // .match - *row+=ConstStringPtrZero; // .postmatch + *row+=StringPtr(0); // .prematch column value + *row+=StringPtr(0); // .match + *row+=StringPtr(0); // .postmatch } for(int i=1; i(kind)); // never a=b=0; // calm, compiler @@ -513,8 +519,8 @@ StringPtr String::change_case(Pool& pool STRING_FOREACH_FRAGMENT( char *new_cstr=new(pool) char[fragment->size]; char *dest=new_cstr; - const char *end=fragment->ptr+fragment->size; - for(const char *current=fragment->ptr; currentptr+fragment->size; + for(const char* current=fragment->ptr; currentorigin.file; + const char* joined_origin_file=fragment->origin.file; const size_t joined_origin_line=fragment->origin.line; ); - uchar joined_lang=fragment->lang; - const char *joined_ptr=current; + String_UL joined_lang=fragment->lang; + const char* joined_ptr=current; // calc size size_t joined_size=0; STRING_PREPARED_FOREACH_FRAGMENT( @@ -563,8 +569,8 @@ IFNDEF_NO_STRING_ORIGIN( // there is a fragment where first column starts 'joined_ptr' if(Table::element_type row=dict.first_that_starts(joined_ptr, joined_size)) { // get a=>b values - ConstStringPtr a=row->get(0); - ConstStringPtr b=row->get(1); + StringPtr a=row->get(0); + StringPtr b=row->get(1); // skip 'a' in 'joined_ptr' && reduce work size joined_ptr+=a->size(); joined_size-=a->size(); // write 'b' to 'dest' && skip 'b' in 'dest' @@ -587,15 +593,15 @@ StringPtr String::join_chains(Pool& pool char *pooled_buf=new(pool) char[cstr_bufsize()]; store_to(pooled_buf, String::UL_AS_IS); - const char *current=pooled_buf; + const char* current=pooled_buf; STRING_FOREACH_FRAGMENT( IFNDEF_NO_STRING_ORIGIN( - const char *joined_origin_file=fragment->origin.file; + const char* joined_origin_file=fragment->origin.file; const size_t joined_origin_line=fragment->origin.line; ); - uchar joined_lang=fragment->lang; - const char *joined_ptr=current; + String_UL joined_lang=fragment->lang; + const char* joined_ptr=current; // calc size size_t joined_size=0; STRING_PREPARED_FOREACH_FRAGMENT( @@ -617,15 +623,15 @@ IFNDEF_NO_STRING_ORIGIN( return result; } -double String::as_double() const { +double String::as_double() { double result; char buf[MAX_STRING]; if(size()>MAX_STRING-1) throw Exception("number.format", - ConstStringPtr(this), + StringPtr(this), "invalid number too long a string (%u>%u)", size(), MAX_STRING-1); char *eol=store_to(buf, String::UL_AS_IS); *eol=0; - const char *cstr=buf; + const char* cstr=buf; while(*cstr && isspace(*cstr)) cstr++; @@ -645,20 +651,20 @@ double String::as_double() const { while(char c=*error_pos++) if(!isspace(c)) throw Exception("number.format", - ConstStringPtr(this), + StringPtr(this), "invalid number (double)"); return result; } -int String::as_int() const { +int String::as_int() { int result; char buf[MAX_STRING]; if(size()>MAX_STRING-1) throw Exception("number.format", - ConstStringPtr(this), + StringPtr(this), "invalid number too long a string (%u>%u)", size(), MAX_STRING-1); char *eol=store_to(buf, String::UL_AS_IS); *eol=0; - const char *cstr=buf; + const char* cstr=buf; while(*cstr && isspace(*cstr)) cstr++; @@ -678,7 +684,7 @@ int String::as_int() const { while(char c=*error_pos++) if(!isspace(c)) throw Exception("number.format", - ConstStringPtr(this), + StringPtr(this), "invalid number (int)"); return result; @@ -700,7 +706,7 @@ inline uint uchars2uint(uchar *bytes) { void String::serialize(Pool& pool, size_t prolog_size, char *& buf, size_t& buf_size) const { buf_size= prolog_size - +fused*(sizeof(uchar)+sizeof(size_t)) + +fused*(sizeof(String_UL)+sizeof(size_t)) +size(); buf=new(pool) char[buf_size]; char *cur=buf+prolog_size; @@ -720,7 +726,7 @@ void String::serialize(Pool& pool, size_ cur+=fragment->size; ); } -bool String::deserialize(size_t prolog_size, void *buf, size_t buf_size, const char *file) { +bool String::deserialize(size_t prolog_size, void *buf, size_t buf_size, const char* file) { if(buf_size<=prolog_size) return false; @@ -728,17 +734,17 @@ bool String::deserialize(size_t prolog_s buf_size-=prolog_size; while(buf_size) { - if(sizeof(uchar)+sizeof(size_t)>buf_size) // lang+size + if(sizeof(String_UL)+sizeof(size_t)>buf_size) // lang+size return false; String_UL lang=*(String_UL *)(cur); size_t size=uchars2uint((uchar *)cur); - size_t piece_size=sizeof(uchar)+sizeof(size_t)+size; + size_t piece_size=sizeof(String_UL)+sizeof(size_t)+size; if(piece_size>buf_size) // buffer overrun, can be on incomplete cache files return false; - const char *ptr=(const char*)(cur+sizeof(uchar)+sizeof(size_t)); + const char* ptr=(const char*)(cur+sizeof(String_UL)+sizeof(size_t)); APPEND(ptr, size, lang, file, 0); cur+=piece_size;