--- parser3/src/include/pa_string.h 2025/05/25 16:36:13 1.235 +++ parser3/src/include/pa_string.h 2026/10/13 20:02:00 1.244 @@ -1,17 +1,18 @@ /** @file Parser: string class decl. - Copyright (c) 2001-2024 Art. Lebedev Studio (http://www.artlebedev.com) + Copyright (c) 2001-2026 Art. Lebedev Studio (https://www.artlebedev.com) Authors: Konstantin Morshnev , Alexandr Petrosian */ #ifndef PA_STRING_H #define PA_STRING_H -#define IDENT_PA_STRING_H "$Id: pa_string.h,v 1.235 2025/05/25 16:36:13 moko Exp $" +#define IDENT_PA_STRING_H "$Id: pa_string.h,v 1.244 2026/10/13 20:02:00 moko Exp $" // includes #include "pa_types.h" +#include "pa_int.h" #include "pa_array.h" extern "C" { // cord's author forgot to do that @@ -71,11 +72,6 @@ public: // generally useful -double pa_atod(const char* str, const String* problem_source); -int pa_atoi(const char* str, int base=10, const String* problem_source=0); -unsigned int pa_atoui(const char *str, int base=10, const String* problem_source=0); -uint64_t pa_atoul(const char *str, int base=10, const String* problem_source=0); - /// this is result of pos functions which mean that substr were not found #define STRING_NOT_FOUND ((size_t)-1) @@ -96,7 +92,7 @@ class String: public PA_Object { public: /** piece is tainted or not. the lang to use when detaint - remember to change String_Untaint_lang_name @ untaint.C along + remember to change Name2lang_hash @ untaint.C along WARNING WARNING WARNING WARNING WARNING WARNING @@ -139,6 +135,11 @@ public: L_OPTIMIZE_BIT = 0x80 ///< flag, requiring cstr whitespace optimization }; + /// throws an exception for an unknown name + static Language name2lang(const String& name); + /// 0 if there is none + static const char* lang2name(Language lang); + enum Trim_kind { TRIM_BOTH, TRIM_START, @@ -378,8 +379,8 @@ public: void dump() const; Body(): body(CORD_EMPTY) INIT_HASH_CODE(0) INIT_LENGTH(0) {} - Body(const char *abody): body(AS_CORD(abody)) INIT_HASH_CODE(0) INIT_LENGTH(0) {} - Body(CORD abody, uint ahash_code): body(abody) INIT_HASH_CODE(ahash_code) INIT_LENGTH(0) {} + explicit Body(const char *abody): body(AS_CORD(abody)) INIT_HASH_CODE(0) INIT_LENGTH(0) {} + explicit Body(CORD abody, uint ahash_code): body(abody) INIT_HASH_CODE(ahash_code) INIT_LENGTH(0) {} explicit Body(C ac): body(AS_CORD(ac.str)) INIT_HASH_CODE(0) INIT_LENGTH(ac.length) {} explicit Body(CORD abody): body(abody) INIT_HASH_CODE(0) INIT_LENGTH(0) { #ifdef CORD_CAT_OPTIMIZATION @@ -400,6 +401,7 @@ public: #endif } + static Body uitoa(size_t aindex); void clear() { ZERO_LENGTH ZERO_HASH_CODE body=CORD_EMPTY; } @@ -486,6 +488,12 @@ public: return CORD_chr(body, offset, c); } + size_t strrchr(char c, size_t right) const { + if(right>=length()) // CORD_rchr does not check that [and ABORT's in that case] + return STRING_NOT_FOUND; + + return CORD_rchr(body, right, c); + } size_t strrpbrk(const char* chars, size_t left, size_t right) const; @@ -659,6 +667,8 @@ public: size_t pos(const Body substr, size_t this_offset, Language lang) const; size_t pos(const String& substr, size_t this_offset, Language lang) const; size_t pos(Charset& charset, const String& substr, size_t this_offset=0, Language lang=L_UNSPECIFIED) const; + /// true if the characters from offset to offset+length are of lang or a cleaner one + bool check_lang(Language lang, size_t offset, size_t length) const { return langs.check_lang(lang, offset, length); } size_t strrpbrk(const char* chars, size_t left=0) const { return (length()) ? body.strrpbrk(chars, left, length()-1) : STRING_NOT_FOUND; @@ -666,6 +676,12 @@ public: size_t strrpbrk(const char* chars, size_t left, size_t right) const { return body.strrpbrk(chars, left, right); } + size_t strrchr(char c) const { + return (length()) ? body.strrchr(c, length()-1) : STRING_NOT_FOUND; + } + size_t strrchr(char c, size_t right) const { + return body.strrchr(c, right); + } size_t rskipchars(const char* chars, size_t left=0) const { return (length()) ? body.rskipchars(chars, left, length()-1) : STRING_NOT_FOUND; @@ -681,7 +697,7 @@ public: /** @return table of found items, if any. - table format is defined and fixed[can be used by others]: + table format is defined and fixed[can be used by others]: @verbatim prematch/match/postmatch/1/2/3/... @endverbatim @@ -692,13 +708,17 @@ public: CC_UPPER, CC_LOWER }; + /// keeps the chars languages String& change_case(Charset& source_charset, Change_case_kind kind) const; + /// keeps the chars languages + String& change_char(char from, char to) const; const String& replace(const Dictionary& dict) const; const String& trim(Trim_kind kind=TRIM_BOTH, const char* chars=0, Charset* source_charset=0) const; double as_double() const { return pa_atod(cstr(), this); } int as_int() const { return pa_atoi(cstr(), 0, this); } - bool as_bool() const { return as_int()!=0; } + pa_wint as_wint() const { return pa_atowi(cstr(), 0, this); } + bool as_bool() const { return as_wint()!=0; } const String& escape(Charset& source_charset) const; private: //disabled