--- parser3/src/main/pa_string.C 2012/06/20 21:01:20 1.243 +++ parser3/src/main/pa_string.C 2015/10/09 16:03:28 1.252 @@ -12,15 +12,18 @@ #include "pa_charset.h" #include "pa_vregex.h" -volatile const char * IDENT_PA_STRING_C="$Id: pa_string.C,v 1.243 2012/06/20 21:01:20 moko Exp $" IDENT_PA_STRING_H; +#ifndef ULLONG_MAX +#define ULLONG_MAX 18446744073709551615ULL +#endif -const String String::Empty; +volatile const char * IDENT_PA_STRING_C="$Id: pa_string.C,v 1.252 2015/10/09 16:03:28 moko Exp $" IDENT_PA_STRING_H; +const String String::Empty; // pa_atoui is based on Manuel Novoa III _strto_l for uClibc -unsigned int pa_atoui(const char *str, int base, const String* problem_source){ - unsigned int result = 0; +template inline T pa_ato_any(const char *str, int base, const String* problem_source,const T max){ + T result = 0; const char *pos = str; while (isspace(*pos)) /* skip leading whitespace */ @@ -37,9 +40,10 @@ unsigned int pa_atoui(const char *str, i base = 10; /* default is 10 */ if (*pos == '0') { ++pos; - if (*pos == 'x' || *pos == 'X') + if (*pos == 'x' || *pos == 'X'){ ++pos; base=16; + } } } @@ -47,8 +51,8 @@ unsigned int pa_atoui(const char *str, i throw Exception(PARSER_RUNTIME, 0, "base to must be an integer from 2 to 16"); } - unsigned int cutoff = UINT_MAX / base; - int cutoff_digit = UINT_MAX - cutoff * base; + T cutoff = max / base; + int cutoff_digit = (int)(max - cutoff * base); while(true) { int digit; @@ -82,6 +86,14 @@ unsigned int pa_atoui(const char *str, i return result; } +unsigned int pa_atoui(const char *str, int base, const String* problem_source){ + return pa_ato_any(str, base, problem_source, UINT_MAX); +} + +unsigned long long pa_atoul(const char *str, int base, const String* problem_source){ + return pa_ato_any(str, base, problem_source, ULLONG_MAX); +} + int pa_atoi(const char* str, const String* problem_source) { if(!str) return 0; @@ -130,15 +142,16 @@ double pa_atod(const char* str, const St } double result; - if(str[0]=='0') - if(str[1]=='x' || str[1]=='X'){ + if(str[0]=='0') { + if(str[1]=='x' || str[1]=='X') { // 0xABC - result=(double)pa_atoui(str, 0, problem_source); + result=(double)pa_atoul(str, 0, problem_source); return negative ? -result : result; } else { // skip leading 0000, to disable octal interpretation do str++; while(*str=='0'); } + } char *error_pos; result=strtod(str, &error_pos); @@ -158,6 +171,7 @@ typedef struct { int target; /* Character we're looking for */ } chr_data; #endif + static int CORD_range_contains_chr_greater_then_proc(char c, size_t size, void* client_data) { register chr_data * d = (chr_data *)client_data; @@ -167,6 +181,7 @@ static int CORD_range_contains_chr_great if (c > d -> target) return(1); return(0); } + int CORD_range_contains_chr_greater_then(CORD x, size_t i, size_t n, int c) { chr_data d; @@ -182,6 +197,7 @@ static int CORD_block_count_proc(char /* (*result)++; return(0); // 0=continue } + size_t CORD_block_count(CORD x) { size_t result=0; @@ -340,11 +356,13 @@ static int CORD_batched_iter_fn_generic_ generic_hash_code(result, c); return 0; } + static int CORD_batched_iter_fn_generic_hash_code(const char* s, void * client_data) { uint& result=*static_cast(client_data); generic_hash_code(result, s); return 0; -}; +} + uint String::Body::get_hash_code() const { #ifdef HASH_CODE_CACHING if(hash_code) @@ -353,7 +371,7 @@ uint String::Body::get_hash_code() const uint hash_code=0; #endif if (body && CORD_IS_STRING(body)){ - generic_hash_code(hash_code, body); + generic_hash_code(hash_code, (const char *)body); } else { CORD_iter5(body, 0, CORD_batched_iter_fn_generic_hash_code, @@ -427,6 +445,7 @@ String& String::append_know_length(const ASSERT_STRING_INVARIANT(*this); return *this; } + String& String::append_help_length(const char* str, size_t helper_length, Language lang) { if(!str) return *this; @@ -436,10 +455,12 @@ String& String::append_help_length(const return append_know_length(str, known_length, lang); } -String::String(int value, char *format) : langs(L_CLEAN){ + +String::String(int value, const char *format) : langs(L_CLEAN){ char buf[MAX_NUMBER]; body.append_strdup_know_length(buf, snprintf(buf, MAX_NUMBER, format, value)); } + String& String::append_strdup(const char* str, size_t helper_length, Language lang) { size_t known_length=helper_length?helper_length:strlen(str); if(!known_length) @@ -824,12 +845,14 @@ const String& String::replace(const Dict static int serialize_body_char(char c, char** cur) { *((*cur)++)=c; return 0; // 0=continue -}; +} + static int serialize_body_piece(const char* s, char** cur) { size_t length=strlen(s); memcpy(*cur, s, length); *cur+=length; return 0; // 0=continue -}; +} + static int serialize_lang_piece(char alang, size_t asize, char** cur) { // lang **cur=alang; (*cur)++; @@ -838,6 +861,7 @@ static int serialize_lang_piece(char ala return 0; // 0=continue } + String::Cm String::serialize(size_t prolog_length) const { size_t fragments_count=langs.count(); size_t body_length=body.length(); @@ -866,6 +890,7 @@ String::Cm String::serialize(size_t prol return result; } + bool String::deserialize(size_t prolog_size, void *buf, size_t buf_size) { size_t in_buf=buf_size; if(in_buf<=prolog_size) @@ -889,10 +914,7 @@ bool String::deserialize(size_t prolog_s if(cur[body_length] != 0) // in place? return false; // 3: letters - body=String::Body(*cur?cur:0); -#ifdef STRING_LENGTH_CACHING - body.set_length(body_length); -#endif + body=String::Body(String::C(cur, body_length)); cur+=body_length+1; in_buf-=body_length+1; @@ -941,6 +963,7 @@ bool String::deserialize(size_t prolog_s const char* String::Body::v() const { return CORD_to_const_char_star(body, length()); } + void String::Body::dump() const { CORD_dump(body); } @@ -951,15 +974,17 @@ const char* String::Languages::v() const else return (const char*)&langs; } + void String::Languages::dump() const { if(opt.is_not_just_lang) CORD_dump(langs); else puts((const char*)&langs); } + const char* String::v() const { const uint LIMIT_VIEW=20; - char* buf=(char*)malloc(MAX_STRING); + char* buf=(char*)pa_malloc(MAX_STRING); const char*body_view=body.v(); const char*langs_view=langs.v(); snprintf(buf, MAX_STRING,