--- parser3/src/main/pa_int.C 2026/01/07 01:10:05 1.4 +++ parser3/src/main/pa_int.C 2026/01/07 18:11:33 1.8 @@ -5,11 +5,12 @@ Authors: Konstantin Morshnev , Alexandr Petrosian */ +#include "pa_common.h" #include "pa_int.h" #include "pa_string.h" #include "pa_exception.h" -volatile const char * IDENT_PA_INT_C="$Id: pa_int.C,v 1.4 2026/01/07 01:10:05 moko Exp $" IDENT_PA_INT_H; +volatile const char * IDENT_PA_INT_C="$Id: pa_int.C,v 1.8 2026/01/07 18:11:33 moko Exp $" IDENT_PA_INT_H; #ifdef PA_WIDE_INT int check4int(pa_wint avalue){ @@ -18,6 +19,27 @@ int check4int(pa_wint avalue){ return (int)avalue; } #endif + +char* pa_itoa(int i){ // custom to support INT_MIN + const int base=10; + char buf[MAX_NUMBER + 1]; + char* pos=buf + MAX_NUMBER; + *pos='\0'; + + bool negative=i < 0; + unsigned int n= i < 0 ? 0u-(unsigned int)i : (unsigned int)i; + + do { + *(--pos)=(char)(n % base) + '0'; + n/=base; + } while (n > 0); + + if (negative) { + *(--pos) = '-'; + } + return pa_strdup(pos, buf + MAX_NUMBER - pos); +} + // pa_atoui is based on Manuel Novoa III _strto_l for uClibc template inline T pa_ato_any(const char *str, int base, const String* problem_source,const T max){ @@ -123,7 +145,7 @@ int pa_atoi(const char* str, int base, c } if(negative){ - const uint min_abs = (uint)(-( (uint)INT_MIN + 1 )) + 1; + const uint min_abs = (uint)0 - (uint)INT_MIN; uint result=pa_ato_any(str, base, problem_source, min_abs); if(result==min_abs) return INT_MIN; return -(int)result; @@ -156,7 +178,7 @@ pa_wint pa_atowi(const char* str, int ba } if(negative){ - const pa_uwint min_abs = (pa_uwint)(-( (pa_wint)PA_WINT_MIN + 1 )) + 1; + const pa_uwint min_abs = (pa_uwint)0 - (pa_uwint)PA_WINT_MIN; pa_uwint result=pa_ato_any(str, base, problem_source, min_abs); if(result==min_abs) return PA_WINT_MIN; return -(pa_wint)result; @@ -213,6 +235,9 @@ double pa_atod(const char* str, const St // format: %[flags][width][.precision]type https://msdn.microsoft.com/ru-ru/library/56e442dc(en-us,VS.80).aspx // flags: '-', '+', ' ', '#', '0' https://msdn.microsoft.com/ru-ru/library/8aky45ct(en-us,VS.80).aspx // width, precision: non negative decimal number + +#define MAX_FORMAT_LEN 10 // %+0XX.XXg\0 + enum FormatType { FormatInvalid, FormatInt, @@ -271,7 +296,7 @@ FormatType format_type(const char* fmt){ return FormatInvalid; // no chars allowed after 'type' } } - return result; + return pos-fmt > MAX_FORMAT_LEN ? FormatInvalid : result; } #ifdef PA_WIDE_INT @@ -308,7 +333,7 @@ const char* format_double(double value, case FormatUInt: if(value >= 0){ // on Apple M1 (uint) is 0 #ifdef PA_WIDE_INT - char fmt_buf[strlen(fmt)+4]; + char fmt_buf[MAX_FORMAT_LEN+4]; size=snprintf(local_buf, sizeof(local_buf), wide_int_fmt(fmt, fmt_buf), (unsigned long long)clip2wint(value)); // WUINT_MAX == WINT_MAX #else size=snprintf(local_buf, sizeof(local_buf), fmt, clip2uint(value)); @@ -320,7 +345,7 @@ const char* format_double(double value, break; case FormatInt:{ #ifdef PA_WIDE_INT - char fmt_buf[strlen(fmt)+4]; + char fmt_buf[MAX_FORMAT_LEN+4]; size=snprintf(local_buf, sizeof(local_buf), wide_int_fmt(fmt, fmt_buf), (long long)clip2wint(value)); #else size=snprintf(local_buf, sizeof(local_buf), fmt, clip2int(value));