diff --git a/.travis.yml b/.travis.yml index c8693890..0350198d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,8 @@ -#dist: trusty +dist: trusty language: cpp compiler: - gcc - - clang +# - clang #before_install: # - sudo pip install cpp-coveralls #install: diff --git a/include/ulib/base/base.h b/include/ulib/base/base.h index 5f35abe3..0c6dbe3d 100644 --- a/include/ulib/base/base.h +++ b/include/ulib/base/base.h @@ -460,8 +460,7 @@ static inline uint32_t u_strftime2(char* restrict buffer, uint32_t buffer_size, /* conversion number to string */ -extern U_EXPORT const char* u_ctn2s; -extern U_EXPORT const double u_pow10[309]; /* 1e-0...1e308: 309 * 8 bytes = 2472 bytes */ +extern U_EXPORT const char* u_ctn2s; extern U_EXPORT pcPFdpc u_dbl2str; extern U_EXPORT pcPFu32pc u_num2str32; diff --git a/include/ulib/date.h b/include/ulib/date.h index 1ff209b4..7cd94588 100644 --- a/include/ulib/date.h +++ b/include/ulib/date.h @@ -224,8 +224,8 @@ public: U_INTERNAL_ASSERT(u_now->tv_sec % U_ONE_HOUR_IN_SECOND) - U_NUM2STR16(ptr, (u_now->tv_sec / 60) % 60); - U_NUM2STR16(ptr+3,u_now->tv_sec % 60); + u_put_unalignedp16(ptr, u_dd((u_now->tv_sec / 60) % 60)); + u_put_unalignedp16(ptr+3, u_dd( u_now->tv_sec % 60)); } // The daysTo() function returns the number of days between two date diff --git a/include/ulib/examples/wi_auth_declaration.h b/include/ulib/examples/wi_auth_declaration.h index b4273b3b..5a159f64 100644 --- a/include/ulib/examples/wi_auth_declaration.h +++ b/include/ulib/examples/wi_auth_declaration.h @@ -2612,7 +2612,7 @@ next: else (void) db_user->insertDataStorage(*uid); } - static const char* getPointerToConnection(UStringRep* data) + static const char* getPointerToConnection(UStringRep* data) __pure { U_TRACE(5, "WiAuthUser::getPointerToConnection(%p)", data) @@ -2630,7 +2630,7 @@ next: return ptr; } - static bool isConnected(UStringRep* data) + static bool isConnected(UStringRep* data) __pure { U_TRACE(5, "WiAuthUser::isConnected(%p)", data) @@ -7463,7 +7463,7 @@ static void GET_admin_status_nodog_and_user_as_csv() // TAVARNELLE -int WiAuthNodog::dbNodogFilter(UStringRep* key, UStringRep* data) +__pure int WiAuthNodog::dbNodogFilter(UStringRep* key, UStringRep* data) { U_TRACE(5, "WiAuthNodog::dbNodogFilter(%p,%p)", key, data) diff --git a/include/ulib/internal/common.h b/include/ulib/internal/common.h index d90dec33..c26c6abd 100644 --- a/include/ulib/internal/common.h +++ b/include/ulib/internal/common.h @@ -165,6 +165,29 @@ private: U_DISALLOW_COPY_AND_ASSIGN(ULib) }; +extern U_EXPORT const double u_pow10[309]; /* 1e-0...1e308: 309 * 8 bytes = 2472 bytes */ + +#ifndef HAVE_CXX11 +static inline uint16_t u_dd(uint8_t i) { return U_MULTICHAR_CONSTANT16(u_ctn2s[i], u_ctn2s[i+1]); } +#else +static inline constexpr uint16_t u_dd(uint8_t i) +{ + return U_MULTICHAR_CONSTANT16('0' + ((i%2) ? ((i/2)%10) : ((i/2)/10)), + '0' + (((i+1)%2) ? (((i+1)/2)%10) : (((i+1)/2)/10))); +} + +static_assert( u_dd(0) == U_MULTICHAR_CONSTANT16('0','0'), "should be U_MULTICHAR_CONSTANT16('0','0')" ); +static_assert( u_dd(1) == U_MULTICHAR_CONSTANT16('0','0'), "should be U_MULTICHAR_CONSTANT16('0','0')" ); +static_assert( u_dd(2) == U_MULTICHAR_CONSTANT16('0','1'), "should be U_MULTICHAR_CONSTANT16('0','1')" ); +static_assert( u_dd(3) == U_MULTICHAR_CONSTANT16('1','0'), "should be U_MULTICHAR_CONSTANT16('1','0')" ); +static_assert( u_dd(4) == U_MULTICHAR_CONSTANT16('0','2'), "should be U_MULTICHAR_CONSTANT16('0','2')" ); + +template static constexpr T pow10(size_t x) { return x ? 10*pow10(x-1) : 1; } + +static_assert( pow10(29) == 1e+29, "should be 1e+29" ); // NB: fail for exponent >= 30 +static_assert( pow10(19) == 10000000000000000000ULL, "should be 1e+19" ); +#endif + // Init library #define U_ULIB_INIT(argv) U_SET_LOCATION_INFO, ULib::init(0, argv) diff --git a/src/ulib/base/base.c b/src/ulib/base/base.c index 8f9c4d9d..05b3f81c 100644 --- a/src/ulib/base/base.c +++ b/src/ulib/base/base.c @@ -103,26 +103,6 @@ const char* u_ctn2s = "00010203040506070809" "80818283848586878889" "90919293949596979899"; -const double u_pow10[309] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes - 1, - 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, - 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, - 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, - 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, - 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, - 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, - 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, - 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, - 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, - 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, - 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, - 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, - 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, - 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, - 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, - 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 -}; - /* Startup */ bool u_is_tty; diff --git a/src/ulib/internal/common.cpp b/src/ulib/internal/common.cpp index 90168559..ee35aa83 100644 --- a/src/ulib/internal/common.cpp +++ b/src/ulib/internal/common.cpp @@ -42,6 +42,26 @@ U_EXPORT void operator delete[](void* p, long unsigned int) { free(p); } # endif #endif +const double u_pow10[309] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes + 1, + 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, + 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, + 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, + 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, + 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, + 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, + 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, + 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, + 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, + 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, + 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, + 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, + 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, + 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, + 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, + 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 +}; + #if defined(USE_LIBSSL) && OPENSSL_VERSION_NUMBER < 0x10100000L # include # include @@ -82,7 +102,7 @@ void ULib::init(const char* mempool, char** argv) // conversion number => string #ifndef HAVE_OLD_IOSTREAM - u_dbl2str = dtoa_rapidjson; + u_dbl2str = dtoa_rapidjson; #endif #ifdef DEBUG char buffer[32]; @@ -90,11 +110,11 @@ void ULib::init(const char* mempool, char** argv) UMemoryPool::obj_class = ""; UMemoryPool::func_call = __PRETTY_FUNCTION__; - U_INTERNAL_ASSERT_EQUALS(u_num2str64(1234567890, buffer)-buffer, 10) - U_INTERNAL_ASSERT_EQUALS(memcmp(buffer, "1234567890", 10), 0) - U_INTERNAL_ASSERT_EQUALS(u_dbl2str(1234567890, buffer)-buffer, 12) U_INTERNAL_ASSERT_EQUALS(memcmp(buffer, "1234567890.0", 12), 0) + + U_INTERNAL_ASSERT_EQUALS(u_num2str64(1234567890, buffer)-buffer, 10) + U_INTERNAL_ASSERT_EQUALS(memcmp(buffer, "1234567890", 10), 0) #endif #if defined(HAVE_CXX14) && GCC_VERSION_NUM > 60100 && defined(HAVE_ARCH64) @@ -102,6 +122,7 @@ void ULib::init(const char* mempool, char** argv) u_num2str64 = itoa_fwd; U_INTERNAL_ASSERT_EQUALS(u_num2str64(1234567890, buffer)-buffer, 10) + U_INTERNAL_DUMP("buffer = %.10S", buffer) U_INTERNAL_ASSERT_EQUALS(memcmp(buffer, "1234567890", 10), 0) #endif diff --git a/src/ulib/internal/dtoa.h b/src/ulib/internal/dtoa.h index d23b9815..daa9f2bc 100644 --- a/src/ulib/internal/dtoa.h +++ b/src/ulib/internal/dtoa.h @@ -27,9 +27,6 @@ #define UINT64_C2(h, l) ((static_cast(h) << 32) | static_cast(l)) -extern const char* u_ctn2s; -extern const double u_pow10[309]; - struct DiyFp { DiyFp() : f(), e() {} @@ -337,7 +334,11 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff uint64_t tmp = (static_cast(p1) << -one.e) + p2; if (tmp <= delta) { *K += kappa; - GrisuRound(buffer, *len, delta, tmp, static_cast(u_pow10[kappa]) << -one.e, wp_w.f); +# ifdef HAVE_CXX11 + GrisuRound(buffer, *len, delta, tmp, pow10(kappa) << -one.e, wp_w.f); +# else + GrisuRound(buffer, *len, delta, tmp, (uint64_t)u_pow10[kappa] << -one.e, wp_w.f); +# endif return; } } @@ -354,92 +355,17 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff if (p2 < delta) { *K += kappa; int index = -static_cast(kappa); - GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? (const uint32_t)u_pow10[-static_cast(kappa)] : 0)); +# ifdef HAVE_CXX11 + GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? pow10(index) : 0)); +# else + GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? (uint64_t)u_pow10[index] : 0)); +# endif return; } } } -inline void Grisu2(double value, char* buffer, int* length, int* K) { - const DiyFp v(value); - DiyFp w_m, w_p; - v.NormalizedBoundaries(&w_m, &w_p); - - const DiyFp c_mk = GetCachedPower(w_p.e, K); - const DiyFp W = v.Normalize() * c_mk; - DiyFp Wp = w_p * c_mk; - DiyFp Wm = w_m * c_mk; - Wm.f++; - Wp.f--; - DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K); -} - -inline char* WriteExponent(int K, char* buffer) { - if (K < 0) { - *buffer++ = '-'; - K = -K; - } - - if (K >= 100) { - *buffer++ = static_cast('0' + static_cast(K / 100)); - K %= 100; - const char* d = u_ctn2s + K * 2; - *buffer++ = d[0]; - *buffer++ = d[1]; - } - else if (K >= 10) { - const char* d = u_ctn2s + K * 2; - *buffer++ = d[0]; - *buffer++ = d[1]; - } - else - *buffer++ = static_cast('0' + static_cast(K)); - - return buffer; -} - -inline char* Prettify(char* buffer, int length, int k) { - const int kk = length + k; // 10^(kk-1) <= v < 10^kk - - if (0 <= k && kk <= 21) { - // 1234e7 -> 12340000000 - for (int i = length; i < kk; i++) - buffer[i] = '0'; - buffer[kk] = '.'; - buffer[kk + 1] = '0'; - return &buffer[kk + 2]; - } - else if (0 < kk && kk <= 21) { - // 1234e-2 -> 12.34 - memmove(&buffer[kk + 1], &buffer[kk], static_cast(length - kk)); - buffer[kk] = '.'; - return &buffer[length + 1]; - } - else if (-6 < kk && kk <= 0) { - // 1234e-6 -> 0.001234 - const int offset = 2 - kk; - memmove(&buffer[offset], &buffer[0], static_cast(length)); - buffer[0] = '0'; - buffer[1] = '.'; - for (int i = 2; i < offset; i++) - buffer[i] = '0'; - return &buffer[length + offset]; - } - else if (length == 1) { - // 1e30 - buffer[1] = 'e'; - return WriteExponent(kk - 1, &buffer[2]); - } - else { - // 1234e30 -> 1.234e33 - memmove(&buffer[2], &buffer[1], static_cast(length - 1)); - buffer[1] = '.'; - buffer[length + 1] = 'e'; - return WriteExponent(kk - 1, &buffer[0 + length + 2]); - } -} - -inline char* dtoa_rapidjson(double value, char* buffer) +static char* dtoa_rapidjson(double value, char* buffer) { Double d(value); @@ -449,19 +375,122 @@ inline char* dtoa_rapidjson(double value, char* buffer) { u_put_unalignedp32(buffer, U_MULTICHAR_CONSTANT32('-','0','.','0')); - return &buffer[4]; + return buffer+4; } u_put_unalignedp32(buffer, U_MULTICHAR_CONSTANT32('0','.','0','\0')); - return &buffer[3]; + return buffer+3; } - int length, K; + int length, k; + const DiyFp v(value); + DiyFp w_m, w_p; - Grisu2(value, buffer, &length, &K); + v.NormalizedBoundaries(&w_m, &w_p); - return Prettify(buffer, length, K); + const DiyFp c_mk = GetCachedPower(w_p.e, &k); + const DiyFp W = v.Normalize() * c_mk; + DiyFp Wp = w_p * c_mk; + DiyFp Wm = w_m * c_mk; + + Wm.f++; + Wp.f--; + + DigitGen(W, Wp, Wp.f - Wm.f, buffer, &length, &k); + + int kk = length + k; // 10^(kk-1) <= v < 10^kk + + if (0 <= k && + kk <= 21) + { + // 1234e7 -> 12340000000 + + memset(buffer+length, '0', k); + + buffer += kk; + + u_put_unalignedp16(buffer, U_MULTICHAR_CONSTANT16('.','0')); + + return buffer+2; + } + + if (0 < kk && + kk <= 21) + { + // 1234e-2 -> 12.34 + + char* ptr = buffer+kk; + + memmove(ptr+1, ptr, static_cast(length - kk)); + + *ptr = '.'; + + return buffer+length+1; + } + + if (-6 < kk && + kk <= 0) + { + // 1234e-6 -> 0.001234 + + const int offset = 2 - kk; + + memmove(buffer+offset, buffer, static_cast(length)); + + u_put_unalignedp16(buffer, U_MULTICHAR_CONSTANT16('0','.')); + + memset(buffer+2, '0', -kk); + + return buffer+length+offset; + } + + if (length == 1) + { + // 1e30 + + buffer[1] = 'e'; + + buffer += 2; + + goto exp; + } + + // 1234e30 -> 1.234e33 + + memmove(buffer+2, buffer+1, static_cast(length - 1)); + + buffer[1] = '.'; + buffer[length+1] = 'e'; + + buffer += length+2; + +exp: + if (--kk < 0) + { + kk = -kk; + + *buffer++ = '-'; + } + + if (kk >= 100) + { + *buffer++ = '0' + (kk / 100); + kk %= 100; + + goto next; + } + + if (kk >= 10) + { +next: u_put_unalignedp16(buffer, u_dd(kk * 2)); + + return buffer + 2; + } + + *buffer++ = '0' + kk; + + return buffer; } #endif diff --git a/src/ulib/internal/itoa.h b/src/ulib/internal/itoa.h index 300b4141..dcaf29d1 100644 --- a/src/ulib/internal/itoa.h +++ b/src/ulib/internal/itoa.h @@ -56,9 +56,11 @@ namespace dec_ { // return reinterpret_cast(digits.data())[u]; } + /* template static constexpr T pow10(size_t x) { return x ? 10*pow10(x-1) : 1; } + */ // Division by a power of 10 is implemented using a multiplicative inverse. // This strength reduction is also done by optimizing compilers, but diff --git a/src/ulib/json/value.cpp b/src/ulib/json/value.cpp index d06128a1..a4d1cebe 100644 --- a/src/ulib/json/value.cpp +++ b/src/ulib/json/value.cpp @@ -1209,8 +1209,8 @@ mreal: U_INTERNAL_ASSERT_MINOR(significandDigit, 17) - if (gexponent > 0) val = (double)integerPart * u_pow10[ gexponent]; - else val = (double)integerPart / u_pow10[-gexponent]; + val = (gexponent > 0 ? (double)integerPart * u_pow10[ gexponent] + : (double)integerPart / u_pow10[-gexponent]); mreal1: # ifdef DEBUG diff --git a/src/ulib/orm/driver/orm_driver_mysql.cpp b/src/ulib/orm/driver/orm_driver_mysql.cpp index 60645253..259d4cae 100644 --- a/src/ulib/orm/driver/orm_driver_mysql.cpp +++ b/src/ulib/orm/driver/orm_driver_mysql.cpp @@ -103,9 +103,10 @@ void UOrmDriverMySql::handlerError() U_ENTRY(CR_AUTH_PLUGIN_CANNOT_LOAD) }; - if (UOrmDriver::errmsg == 0) UOrmDriver::errmsg = U_SYSCALL(mysql_error, "%p", (MYSQL*)UOrmDriver::connection); - UOrmDriver::errcode = U_SYSCALL(mysql_errno, "%p", (MYSQL*)UOrmDriver::connection); - UOrmDriver::SQLSTATE = U_SYSCALL(mysql_sqlstate, "%p", (MYSQL*)UOrmDriver::connection); + UOrmDriver::errcode = U_SYSCALL(mysql_errno, "%p", (MYSQL*)UOrmDriver::connection); + UOrmDriver::SQLSTATE = U_SYSCALL(mysql_sqlstate, "%p", (MYSQL*)UOrmDriver::connection); + + if (UOrmDriver::errmsg == 0) UOrmDriver::errmsg = U_SYSCALL(mysql_error, "%p", (MYSQL*)UOrmDriver::connection); if (UOrmDriver::errcode >= CR_ERROR_FIRST) UOrmDriver::errcode -= CR_ERROR_FIRST; // 2000 diff --git a/src/ulib/utility/http2.cpp b/src/ulib/utility/http2.cpp index 39b842be..259d9774 100644 --- a/src/ulib/utility/http2.cpp +++ b/src/ulib/utility/http2.cpp @@ -2256,7 +2256,7 @@ void UHTTP2::handlerResponse() default: // use literal header field without indexing - indexed name { u_put_unalignedp32(ptr+HTTP2_FRAME_HEADER_SIZE, U_MULTICHAR_CONSTANT32(0x08,0x03,0x30+(U_http_info.nResponseCode / 100),'\0')); - U_NUM2STR16(ptr+HTTP2_FRAME_HEADER_SIZE+3, U_http_info.nResponseCode % 100); + u_put_unalignedp16(ptr+HTTP2_FRAME_HEADER_SIZE+3, u_dd(U_http_info.nResponseCode % 100)); sz += 4; dst += 4;