--- parser3/src/main/pa_string.C 2002/08/07 13:44:00 1.166 +++ parser3/src/main/pa_string.C 2003/04/11 15:00:05 1.173 @@ -1,11 +1,11 @@ /** @file Parser: string class. @see untasize_t.C. - Copyright (c) 2001, 2002 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: 2002/08/07 13:44:00 $"; +static const char* IDENT_STRING_C="$Date: 2003/04/11 15:00:05 $"; #include "pcre.h" @@ -57,7 +57,7 @@ String::String(const String& src) : head.chunk.count=CR_PREALLOCATED_COUNT; append_here=head.chunk.rows; - append(src, UL_UNSPECIFIED); + append(src, UL_PASS_APPENDED); } size_t String::size() const { @@ -144,15 +144,6 @@ String& String::real_append(STRING_APPEN return *this; } -char String::first_char() const { - if(is_empty()) - throw Exception(0, - this, - "getting first char of empty string"); - - return *head.chunk.rows[0].item.ptr; -} - uint String::hash_code() const { uint result=0; STRING_FOREACH_ROW( @@ -344,7 +335,7 @@ String& String::mid(size_t start, size_t String& result=*NEW String(pool()); start=min(start, size()); - finish=max(finish, start); + finish=max(start, finish); if(start==finish) return result; @@ -468,7 +459,7 @@ static void regex_options(const String * {"'", 0, 0, 0, 0, &need_pre_post_match}, {0} }; - result[0]=PCRE_EXTRA | PCRE_DOTALL; + result[0]=PCRE_EXTRA | PCRE_DOTALL | PCRE_DOLLAR_ENDONLY; result[1]=0; if(options) @@ -486,12 +477,12 @@ static void regex_options(const String * /// @todo make replacement Table stacked bool String::match( - const String *aorigin, - const String& regexp, - const String *options, - Table **table, - Row_action row_action, void *info, - bool *was_global) const { + const String *aorigin, + const String& regexp, + const String *options, + Table **table, + Row_action row_action, void *info, + bool *was_global) const { if(regexp.is_empty()) throw Exception(0, @@ -501,7 +492,7 @@ bool String::match( const char *pattern=regexp.cstr(); const char *errptr; int erroffset; - bool need_pre_post_match=false; + 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; @@ -529,7 +520,8 @@ bool String::match( int ovector[ovecsize]; // create table - *table=NEW Table(pool(), *string_match_table_template); + Table::Action_options table_options; + *table=NEW Table(pool(), *string_match_table_template, table_options); int exec_option_bits=0; int prestart=0; @@ -629,33 +621,53 @@ String& String::change_case(Pool& pool, /// @test if in some piece were found no dict words, append it, not it's duplicate String& String::replace(Pool& pool, Dictionary& dict) const { -// return reconstruct(pool).replace_in_reconstructed(pool, dict); - String& result=*new(pool) String(pool); + char *lcstr=cstr(); + const char *current=lcstr; + String& result=*new(pool) String(pool); STRING_FOREACH_ROW( - const char *src=row->item.ptr; - size_t src_size=row->item.size; - char *new_cstr=(char *)pool.malloc((size_t)ceil(src_size*dict.max_ratio()), 14); +IFNDEF_NO_STRING_ORIGIN( + const char *joined_origin_file=row->item.origin.file; + const size_t joined_origin_line=row->item.origin.line; +); + uchar joined_lang=row->item.lang; + const char *joined_ptr=current; + // calc size + size_t joined_size=0; + STRING_PREPARED_FOREACH_ROW(*this, + if(row->item.lang==joined_lang) + joined_size+=row->item.size; + else + break; // before non-ours + ); + current+=joined_size; + + // pointers are after joined piece + // & one step back, see STRING_FOREACH_ROW + --row; ++countdown; + + char *new_cstr=(char *)pool.malloc((size_t)ceil(joined_size*dict.max_ratio()), 14); char *dest=new_cstr; - while(src_size) { - // there is a row where first column starts 'src' - if(Table::Item *item=dict.first_that_starts(src, src_size)) { + while(joined_size) { + // there is a row where first column starts 'joined_ptr' + if(Table::Item *item=dict.first_that_starts(joined_ptr, joined_size)) { // get a=>b values const String& a=*static_cast(item)->get_string(0); const String& b=*static_cast(item)->get_string(1); - // skip 'a' in 'src' && reduce work size - src+=a.size(); src_size-=a.size(); + // skip 'a' in 'joined_ptr' && reduce work size + joined_ptr+=a.size(); joined_size-=a.size(); // write 'b' to 'dest' && skip 'b' in 'dest' b.store_to(dest); dest+=b.size(); } else { // write a char to b && reduce work size - *dest++=*src++; src_size--; + *dest++=*joined_ptr++; joined_size--; } } - result.APPEND(new_cstr, dest-new_cstr, row->item.lang, - row->item.origin.file, row->item.origin.line); + result.APPEND(new_cstr, dest-new_cstr, joined_lang, + joined_origin_file, joined_origin_line); ); + return result; }