/*- * Copyright 2005-2007 Guram Dukashvili * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ //--------------------------------------------------------------------------- #include //#include //--------------------------------------------------------------------------- namespace ksys { //--------------------------------------------------------------------------- uint8_t strErrorHandlersHolder[sizeof(StrErrorHandlers)]; //--------------------------------------------------------------------------- void addStrErrorHandler(StrErrorHandler strErrorHandler) { strErrorHandlers().add(strErrorHandler); } //--------------------------------------------------------------------------- utf8::String strError(int32_t err) { if( err - errorOffset != 0 ){ intptr_t i; for( i = strErrorHandlers().count() - 1; i >= 0; i-- ){ utf8::String se(strErrorHandlers()[i](err)); if( se.strlen() > 0 ) return se; } #if defined(__WIN32__) || defined(__WIN64__) if( err >= errorOffset ){ DWORD bytes; LPVOID lpMsgBuf = NULL; utf8::String wes; try { if( isWin9x() ){ bytes = FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err - errorOffset, LANG_USER_DEFAULT, // Default language (LPSTR) &lpMsgBuf, 0, NULL ); if( bytes > 0 ){ ((LPSTR) lpMsgBuf)[bytes - 1] = '\0'; LPSTR nl = strchr((LPSTR) lpMsgBuf,'\r'); if( nl != NULL ) *nl = '\0'; nl = strchr((LPSTR) lpMsgBuf,'\n'); if( nl != NULL ) *nl = '\0'; wes = (LPCSTR) lpMsgBuf; } } else { bytes = FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err - errorOffset, LANG_USER_DEFAULT, // Default language (LPWSTR) &lpMsgBuf, 0, NULL ); if( bytes > 0 ){ ((LPWSTR) lpMsgBuf)[bytes - 1] = L'\0'; LPWSTR nl = wcschr((LPWSTR) lpMsgBuf,L'\r'); if( nl != NULL ) *nl = L'\0'; nl = wcschr((LPWSTR) lpMsgBuf,L'\n'); if( nl != NULL ) *nl = L'\0'; wes = (LPCWSTR) lpMsgBuf; } } } catch( ... ){ LocalFree(lpMsgBuf); throw; } LocalFree(lpMsgBuf); if( bytes > 0 ) return wes; } /* intptr_t c = sizeof(winErrsDesc) / sizeof(winErrsDesc[0]) - 1; if( err >= errorOffset && err < winErrsDesc[c].code_ + errorOffset ){ struct WinErrDesc bs; bs.code_ = err - errorOffset; c = sizeof(winErrsDesc) / sizeof(winErrsDesc[0]); i = bSearch(winErrsDesc, bs, c); if( c == 0 ) return winErrsDesc[i].text_; err -= errorOffset; }*/ #endif AutoPtr serr; #if HAVE_STRERROR_R && !__linux__ int32_t er; size_t sel = 16; for(;;){ serr.realloc(sel = (sel << 1) + (sel == 0)); // memset(serr,'@',sel); // fprintf(stderr,"%s %d sel = %u\n",__FILE__,__LINE__,sel); if( (er = strerror_r(err,serr,sel)) != 0 && er != ERANGE && er != EINVAL ){ perror(NULL); abort(); } if( er == 0 || er == EINVAL ) break; } #elif HAVE_STRERROR serr.realloc(::strlen(strerror(err)) + 1); strcpy(serr,strerror(err)); #endif if( strchr(serr.ptr(),'\r') != NULL ) *strchr(serr.ptr(),'\r') = '\0'; if( strchr(serr.ptr(),'\n') != NULL ) *strchr(serr.ptr(),'\n') = '\0'; if( strlen(serr) > 0 && ::strncmp(serr,"Unknown error",13) != 0 ) return serr.ptr(); return utf8::int2Str(err); } return utf8::String(); } //--------------------------------------------------------------------------- void strErrorInitialize() { new (strErrorHandlersHolder) Array; #if defined(__WIN32__) || defined(__WIN64__) // qSort(winErrsDesc, 0, sizeof(winErrsDesc) / sizeof(winErrsDesc[0]) - 1); #endif } //--------------------------------------------------------------------------- void strErrorCleanup() { strErrorHandlers().~StrErrorHandlers(); } //--------------------------------------------------------------------------- } // namespace ksys //---------------------------------------------------------------------------