michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsError_h__ michael@0: #define nsError_h__ michael@0: michael@0: #include "mozilla/Likely.h" michael@0: #include "mozilla/TypedEnum.h" michael@0: michael@0: #include michael@0: michael@0: /* michael@0: * To add error code to your module, you need to do the following: michael@0: * michael@0: * 1) Add a module offset code. Add yours to the bottom of the list michael@0: * right below this comment, adding 1. michael@0: * michael@0: * 2) In your module, define a header file which uses one of the michael@0: * NE_ERROR_GENERATExxxxxx macros. Some examples below: michael@0: * michael@0: * #define NS_ERROR_MYMODULE_MYERROR1 NS_ERROR_GENERATE(NS_ERROR_SEVERITY_ERROR,NS_ERROR_MODULE_MYMODULE,1) michael@0: * #define NS_ERROR_MYMODULE_MYERROR2 NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_MYMODULE,2) michael@0: * #define NS_ERROR_MYMODULE_MYERROR3 NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_MYMODULE,3) michael@0: * michael@0: */ michael@0: michael@0: michael@0: /** michael@0: * @name Standard Module Offset Code. Each Module should identify a unique number michael@0: * and then all errors associated with that module become offsets from the michael@0: * base associated with that module id. There are 16 bits of code bits for michael@0: * each module. michael@0: */ michael@0: michael@0: #define NS_ERROR_MODULE_XPCOM 1 michael@0: #define NS_ERROR_MODULE_BASE 2 michael@0: #define NS_ERROR_MODULE_GFX 3 michael@0: #define NS_ERROR_MODULE_WIDGET 4 michael@0: #define NS_ERROR_MODULE_CALENDAR 5 michael@0: #define NS_ERROR_MODULE_NETWORK 6 michael@0: #define NS_ERROR_MODULE_PLUGINS 7 michael@0: #define NS_ERROR_MODULE_LAYOUT 8 michael@0: #define NS_ERROR_MODULE_HTMLPARSER 9 michael@0: #define NS_ERROR_MODULE_RDF 10 michael@0: #define NS_ERROR_MODULE_UCONV 11 michael@0: #define NS_ERROR_MODULE_REG 12 michael@0: #define NS_ERROR_MODULE_FILES 13 michael@0: #define NS_ERROR_MODULE_DOM 14 michael@0: #define NS_ERROR_MODULE_IMGLIB 15 michael@0: #define NS_ERROR_MODULE_MAILNEWS 16 michael@0: #define NS_ERROR_MODULE_EDITOR 17 michael@0: #define NS_ERROR_MODULE_XPCONNECT 18 michael@0: #define NS_ERROR_MODULE_PROFILE 19 michael@0: #define NS_ERROR_MODULE_LDAP 20 michael@0: #define NS_ERROR_MODULE_SECURITY 21 michael@0: #define NS_ERROR_MODULE_DOM_XPATH 22 michael@0: /* 23 used to be NS_ERROR_MODULE_DOM_RANGE (see bug 711047) */ michael@0: #define NS_ERROR_MODULE_URILOADER 24 michael@0: #define NS_ERROR_MODULE_CONTENT 25 michael@0: #define NS_ERROR_MODULE_PYXPCOM 26 michael@0: #define NS_ERROR_MODULE_XSLT 27 michael@0: #define NS_ERROR_MODULE_IPC 28 michael@0: #define NS_ERROR_MODULE_SVG 29 michael@0: #define NS_ERROR_MODULE_STORAGE 30 michael@0: #define NS_ERROR_MODULE_SCHEMA 31 michael@0: #define NS_ERROR_MODULE_DOM_FILE 32 michael@0: #define NS_ERROR_MODULE_DOM_INDEXEDDB 33 michael@0: #define NS_ERROR_MODULE_DOM_FILEHANDLE 34 michael@0: #define NS_ERROR_MODULE_SIGNED_JAR 35 michael@0: #define NS_ERROR_MODULE_DOM_FILESYSTEM 36 michael@0: michael@0: /* NS_ERROR_MODULE_GENERAL should be used by modules that do not michael@0: * care if return code values overlap. Callers of methods that michael@0: * return such codes should be aware that they are not michael@0: * globally unique. Implementors should be careful about blindly michael@0: * returning codes from other modules that might also use michael@0: * the generic base. michael@0: */ michael@0: #define NS_ERROR_MODULE_GENERAL 51 michael@0: michael@0: /** michael@0: * @name Severity Code. This flag identifies the level of warning michael@0: */ michael@0: michael@0: #define NS_ERROR_SEVERITY_SUCCESS 0 michael@0: #define NS_ERROR_SEVERITY_ERROR 1 michael@0: michael@0: /** michael@0: * @name Mozilla Code. This flag separates consumers of mozilla code michael@0: * from the native platform michael@0: */ michael@0: michael@0: #define NS_ERROR_MODULE_BASE_OFFSET 0x45 michael@0: michael@0: /* Helpers for defining our enum, to be undef'd later */ michael@0: #define SUCCESS_OR_FAILURE(sev, module, code) \ michael@0: ((uint32_t)(sev) << 31) | \ michael@0: ((uint32_t)(module + NS_ERROR_MODULE_BASE_OFFSET) << 16) | \ michael@0: (uint32_t)(code) michael@0: #define SUCCESS(code) \ michael@0: SUCCESS_OR_FAILURE(NS_ERROR_SEVERITY_SUCCESS, MODULE, code) michael@0: #define FAILURE(code) \ michael@0: SUCCESS_OR_FAILURE(NS_ERROR_SEVERITY_ERROR, MODULE, code) michael@0: michael@0: /** michael@0: * @name Standard return values michael@0: */ michael@0: michael@0: /*@{*/ michael@0: michael@0: /* Unfortunately, our workaround for compilers that don't support enum class michael@0: * doesn't really work for nsresult. We need constants like NS_OK with type michael@0: * nsresult, but they can't be used in (e.g.) switch cases if they're objects. michael@0: * But if we define them to be of type nsresult::Enum instead, that causes michael@0: * return foo ? F() : NS_ERROR_FAILURE; michael@0: * to fail, because nsresult and nsresult::Enum are two distinct types and michael@0: * either can be converted to the other, so it's ambiguous. So we have to fall michael@0: * back to a regular enum. michael@0: */ michael@0: #if defined(MOZ_HAVE_CXX11_STRONG_ENUMS) michael@0: typedef enum class tag_nsresult : uint32_t michael@0: { michael@0: #undef ERROR michael@0: #define ERROR(key, val) key = val michael@0: #include "ErrorList.h" michael@0: #undef ERROR michael@0: } nsresult; michael@0: michael@0: /* michael@0: * enum classes don't place their initializers in the global scope, so we need michael@0: * #define's for compatibility with old code. michael@0: */ michael@0: #include "ErrorListCxxDefines.h" michael@0: #elif defined(MOZ_HAVE_CXX11_ENUM_TYPE) michael@0: typedef enum tag_nsresult : uint32_t michael@0: { michael@0: #undef ERROR michael@0: #define ERROR(key, val) key = val michael@0: #include "ErrorList.h" michael@0: #undef ERROR michael@0: } nsresult; michael@0: #elif defined(__cplusplus) michael@0: /* michael@0: * We're C++ in an old compiler lacking enum classes *and* typed enums (likely michael@0: * gcc < 4.5.1 as clang/MSVC have long supported one or both), or compiler michael@0: * support is unknown. Yet nsresult must have unsigned 32-bit representation. michael@0: * So just make it a typedef, and implement the constants with global consts. michael@0: */ michael@0: typedef uint32_t nsresult; michael@0: michael@0: const nsresult michael@0: #undef ERROR michael@0: #define ERROR(key, val) key = val michael@0: #include "ErrorList.h" michael@0: #undef ERROR michael@0: ; michael@0: #else michael@0: /* michael@0: * C doesn't have any way to fix the type underlying an enum, and enum michael@0: * initializers can't have values outside the range of 'int'. So typedef michael@0: * nsresult to the correct unsigned type, and fall back to using #defines for michael@0: * all error constants. michael@0: */ michael@0: typedef uint32_t nsresult; michael@0: #include "ErrorListCDefines.h" michael@0: #endif michael@0: michael@0: #undef SUCCESS_OR_FAILURE michael@0: #undef SUCCESS michael@0: #undef FAILURE michael@0: michael@0: /** michael@0: * @name Standard Error Handling Macros michael@0: * @return 0 or 1 (false/true with bool type for C++) michael@0: */ michael@0: michael@0: #ifdef __cplusplus michael@0: inline uint32_t NS_FAILED_impl(nsresult _nsresult) { michael@0: return static_cast(_nsresult) & 0x80000000; michael@0: } michael@0: #define NS_FAILED(_nsresult) ((bool)MOZ_UNLIKELY(NS_FAILED_impl(_nsresult))) michael@0: #define NS_SUCCEEDED(_nsresult) ((bool)MOZ_LIKELY(!NS_FAILED_impl(_nsresult))) michael@0: michael@0: /* Check that our enum type is actually uint32_t as expected */ michael@0: static_assert(((nsresult)0) < ((nsresult)-1), michael@0: "nsresult must be an unsigned type"); michael@0: static_assert(sizeof(nsresult) == sizeof(uint32_t), michael@0: "nsresult must be 32 bits"); michael@0: #else michael@0: #define NS_FAILED_impl(_nsresult) ((_nsresult) & 0x80000000) michael@0: #define NS_FAILED(_nsresult) (MOZ_UNLIKELY(NS_FAILED_impl(_nsresult))) michael@0: #define NS_SUCCEEDED(_nsresult) (MOZ_LIKELY(!NS_FAILED_impl(_nsresult))) michael@0: #endif michael@0: michael@0: /** michael@0: * @name Standard Error Generating Macros michael@0: */ michael@0: michael@0: #define NS_ERROR_GENERATE(sev, module, code) \ michael@0: (nsresult)(((uint32_t)(sev) << 31) | \ michael@0: ((uint32_t)(module + NS_ERROR_MODULE_BASE_OFFSET) << 16) | \ michael@0: ((uint32_t)(code))) michael@0: michael@0: #define NS_ERROR_GENERATE_SUCCESS(module, code) \ michael@0: NS_ERROR_GENERATE(NS_ERROR_SEVERITY_SUCCESS, module, code) michael@0: michael@0: #define NS_ERROR_GENERATE_FAILURE(module, code) \ michael@0: NS_ERROR_GENERATE(NS_ERROR_SEVERITY_ERROR, module, code) michael@0: michael@0: /* michael@0: * This will return the nsresult corresponding to the most recent NSPR failure michael@0: * returned by PR_GetError. michael@0: * michael@0: *********************************************************************** michael@0: * Do not depend on this function. It will be going away! michael@0: *********************************************************************** michael@0: */ michael@0: extern nsresult michael@0: NS_ErrorAccordingToNSPR(); michael@0: michael@0: michael@0: /** michael@0: * @name Standard Macros for retrieving error bits michael@0: */ michael@0: michael@0: #ifdef __cplusplus michael@0: inline uint16_t NS_ERROR_GET_CODE(nsresult err) { michael@0: return uint32_t(err) & 0xffff; michael@0: } michael@0: inline uint16_t NS_ERROR_GET_MODULE(nsresult err) { michael@0: return ((uint32_t(err) >> 16) - NS_ERROR_MODULE_BASE_OFFSET) & 0x1fff; michael@0: } michael@0: inline bool NS_ERROR_GET_SEVERITY(nsresult err) { michael@0: return uint32_t(err) >> 31; michael@0: } michael@0: #else michael@0: #define NS_ERROR_GET_CODE(err) ((err) & 0xffff) michael@0: #define NS_ERROR_GET_MODULE(err) ((((err) >> 16) - NS_ERROR_MODULE_BASE_OFFSET) & 0x1fff) michael@0: #define NS_ERROR_GET_SEVERITY(err) (((err) >> 31) & 0x1) michael@0: #endif michael@0: michael@0: michael@0: #ifdef _MSC_VER michael@0: #pragma warning(disable: 4251) /* 'nsCOMPtr' needs to have dll-interface to be used by clients of class 'nsInputStream' */ michael@0: #pragma warning(disable: 4275) /* non dll-interface class 'nsISupports' used as base for dll-interface class 'nsIRDFNode' */ michael@0: #endif michael@0: michael@0: #endif