|
|
| version 1.125.2.1.2.2, 2001/12/07 13:10:18 | version 1.137, 2002/02/08 07:27:49 |
|---|---|
| Line 1 | Line 1 |
| /** @file | /** @file |
| Parser: string class. @see untasize_t.C. | Parser: string class. @see untasize_t.C. |
| Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) | Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) |
| Author: Alexander Petrosyan <paf@design.ru> (http://paf.design.ru) | Author: Alexander Petrosyan <paf@design.ru> (http://paf.design.ru) |
| $Id$ | $Id$ |
| */ | */ |
| #include "pa_config_includes.h" | |
| #include "pcre.h" | #include "pcre.h" |
| #include "internal.h" | |
| #include "pa_pool.h" | #include "pa_pool.h" |
| #include "pa_string.h" | #include "pa_string.h" |
| Line 21 | Line 18 |
| #include "pa_globals.h" | #include "pa_globals.h" |
| #include "pa_table.h" | #include "pa_table.h" |
| #include "pa_dictionary.h" | #include "pa_dictionary.h" |
| #include "pa_charset.h" | |
| String::String(Pool& apool, const char *src, size_t src_size, bool tainted) : | String::String(Pool& apool, const char *src, size_t src_size, bool tainted) : |
| Pooled(apool) { | Pooled(apool) { |
| Line 209 int String::cmp(int& partial, const Stri | Line 207 int String::cmp(int& partial, const Stri |
| bool b_break=src.size()==0; | bool b_break=src.size()==0; |
| if(!(a_break || b_break)) while(true) { | if(!(a_break || b_break)) while(true) { |
| if(pos+a_row->item.size > this_offset) { | if(pos+a_row->item.size > this_offset) { |
| if(lang!=UL_UNSPECIFIED && a_row->item.lang!=lang) | if(lang!=UL_UNSPECIFIED && a_row->item.lang>lang) |
| return -1; // wrong lang -- bail out | return -1; // wrong lang -- bail out |
| int size_diff= | int size_diff= |
| Line 294 int String::cmp(int& partial, const char | Line 292 int String::cmp(int& partial, const char |
| bool b_break=b_size==0; | bool b_break=b_size==0; |
| if(!(a_break || b_break)) while(true) { | if(!(a_break || b_break)) while(true) { |
| if(pos+a_row->item.size > this_offset) { | if(pos+a_row->item.size > this_offset) { |
| if(lang!=UL_UNSPECIFIED && a_row->item.lang!=lang) | if(lang!=UL_UNSPECIFIED && a_row->item.lang>lang) |
| return -1; // wrong lang -- bail out | return -1; // wrong lang -- bail out |
| int size_diff= | int size_diff= |
| Line 398 break2: | Line 396 break2: |
| int String::pos(const String& substr, | int String::pos(const String& substr, |
| int result, Untaint_lang lang) const { | int result, Untaint_lang lang) const { |
| size_t self_size=size(); | size_t self_size=size(); |
| for(; result<self_size; result++) { | for(; size_t(result)<self_size; result++) { |
| int partial; cmp(partial, substr, result, lang); | int partial; cmp(partial, substr, result, lang); |
| if( | if( |
| partial==0 || // full match | partial==0 || // full match |
| Line 412 int String::pos(const String& substr, | Line 410 int String::pos(const String& substr, |
| 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 { | int result, Untaint_lang lang) const { |
| size_t self_size=size(); | size_t self_size=size(); |
| for(; result<self_size; result++) { | for(; size_t(result)<self_size; result++) { |
| int partial; cmp(partial, substr, substr_size, result, lang); | int partial; cmp(partial, substr, substr_size, result, lang); |
| if( | if( |
| partial==0 || // full match | partial==0 || // full match |
| Line 503 static void regex_options(char *options, | Line 501 static void regex_options(char *options, |
| } | } |
| /// @todo maybe need speedup: some option to remove pre/match/post string generation | /// @todo maybe need speedup: some option to remove pre/match/post string generation |
| bool String::match(const unsigned char *pcre_tables, | bool String::match( |
| const String *aorigin, | const String *aorigin, |
| const String& regexp, | const String& regexp, |
| const String *options, | const String *options, |
| Line 523 bool String::match(const unsigned char * | Line 521 bool String::match(const unsigned char * |
| *was_global=option_bits[1]!=0; | *was_global=option_bits[1]!=0; |
| pcre *code=pcre_compile(pattern, option_bits[0], | pcre *code=pcre_compile(pattern, option_bits[0], |
| &errptr, &erroffset, | &errptr, &erroffset, |
| pcre_tables); | pool().get_source_charset().pcre_tables); |
| if(!code) | if(!code) |
| throw Exception(0, 0, | throw Exception(0, 0, |
| Line 605 bool String::match(const unsigned char * | Line 603 bool String::match(const unsigned char * |
| } | } |
| } | } |
| String& String::change_case(Pool& pool, const unsigned char *tables, | String& String::change_case(Pool& pool, |
| Change_case_kind kind) const { | Change_case_kind kind) const { |
| const unsigned char *tables=pool.get_source_charset().pcre_tables; | |
| String& result=*new(pool) String(pool); | String& result=*new(pool) String(pool); |
| const unsigned char *a; | const unsigned char *a; |
| Line 678 void String::join_chain(Pool& pool, | Line 677 void String::join_chain(Pool& pool, |
| if(row->item.lang==joined_lang) | if(row->item.lang==joined_lang) |
| joined_size+=row->item.size; | joined_size+=row->item.size; |
| else | else |
| break; | goto break21; |
| } | } |
| if(chunk=row->link) { | if(chunk=row->link) { |
| start_i=0; | start_i=0; |
| Line 693 break21:; | Line 692 break21:; |
| if(joined_size==arow->item.size) { | if(joined_size==arow->item.size) { |
| joined_ptr=arow->item.ptr; | joined_ptr=arow->item.ptr; |
| ai++; arow++; | ai++; arow++; |
| if(ai==achunk->count) | if(ai==achunk->count) { |
| achunk=arow->link; | if(achunk=arow->link) { |
| ai=0; | |
| arow=achunk->rows; | |
| } | |
| } | |
| } else { | } else { |
| // join adjacent rows | // join adjacent rows |
| char *ptr=(char *)pool.malloc(joined_size,13); | char *ptr=(char *)pool.malloc(joined_size,13); |
| Line 714 break21:; | Line 717 break21:; |
| memcpy(ptr, row->item.ptr, row->item.size); | memcpy(ptr, row->item.ptr, row->item.size); |
| ptr+=row->item.size; | ptr+=row->item.size; |
| } else | } else |
| break; | goto break22; |
| } | } |
| if(chunk=row->link) { | if(chunk=row->link) { |
| start_i=0; | start_i=0; |
| Line 735 String& String::reconstruct(Pool& pool) | Line 738 String& String::reconstruct(Pool& pool) |
| //_asm int 3; | //_asm int 3; |
| String& result=*new(pool) String(pool); | String& result=*new(pool) String(pool); |
| const Chunk *chunk=&head; | const Chunk *chunk=&head; |
| do { | const Chunk::Row *row=chunk->rows; |
| const Chunk::Row *row=chunk->rows; | for(uint i=0; i<chunk->count; ) { |
| for(uint i=0; i<chunk->count; ) { | if(row==append_here) |
| if(row==append_here) | break; |
| goto break2; | |
| uchar joined_lang; | uchar joined_lang; |
| const char *joined_ptr; | const char *joined_ptr; |
| size_t joined_size; | size_t joined_size; |
| join_chain(pool, i, chunk, row, | #ifndef NO_STRING_ORIGIN |
| joined_lang, joined_ptr, joined_size); | const char *joined_origin_file=row->item.origin.file; |
| const size_t joined_origin_line=row->item.origin.line; | |
| #endif | |
| join_chain(pool, i, chunk, row, | |
| joined_lang, joined_ptr, joined_size); | |
| result.APPEND(joined_ptr, joined_size, | result.APPEND(joined_ptr, joined_size, joined_lang, |
| joined_lang, | joined_origin_file, joined_origin_line); |
| row->item.origin.file, row->item.origin.line); | |
| if(!chunk) | if(!chunk) |
| goto break2; | break; |
| } | } |
| } while(true); | |
| break2: | |
| return result; | return result; |
| }; | }; |
| Line 889 break2: | Line 893 break2: |
| ; | ; |
| } | } |
| void String::deserialize(size_t prolog_size, void *buf, size_t buf_size, const char *file) { | void String::deserialize(size_t prolog_size, void *buf, size_t buf_size, const char *file) { |
| if(buf_size<=prolog_size) | |
| return; | |
| char *cur=(char *)buf+prolog_size; | char *cur=(char *)buf+prolog_size; |
| buf_size-=prolog_size; | buf_size-=prolog_size; |