--- parser3/src/main/pa_string.C 2012/03/12 22:29:41 1.239 +++ parser3/src/main/pa_string.C 2012/05/24 12:49:49 1.241 @@ -1,12 +1,10 @@ /** @file Parser: string class. @see untalength_t.C. - Copyright (c) 2001-2009 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_STRING_C="$Date: 2012/03/12 22:29:41 $"; - #include "pa_string.h" #include "pa_exception.h" #include "pa_table.h" @@ -14,6 +12,8 @@ static const char * const IDENT_STRING_C #include "pa_charset.h" #include "pa_vregex.h" +volatile const char * IDENT_PA_STRING_C="$Id: pa_string.C,v 1.241 2012/05/24 12:49:49 misha Exp $" IDENT_PA_STRING_H; + const String String::Empty; int pa_atoi(const char* str, const String* problem_source) { @@ -310,6 +310,57 @@ uint String::Body::get_hash_code() const return hash_code; } +struct CORD_pos_info { + const char* chars; + size_t left; + size_t pos; +}; + +// can be called only for IS_FUNCTION(CORD) which is used in String::Body::strrpbrk +static int CORD_iter_fn_rpos(char c, CORD_pos_info* info) { + if(info->pos < info->left){ + info->pos=STRING_NOT_FOUND; + return 1; + } + if(strchr(info->chars, c)) + return 1; + --(info->pos); + return 0; +} + +size_t String::Body::strrpbrk(const char* chars, size_t left, size_t right) const { + if(is_empty() || !chars || !strlen(chars)) + return STRING_NOT_FOUND; + CORD_pos_info info={chars, left, right}; + if(CORD_riter4(body, right, (CORD_iter_fn)CORD_iter_fn_rpos, &info)) + return info.pos; + else + return STRING_NOT_FOUND; +} + + +// can be called only for IS_FUNCTION(CORD) which is used in String::Body::rskipchars +static int CORD_iter_fn_rskip(char c, CORD_pos_info* info) { + if(info->pos < info->left) { + info->pos=STRING_NOT_FOUND; + return 1; + } + if(!strchr(info->chars, c)) + return 1; + --(info->pos); + return 0; +} + +size_t String::Body::rskipchars(const char* chars, size_t left, size_t right) const { + if(is_empty() || !chars || !strlen(chars)) + return STRING_NOT_FOUND; + CORD_pos_info info={chars, left, right}; + if(CORD_riter4(body, right, (CORD_iter_fn)CORD_iter_fn_rskip, &info)) + return info.pos; + else + return STRING_NOT_FOUND; +} + // String methods String& String::append_know_length(const char* str, size_t known_length, Language lang) {