cleanup (requires update-workspaces)

lib_errors.cpp: replace with status.cpp, adapt to needs at work
wutil: fix runtime warning reported via feedback box
config: merge CONFIG_PARANOIA and !CONFIG_FINAL into
CONFIG_ENABLE_CHECKS
add openmp, pointer_typedefs.h

This was SVN commit r9410.
This commit is contained in:
janwas 2011-05-03 12:38:42 +00:00
parent 114ca8e4ce
commit cccd6849a7
198 changed files with 1995 additions and 1961 deletions

View file

@ -147,7 +147,7 @@ public:
// logic warns when asked to load such.
if(writeBuffer.Size())
{
LibError ret = g_VFS->CreateFile(pmdFilename, writeBuffer.Data(), writeBuffer.Size());
Status ret = g_VFS->CreateFile(pmdFilename, writeBuffer.Data(), writeBuffer.Size());
ENSURE(ret == INFO::OK);
}
@ -241,7 +241,7 @@ VfsPath CColladaManager::GetLoadableFilename(const VfsPath& pathnameNoExtension,
// realDaePath_ is "[..]/mods/whatever/art/meshes/whatever.dae"
OsPath realDaePath_;
LibError ret = g_VFS->GetRealPath(dae, realDaePath_);
Status ret = g_VFS->GetRealPath(dae, realDaePath_);
ENSURE(ret == INFO::OK);
wchar_t realDaeBuf[PATH_MAX];
wcscpy_s(realDaeBuf, ARRAY_SIZE(realDaeBuf), realDaePath_.string().c_str());

View file

@ -220,7 +220,7 @@ bool CMapGeneratorWorker::LoadScripts(const std::wstring& libraryName)
return true;
}
LibError CMapGeneratorWorker::PreloadScript(const VfsPath& pathname, const FileInfo& UNUSED(fileInfo), const uintptr_t cbData)
Status CMapGeneratorWorker::PreloadScript(const VfsPath& pathname, const FileInfo& UNUSED(fileInfo), const uintptr_t cbData)
{
CMapGeneratorWorker* self = (CMapGeneratorWorker*)cbData;

View file

@ -139,7 +139,7 @@ private:
ScriptFilesMap m_ScriptFiles;
// callback for VFS preloading
static LibError PreloadScript(const VfsPath& pathname, const FileInfo& fileInfo, const uintptr_t cbData);
static Status PreloadScript(const VfsPath& pathname, const FileInfo& fileInfo, const uintptr_t cbData);
// Thread
static void* RunThread(void* data);

View file

@ -53,7 +53,7 @@ bool CObjectManager::ObjectKey::operator< (const CObjectManager::ObjectKey& a) c
return ActorVariation < a.ActorVariation;
}
static LibError ReloadChangedFileCB(void* param, const VfsPath& path)
static Status ReloadChangedFileCB(void* param, const VfsPath& path)
{
return static_cast<CObjectManager*>(param)->ReloadChangedFile(path);
}
@ -191,7 +191,7 @@ void CObjectManager::UnloadObjects()
m_ObjectBases.clear();
}
LibError CObjectManager::ReloadChangedFile(const VfsPath& path)
Status CObjectManager::ReloadChangedFile(const VfsPath& path)
{
// Mark old entries as outdated so we don't reload them from the cache
for (std::map<ObjectKey, CObjectEntry*>::iterator it = m_Objects.begin(); it != m_Objects.end(); ++it)

View file

@ -83,7 +83,7 @@ public:
* Reload any scripts that were loaded from the given filename.
* (This is used to implement hotloading.)
*/
LibError ReloadChangedFile(const VfsPath& path);
Status ReloadChangedFile(const VfsPath& path);
private:
CMeshManager& m_MeshManager;

View file

@ -23,7 +23,7 @@
#include "ps/Profile.h"
#include "renderer/Scene.h"
static LibError ReloadChangedFileCB(void* param, const VfsPath& path)
static Status ReloadChangedFileCB(void* param, const VfsPath& path)
{
return static_cast<CParticleManager*>(param)->ReloadChangedFile(path);
}
@ -88,7 +88,7 @@ void CParticleManager::RenderSubmit(SceneCollector& collector, const CFrustum& U
collector.Submit(it->get());
}
LibError CParticleManager::ReloadChangedFile(const VfsPath& path)
Status CParticleManager::ReloadChangedFile(const VfsPath& path)
{
m_EmitterTypes.erase(path);
return INFO::OK;

View file

@ -46,7 +46,7 @@ public:
float GetCurrentTime() const { return m_CurrentTime; }
LibError ReloadChangedFile(const VfsPath& path);
Status ReloadChangedFile(const VfsPath& path);
/// Random number generator shared between all particle emitters.
boost::mt19937 m_RNG;

View file

@ -187,12 +187,12 @@ bool CShaderManager::NewProgram(const char* name, const std::map<CStr, CStr>& ba
return PSRETURN_OK;
}
/*static*/ LibError CShaderManager::ReloadChangedFileCB(void* param, const VfsPath& path)
/*static*/ Status CShaderManager::ReloadChangedFileCB(void* param, const VfsPath& path)
{
return static_cast<CShaderManager*>(param)->ReloadChangedFile(path);
}
LibError CShaderManager::ReloadChangedFile(const VfsPath& path)
Status CShaderManager::ReloadChangedFile(const VfsPath& path)
{
// Find all shaders using this file
HotloadFilesMap::iterator files = m_HotloadFiles.find(path);

View file

@ -49,8 +49,8 @@ public:
private:
bool NewProgram(const char* name, const std::map<CStr, CStr>& defines, CShaderProgramPtr& program);
static LibError ReloadChangedFileCB(void* param, const VfsPath& path);
LibError ReloadChangedFile(const VfsPath& path);
static Status ReloadChangedFileCB(void* param, const VfsPath& path);
Status ReloadChangedFile(const VfsPath& path);
struct CacheKey
{

View file

@ -251,7 +251,7 @@ public:
PrepareCacheKey(texture, hash, version);
VfsPath loadPath;
LibError ret = m_CacheLoader.TryLoadingCached(texture->m_Properties.m_Path, hash, version, loadPath);
Status ret = m_CacheLoader.TryLoadingCached(texture->m_Properties.m_Path, hash, version, loadPath);
if (ret == INFO::OK)
{
@ -443,12 +443,12 @@ public:
}
}
static LibError ReloadChangedFileCB(void* param, const VfsPath& path)
static Status ReloadChangedFileCB(void* param, const VfsPath& path)
{
return static_cast<CTextureManagerImpl*>(param)->ReloadChangedFile(path);
}
LibError ReloadChangedFile(const VfsPath& path)
Status ReloadChangedFile(const VfsPath& path)
{
// Uncache settings file, if this is one
m_SettingsFiles.erase(path);

View file

@ -163,7 +163,7 @@ void CGUIManager::LoadPage(SGUIPage& page)
m_CurrentGUI = oldGUI;
}
LibError CGUIManager::ReloadChangedFiles(const VfsPath& path)
Status CGUIManager::ReloadChangedFiles(const VfsPath& path)
{
for (PageStackType::iterator it = m_PageStack.begin(); it != m_PageStack.end(); ++it)
{

View file

@ -82,7 +82,7 @@ public:
/**
* Call when a file has bee modified, to hotload pages if their .xml files changed.
*/
LibError ReloadChangedFiles(const VfsPath& path);
Status ReloadChangedFiles(const VfsPath& path);
/**
* Pass input events to the currently active GUI page.

View file

@ -24,11 +24,11 @@ inline size_t Align(size_t n)
static const size_t vectorSize = 16;
#define VERIFY_VECTOR_MULTIPLE(size)\
VERIFY(IsAligned(size, vectorSize))
#define ASSERT_VECTOR_MULTIPLE(size)\
ASSERT(IsAligned(size, vectorSize))
#define VERIFY_VECTOR_ALIGNED(pointer)\
VERIFY_VECTOR_MULTIPLE(pointer);\
#define ASSERT_VECTOR_ALIGNED(pointer)\
ASSERT_VECTOR_MULTIPLE(pointer);\
ASSUME_ALIGNED(pointer, vectorSize)

View file

@ -35,7 +35,7 @@
const size_t bucketSize = 4000;
LibError bucket_create(Bucket* b, size_t el_size)
Status bucket_create(Bucket* b, size_t el_size)
{
b->freelist = mem_freelist_Sentinel();
b->el_size = Align<allocationAlignment>(el_size);

View file

@ -73,9 +73,9 @@ struct Bucket
* @param el_size 0 to allow variable-sized allocations (which cannot be
* freed individually); otherwise, it specifies the number of bytes that
* will be returned by bucket_alloc (whose size parameter is then ignored).
* @return LibError.
* @return Status.
**/
LIB_API LibError bucket_create(Bucket* b, size_t el_size);
LIB_API Status bucket_create(Bucket* b, size_t el_size);
/**
* free all memory that ensued from \<b\>.

View file

@ -36,7 +36,7 @@
// stored in da->prot to reduce size; doesn't conflict with any PROT_* flags.
const int DA_NOT_OUR_MEM = 0x40000000;
static LibError validate_da(DynArray* da)
static Status validate_da(DynArray* da)
{
if(!da)
WARN_RETURN(ERR::INVALID_PARAM);
@ -63,16 +63,16 @@ static LibError validate_da(DynArray* da)
return INFO::OK;
}
#define CHECK_DA(da) RETURN_ERR(validate_da(da))
#define CHECK_DA(da) RETURN_STATUS_IF_ERR(validate_da(da))
LibError da_alloc(DynArray* da, size_t max_size)
Status da_alloc(DynArray* da, size_t max_size)
{
const size_t max_size_pa = Align<pageSize>(max_size);
u8* p = 0;
if(max_size_pa) // (avoid mmap failure)
RETURN_ERR(mem_Reserve(max_size_pa, &p));
RETURN_STATUS_IF_ERR(mem_Reserve(max_size_pa, &p));
da->base = p;
da->max_size_pa = max_size_pa;
@ -85,7 +85,7 @@ LibError da_alloc(DynArray* da, size_t max_size)
}
LibError da_free(DynArray* da)
Status da_free(DynArray* da)
{
CHECK_DA(da);
@ -101,12 +101,12 @@ LibError da_free(DynArray* da)
// (i.e. it doesn't actually own any memory). don't complain;
// da_free is supposed to be called even in the above case.
if(!was_wrapped && size_pa)
RETURN_ERR(mem_Release(p, size_pa));
RETURN_STATUS_IF_ERR(mem_Release(p, size_pa));
return INFO::OK;
}
LibError da_set_size(DynArray* da, size_t new_size)
Status da_set_size(DynArray* da, size_t new_size)
{
CHECK_DA(da);
@ -127,10 +127,10 @@ LibError da_set_size(DynArray* da, size_t new_size)
u8* end = da->base + cur_size_pa;
// expanding
if(size_delta_pa > 0)
RETURN_ERR(mem_Commit(end, size_delta_pa, da->prot));
RETURN_STATUS_IF_ERR(mem_Commit(end, size_delta_pa, da->prot));
// shrinking
else if(size_delta_pa < 0)
RETURN_ERR(mem_Decommit(end+size_delta_pa, -size_delta_pa));
RETURN_STATUS_IF_ERR(mem_Decommit(end+size_delta_pa, -size_delta_pa));
// else: no change in page count, e.g. if going from size=1 to 2
// (we don't want mem_* to have to handle size=0)
@ -141,16 +141,16 @@ LibError da_set_size(DynArray* da, size_t new_size)
}
LibError da_reserve(DynArray* da, size_t size)
Status da_reserve(DynArray* da, size_t size)
{
if(da->pos+size > da->cur_size_pa)
RETURN_ERR(da_set_size(da, da->cur_size_pa+size));
RETURN_STATUS_IF_ERR(da_set_size(da, da->cur_size_pa+size));
da->cur_size = std::max(da->cur_size, da->pos+size);
return INFO::OK;
}
LibError da_set_prot(DynArray* da, int prot)
Status da_set_prot(DynArray* da, int prot)
{
CHECK_DA(da);
@ -160,14 +160,14 @@ LibError da_set_prot(DynArray* da, int prot)
WARN_RETURN(ERR::LOGIC);
da->prot = prot;
RETURN_ERR(mem_Protect(da->base, da->cur_size_pa, prot));
RETURN_STATUS_IF_ERR(mem_Protect(da->base, da->cur_size_pa, prot));
CHECK_DA(da);
return INFO::OK;
}
LibError da_wrap_fixed(DynArray* da, u8* p, size_t size)
Status da_wrap_fixed(DynArray* da, u8* p, size_t size)
{
da->base = p;
da->max_size_pa = Align<pageSize>(size);
@ -180,7 +180,7 @@ LibError da_wrap_fixed(DynArray* da, u8* p, size_t size)
}
LibError da_read(DynArray* da, void* data, size_t size)
Status da_read(DynArray* da, void* data, size_t size)
{
// make sure we have enough data to read
if(da->pos+size > da->cur_size)
@ -192,9 +192,9 @@ LibError da_read(DynArray* da, void* data, size_t size)
}
LibError da_append(DynArray* da, const void* data, size_t size)
Status da_append(DynArray* da, const void* data, size_t size)
{
RETURN_ERR(da_reserve(da, size));
RETURN_STATUS_IF_ERR(da_reserve(da, size));
memcpy(da->base+da->pos, data, size);
da->pos += size;
return INFO::OK;

View file

@ -61,9 +61,9 @@ struct DynArray
* @param max_size size [bytes] of address space to reserve (*);
* the DynArray can never expand beyond this.
* (* rounded up to next page size multiple)
* @return LibError.
* @return Status.
**/
LIB_API LibError da_alloc(DynArray* da, size_t max_size);
LIB_API Status da_alloc(DynArray* da, size_t max_size);
/**
* free all memory (address space + physical) that constitutes the
@ -72,9 +72,9 @@ LIB_API LibError da_alloc(DynArray* da, size_t max_size);
* use-after-free is impossible because the memory is unmapped.
*
* @param da DynArray* zeroed afterwards.
* @return LibError
* @return Status
**/
LIB_API LibError da_free(DynArray* da);
LIB_API Status da_free(DynArray* da);
/**
* expand or shrink the array: changes the amount of currently committed
@ -83,9 +83,9 @@ LIB_API LibError da_free(DynArray* da);
* @param da DynArray.
* @param new_size target size (rounded up to next page multiple).
* pages are added/removed until this is met.
* @return LibError.
* @return Status.
**/
LIB_API LibError da_set_size(DynArray* da, size_t new_size);
LIB_API Status da_set_size(DynArray* da, size_t new_size);
/**
* Make sure at least \<size\> bytes starting at da->pos are committed and
@ -93,9 +93,9 @@ LIB_API LibError da_set_size(DynArray* da, size_t new_size);
*
* @param da DynArray*
* @param size Minimum amount to guarantee [bytes]
* @return LibError
* @return Status
**/
LIB_API LibError da_reserve(DynArray* da, size_t size);
LIB_API Status da_reserve(DynArray* da, size_t size);
/**
* change access rights of the array memory.
@ -105,9 +105,9 @@ LIB_API LibError da_reserve(DynArray* da, size_t size);
*
* @param da DynArray.
* @param prot a combination of the PROT_* values used with mprotect.
* @return LibError.
* @return Status.
**/
LIB_API LibError da_set_prot(DynArray* da, int prot);
LIB_API Status da_set_prot(DynArray* da, int prot);
/**
* "wrap" (i.e. store information about) the given buffer in a DynArray.
@ -120,9 +120,9 @@ LIB_API LibError da_set_prot(DynArray* da, int prot);
* change the underlying memory (e.g. da_set_size) will fail.
* @param p target memory (no alignment/padding requirements)
* @param size maximum size (no alignment requirements)
* @return LibError.
* @return Status.
**/
LIB_API LibError da_wrap_fixed(DynArray* da, u8* p, size_t size);
LIB_API Status da_wrap_fixed(DynArray* da, u8* p, size_t size);
/**
* "read" from array, i.e. copy into the given buffer.
@ -132,9 +132,9 @@ LIB_API LibError da_wrap_fixed(DynArray* da, u8* p, size_t size);
* @param da DynArray.
* @param data_dst destination memory
* @param size [bytes] to copy
* @return LibError.
* @return Status.
**/
LIB_API LibError da_read(DynArray* da, void* data_dst, size_t size);
LIB_API Status da_read(DynArray* da, void* data_dst, size_t size);
/**
* "write" to array, i.e. copy from the given buffer.
@ -144,8 +144,8 @@ LIB_API LibError da_read(DynArray* da, void* data_dst, size_t size);
* @param da DynArray.
* @param data_src source memory
* @param size [bytes] to copy
* @return LibError.
* @return Status.
**/
LIB_API LibError da_append(DynArray* da, const void* data_src, size_t size);
LIB_API Status da_append(DynArray* da, const void* data_src, size_t size);
#endif // #ifndef INCLUDED_ALLOCATORS_DYNARRAY

View file

@ -29,11 +29,11 @@
//-----------------------------------------------------------------------------
static inline LibError LibError_from_mmap(void* ret, bool warn_if_failed = true)
static inline Status StatusFromMap(void* ret)
{
if(ret != MAP_FAILED)
return INFO::OK;
return LibError_from_errno(warn_if_failed);
WARN_RETURN(StatusFromErrno());
}
// "anonymous" effectively means mapping /dev/zero, but is more efficient.
@ -46,22 +46,23 @@ static inline LibError LibError_from_mmap(void* ret, bool warn_if_failed = true)
static const int mmap_flags = MAP_PRIVATE|MAP_ANONYMOUS;
LibError mem_Reserve(size_t size, u8** pp)
Status mem_Reserve(size_t size, u8** pp)
{
errno = 0;
void* ret = mmap(0, size, PROT_NONE, mmap_flags|MAP_NORESERVE, -1, 0);
*pp = (u8*)ret;
return LibError_from_mmap(ret);
return StatusFromMap(ret);
}
LibError mem_Release(u8* p, size_t size)
Status mem_Release(u8* p, size_t size)
{
errno = 0;
int ret = munmap(p, size);
return LibError_from_posix(ret);
if(munmap(p, size) != 0)
WARN_RETURN(StatusFromErrno());
return 0;
}
LibError mem_Commit(u8* p, size_t size, int prot)
Status mem_Commit(u8* p, size_t size, int prot)
{
// avoid misinterpretation by mmap.
if(prot == PROT_NONE)
@ -69,21 +70,23 @@ LibError mem_Commit(u8* p, size_t size, int prot)
errno = 0;
void* ret = mmap(p, size, prot, mmap_flags|MAP_FIXED, -1, 0);
return LibError_from_mmap(ret);
return StatusFromMap(ret);
}
LibError mem_Decommit(u8* p, size_t size)
Status mem_Decommit(u8* p, size_t size)
{
errno = 0;
void* ret = mmap(p, size, PROT_NONE, mmap_flags|MAP_NORESERVE|MAP_FIXED, -1, 0);
return LibError_from_mmap(ret);
return StatusFromMap(ret);
}
LibError mem_Protect(u8* p, size_t size, int prot)
Status mem_Protect(u8* p, size_t size, int prot)
{
errno = 0;
int ret = mprotect(p, size, prot);
return LibError_from_posix(ret);
if(mprotect(p, size, prot) != 0)
WARN_RETURN(StatusFromErrno());
return 0;
}
@ -93,8 +96,8 @@ void* page_aligned_alloc(size_t size)
{
const size_t alignedSize = Align<pageSize>(size);
u8* p = 0;
RETURN0_IF_ERR(mem_Reserve(alignedSize, &p));
RETURN0_IF_ERR(mem_Commit(p, alignedSize, PROT_READ|PROT_WRITE));
RETURN_0_IF_ERR(mem_Reserve(alignedSize, &p));
RETURN_0_IF_ERR(mem_Commit(p, alignedSize, PROT_READ|PROT_WRITE));
return p;
}

View file

@ -27,11 +27,11 @@
// very thin wrapper on top of sys/mman.h that makes the intent more obvious
// (its commit/decommit semantics are difficult to tell apart)
LIB_API LibError mem_Reserve(size_t size, u8** pp);
LIB_API LibError mem_Release(u8* p, size_t size);
LIB_API LibError mem_Commit(u8* p, size_t size, int prot);
LIB_API LibError mem_Decommit(u8* p, size_t size);
LIB_API LibError mem_Protect(u8* p, size_t size, int prot);
LIB_API Status mem_Reserve(size_t size, u8** pp);
LIB_API Status mem_Release(u8* p, size_t size);
LIB_API Status mem_Commit(u8* p, size_t size, int prot);
LIB_API Status mem_Decommit(u8* p, size_t size);
LIB_API Status mem_Protect(u8* p, size_t size, int prot);
/**

View file

@ -35,19 +35,19 @@
TIMER_ADD_CLIENT(tc_pool_alloc);
LibError pool_create(Pool* p, size_t max_size, size_t el_size)
Status pool_create(Pool* p, size_t max_size, size_t el_size)
{
if(el_size == POOL_VARIABLE_ALLOCS)
p->el_size = 0;
else
p->el_size = Align<allocationAlignment>(el_size);
p->freelist = mem_freelist_Sentinel();
RETURN_ERR(da_alloc(&p->da, max_size));
RETURN_STATUS_IF_ERR(da_alloc(&p->da, max_size));
return INFO::OK;
}
LibError pool_destroy(Pool* p)
Status pool_destroy(Pool* p)
{
// don't be picky and complain if the freelist isn't empty;
// we don't care since it's all part of the da anyway.

View file

@ -71,9 +71,9 @@ const size_t POOL_VARIABLE_ALLOCS = ~(size_t)0u;
* @param el_size Number of bytes that will be returned by each
* pool_alloc (whose size parameter is then ignored). Can be 0 to
* allow variable-sized allocations, but pool_free is then unusable.
* @return LibError
* @return Status
**/
LIB_API LibError pool_create(Pool* p, size_t max_size, size_t el_size);
LIB_API Status pool_create(Pool* p, size_t max_size, size_t el_size);
/**
* free all memory (address space + physical) that constitutes the
@ -85,9 +85,9 @@ LIB_API LibError pool_create(Pool* p, size_t max_size, size_t el_size);
* (* no matter if in freelist or unused or "allocated" to user)
*
* @param p Pool*
* @return LibError.
* @return Status.
**/
LIB_API LibError pool_destroy(Pool* p);
LIB_API Status pool_destroy(Pool* p);
/**
* indicate whether a pointer was allocated from the given pool.

View file

@ -63,7 +63,7 @@ struct AlignedDeleter
};
template<class T>
static inline LibError AllocateAligned(shared_ptr<T>& p, size_t size, size_t alignment = cacheLineSize)
static inline Status AllocateAligned(shared_ptr<T>& p, size_t size, size_t alignment = cacheLineSize)
{
void* mem = rtl_AllocateAligned(size, alignment);
if(!mem)

View file

@ -96,9 +96,9 @@
// compiler supports ASSUME_UNREACHABLE => allow it to assume the code is
// never reached (improves optimization at the cost of undefined behavior
// if the annotation turns out to be incorrect).
#if HAVE_ASSUME_UNREACHABLE && !CONFIG_PARANOIA
#if HAVE_ASSUME_UNREACHABLE && !CONFIG_ENABLE_CHECKS
# define UNREACHABLE ASSUME_UNREACHABLE
// otherwise (or if CONFIG_PARANOIA is set), add a user-visible
// otherwise (or if CONFIG_ENABLE_CHECKS is set), add a user-visible
// warning if the code is reached. note that abort() fails to stop
// ICC from warning about the lack of a return statement, so we
// use an infinite loop instead.

View file

@ -56,14 +56,9 @@
# define CONFIG_DISABLE_EXCEPTIONS 0
#endif
// enable additional debug checks (very slow).
#ifndef CONFIG_PARANOIA
# define CONFIG_PARANOIA 0
#endif
// final release; disables some safety checks.
#ifndef CONFIG_FINAL
# define CONFIG_FINAL 0
// enable additional debug checks (potentially rather slow).
#ifndef CONFIG_ENABLE_CHECKS
# define CONFIG_ENABLE_CHECKS 0
#endif
// static type checking with Dehydra

View file

@ -43,16 +43,16 @@
#endif
ERROR_ASSOCIATE(ERR::SYM_NO_STACK_FRAMES_FOUND, L"No stack frames found", -1);
ERROR_ASSOCIATE(ERR::SYM_UNRETRIEVABLE_STATIC, L"Value unretrievable (stored in external module)", -1);
ERROR_ASSOCIATE(ERR::SYM_UNRETRIEVABLE, L"Value unretrievable", -1);
ERROR_ASSOCIATE(ERR::SYM_TYPE_INFO_UNAVAILABLE, L"Error getting type_info", -1);
ERROR_ASSOCIATE(ERR::SYM_INTERNAL_ERROR, L"Exception raised while processing a symbol", -1);
ERROR_ASSOCIATE(ERR::SYM_UNSUPPORTED, L"Symbol type not (fully) supported", -1);
ERROR_ASSOCIATE(ERR::SYM_CHILD_NOT_FOUND, L"Symbol does not have the given child", -1);
ERROR_ASSOCIATE(ERR::SYM_NESTING_LIMIT, L"Symbol nesting too deep or infinite recursion", -1);
ERROR_ASSOCIATE(ERR::SYM_SINGLE_SYMBOL_LIMIT, L"Symbol has produced too much output", -1);
ERROR_ASSOCIATE(INFO::SYM_SUPPRESS_OUTPUT, L"Symbol was suppressed", -1);
STATUS_DEFINE(ERR, SYM_NO_STACK_FRAMES_FOUND, L"No stack frames found", -1);
STATUS_DEFINE(ERR, SYM_UNRETRIEVABLE_STATIC, L"Value unretrievable (stored in external module)", -1);
STATUS_DEFINE(ERR, SYM_UNRETRIEVABLE, L"Value unretrievable", -1);
STATUS_DEFINE(ERR, SYM_TYPE_INFO_UNAVAILABLE, L"Error getting type_info", -1);
STATUS_DEFINE(ERR, SYM_INTERNAL_ERROR, L"Exception raised while processing a symbol", -1);
STATUS_DEFINE(ERR, SYM_UNSUPPORTED, L"Symbol type not (fully) supported", -1);
STATUS_DEFINE(ERR, SYM_CHILD_NOT_FOUND, L"Symbol does not have the given child", -1);
STATUS_DEFINE(ERR, SYM_NESTING_LIMIT, L"Symbol nesting too deep or infinite recursion", -1);
STATUS_DEFINE(ERR, SYM_SINGLE_SYMBOL_LIMIT, L"Symbol has produced too much output", -1);
STATUS_DEFINE(INFO, SYM_SUPPRESS_OUTPUT, L"Symbol was suppressed", -1);
// need to shoehorn printf-style variable params into
@ -154,7 +154,7 @@ void debug_printf(const wchar_t* fmt, ...)
//-----------------------------------------------------------------------------
LibError debug_WriteCrashlog(const wchar_t* text)
Status debug_WriteCrashlog(const wchar_t* text)
{
// (avoid infinite recursion and/or reentering this function if it
// fails/reports an error)
@ -284,7 +284,7 @@ fail:
}
// append stack trace
LibError ret = debug_DumpStack(writer.Position(), writer.CharsLeft(), context, lastFuncToSkip);
Status ret = debug_DumpStack(writer.Position(), writer.CharsLeft(), context, lastFuncToSkip);
if(ret == ERR::REENTERED)
{
if(!writer(
@ -299,7 +299,7 @@ fail:
wchar_t description_buf[100] = {'?'};
if(!writer(
L"(error while dumping stack: %ls)",
error_description_r(ret, description_buf, ARRAY_SIZE(description_buf))
StatusDescription(ret, description_buf, ARRAY_SIZE(description_buf))
))
goto fail;
}
@ -311,11 +311,11 @@ fail:
// append OS error (just in case it happens to be relevant -
// it's usually still set from unrelated operations)
wchar_t description_buf[100] = L"?";
LibError errno_equiv = LibError_from_errno(false);
Status errno_equiv = StatusFromErrno(); // NOWARN
if(errno_equiv != ERR::FAIL) // meaningful translation
error_description_r(errno_equiv, description_buf, ARRAY_SIZE(description_buf));
StatusDescription(errno_equiv, description_buf, ARRAY_SIZE(description_buf));
wchar_t os_error[100] = L"?";
sys_error_description_r(0, os_error, ARRAY_SIZE(os_error));
sys_StatusDescription(0, os_error, ARRAY_SIZE(os_error));
if(!writer(
L"\r\n"
L"errno = %d (%ls)\r\n"
@ -480,10 +480,10 @@ enum SkipStatus
INVALID, VALID, BUSY
};
static intptr_t skipStatus = INVALID;
static LibError errorToSkip;
static Status errorToSkip;
static size_t numSkipped;
void debug_SkipErrors(LibError err)
void debug_SkipErrors(Status err)
{
if(cpu_CAS(&skipStatus, INVALID, BUSY))
{
@ -512,7 +512,7 @@ size_t debug_StopSkippingErrors()
}
}
static bool ShouldSkipError(LibError err)
static bool ShouldSkipError(Status err)
{
if(cpu_CAS(&skipStatus, VALID, BUSY))
{
@ -526,7 +526,7 @@ static bool ShouldSkipError(LibError err)
}
ErrorReaction debug_OnError(LibError err, atomic_bool* suppress, const wchar_t* file, int line, const char* func)
ErrorReaction debug_OnError(Status err, atomic_bool* suppress, const wchar_t* file, int line, const char* func)
{
if(ShouldSkipError(err))
return ER_CONTINUE;
@ -534,8 +534,8 @@ ErrorReaction debug_OnError(LibError err, atomic_bool* suppress, const wchar_t*
void* context = 0;
const wchar_t* lastFuncToSkip = L"debug_OnError";
wchar_t buf[400];
wchar_t err_buf[200]; error_description_r(err, err_buf, ARRAY_SIZE(err_buf));
swprintf_s(buf, ARRAY_SIZE(buf), L"Function call failed: return value was %ld (%ls)", err, err_buf);
wchar_t err_buf[200]; StatusDescription(err, err_buf, ARRAY_SIZE(err_buf));
swprintf_s(buf, ARRAY_SIZE(buf), L"Function call failed: return value was %lld (%ls)", err, err_buf);
return debug_DisplayError(buf, DE_MANUAL_BREAK, context, lastFuncToSkip, file,line,func, suppress);
}

View file

@ -36,7 +36,9 @@
// - the output routines make for platform-independent logging and
// crashlogs with "last-known activity" reporting.
#include "lib/lib_errors.h"
#include "lib/lib_api.h"
#include "lib/types.h" // intptr_t
#include "lib/status.h"
#include "lib/code_annotation.h"
#include "lib/code_generation.h"
@ -253,10 +255,10 @@ LIB_API bool debug_filter_allows(const wchar_t* text);
* @param text description of the error (including stack trace);
* typically generated by debug_BuildErrorMessage.
*
* @return LibError; ERR::REENTERED if reentered via recursion or
* @return Status; ERR::REENTERED if reentered via recursion or
* multithreading (not allowed since an infinite loop may result).
**/
LIB_API LibError debug_WriteCrashlog(const wchar_t* text);
LIB_API Status debug_WriteCrashlog(const wchar_t* text);
//-----------------------------------------------------------------------------
@ -318,14 +320,14 @@ LIB_API LibError debug_WriteCrashlog(const wchar_t* text);
/**
* display the error dialog with text corresponding to the given error code.
* used by CHECK_ERR et al., which wrap function calls and automatically
* used by WARN_RETURN_STATUS_IF_ERR et al., which wrap function calls and automatically
* raise warnings and return to the caller.
**/
#define DEBUG_WARN_ERR(err)\
#define DEBUG_WARN_ERR(status)\
do\
{\
static atomic_bool suppress__;\
switch(debug_OnError(err, &suppress__, WIDEN(__FILE__), __LINE__, __func__))\
switch(debug_OnError(status, &suppress__, WIDEN(__FILE__), __LINE__, __func__))\
{\
case ER_CONTINUE:\
break;\
@ -354,30 +356,30 @@ LIB_API ErrorReaction debug_OnAssertionFailure(const wchar_t* assert_expr, atomi
* called when a DEBUG_WARN_ERR indicates an error occurred;
* notifies the user via debug_DisplayError.
*
* @param err LibError value indicating the error that occurred
* @param err Status value indicating the error that occurred
* @param suppress see debug_DisplayError.
* @param file, line source file name and line number of the spot that failed
* @param func name of the function containing it
* @return ErrorReaction (user's choice: continue running or stop?)
**/
LIB_API ErrorReaction debug_OnError(LibError err, atomic_bool* suppress, const wchar_t* file, int line, const char* func);
LIB_API ErrorReaction debug_OnError(Status err, atomic_bool* suppress, const wchar_t* file, int line, const char* func);
/**
* suppress (prevent from showing) the error dialog from subsequent
* debug_OnError for the given LibError.
* debug_OnError for the given Status.
*
* rationale: for edge cases in some functions, warnings are raised in
* addition to returning an error code. self-tests deliberately trigger
* these cases and check for the latter but shouldn't cause the former.
* we therefore need to squelch them.
*
* @param err the LibError to skip.
* @param err the Status to skip.
*
* note: only one concurrent skip request is allowed; call
* debug_StopSkippingErrors before the next debug_SkipErrors.
*/
LIB_API void debug_SkipErrors(LibError err);
LIB_API void debug_SkipErrors(Status err);
/**
* @return how many errors were skipped since the call to debug_SkipErrors()
@ -391,18 +393,18 @@ LIB_API size_t debug_StopSkippingErrors();
namespace ERR
{
const LibError SYM_NO_STACK_FRAMES_FOUND = -100400;
const LibError SYM_UNRETRIEVABLE_STATIC = -100401;
const LibError SYM_UNRETRIEVABLE = -100402;
const LibError SYM_TYPE_INFO_UNAVAILABLE = -100403;
const LibError SYM_INTERNAL_ERROR = -100404;
const LibError SYM_UNSUPPORTED = -100405;
const LibError SYM_CHILD_NOT_FOUND = -100406;
const Status SYM_NO_STACK_FRAMES_FOUND = -100400;
const Status SYM_UNRETRIEVABLE_STATIC = -100401;
const Status SYM_UNRETRIEVABLE = -100402;
const Status SYM_TYPE_INFO_UNAVAILABLE = -100403;
const Status SYM_INTERNAL_ERROR = -100404;
const Status SYM_UNSUPPORTED = -100405;
const Status SYM_CHILD_NOT_FOUND = -100406;
// this limit is to prevent infinite recursion.
const LibError SYM_NESTING_LIMIT = -100407;
const Status SYM_NESTING_LIMIT = -100407;
// this limit is to prevent large symbols (e.g. arrays or linked lists)
// from taking up all available output space.
const LibError SYM_SINGLE_SYMBOL_LIMIT = -100408;
const Status SYM_SINGLE_SYMBOL_LIMIT = -100408;
}
namespace INFO
@ -410,7 +412,7 @@ namespace INFO
// one of the dump_sym* functions decided not to output anything at
// all (e.g. for member functions in UDTs - we don't want those).
// therefore, skip any post-symbol formatting (e.g. ) as well.
const LibError SYM_SUPPRESS_OUTPUT = +100409;
const Status SYM_SUPPRESS_OUTPUT = +100409;
}
@ -436,10 +438,10 @@ const size_t DBG_FILE_LEN = 100;
*
* note: all of the output parameters are optional; we pass back as much
* information as is available and desired.
* @return LibError; INFO::OK iff any information was successfully
* @return Status; INFO::OK iff any information was successfully
* retrieved and stored.
**/
LIB_API LibError debug_ResolveSymbol(void* ptr_of_interest, wchar_t* sym_name, wchar_t* file, int* line);
LIB_API Status debug_ResolveSymbol(void* ptr_of_interest, wchar_t* sym_name, wchar_t* file, int* line);
/**
* write a complete stack trace (including values of local variables) into
@ -456,10 +458,10 @@ LIB_API LibError debug_ResolveSymbol(void* ptr_of_interest, wchar_t* sym_name, w
* matching of stdcall-decorated names).
* Rationale: this is safer than specifying a fixed number of frames,
* which can be incorrect due to inlining.
* @return LibError; ERR::REENTERED if reentered via recursion or
* @return Status; ERR::REENTERED if reentered via recursion or
* multithreading (not allowed since static data is used).
**/
LIB_API LibError debug_DumpStack(wchar_t* buf, size_t maxChars, void* context, const wchar_t* lastFuncToSkip);
LIB_API Status debug_DumpStack(wchar_t* buf, size_t maxChars, void* context, const wchar_t* lastFuncToSkip);
//-----------------------------------------------------------------------------

View file

@ -36,8 +36,8 @@
#include "lib/regex.h"
ERROR_ASSOCIATE(ERR::STL_CNT_UNKNOWN, L"Unknown STL container type_name", -1);
ERROR_ASSOCIATE(ERR::STL_CNT_INVALID, L"Container type is known but contents are invalid", -1);
STATUS_DEFINE(ERR, STL_CNT_UNKNOWN, L"Unknown STL container type_name", -1);
STATUS_DEFINE(ERR, STL_CNT_INVALID, L"Container type is known but contents are invalid", -1);
// used in debug_stl_simplify_name.
@ -541,7 +541,7 @@ template<class T> bool get_container_info(const T& t, size_t size, size_t el_siz
// return number of elements and an iterator (any data it needs is stored in
// it_mem, which must hold DEBUG_STL_MAX_ITERATOR_SIZE bytes).
// returns 0 on success or an StlContainerError.
LibError debug_stl_get_container_info(const wchar_t* type_name, const u8* p, size_t size,
Status debug_stl_get_container_info(const wchar_t* type_name, const u8* p, size_t size,
size_t el_size, size_t* el_count, DebugStlIterator* el_iterator, void* it_mem)
{
#if MSC_VERSION >= 1400

View file

@ -30,9 +30,9 @@
namespace ERR
{
const LibError STL_CNT_UNKNOWN = -100500;
const Status STL_CNT_UNKNOWN = -100500;
// likely causes: not yet initialized or memory corruption.
const LibError STL_CNT_INVALID = -100501;
const Status STL_CNT_INVALID = -100501;
}
@ -77,9 +77,9 @@ const size_t DEBUG_STL_MAX_ITERATOR_SIZE = 64;
* @param el_iterator out; callback function that acts as an iterator
* @param it_mem out; buffer holding the iterator state. must be
* at least DEBUG_STL_MAX_ITERATOR_SIZE bytes.
* @return LibError (ERR::STL_*)
* @return Status (ERR::STL_*)
**/
extern LibError debug_stl_get_container_info(const wchar_t* type_name, const u8* p, size_t size,
extern Status debug_stl_get_container_info(const wchar_t* type_name, const u8* p, size_t size,
size_t el_size, size_t* el_count, DebugStlIterator* el_iterator, void* it_mem);
#endif // #ifndef INCLUDED_DEBUG_STL

View file

@ -0,0 +1,41 @@
#ifndef INCLUDED_EXTERNAL_LIBRARIES_OPENMP
#define INCLUDED_EXTERNAL_LIBRARIES_OPENMP
// allows removing all OpenMP-related code via #define ENABLE_OPENMP 0
// before including this header. (useful during debugging, because the
// VC debugger isn't able to display OpenMP private variables)
#ifdef ENABLE_OPENMP
# if ENABLE_OPENMP && !defined(_OPENMP)
# error "either enable OpenMP in the compiler settings or don't set ENABLE_OPENMP to 1"
# endif
#else // no user preference; default to compiler setting
# ifdef _OPENMP
# define ENABLE_OPENMP 1
# else
# define ENABLE_OPENMP 0
# endif
#endif
#if ENABLE_OPENMP
# include <omp.h>
#else
# define omp_get_num_threads() 1
# define omp_get_thread_num() 0
# define omp_in_parallel() 0
#endif
// wrapper macro that evaluates to nothing if !ENABLE_OPENMP
// (much more convenient than individual #if ENABLE_OPENMP)
#if ENABLE_OPENMP
# if MSC_VERSION
# define OMP(args) __pragma(omp args)
# elif GCC_VERSION
# define OMP _Pragma("omp " #args)
# else
# error "port"
# endif
#else
# define OMP(args)
#endif
#endif // #ifndef INCLUDED_EXTERNAL_LIBRARIES_OPENMP

View file

@ -27,8 +27,8 @@
#include "precompiled.h"
#include "lib/file/archive/archive.h"
ERROR_ASSOCIATE(ERR::ARCHIVE_UNKNOWN_FORMAT, L"Unknown archive format", -1);
ERROR_ASSOCIATE(ERR::ARCHIVE_UNKNOWN_METHOD, L"Unknown compression method", -1);
STATUS_DEFINE(ERR, ARCHIVE_UNKNOWN_FORMAT, L"Unknown archive format", -1);
STATUS_DEFINE(ERR, ARCHIVE_UNKNOWN_METHOD, L"Unknown compression method", -1);
IArchiveReader::~IArchiveReader()
{

View file

@ -37,8 +37,8 @@
namespace ERR
{
const LibError ARCHIVE_UNKNOWN_FORMAT = -110400;
const LibError ARCHIVE_UNKNOWN_METHOD = -110401;
const Status ARCHIVE_UNKNOWN_FORMAT = -110400;
const Status ARCHIVE_UNKNOWN_METHOD = -110401;
}
struct IArchiveFile : public IFileLoader
@ -56,7 +56,7 @@ struct IArchiveReader
* @param pathname full pathname of entry; only valid during the callback.
**/
typedef void (*ArchiveEntryCallback)(const VfsPath& pathname, const FileInfo& fileInfo, PIArchiveFile archiveFile, uintptr_t cbData);
virtual LibError ReadEntries(ArchiveEntryCallback cb, uintptr_t cbData) = 0;
virtual Status ReadEntries(ArchiveEntryCallback cb, uintptr_t cbData) = 0;
};
typedef shared_ptr<IArchiveReader> PIArchiveReader;
@ -91,7 +91,7 @@ struct IArchiveWriter
* @param pathname the actual file to add
* @param pathnameInArchive the name to store in the archive
**/
virtual LibError AddFile(const OsPath& pathname, const Path& pathameInArchive) = 0;
virtual Status AddFile(const OsPath& pathname, const Path& pathameInArchive) = 0;
};
typedef shared_ptr<IArchiveWriter> PIArchiveWriter;

View file

@ -175,7 +175,7 @@ public:
// note: use this instead of resize because FileNode doesn't have
// a default ctor. NB: this is how resize is implemented anyway.
file_nodes.erase(file_nodes.begin() + MAX_IDS, file_nodes.end());
WARN_ERR(ERR::LIMIT);
WARN_IF_ERR(ERR::LIMIT);
}
}
};
@ -306,10 +306,10 @@ class ConnectionBuilder
}
public:
LibError run(const char* trace_filename, Connections& connections)
Status run(const char* trace_filename, Connections& connections)
{
Trace t;
RETURN_ERR(trace_read_from_file(trace_filename, &t));
RETURN_STATUS_IF_ERR(trace_read_from_file(trace_filename, &t));
// reserve memory for worst-case amount of connections (happens if
// all accesses are unique). this is necessary because we store
@ -560,7 +560,7 @@ public:
}
};
static LibError vfs_opt_init(const char* trace_filename, const char* archive_fn_fmt, bool force_build)
static Status vfs_opt_init(const char* trace_filename, const char* archive_fn_fmt, bool force_build)
{
Filesystem_Posix fsPosix;
@ -575,7 +575,7 @@ static LibError vfs_opt_init(const char* trace_filename, const char* archive_fn_
{
char dir[PATH_MAX];
path_dir_only(archive_fn_fmt, dir);
RETURN_ERR(dir_GatherSortedEntries(&fsPosix, dir, existing_archives));
RETURN_STATUS_IF_ERR(dir_GatherSortedEntries(&fsPosix, dir, existing_archives));
DirEntIt new_end = std::remove_if(existing_archives.begin(), existing_archives.end(), IsArchive(archive_fn));
existing_archives.erase(new_end, existing_archives.end());
}
@ -597,7 +597,7 @@ static LibError vfs_opt_init(const char* trace_filename, const char* archive_fn_
// are defined by trace entries.
Connections connections;
ConnectionBuilder cbuilder;
RETURN_ERR(cbuilder.run(trace_filename, connections));
RETURN_STATUS_IF_ERR(cbuilder.run(trace_filename, connections));
// create output filename list by first adding the above edges (most
// frequent first) and then adding the rest sequentially.
@ -605,7 +605,7 @@ static LibError vfs_opt_init(const char* trace_filename, const char* archive_fn_
fn_vector.push_back(0); // 0-terminate for use as Filenames
Filenames V_fns = &fn_vector[0];
RETURN_ERR(archive_build_init(archive_fn, V_fns, &ab));
RETURN_STATUS_IF_ERR(archive_build_init(archive_fn, V_fns, &ab));
return INFO::OK;
}
@ -660,7 +660,7 @@ static bool should_build_mini_archive(const char* UNUSED(mini_archive_fn_fmt))
return false;
}
static LibError build_mini_archive(const char* mini_archive_fn_fmt)
static Status build_mini_archive(const char* mini_archive_fn_fmt)
{
if(!should_build_mini_archive(mini_archive_fn_fmt))
return INFO::SKIPPED;
@ -676,7 +676,7 @@ static LibError build_mini_archive(const char* mini_archive_fn_fmt)
Filesystem_Posix fsPosix;
dir_NextNumberedFilename(&fsPosix, mini_archive_fn_fmt, &nfi, mini_archive_fn);
RETURN_ERR(archive_build(mini_archive_fn, V_fns));
RETURN_STATUS_IF_ERR(archive_build(mini_archive_fn, V_fns));
delete[] V_fns;
return INFO::OK;
#else
@ -712,7 +712,7 @@ struct ArchiveBuildState
// create an archive (overwriting previous file) and fill it with the given
// files. compression method is chosen based on extension.
LibError archive_build_init(const char* P_archive_filename, Filenames V_fns, ArchiveBuildState* ab)
Status archive_build_init(const char* P_archive_filename, Filenames V_fns, ArchiveBuildState* ab)
{
ab->archiveBuilder = CreateArchiveBuilder_Zip(P_archive_filename);
@ -779,14 +779,14 @@ void archive_build_cancel(ArchiveBuildState* ab)
}
LibError archive_build(const char* P_archive_filename, Filenames V_fns)
Status archive_build(const char* P_archive_filename, Filenames V_fns)
{
ArchiveBuildState ab;
RETURN_ERR(archive_build_init(P_archive_filename, V_fns, &ab));
RETURN_STATUS_IF_ERR(archive_build_init(P_archive_filename, V_fns, &ab));
for(;;)
{
int ret = archive_build_continue(&ab);
RETURN_ERR(ret);
RETURN_STATUS_IF_ERR(ret);
if(ret == INFO::OK)
return INFO::OK;
}
@ -835,7 +835,7 @@ int vfs_opt_auto_build(const char* trace_filename,
else
{
// create mini-archive (if needed)
RETURN_ERR(build_mini_archive(mini_archive_fn_fmt));
RETURN_STATUS_IF_ERR(build_mini_archive(mini_archive_fn_fmt));
state = NOP;
return INFO::OK; // "finished"
@ -854,12 +854,12 @@ int vfs_opt_auto_build(const char* trace_filename,
UNREACHABLE;
}
LibError vfs_opt_rebuild_main_archive(const char* trace_filename, const char* archive_fn_fmt)
Status vfs_opt_rebuild_main_archive(const char* trace_filename, const char* archive_fn_fmt)
{
for(;;)
{
int ret = vfs_opt_auto_build(trace_filename, archive_fn_fmt, 0, true);
RETURN_ERR(ret);
RETURN_STATUS_IF_ERR(ret);
if(ret == INFO::OK)
return INFO::OK;
}
@ -912,8 +912,8 @@ struct Trace
};
extern void trace_get(Trace* t);
extern LibError trace_write_to_file(const char* trace_filename);
extern LibError trace_read_from_file(const char* trace_filename, Trace* t);
extern Status trace_write_to_file(const char* trace_filename);
extern Status trace_read_from_file(const char* trace_filename, Trace* t);
// simulate carrying out the entry's TraceOp to determine
@ -922,7 +922,7 @@ extern bool trace_entry_causes_io(const TraceEntry* ent);
// carry out all operations specified in the trace.
extern LibError trace_run(const char* trace_filename);
extern Status trace_run(const char* trace_filename);
@ -1108,10 +1108,10 @@ bool trace_entry_causes_io(FileCache& simulatedCache, const TraceEntry* ent)
LibError trace_run(const char* osPathname)
Status trace_run(const char* osPathname)
{
Trace trace;
RETURN_ERR(trace.Load(osPathname));
RETURN_STATUS_IF_ERR(trace.Load(osPathname));
for(size_t i = 0; i < trace.NumEntries(); i++)
trace.Entries()[i]->Run();
return INFO::OK;

View file

@ -29,7 +29,7 @@
#define INCLUDED_VFS_OPTIMIZER
extern LibError vfs_opt_rebuild_main_archive(const char* trace_filename, const char* archive_fn_fmt);
extern Status vfs_opt_rebuild_main_archive(const char* trace_filename, const char* archive_fn_fmt);
extern void vfs_opt_auto_build_cancel();

View file

@ -314,7 +314,7 @@ public:
return m_file->Pathname();
}
virtual LibError Load(const OsPath& UNUSED(name), const shared_ptr<u8>& buf, size_t size) const
virtual Status Load(const OsPath& UNUSED(name), const shared_ptr<u8>& buf, size_t size) const
{
AdjustOffset();
@ -335,8 +335,8 @@ public:
stream.SetOutputBuffer(buf.get(), size);
io::Operation op(*m_file.get(), 0, m_csize, m_ofs);
StreamFeeder streamFeeder(stream);
RETURN_ERR(io::Run(op, io::Parameters(), streamFeeder));
RETURN_ERR(stream.Finish());
RETURN_STATUS_IF_ERR(io::Run(op, io::Parameters(), streamFeeder));
RETURN_STATUS_IF_ERR(stream.Finish());
#if CODEC_COMPUTE_CHECKSUM
ENSURE(m_checksum == stream.Checksum());
#endif
@ -374,7 +374,7 @@ private:
// rationale: this allows using temp buffers for zip_fixup_lfh,
// which avoids involving the file buffer manager and thus
// avoids cluttering the trace and cache contents.
LibError operator()(const u8* block, size_t size) const
Status operator()(const u8* block, size_t size) const
{
ENSURE(size <= lfh_bytes_remaining);
memcpy(lfh_dst, block, size);
@ -441,17 +441,17 @@ public:
ENSURE(m_fileSize >= off_t(minFileSize));
}
virtual LibError ReadEntries(ArchiveEntryCallback cb, uintptr_t cbData)
virtual Status ReadEntries(ArchiveEntryCallback cb, uintptr_t cbData)
{
// locate and read Central Directory
off_t cd_ofs = 0;
size_t cd_numEntries = 0;
size_t cd_size = 0;
RETURN_ERR(LocateCentralDirectory(m_file, m_fileSize, cd_ofs, cd_numEntries, cd_size));
RETURN_STATUS_IF_ERR(LocateCentralDirectory(m_file, m_fileSize, cd_ofs, cd_numEntries, cd_size));
UniqueRange buf(RVALUE(io::Allocate(cd_size)));
io::Operation op(*m_file.get(), buf.get(), cd_size, cd_ofs);
RETURN_ERR(io::Run(op));
RETURN_STATUS_IF_ERR(io::Run(op));
// iterate over Central Directory
const u8* pos = (const u8*)buf.get();
@ -511,7 +511,7 @@ private:
// search for ECDR in the last <maxScanSize> bytes of the file.
// if found, fill <dst_ecdr> with a copy of the (little-endian) ECDR and
// return INFO::OK, otherwise IO error or ERR::CORRUPTED.
static LibError ScanForEcdr(const PFile& file, off_t fileSize, u8* buf, size_t maxScanSize, size_t& cd_numEntries, off_t& cd_ofs, size_t& cd_size)
static Status ScanForEcdr(const PFile& file, off_t fileSize, u8* buf, size_t maxScanSize, size_t& cd_numEntries, off_t& cd_ofs, size_t& cd_size)
{
// don't scan more than the entire file
const size_t scanSize = std::min(maxScanSize, size_t(fileSize));
@ -519,7 +519,7 @@ private:
// read desired chunk of file into memory
const off_t ofs = fileSize - off_t(scanSize);
io::Operation op(*file.get(), buf, scanSize, ofs);
RETURN_ERR(io::Run(op));
RETURN_STATUS_IF_ERR(io::Run(op));
// look for ECDR in buffer
const ECDR* ecdr = (const ECDR*)FindRecord(buf, scanSize, buf, ecdr_magic, sizeof(ECDR));
@ -530,13 +530,13 @@ private:
return INFO::OK;
}
static LibError LocateCentralDirectory(const PFile& file, off_t fileSize, off_t& cd_ofs, size_t& cd_numEntries, size_t& cd_size)
static Status LocateCentralDirectory(const PFile& file, off_t fileSize, off_t& cd_ofs, size_t& cd_numEntries, size_t& cd_size)
{
const size_t maxScanSize = 66000u; // see below
UniqueRange buf(RVALUE(io::Allocate(maxScanSize)));
// expected case: ECDR at EOF; no file comment
LibError ret = ScanForEcdr(file, fileSize, (u8*)buf.get(), sizeof(ECDR), cd_numEntries, cd_ofs, cd_size);
Status ret = ScanForEcdr(file, fileSize, (u8*)buf.get(), sizeof(ECDR), cd_numEntries, cd_ofs, cd_size);
if(ret == INFO::OK)
return INFO::OK;
// worst case: ECDR precedes 64 KiB of file comment
@ -546,7 +546,7 @@ private:
// both ECDR scans failed - this is not a valid Zip file.
io::Operation op(*file.get(), buf.get(), sizeof(LFH));
RETURN_ERR(io::Run(op));
RETURN_STATUS_IF_ERR(io::Run(op));
// the Zip file has an LFH but lacks an ECDR. this can happen if
// the user hard-exits while an archive is being written.
// notes:
@ -583,7 +583,7 @@ public:
: m_file(new File(archivePathname, LIO_WRITE)), m_fileSize(0)
, m_numEntries(0), m_noDeflate(noDeflate)
{
THROW_ERR(pool_create(&m_cdfhPool, 10*MiB, 0));
THROW_STATUS_IF_ERR(pool_create(&m_cdfhPool, 10*MiB, 0));
}
~ArchiveWriter_Zip()
@ -603,10 +603,10 @@ public:
(void)pool_destroy(&m_cdfhPool);
}
LibError AddFile(const OsPath& pathname, const OsPath& pathnameInArchive)
Status AddFile(const OsPath& pathname, const OsPath& pathnameInArchive)
{
FileInfo fileInfo;
RETURN_ERR(GetFileInfo(pathname, &fileInfo));
RETURN_STATUS_IF_ERR(GetFileInfo(pathname, &fileInfo));
const off_t usize = fileInfo.Size();
// skip 0-length files.
// rationale: zip.cpp needs to determine whether a CDFH entry is
@ -620,7 +620,7 @@ public:
return INFO::SKIPPED;
PFile file(new File);
RETURN_ERR(file->Open(pathname, LIO_READ));
RETURN_STATUS_IF_ERR(file->Open(pathname, LIO_READ));
const size_t pathnameLength = pathnameInArchive.string().length();
@ -650,8 +650,8 @@ public:
stream.SetOutputBuffer(cdata, csizeMax);
io::Operation op(*file.get(), 0, usize);
StreamFeeder streamFeeder(stream);
RETURN_ERR(io::Run(op, io::Parameters(), streamFeeder));
RETURN_ERR(stream.Finish());
RETURN_STATUS_IF_ERR(io::Run(op, io::Parameters(), streamFeeder));
RETURN_STATUS_IF_ERR(stream.Finish());
csize = stream.OutSize();
checksum = stream.Checksum();
}

View file

@ -53,7 +53,7 @@ public:
* efficient since it avoids reallocating a considerable amount of
* memory (about 200KB for LZ).
**/
virtual LibError Reset() = 0;
virtual Status Reset() = 0;
/**
* process (i.e. compress or decompress) data.
@ -66,7 +66,7 @@ public:
* output buffers were used. either or both of these can be zero if
* the input size is small or there's not enough output space.
**/
virtual LibError Process(const u8* in, size_t inSize, u8* out, size_t outSize, size_t& inConsumed, size_t& outProduced) = 0;
virtual Status Process(const u8* in, size_t inSize, u8* out, size_t outSize, size_t& inConsumed, size_t& outProduced) = 0;
/**
* Flush buffers and make sure all output has been produced.
@ -75,7 +75,7 @@ public:
* @param outProduced
* @return error status for the entire operation.
**/
virtual LibError Finish(u32& checksum, size_t& outProduced) = 0;
virtual Status Finish(u32& checksum, size_t& outProduced) = 0;
/**
* update a checksum to reflect the contents of a buffer.

View file

@ -76,13 +76,13 @@ public:
return inSize;
}
virtual LibError Reset()
virtual Status Reset()
{
m_checksum = InitializeChecksum();
return INFO::OK;
}
virtual LibError Process(const u8* in, size_t inSize, u8* out, size_t outSize, size_t& inConsumed, size_t& outProduced)
virtual Status Process(const u8* in, size_t inSize, u8* out, size_t outSize, size_t& inConsumed, size_t& outProduced)
{
const size_t transferSize = std::min(inSize, outSize);
memcpy(out, in, transferSize);
@ -91,7 +91,7 @@ public:
return INFO::OK;
}
virtual LibError Finish(u32& checksum, size_t& outProduced)
virtual Status Finish(u32& checksum, size_t& outProduced)
{
outProduced = 0;
checksum = m_checksum;
@ -114,7 +114,7 @@ protected:
m_checksum = InitializeChecksum();
}
static LibError LibError_from_zlib(int zlib_ret)
static Status LibError_from_zlib(int zlib_ret)
{
switch(zlib_ret)
{
@ -140,7 +140,7 @@ protected:
typedef int ZEXPORT (*ZLibFunc)(z_streamp strm, int flush);
LibError CallStreamFunc(ZLibFunc func, int flush, const u8* in, const size_t inSize, u8* out, const size_t outSize, size_t& inConsumed, size_t& outProduced)
Status CallStreamFunc(ZLibFunc func, int flush, const u8* in, const size_t inSize, u8* out, const size_t outSize, size_t& inConsumed, size_t& outProduced)
{
m_zs.next_in = (Byte*)in;
m_zs.avail_in = (uInt)inSize;
@ -184,14 +184,8 @@ public:
// note: with Z_BEST_COMPRESSION, 78% percent of
// archive builder CPU time is spent in ZLib, even though
// that is interleaved with IO; everything else is negligible.
// we therefore enable this only in final builds; during
// development, 1.5% bigger archives are definitely worth much
// faster build time.
#if CONFIG_FINAL
const int level = Z_BEST_COMPRESSION;
#else
// we prefer faster speed at the cost of 1.5% larger archives.
const int level = Z_BEST_SPEED;
#endif
const int windowBits = -MAX_WBITS; // max window size; omit ZLib header
const int memLevel = 9; // max speed; total mem ~= 384KiB
const int strategy = Z_DEFAULT_STRATEGY; // normal data - not RLE
@ -210,20 +204,20 @@ public:
return (size_t)deflateBound(&m_zs, (uLong)inSize);
}
virtual LibError Reset()
virtual Status Reset()
{
m_checksum = InitializeChecksum();
const int ret = deflateReset(&m_zs);
return LibError_from_zlib(ret);
}
virtual LibError Process(const u8* in, size_t inSize, u8* out, size_t outSize, size_t& inConsumed, size_t& outProduced)
virtual Status Process(const u8* in, size_t inSize, u8* out, size_t outSize, size_t& inConsumed, size_t& outProduced)
{
m_checksum = UpdateChecksum(m_checksum, in, inSize);
return CodecZLibStream::CallStreamFunc(deflate, 0, in, inSize, out, outSize, inConsumed, outProduced);
}
virtual LibError Finish(u32& checksum, size_t& outProduced)
virtual Status Finish(u32& checksum, size_t& outProduced)
{
const uInt availOut = m_zs.avail_out;
@ -269,21 +263,21 @@ public:
return inSize*1032; // see http://www.zlib.org/zlib_tech.html
}
virtual LibError Reset()
virtual Status Reset()
{
m_checksum = InitializeChecksum();
const int ret = inflateReset(&m_zs);
return LibError_from_zlib(ret);
}
virtual LibError Process(const u8* in, size_t inSize, u8* out, size_t outSize, size_t& inConsumed, size_t& outProduced)
virtual Status Process(const u8* in, size_t inSize, u8* out, size_t outSize, size_t& inConsumed, size_t& outProduced)
{
const LibError ret = CodecZLibStream::CallStreamFunc(inflate, Z_SYNC_FLUSH, in, inSize, out, outSize, inConsumed, outProduced);
const Status ret = CodecZLibStream::CallStreamFunc(inflate, Z_SYNC_FLUSH, in, inSize, out, outSize, inConsumed, outProduced);
m_checksum = UpdateChecksum(m_checksum, out, outProduced);
return ret;
}
virtual LibError Finish(u32& checksum, size_t& outProduced)
virtual Status Finish(u32& checksum, size_t& outProduced)
{
// no action needed - decompression always flushes immediately.
outProduced = 0;

View file

@ -113,7 +113,7 @@ void Stream::SetOutputBuffer(u8* out, size_t outSize)
}
LibError Stream::Feed(const u8* in, size_t inSize)
Status Stream::Feed(const u8* in, size_t inSize)
{
if(m_outProduced == m_outputBufferManager.Size()) // output buffer full; must not call Process
return INFO::OK;
@ -121,7 +121,7 @@ LibError Stream::Feed(const u8* in, size_t inSize)
size_t inConsumed, outProduced;
u8* const out = m_outputBufferManager.Buffer() + m_outProduced;
const size_t outSize = m_outputBufferManager.Size() - m_outProduced;
RETURN_ERR(m_codec->Process(in, inSize, out, outSize, inConsumed, outProduced));
RETURN_STATUS_IF_ERR(m_codec->Process(in, inSize, out, outSize, inConsumed, outProduced));
m_inConsumed += inConsumed;
m_outProduced += outProduced;
@ -129,10 +129,10 @@ LibError Stream::Feed(const u8* in, size_t inSize)
}
LibError Stream::Finish()
Status Stream::Finish()
{
size_t outProduced;
RETURN_ERR(m_codec->Finish(m_checksum, outProduced));
RETURN_STATUS_IF_ERR(m_codec->Finish(m_checksum, outProduced));
m_outProduced += outProduced;
return INFO::OK;
}

View file

@ -87,9 +87,9 @@ public:
/**
* 'feed' the codec with a data block.
**/
LibError Feed(const u8* in, size_t inSize);
Status Feed(const u8* in, size_t inSize);
LibError Finish();
Status Finish();
size_t OutSize() const
{
@ -121,7 +121,7 @@ public:
{
}
LibError operator()(const u8* data, size_t size) const
Status operator()(const u8* data, size_t size) const
{
return stream.Feed(data, size);
}

View file

@ -33,7 +33,7 @@ struct IFileLoader
virtual wchar_t LocationCode() const = 0;
virtual OsPath Path() const = 0;
virtual LibError Load(const OsPath& name, const shared_ptr<u8>& buf, size_t size) const = 0;
virtual Status Load(const OsPath& name, const shared_ptr<u8>& buf, size_t size) const = 0;
};
typedef shared_ptr<IFileLoader> PIFileLoader;

View file

@ -46,13 +46,13 @@ RealDirectory::RealDirectory(const OsPath& path, size_t priority, size_t flags)
}
/*virtual*/ LibError RealDirectory::Load(const OsPath& name, const shared_ptr<u8>& buf, size_t size) const
/*virtual*/ Status RealDirectory::Load(const OsPath& name, const shared_ptr<u8>& buf, size_t size) const
{
return io::Load(m_path / name, buf.get(), size);
}
LibError RealDirectory::Store(const OsPath& name, const shared_ptr<u8>& fileContents, size_t size)
Status RealDirectory::Store(const OsPath& name, const shared_ptr<u8>& fileContents, size_t size)
{
return io::Store(m_path / name, fileContents.get(), size);
}

View file

@ -49,9 +49,9 @@ public:
{
return m_path;
}
virtual LibError Load(const OsPath& name, const shared_ptr<u8>& buf, size_t size) const;
virtual Status Load(const OsPath& name, const shared_ptr<u8>& buf, size_t size) const;
LibError Store(const OsPath& name, const shared_ptr<u8>& fileContents, size_t size);
Status Store(const OsPath& name, const shared_ptr<u8>& fileContents, size_t size);
void Watch();

View file

@ -112,12 +112,12 @@ public:
{
}
virtual LibError Load(const OsPath& UNUSED(pathname))
virtual Status Load(const OsPath& UNUSED(pathname))
{
return INFO::OK;
}
virtual LibError Store(const OsPath& UNUSED(pathname)) const
virtual Status Store(const OsPath& UNUSED(pathname)) const
{
return INFO::OK;
}
@ -165,14 +165,14 @@ public:
new(Allocate()) TraceEntry(TraceEntry::Store, pathname, size);
}
virtual LibError Load(const OsPath& pathname)
virtual Status Load(const OsPath& pathname)
{
pool_free_all(&m_pool);
errno = 0;
FILE* file = sys_OpenFile(pathname, "rt");
if(!file)
return LibError_from_errno();
WARN_RETURN(StatusFromErrno());
for(;;)
{
@ -186,12 +186,12 @@ public:
return INFO::OK;
}
virtual LibError Store(const OsPath& pathname) const
virtual Status Store(const OsPath& pathname) const
{
errno = 0;
FILE* file = sys_OpenFile(pathname, "at");
if(!file)
return LibError_from_errno();
WARN_RETURN(StatusFromErrno());
for(size_t i = 0; i < NumEntries(); i++)
{
std::wstring text = Entries()[i].EncodeAsText();

View file

@ -105,7 +105,7 @@ struct ITrace
* because storing filename strings in a binary format would be a
* bit awkward.
**/
virtual LibError Store(const OsPath& pathname) const = 0;
virtual Status Store(const OsPath& pathname) const = 0;
/**
* load entries from file.
@ -114,7 +114,7 @@ struct ITrace
*
* replaces any existing entries.
**/
virtual LibError Load(const OsPath& pathname) = 0;
virtual Status Load(const OsPath& pathname) = 0;
virtual const TraceEntry* Entries() const = 0;
virtual size_t NumEntries() const = 0;

View file

@ -31,11 +31,11 @@
#include "lib/file/common/file_stats.h"
ERROR_ASSOCIATE(ERR::FILE_ACCESS, L"Insufficient access rights to open file", EACCES);
ERROR_ASSOCIATE(ERR::FILE_NOT_FOUND, L"No such file or directory", ENOENT);
STATUS_DEFINE(ERR, FILE_ACCESS, L"Insufficient access rights to open file", EACCES);
STATUS_DEFINE(ERR, FILE_NOT_FOUND, L"No such file or directory", ENOENT);
LibError FileOpen(const OsPath& pathname, int opcode, int& fd)
Status FileOpen(const OsPath& pathname, int opcode, int& fd)
{
int oflag = 0;
switch(opcode)
@ -58,7 +58,7 @@ LibError FileOpen(const OsPath& pathname, int opcode, int& fd)
const mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH; // 0644
fd = wopen(pathname, oflag, mode);
if(fd < 0)
return LibError_from_errno(false);
return StatusFromErrno(); // NOWARN
stats_open();
return INFO::OK;

View file

@ -32,11 +32,11 @@
namespace ERR
{
const LibError FILE_ACCESS = -110300;
const LibError FILE_NOT_FOUND = -110301;
const Status FILE_ACCESS = -110300;
const Status FILE_NOT_FOUND = -110301;
}
LIB_API LibError FileOpen(const OsPath& pathname, int opcode, int& fd);
LIB_API Status FileOpen(const OsPath& pathname, int opcode, int& fd);
LIB_API void FileClose(int& fd);
class File
@ -57,9 +57,9 @@ public:
Close();
}
LibError Open(const OsPath& pathname, int opcode)
Status Open(const OsPath& pathname, int opcode)
{
RETURN_ERR(FileOpen(pathname, opcode, fd));
RETURN_STATUS_IF_ERR(FileOpen(pathname, opcode, fd));
this->pathname = pathname;
this->opcode = opcode;
return INFO::OK;

View file

@ -38,13 +38,13 @@ struct DirDeleter
}
};
LibError GetDirectoryEntries(const OsPath& path, FileInfos* files, DirectoryNames* subdirectoryNames)
Status GetDirectoryEntries(const OsPath& path, FileInfos* files, DirectoryNames* subdirectoryNames)
{
// open directory
errno = 0;
WDIR* pDir = wopendir(path);
if(!pDir)
return LibError_from_errno(false);
return StatusFromErrno(); // NOWARN
shared_ptr<WDIR> osDir(pDir, DirDeleter());
for(;;)
@ -56,24 +56,24 @@ LibError GetDirectoryEntries(const OsPath& path, FileInfos* files, DirectoryName
// no error, just no more entries to return
if(!errno)
return INFO::OK;
return LibError_from_errno();
WARN_RETURN(StatusFromErrno());
}
for(size_t i = 0; osEnt->d_name[i] != '\0'; i++)
RETURN_ERR(Path::Validate(osEnt->d_name[i]));
RETURN_STATUS_IF_ERR(Path::Validate(osEnt->d_name[i]));
const OsPath name(osEnt->d_name);
// get file information (mode, size, mtime)
struct stat s;
#if OS_WIN
// .. return wdirent directly (much faster than calling stat).
RETURN_ERR(wreaddir_stat_np(osDir.get(), &s));
RETURN_STATUS_IF_ERR(wreaddir_stat_np(osDir.get(), &s));
#else
// .. call regular stat().
errno = 0;
const OsPath pathname = path / name;
if(wstat(pathname, &s) != 0)
return LibError_from_errno();
WARN_RETURN(StatusFromErrno());
#endif
if(files && S_ISREG(s.st_mode))
@ -84,20 +84,20 @@ LibError GetDirectoryEntries(const OsPath& path, FileInfos* files, DirectoryName
}
LibError GetFileInfo(const OsPath& pathname, FileInfo* pfileInfo)
Status GetFileInfo(const OsPath& pathname, FileInfo* pfileInfo)
{
errno = 0;
struct stat s;
memset(&s, 0, sizeof(s));
if(wstat(pathname, &s) != 0)
return LibError_from_errno();
WARN_RETURN(StatusFromErrno());
*pfileInfo = FileInfo(pathname.Filename(), s.st_size, s.st_mtime);
return INFO::OK;
}
LibError CreateDirectories(const OsPath& path, mode_t mode)
Status CreateDirectories(const OsPath& path, mode_t mode)
{
if(path.empty())
return INFO::OK;
@ -115,23 +115,23 @@ LibError CreateDirectories(const OsPath& path, mode_t mode)
if(path.IsDirectory())
return CreateDirectories(path.Parent(), mode);
RETURN_ERR(CreateDirectories(path.Parent(), mode));
RETURN_STATUS_IF_ERR(CreateDirectories(path.Parent(), mode));
errno = 0;
if(wmkdir(path, mode) != 0)
return LibError_from_errno();
WARN_RETURN(StatusFromErrno());
return INFO::OK;
}
LibError DeleteDirectory(const OsPath& path)
Status DeleteDirectory(const OsPath& path)
{
// note: we have to recursively empty the directory before it can
// be deleted (required by Windows and POSIX rmdir()).
FileInfos files; DirectoryNames subdirectoryNames;
RETURN_ERR(GetDirectoryEntries(path, &files, &subdirectoryNames));
RETURN_STATUS_IF_ERR(GetDirectoryEntries(path, &files, &subdirectoryNames));
// delete files
for(size_t i = 0; i < files.size(); i++)
@ -139,16 +139,16 @@ LibError DeleteDirectory(const OsPath& path)
const OsPath pathname = path / files[i].Name();
errno = 0;
if(wunlink(pathname) != 0)
return LibError_from_errno();
WARN_RETURN(StatusFromErrno());
}
// recurse over subdirectoryNames
for(size_t i = 0; i < subdirectoryNames.size(); i++)
RETURN_ERR(DeleteDirectory(path / subdirectoryNames[i]));
RETURN_STATUS_IF_ERR(DeleteDirectory(path / subdirectoryNames[i]));
errno = 0;
if(wrmdir(path) != 0)
return LibError_from_errno();
WARN_RETURN(StatusFromErrno());
return INFO::OK;
}

View file

@ -60,17 +60,17 @@ private:
time_t mtime;
};
extern LibError GetFileInfo(const OsPath& pathname, FileInfo* fileInfo);
extern Status GetFileInfo(const OsPath& pathname, FileInfo* fileInfo);
typedef std::vector<FileInfo> FileInfos;
typedef std::vector<OsPath> DirectoryNames;
extern LibError GetDirectoryEntries(const OsPath& path, FileInfos* files, DirectoryNames* subdirectoryNames);
extern Status GetDirectoryEntries(const OsPath& path, FileInfos* files, DirectoryNames* subdirectoryNames);
// same as boost::filesystem::create_directories, except that mkdir is invoked with
// <mode> instead of 0755.
extern LibError CreateDirectories(const OsPath& path, mode_t mode);
extern Status CreateDirectories(const OsPath& path, mode_t mode);
extern LibError DeleteDirectory(const OsPath& dirPath);
extern Status DeleteDirectory(const OsPath& dirPath);
#endif // #ifndef INCLUDED_FILE_SYSTEM

View file

@ -65,10 +65,10 @@ u64 FileSize(const OsPath& pathname)
}
LibError GetPathnames(const PIVFS& fs, const VfsPath& path, const wchar_t* filter, VfsPaths& pathnames)
Status GetPathnames(const PIVFS& fs, const VfsPath& path, const wchar_t* filter, VfsPaths& pathnames)
{
std::vector<FileInfo> files;
RETURN_ERR(fs->GetDirectoryEntries(path, &files, 0));
RETURN_STATUS_IF_ERR(fs->GetDirectoryEntries(path, &files, 0));
pathnames.clear();
pathnames.reserve(files.size());
@ -83,7 +83,7 @@ LibError GetPathnames(const PIVFS& fs, const VfsPath& path, const wchar_t* filte
}
LibError ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb, uintptr_t cbData, const wchar_t* pattern, size_t flags)
Status ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb, uintptr_t cbData, const wchar_t* pattern, size_t flags)
{
// (declare here to avoid reallocations)
FileInfos files; DirectoryNames subdirectoryNames;
@ -96,7 +96,7 @@ LibError ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb,
{
const VfsPath& path = pendingDirectories.front();
RETURN_ERR(fs->GetDirectoryEntries(path, &files, &subdirectoryNames));
RETURN_STATUS_IF_ERR(fs->GetDirectoryEntries(path, &files, &subdirectoryNames));
for(size_t i = 0; i < files.size(); i++)
{

View file

@ -37,7 +37,7 @@ LIB_API bool FileExists(const OsPath& pathname);
LIB_API u64 FileSize(const OsPath& pathname);
extern LibError GetPathnames(const PIVFS& fs, const VfsPath& path, const wchar_t* filter, VfsPaths& pathnames);
extern Status GetPathnames(const PIVFS& fs, const VfsPath& path, const wchar_t* filter, VfsPaths& pathnames);
/**
* called for files in a directory.
@ -51,7 +51,7 @@ extern LibError GetPathnames(const PIVFS& fs, const VfsPath& path, const wchar_t
* CAVEAT: pathname and fileInfo are only valid until the function
* returns!
**/
typedef LibError (*FileCallback)(const VfsPath& pathname, const FileInfo& fileInfo, const uintptr_t cbData);
typedef Status (*FileCallback)(const VfsPath& pathname, const FileInfo& fileInfo, const uintptr_t cbData);
enum DirFlags
{
@ -68,9 +68,9 @@ enum DirFlags
* @param pattern that file names must match. '*' and '&' wildcards
* are allowed. 0 matches everything.
* @param flags @ref DirFlags
* @return LibError
* @return Status
**/
extern LibError ForEachFile(const PIVFS& fs, const VfsPath& path, FileCallback cb, uintptr_t cbData, const wchar_t* pattern = 0, size_t flags = 0);
extern Status ForEachFile(const PIVFS& fs, const VfsPath& path, FileCallback cb, uintptr_t cbData, const wchar_t* pattern = 0, size_t flags = 0);
/**

View file

@ -25,7 +25,7 @@
#include "lib/sysdep/rtl.h"
ERROR_ASSOCIATE(ERR::IO, L"Error during IO", EIO);
STATUS_DEFINE(ERR, IO, L"Error during IO", EIO);
namespace io {
@ -45,13 +45,14 @@ UniqueRange Allocate(size_t size, size_t alignment)
// note that the Windows aio implementation requires buffers, sizes and
// offsets to be sector-aligned.
LibError Issue(aiocb& cb, size_t queueDepth)
Status Issue(aiocb& cb, size_t queueDepth)
{
#if CONFIG2_FILE_ENABLE_AIO
if(queueDepth > 1)
{
const int ret = (cb.aio_lio_opcode == LIO_WRITE)? aio_write(&cb): aio_read(&cb);
RETURN_ERR(LibError_from_posix(ret));
if(ret != 0)
WARN_RETURN(StatusFromErrno());
}
else
#else
@ -63,7 +64,7 @@ LibError Issue(aiocb& cb, size_t queueDepth)
void* buf = (void*)cb.aio_buf; // cast from volatile void*
const ssize_t bytesTransferred = (cb.aio_lio_opcode == LIO_WRITE)? write(cb.aio_fildes, buf, cb.aio_nbytes) : read(cb.aio_fildes, buf, cb.aio_nbytes);
if(bytesTransferred < 0)
return LibError_from_errno();
WARN_RETURN(StatusFromErrno());
cb.aio_nbytes = (size_t)bytesTransferred;
}
@ -72,7 +73,7 @@ LibError Issue(aiocb& cb, size_t queueDepth)
}
LibError WaitUntilComplete(aiocb& cb, size_t queueDepth)
Status WaitUntilComplete(aiocb& cb, size_t queueDepth)
{
#if CONFIG2_FILE_ENABLE_AIO
if(queueDepth > 1)
@ -86,7 +87,7 @@ SUSPEND_AGAIN:
{
if(errno == EINTR) // interrupted by signal
goto SUSPEND_AGAIN;
return LibError_from_errno();
WARN_RETURN(StatusFromErrno());
}
const int err = aio_error(&cb);
@ -95,7 +96,7 @@ SUSPEND_AGAIN:
if(bytesTransferred == -1) // transfer failed
{
errno = err;
return LibError_from_errno();
WARN_RETURN(StatusFromErrno());
}
cb.aio_nbytes = (size_t)bytesTransferred;
}

View file

@ -38,7 +38,7 @@
namespace ERR
{
const LibError IO = -110301;
const Status IO = -110301;
}
namespace io {
@ -152,7 +152,7 @@ struct DefaultCompletedHook
* allows progress notification and processing data while waiting for
* previous I/Os to complete.
**/
LibError operator()(const u8* UNUSED(block), size_t UNUSED(blockSize)) const
Status operator()(const u8* UNUSED(block), size_t UNUSED(blockSize)) const
{
return INFO::CB_CONTINUE;
}
@ -170,7 +170,7 @@ struct DefaultIssueHook
* allows generating the data to write while waiting for
* previous I/Os to complete.
**/
LibError operator()(aiocb& UNUSED(cb)) const
Status operator()(aiocb& UNUSED(cb)) const
{
return INFO::CB_CONTINUE;
}
@ -215,8 +215,8 @@ private:
#pragma pack(pop)
LIB_API LibError Issue(aiocb& cb, size_t queueDepth);
LIB_API LibError WaitUntilComplete(aiocb& cb, size_t queueDepth);
LIB_API Status Issue(aiocb& cb, size_t queueDepth);
LIB_API Status WaitUntilComplete(aiocb& cb, size_t queueDepth);
//-----------------------------------------------------------------------------
@ -225,7 +225,7 @@ LIB_API LibError WaitUntilComplete(aiocb& cb, size_t queueDepth);
// (hooks must be passed by const reference to allow passing rvalues.
// functors with non-const member data can mark them as mutable.)
template<class CompletedHook, class IssueHook>
static inline LibError Run(const Operation& op, const Parameters& p = Parameters(), const CompletedHook& completedHook = CompletedHook(), const IssueHook& issueHook = IssueHook())
static inline Status Run(const Operation& op, const Parameters& p = Parameters(), const CompletedHook& completedHook = CompletedHook(), const IssueHook& issueHook = IssueHook())
{
op.Validate();
p.Validate(op);
@ -246,11 +246,11 @@ static inline LibError Run(const Operation& op, const Parameters& p = Parameters
RETURN_IF_NOT_CONTINUE(issueHook(cb));
RETURN_ERR(Issue(cb, p.queueDepth));
RETURN_STATUS_IF_ERR(Issue(cb, p.queueDepth));
}
aiocb& cb = controlBlockRingBuffer[blocksCompleted];
RETURN_ERR(WaitUntilComplete(cb, p.queueDepth));
RETURN_STATUS_IF_ERR(WaitUntilComplete(cb, p.queueDepth));
RETURN_IF_NOT_CONTINUE(completedHook((u8*)cb.aio_buf, cb.aio_nbytes));
}
@ -260,12 +260,12 @@ static inline LibError Run(const Operation& op, const Parameters& p = Parameters
// (overloads allow omitting parameters without requiring a template argument list)
template<class CompletedHook>
static inline LibError Run(const Operation& op, const Parameters& p = Parameters(), const CompletedHook& completedHook = CompletedHook())
static inline Status Run(const Operation& op, const Parameters& p = Parameters(), const CompletedHook& completedHook = CompletedHook())
{
return Run(op, p, completedHook, DefaultIssueHook());
}
static inline LibError Run(const Operation& op, const Parameters& p = Parameters())
static inline Status Run(const Operation& op, const Parameters& p = Parameters())
{
return Run(op, p, DefaultCompletedHook(), DefaultIssueHook());
}
@ -278,32 +278,32 @@ static inline LibError Run(const Operation& op, const Parameters& p = Parameters
// padded to the sector size and needs to be truncated afterwards.
// this function takes care of both.
template<class CompletedHook, class IssueHook>
static inline LibError Store(const OsPath& pathname, const void* data, size_t size, const Parameters& p = Parameters(), const CompletedHook& completedHook = CompletedHook(), const IssueHook& issueHook = IssueHook())
static inline Status Store(const OsPath& pathname, const void* data, size_t size, const Parameters& p = Parameters(), const CompletedHook& completedHook = CompletedHook(), const IssueHook& issueHook = IssueHook())
{
File file;
CHECK_ERR(file.Open(pathname, LIO_WRITE));
WARN_RETURN_STATUS_IF_ERR(file.Open(pathname, LIO_WRITE));
io::Operation op(file, (void*)data, size);
#if OS_WIN && CONFIG2_FILE_ENABLE_AIO
(void)waio_Preallocate(op.fd, (off_t)size);
#endif
RETURN_ERR(io::Run(op, p, completedHook, issueHook));
RETURN_STATUS_IF_ERR(io::Run(op, p, completedHook, issueHook));
file.Close(); // (required by wtruncate)
RETURN_ERR(wtruncate(pathname, size));
RETURN_STATUS_IF_ERR(wtruncate(pathname, size));
return INFO::OK;
}
template<class CompletedHook>
static inline LibError Store(const OsPath& pathname, const void* data, size_t size, const Parameters& p = Parameters(), const CompletedHook& completedHook = CompletedHook())
static inline Status Store(const OsPath& pathname, const void* data, size_t size, const Parameters& p = Parameters(), const CompletedHook& completedHook = CompletedHook())
{
return Store(pathname, data, size, p, completedHook, DefaultIssueHook());
}
static inline LibError Store(const OsPath& pathname, const void* data, size_t size, const Parameters& p = Parameters())
static inline Status Store(const OsPath& pathname, const void* data, size_t size, const Parameters& p = Parameters())
{
return Store(pathname, data, size, p, DefaultCompletedHook(), DefaultIssueHook());
}
@ -314,21 +314,21 @@ static inline LibError Store(const OsPath& pathname, const void* data, size_t si
// convenience function provided for symmetry with Store
template<class CompletedHook, class IssueHook>
static inline LibError Load(const OsPath& pathname, void* buf, size_t size, const Parameters& p = Parameters(), const CompletedHook& completedHook = CompletedHook(), const IssueHook& issueHook = IssueHook())
static inline Status Load(const OsPath& pathname, void* buf, size_t size, const Parameters& p = Parameters(), const CompletedHook& completedHook = CompletedHook(), const IssueHook& issueHook = IssueHook())
{
File file;
RETURN_ERR(file.Open(pathname, LIO_READ));
RETURN_STATUS_IF_ERR(file.Open(pathname, LIO_READ));
io::Operation op(file, buf, size);
return io::Run(op, p, completedHook, issueHook);
}
template<class CompletedHook>
static inline LibError Load(const OsPath& pathname, void* buf, size_t size, const Parameters& p = Parameters(), const CompletedHook& completedHook = CompletedHook())
static inline Status Load(const OsPath& pathname, void* buf, size_t size, const Parameters& p = Parameters(), const CompletedHook& completedHook = CompletedHook())
{
return Load(pathname, buf, size, p, completedHook, DefaultIssueHook());
}
static inline LibError Load(const OsPath& pathname, void* buf, size_t size, const Parameters& p = Parameters())
static inline Status Load(const OsPath& pathname, void* buf, size_t size, const Parameters& p = Parameters())
{
return Load(pathname, buf, size, p, DefaultCompletedHook(), DefaultIssueHook());
}

View file

@ -73,7 +73,7 @@ UnalignedWriter::UnalignedWriter(const PFile& file, off_t ofs)
if(misalignment)
{
io::Operation op(*m_file.get(), m_alignedBuf.get(), BLOCK_SIZE, m_alignedOfs);
THROW_ERR(io::Run(op));
THROW_STATUS_IF_ERR(io::Run(op));
}
m_bytesUsed = misalignment;
}
@ -85,7 +85,7 @@ UnalignedWriter::~UnalignedWriter()
}
LibError UnalignedWriter::Append(const u8* data, size_t size) const
Status UnalignedWriter::Append(const u8* data, size_t size) const
{
while(size != 0)
{
@ -94,7 +94,7 @@ LibError UnalignedWriter::Append(const u8* data, size_t size) const
if(m_bytesUsed == 0 && IsAligned(data, maxSectorSize) && alignedSize != 0)
{
io::Operation op(*m_file.get(), (void*)data, alignedSize, m_alignedOfs);
RETURN_ERR(io::Run(op));
RETURN_STATUS_IF_ERR(io::Run(op));
m_alignedOfs += (off_t)alignedSize;
data += alignedSize;
size -= alignedSize;
@ -107,7 +107,7 @@ LibError UnalignedWriter::Append(const u8* data, size_t size) const
size -= chunkSize;
if(m_bytesUsed == BLOCK_SIZE)
RETURN_ERR(WriteBlock());
RETURN_STATUS_IF_ERR(WriteBlock());
}
return INFO::OK;
@ -124,10 +124,10 @@ void UnalignedWriter::Flush() const
}
LibError UnalignedWriter::WriteBlock() const
Status UnalignedWriter::WriteBlock() const
{
io::Operation op(*m_file.get(), m_alignedBuf.get(), BLOCK_SIZE, m_alignedOfs);
RETURN_ERR(io::Run(op));
RETURN_STATUS_IF_ERR(io::Run(op));
m_alignedOfs += BLOCK_SIZE;
m_bytesUsed = 0;
return INFO::OK;

View file

@ -61,7 +61,7 @@ public:
/**
* add data to the align buffer, writing it out to disk if full.
**/
LibError Append(const u8* data, size_t size) const;
Status Append(const u8* data, size_t size) const;
/**
* zero-initialize any remaining space in the align buffer and write
@ -70,7 +70,7 @@ public:
void Flush() const;
private:
LibError WriteBlock() const;
Status WriteBlock() const;
PFile m_file;
shared_ptr<u8> m_alignedBuf;

View file

@ -35,9 +35,9 @@
#include "lib/file/vfs/vfs_populate.h"
#include "lib/file/vfs/file_cache.h"
ERROR_ASSOCIATE(ERR::VFS_DIR_NOT_FOUND, L"VFS directory not found", -1);
ERROR_ASSOCIATE(ERR::VFS_FILE_NOT_FOUND, L"VFS file not found", -1);
ERROR_ASSOCIATE(ERR::VFS_ALREADY_MOUNTED, L"VFS path already mounted", -1);
STATUS_DEFINE(ERR, VFS_DIR_NOT_FOUND, L"VFS directory not found", -1);
STATUS_DEFINE(ERR, VFS_FILE_NOT_FOUND, L"VFS file not found", -1);
STATUS_DEFINE(ERR, VFS_ALREADY_MOUNTED, L"VFS path already mounted", -1);
static pthread_mutex_t vfs_mutex = PTHREAD_MUTEX_INITIALIZER;
struct ScopedLock
@ -55,7 +55,7 @@ public:
{
}
virtual LibError Mount(const VfsPath& mountPoint, const OsPath& path, size_t flags /* = 0 */, size_t priority /* = 0 */)
virtual Status Mount(const VfsPath& mountPoint, const OsPath& path, size_t flags /* = 0 */, size_t priority /* = 0 */)
{
ScopedLock s;
if(!fs_util::DirectoryExists(path))
@ -63,43 +63,43 @@ public:
if(flags & VFS_MOUNT_MUST_EXIST)
return ERR::VFS_DIR_NOT_FOUND; // NOWARN
else
RETURN_ERR(CreateDirectories(path, 0700));
RETURN_STATUS_IF_ERR(CreateDirectories(path, 0700));
}
VfsDirectory* directory;
CHECK_ERR(vfs_Lookup(mountPoint, &m_rootDirectory, directory, 0, VFS_LOOKUP_ADD|VFS_LOOKUP_SKIP_POPULATE));
WARN_RETURN_STATUS_IF_ERR(vfs_Lookup(mountPoint, &m_rootDirectory, directory, 0, VFS_LOOKUP_ADD|VFS_LOOKUP_SKIP_POPULATE));
PRealDirectory realDirectory(new RealDirectory(path, priority, flags));
RETURN_ERR(vfs_Attach(directory, realDirectory));
RETURN_STATUS_IF_ERR(vfs_Attach(directory, realDirectory));
return INFO::OK;
}
virtual LibError GetFileInfo(const VfsPath& pathname, FileInfo* pfileInfo) const
virtual Status GetFileInfo(const VfsPath& pathname, FileInfo* pfileInfo) const
{
ScopedLock s;
VfsDirectory* directory; VfsFile* file;
LibError ret = vfs_Lookup(pathname, &m_rootDirectory, directory, &file);
Status ret = vfs_Lookup(pathname, &m_rootDirectory, directory, &file);
if(!pfileInfo) // just indicate if the file exists without raising warnings.
return ret;
CHECK_ERR(ret);
WARN_RETURN_STATUS_IF_ERR(ret);
*pfileInfo = FileInfo(file->Name(), file->Size(), file->MTime());
return INFO::OK;
}
virtual LibError GetFilePriority(const VfsPath& pathname, size_t* ppriority) const
virtual Status GetFilePriority(const VfsPath& pathname, size_t* ppriority) const
{
ScopedLock s;
VfsDirectory* directory; VfsFile* file;
RETURN_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file));
RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file));
*ppriority = file->Priority();
return INFO::OK;
}
virtual LibError GetDirectoryEntries(const VfsPath& path, FileInfos* fileInfos, DirectoryNames* subdirectoryNames) const
virtual Status GetDirectoryEntries(const VfsPath& path, FileInfos* fileInfos, DirectoryNames* subdirectoryNames) const
{
ScopedLock s;
VfsDirectory* directory;
CHECK_ERR(vfs_Lookup(path, &m_rootDirectory, directory, 0));
WARN_RETURN_STATUS_IF_ERR(vfs_Lookup(path, &m_rootDirectory, directory, 0));
if(fileInfos)
{
@ -125,15 +125,15 @@ public:
return INFO::OK;
}
virtual LibError CreateFile(const VfsPath& pathname, const shared_ptr<u8>& fileContents, size_t size)
virtual Status CreateFile(const VfsPath& pathname, const shared_ptr<u8>& fileContents, size_t size)
{
ScopedLock s;
VfsDirectory* directory;
CHECK_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, 0, VFS_LOOKUP_ADD|VFS_LOOKUP_CREATE));
WARN_RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, 0, VFS_LOOKUP_ADD|VFS_LOOKUP_CREATE));
const PRealDirectory& realDirectory = directory->AssociatedDirectory();
const OsPath name = pathname.Filename();
RETURN_ERR(realDirectory->Store(name, fileContents, size));
RETURN_STATUS_IF_ERR(realDirectory->Store(name, fileContents, size));
// wipe out any cached blocks. this is necessary to cover the (rare) case
// of file cache contents predating the file write.
@ -146,7 +146,7 @@ public:
return INFO::OK;
}
virtual LibError LoadFile(const VfsPath& pathname, shared_ptr<u8>& fileContents, size_t& size)
virtual Status LoadFile(const VfsPath& pathname, shared_ptr<u8>& fileContents, size_t& size)
{
ScopedLock s;
const bool isCacheHit = m_fileCache.Retrieve(pathname, fileContents, size);
@ -156,7 +156,7 @@ public:
// per 2010-05-01 meeting, this shouldn't raise 'scary error
// dialogs', which might fail to display the culprit pathname
// instead, callers should log the error, including pathname.
RETURN_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file));
RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file));
size = file->Size();
// safely handle zero-length files
@ -164,13 +164,13 @@ public:
fileContents = DummySharedPtr((u8*)0);
else if(size > m_cacheSize)
{
RETURN_ERR(AllocateAligned(fileContents, size, maxSectorSize));
RETURN_ERR(file->Loader()->Load(file->Name(), fileContents, file->Size()));
RETURN_STATUS_IF_ERR(AllocateAligned(fileContents, size, maxSectorSize));
RETURN_STATUS_IF_ERR(file->Loader()->Load(file->Name(), fileContents, file->Size()));
}
else
{
fileContents = m_fileCache.Reserve(size);
RETURN_ERR(file->Loader()->Load(file->Name(), fileContents, file->Size()));
RETURN_STATUS_IF_ERR(file->Loader()->Load(file->Name(), fileContents, file->Size()));
m_fileCache.Add(pathname, fileContents, size);
}
}
@ -191,32 +191,32 @@ public:
return textRepresentation;
}
virtual LibError GetRealPath(const VfsPath& pathname, OsPath& realPathname)
virtual Status GetRealPath(const VfsPath& pathname, OsPath& realPathname)
{
ScopedLock s;
VfsDirectory* directory; VfsFile* file;
CHECK_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file));
WARN_RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file));
realPathname = file->Loader()->Path() / pathname.Filename();
return INFO::OK;
}
virtual LibError GetVirtualPath(const OsPath& realPathname, VfsPath& pathname)
virtual Status GetVirtualPath(const OsPath& realPathname, VfsPath& pathname)
{
ScopedLock s;
const OsPath realPath = realPathname.Parent()/"";
VfsPath path;
RETURN_ERR(FindRealPathR(realPath, m_rootDirectory, L"", path));
RETURN_STATUS_IF_ERR(FindRealPathR(realPath, m_rootDirectory, L"", path));
pathname = path / realPathname.Filename();
return INFO::OK;
}
virtual LibError Invalidate(const VfsPath& pathname)
virtual Status Invalidate(const VfsPath& pathname)
{
ScopedLock s;
m_fileCache.Remove(pathname);
VfsDirectory* directory;
RETURN_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, 0));
RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, 0));
const OsPath name = pathname.Filename();
directory->Invalidate(name);
@ -230,7 +230,7 @@ public:
}
private:
LibError FindRealPathR(const OsPath& realPath, const VfsDirectory& directory, const VfsPath& curPath, VfsPath& path)
Status FindRealPathR(const OsPath& realPath, const VfsDirectory& directory, const VfsPath& curPath, VfsPath& path)
{
PRealDirectory realDirectory = directory.AssociatedDirectory();
if(realDirectory && realDirectory->Path() == realPath)
@ -244,7 +244,7 @@ private:
{
const OsPath& subdirectoryName = it->first;
const VfsDirectory& subdirectory = it->second;
LibError ret = FindRealPathR(realPath, subdirectory, curPath / subdirectoryName/"", path);
Status ret = FindRealPathR(realPath, subdirectory, curPath / subdirectoryName/"", path);
if(ret == INFO::OK)
return INFO::OK;
}

View file

@ -33,9 +33,9 @@
namespace ERR
{
const LibError VFS_DIR_NOT_FOUND = -110100;
const LibError VFS_FILE_NOT_FOUND = -110101;
const LibError VFS_ALREADY_MOUNTED = -110102;
const Status VFS_DIR_NOT_FOUND = -110100;
const Status VFS_FILE_NOT_FOUND = -110101;
const Status VFS_ALREADY_MOUNTED = -110102;
}
// (recursive mounting and mounting archives are no longer optional since they don't hurt)
@ -73,7 +73,7 @@ struct IVFS
* @param path real directory path
* @param flags
* @param priority
* @return LibError.
* @return Status.
*
* if files are encountered that already exist in the VFS (sub)directories,
* the most recent / highest priority/precedence version is preferred.
@ -81,7 +81,7 @@ struct IVFS
* if files with archive extensions are seen, their contents are added
* as well.
**/
virtual LibError Mount(const VfsPath& mountPoint, const OsPath& path, size_t flags = 0, size_t priority = 0) = 0;
virtual Status Mount(const VfsPath& mountPoint, const OsPath& path, size_t flags = 0, size_t priority = 0) = 0;
/**
* Retrieve information about a file (similar to POSIX stat).
@ -90,9 +90,9 @@ struct IVFS
* @param pfileInfo receives information about the file. Passing NULL
* suppresses warnings if the file doesn't exist.
*
* @return LibError.
* @return Status.
**/
virtual LibError GetFileInfo(const VfsPath& pathname, FileInfo* pfileInfo) const = 0;
virtual Status GetFileInfo(const VfsPath& pathname, FileInfo* pfileInfo) const = 0;
/**
* Retrieve mount priority for a file.
@ -100,14 +100,14 @@ struct IVFS
* @param pathname
* @param ppriority receives priority value, if the file can be found.
*
* @return LibError.
* @return Status.
**/
virtual LibError GetFilePriority(const VfsPath& pathname, size_t* ppriority) const = 0;
virtual Status GetFilePriority(const VfsPath& pathname, size_t* ppriority) const = 0;
/**
* Retrieve lists of all files and subdirectories in a directory.
*
* @return LibError.
* @return Status.
*
* Rationale:
* - this interface avoids having to lock the directory while an
@ -115,19 +115,19 @@ struct IVFS
* - we cannot efficiently provide routines for returning files and
* subdirectories separately due to the underlying POSIX interface.
**/
virtual LibError GetDirectoryEntries(const VfsPath& path, FileInfos* fileInfos, DirectoryNames* subdirectoryNames) const = 0;
virtual Status GetDirectoryEntries(const VfsPath& path, FileInfos* fileInfos, DirectoryNames* subdirectoryNames) const = 0;
/**
* Create a file with the given contents.
* @param pathname
* @param fileContents
* @param size [bytes] of the contents, will match that of the file.
* @return LibError.
* @return Status.
*
* rationale: disallowing partial writes simplifies file cache coherency
* (we need only invalidate cached data when closing a newly written file).
**/
virtual LibError CreateFile(const VfsPath& pathname, const shared_ptr<u8>& fileContents, size_t size) = 0;
virtual Status CreateFile(const VfsPath& pathname, const shared_ptr<u8>& fileContents, size_t size) = 0;
/**
* Read an entire file into memory.
@ -139,9 +139,9 @@ struct IVFS
* provision for Copy-on-Write, which means that such buffers
* must not be modified (this is enforced via mprotect).
* @param size receives the size [bytes] of the file contents.
* @return LibError.
* @return Status.
**/
virtual LibError LoadFile(const VfsPath& pathname, shared_ptr<u8>& fileContents, size_t& size) = 0;
virtual Status LoadFile(const VfsPath& pathname, shared_ptr<u8>& fileContents, size_t& size) = 0;
/**
* @return a string representation of all files and directories.
@ -153,7 +153,7 @@ struct IVFS
*
* this is useful for passing paths to external libraries.
**/
virtual LibError GetRealPath(const VfsPath& pathname, OsPath& realPathname) = 0;
virtual Status GetRealPath(const VfsPath& pathname, OsPath& realPathname) = 0;
/**
* retrieve the VFS pathname that corresponds to a real file.
@ -164,13 +164,13 @@ struct IVFS
* number of directories; this could be accelerated by only checking
* directories below a mount point with a matching real path.
**/
virtual LibError GetVirtualPath(const OsPath& realPathname, VfsPath& pathname) = 0;
virtual Status GetVirtualPath(const OsPath& realPathname, VfsPath& pathname) = 0;
/**
* indicate that a file has changed; remove its data from the cache and
* arrange for its directory to be updated.
**/
virtual LibError Invalidate(const VfsPath& pathname) = 0;
virtual Status Invalidate(const VfsPath& pathname) = 0;
/**
* empty the contents of the filesystem.

View file

@ -37,7 +37,7 @@
#include "lib/timer.h"
static LibError CreateDirectory(const OsPath& path)
static Status CreateDirectory(const OsPath& path)
{
{
const mode_t mode = S_IRWXU; // 0700 as prescribed by XDG basedir
@ -64,11 +64,11 @@ static LibError CreateDirectory(const OsPath& path)
// unexpected failure
debug_printf(L"wmkdir failed with errno=%d\n", errno);
ENSURE(0);
return LibError_from_errno();
WARN_RETURN(StatusFromErrno());
}
LibError vfs_Lookup(const VfsPath& pathname, VfsDirectory* startDirectory, VfsDirectory*& directory, VfsFile** pfile, size_t flags)
Status vfs_Lookup(const VfsPath& pathname, VfsDirectory* startDirectory, VfsDirectory*& directory, VfsFile** pfile, size_t flags)
{
// extract and validate flags (ensure no unknown bits are set)
const bool addMissingDirectories = (flags & VFS_LOOKUP_ADD) != 0;
@ -81,7 +81,7 @@ LibError vfs_Lookup(const VfsPath& pathname, VfsDirectory* startDirectory, VfsDi
*pfile = 0;
if(!skipPopulate)
RETURN_ERR(vfs_Populate(directory));
RETURN_STATUS_IF_ERR(vfs_Populate(directory));
// early-out for pathname == "" when mounting into VFS root
if(pathname.empty()) // (prevent iterator error in loop end condition)
@ -118,14 +118,14 @@ LibError vfs_Lookup(const VfsPath& pathname, VfsDirectory* startDirectory, VfsDi
currentPath = directory->AssociatedDirectory()->Path();
currentPath = currentPath / subdirectoryName;
RETURN_ERR(CreateDirectory(currentPath));
RETURN_STATUS_IF_ERR(CreateDirectory(currentPath));
PRealDirectory realDirectory(new RealDirectory(currentPath, 0, 0));
RETURN_ERR(vfs_Attach(subdirectory, realDirectory));
RETURN_STATUS_IF_ERR(vfs_Attach(subdirectory, realDirectory));
}
if(!skipPopulate)
RETURN_ERR(vfs_Populate(subdirectory));
RETURN_STATUS_IF_ERR(vfs_Populate(subdirectory));
directory = subdirectory;
}

View file

@ -61,10 +61,10 @@ enum VfsLookupFlags
* @param pfile File is set to 0 if there is no name component, otherwise the
* corresponding file.
* @param flags @see VfsLookupFlags.
* @return LibError (INFO::OK if all components in pathname exist).
* @return Status (INFO::OK if all components in pathname exist).
*
* to allow noiseless file-existence queries, this does not raise warnings.
**/
extern LibError vfs_Lookup(const VfsPath& pathname, VfsDirectory* startDirectory, VfsDirectory*& directory, VfsFile** pfile, size_t flags = 0);
extern Status vfs_Lookup(const VfsPath& pathname, VfsDirectory* startDirectory, VfsDirectory*& directory, VfsFile** pfile, size_t flags = 0);
#endif // #ifndef INCLUDED_VFS_LOOKUP

View file

@ -50,7 +50,7 @@ public:
{
}
LibError AddEntries() const
Status AddEntries() const
{
#if ENABLE_ARCHIVE_STATS
s_looseFiles.reserve(10000);
@ -58,9 +58,9 @@ public:
FileInfos files; files.reserve(500);
DirectoryNames subdirectoryNames; subdirectoryNames.reserve(50);
RETURN_ERR(GetDirectoryEntries(m_realDirectory->Path(), &files, &subdirectoryNames));
RETURN_STATUS_IF_ERR(GetDirectoryEntries(m_realDirectory->Path(), &files, &subdirectoryNames));
RETURN_ERR(AddFiles(files));
RETURN_STATUS_IF_ERR(AddFiles(files));
AddSubdirectories(subdirectoryNames);
return INFO::OK;
@ -93,7 +93,7 @@ private:
// don't always place directory entries before their files)
const size_t flags = VFS_LOOKUP_ADD|VFS_LOOKUP_SKIP_POPULATE;
VfsDirectory* directory;
WARN_ERR(vfs_Lookup(pathname, this_->m_directory, directory, 0, flags));
WARN_IF_ERR(vfs_Lookup(pathname, this_->m_directory, directory, 0, flags));
const VfsFile file(fileInfo.Name(), (size_t)fileInfo.Size(), fileInfo.MTime(), this_->m_realDirectory->Priority(), archiveFile);
directory->AddFile(file);
#if ENABLE_ARCHIVE_STATS
@ -101,7 +101,7 @@ private:
#endif
}
LibError AddFiles(const FileInfos& files) const
Status AddFiles(const FileInfos& files) const
{
const OsPath path(m_realDirectory->Path());
@ -111,7 +111,7 @@ private:
if(pathname.Extension() == L".zip")
{
PIArchiveReader archiveReader = CreateArchiveReader_Zip(pathname);
RETURN_ERR(archiveReader->ReadEntries(AddArchiveFile, (uintptr_t)this));
RETURN_STATUS_IF_ERR(archiveReader->ReadEntries(AddArchiveFile, (uintptr_t)this));
}
else // regular (non-archive) file
AddFile(files[i]);
@ -140,7 +140,7 @@ private:
};
LibError vfs_Populate(VfsDirectory* directory)
Status vfs_Populate(VfsDirectory* directory)
{
if(!directory->ShouldPopulate())
return INFO::OK;
@ -151,15 +151,15 @@ LibError vfs_Populate(VfsDirectory* directory)
realDirectory->Watch();
PopulateHelper helper(directory, realDirectory);
RETURN_ERR(helper.AddEntries());
RETURN_STATUS_IF_ERR(helper.AddEntries());
return INFO::OK;
}
LibError vfs_Attach(VfsDirectory* directory, const PRealDirectory& realDirectory)
Status vfs_Attach(VfsDirectory* directory, const PRealDirectory& realDirectory)
{
RETURN_ERR(vfs_Populate(directory));
RETURN_STATUS_IF_ERR(vfs_Populate(directory));
directory->SetAssociatedDirectory(realDirectory);
return INFO::OK;
}

View file

@ -42,7 +42,7 @@ class VfsDirectory;
* note: the most recently attached real directory will be used when
* creating files in the VFS directory.
**/
extern LibError vfs_Attach(VfsDirectory* directory, const PRealDirectory& realDirectory);
extern Status vfs_Attach(VfsDirectory* directory, const PRealDirectory& realDirectory);
/**
* populate the directory from the attached real directory.
@ -52,6 +52,6 @@ extern LibError vfs_Attach(VfsDirectory* directory, const PRealDirectory& realDi
*
* has no effect if no directory has been attached since the last populate.
**/
extern LibError vfs_Populate(VfsDirectory* directory);
extern Status vfs_Populate(VfsDirectory* directory);
#endif // #ifndef INCLUDED_VFS_POPULATE

View file

@ -41,7 +41,7 @@ void in_add_handler(InHandler handler)
ENSURE(handler);
if(handler_stack_top >= MAX_HANDLERS)
WARN_ERR_RETURN(ERR::LIMIT);
WARN_IF_ERR(ERR::LIMIT);
handler_stack[handler_stack_top++] = handler;
}

View file

@ -20,6 +20,9 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDED_LIB_API
#define INCLUDED_LIB_API
#include "lib/sysdep/compiler.h"
// note: EXTERN_C cannot be used because shared_ptr is often returned
@ -49,3 +52,5 @@
# error "Don't know how to define LIB_API for this compiler"
# endif
#endif
#endif // #ifndef INCLUDED_LIB_API

View file

@ -1,197 +0,0 @@
/* Copyright (c) 2010 Wildfire Games
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* error handling system: defines error codes, associates them with
* descriptive text, simplifies error notification.
*/
// note: this is called lib_errors.cpp because we have another
// errors.cpp; the MS linker isn't smart enough to deal with
// object files of the same name but in different paths.
#include "precompiled.h"
#include "lib/lib_errors.h"
#include <cstring>
#include <cstdlib> // abs
#include <cstdio>
#include <map>
#include "lib/posix/posix_errno.h"
#include "lib/sysdep/sysdep.h"
// linked list (most recent first)
// note: no memory is allocated, all nodes are static instances.
//
// rationale: don't use a std::map. we don't care about lookup speed,
// dynamic allocation would be ugly, and returning a local static object
// from a function doesn't work, either (the compiler generates calls to
// atexit, which leads to disaster since we're sometimes called by
// winit functions before the CRT has initialized)
static LibErrorAssociation* associations;
int error_AddAssociation(LibErrorAssociation* lea)
{
// insert at front of list
lea->next = associations;
associations = lea;
return 0; // stored in dummy variable
}
static const LibErrorAssociation* AssociationFromLibError(LibError err)
{
for(const LibErrorAssociation* lea = associations; lea; lea = lea->next)
{
if(lea->err == err)
return lea;
}
return 0;
}
static const LibErrorAssociation* AssociationFromErrno(int errno_equivalent)
{
for(const LibErrorAssociation* lea = associations; lea; lea = lea->next)
{
if(lea->errno_equivalent == errno_equivalent)
return lea;
}
return 0;
}
wchar_t* error_description_r(LibError err, wchar_t* buf, size_t max_chars)
{
// lib error
const LibErrorAssociation* lea = AssociationFromLibError(err);
if(lea)
{
wcscpy_s(buf, max_chars, lea->description);
return buf;
}
// unknown
swprintf_s(buf, max_chars, L"Unknown error (%d, 0x%X)", (int)err, (unsigned int)err);
return buf;
}
LibError LibError_from_errno(bool warn_if_failed)
{
LibError ret = ERR::FAIL;
const LibErrorAssociation* lea = AssociationFromErrno(errno);
if(lea)
ret = lea->err;
if(warn_if_failed)
DEBUG_WARN_ERR(ret);
return ret;
}
LibError LibError_from_posix(int ret, bool warn_if_failed)
{
ENSURE(ret == 0 || ret == -1);
if(ret == 0)
return INFO::OK;
return LibError_from_errno(warn_if_failed);
}
// return the errno.h equivalent of <err>.
// does not assign to errno (this simplifies code by allowing direct return)
static int return_errno_from_LibError(LibError err)
{
const LibErrorAssociation* lea = AssociationFromLibError(err);
if(lea && lea->errno_equivalent != -1)
return lea->errno_equivalent;
// somewhat of a quandary: the set of errnos in wposix.h doesn't
// have an "unknown error". we pick EPERM because we don't expect
// that to come up often otherwise.
return EPERM;
}
void LibError_set_errno(LibError err)
{
errno = return_errno_from_LibError(err);
}
//-----------------------------------------------------------------------------
// INFO::OK doesn't really need a string because calling error_description_r(0) should never happen, but go the safe route.
ERROR_ASSOCIATE(INFO::OK, L"(but return value was 0 which indicates success)", -1);
ERROR_ASSOCIATE(ERR::FAIL, L"Function failed (no details available)", -1);
ERROR_ASSOCIATE(INFO::CB_CONTINUE, L"Continue (not an error)", -1);
ERROR_ASSOCIATE(INFO::SKIPPED, L"Skipped (not an error)", -1);
ERROR_ASSOCIATE(INFO::CANNOT_HANDLE, L"Cannot handle (not an error)", -1);
ERROR_ASSOCIATE(INFO::ALL_COMPLETE, L"All complete (not an error)", -1);
ERROR_ASSOCIATE(INFO::ALREADY_EXISTS, L"Already exists (not an error)", -1);
ERROR_ASSOCIATE(ERR::LOGIC, L"Logic error in code", -1);
ERROR_ASSOCIATE(ERR::TIMED_OUT, L"Timed out", -1);
ERROR_ASSOCIATE(ERR::REENTERED, L"Single-call function was reentered", -1);
ERROR_ASSOCIATE(ERR::CORRUPTED, L"File/memory data is corrupted", -1);
ERROR_ASSOCIATE(ERR::INVALID_PARAM, L"Invalid function argument", EINVAL);
ERROR_ASSOCIATE(ERR::INVALID_HANDLE, L"Invalid Handle (argument)", -1);
ERROR_ASSOCIATE(ERR::BUF_SIZE, L"Buffer argument too small", -1);
ERROR_ASSOCIATE(ERR::AGAIN, L"Try again later", -1);
ERROR_ASSOCIATE(ERR::LIMIT, L"Fixed limit exceeded", -1);
ERROR_ASSOCIATE(ERR::NO_SYS, L"OS doesn't provide a required API", -1);
ERROR_ASSOCIATE(ERR::NOT_IMPLEMENTED, L"Feature currently not implemented", ENOSYS);
ERROR_ASSOCIATE(ERR::NOT_SUPPORTED, L"Feature isn't and won't be supported", -1);
ERROR_ASSOCIATE(ERR::NO_MEM, L"Not enough memory", ENOMEM);
ERROR_ASSOCIATE(ERR::_1, L"Case 1", -1);
ERROR_ASSOCIATE(ERR::_2, L"Case 2", -1);
ERROR_ASSOCIATE(ERR::_3, L"Case 3", -1);
ERROR_ASSOCIATE(ERR::_4, L"Case 4", -1);
ERROR_ASSOCIATE(ERR::_5, L"Case 5", -1);
ERROR_ASSOCIATE(ERR::_6, L"Case 6", -1);
ERROR_ASSOCIATE(ERR::_7, L"Case 7", -1);
ERROR_ASSOCIATE(ERR::_8, L"Case 8", -1);
ERROR_ASSOCIATE(ERR::_9, L"Case 9", -1);
ERROR_ASSOCIATE(ERR::_11, L"Case 11", -1);
ERROR_ASSOCIATE(ERR::_12, L"Case 12", -1);
ERROR_ASSOCIATE(ERR::_13, L"Case 13", -1);
ERROR_ASSOCIATE(ERR::_14, L"Case 14", -1);
ERROR_ASSOCIATE(ERR::_15, L"Case 15", -1);
ERROR_ASSOCIATE(ERR::_16, L"Case 16", -1);
ERROR_ASSOCIATE(ERR::_17, L"Case 17", -1);
ERROR_ASSOCIATE(ERR::_18, L"Case 18", -1);
ERROR_ASSOCIATE(ERR::_19, L"Case 19", -1);
ERROR_ASSOCIATE(ERR::_21, L"Case 21", -1);
ERROR_ASSOCIATE(ERR::_22, L"Case 22", -1);
ERROR_ASSOCIATE(ERR::_23, L"Case 23", -1);
ERROR_ASSOCIATE(ERR::_24, L"Case 24", -1);
ERROR_ASSOCIATE(ERR::_25, L"Case 25", -1);
ERROR_ASSOCIATE(ERR::_26, L"Case 26", -1);
ERROR_ASSOCIATE(ERR::_27, L"Case 27", -1);
ERROR_ASSOCIATE(ERR::_28, L"Case 28", -1);
ERROR_ASSOCIATE(ERR::_29, L"Case 29", -1);

View file

@ -1,496 +0,0 @@
/* Copyright (c) 2010 Wildfire Games
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* error handling system: defines error codes, associates them with
* descriptive text, simplifies error notification.
*/
/**
Error handling system
Introduction
------------
This module defines error codes, translates them to/from other systems
(e.g. errno), provides several macros that simplify returning errors /
checking if a function failed, and associates codes with descriptive text.
Why Error Codes?
----------------
To convey information about what failed, the alternatives are unique
integral codes and direct pointers to descriptive text. Both occupy the
same amount of space, but codes are easier to internationalize.
Method of Propagating Errors
----------------------------
When a low-level function has failed, this must be conveyed to the
higher-level application logic across several functions on the call stack.
There are two alternatives:
1) check at each call site whether a function failed;
if so, return to the caller.
2) throw an exception.
We will discuss the advantages and disadvantages of exceptions,
which mirror those of call site checking.
- performance: they shouldn't be used in time-critical code.
- predictability: exceptions can come up almost anywhere,
so it is hard to say what execution path will be taken.
- interoperability: not compatible with other languages.
+ readability: cleans up code by separating application logic and
error handling. however, this is also a disadvantage because it
may be difficult to see at a glance if a piece of code does
error checking at all.
+ visibility: errors are more likely to be seen than relying on
callers to check return codes; less reliant on discipline.
Both have their place. Our recommendation is to throw error code
exceptions when checking call sites and propagating errors becomes tedious.
However, inter-module boundaries should always return error codes for
interoperability with other languages.
Simplifying Call-Site Checking
------------------------------
As mentioned above, this approach requires discipline. We provide
macros to simplify this task: function calls can be wrapped in an
"enforcer" that checks whether they succeeded and can take action
(e.g. returning to caller or warning user) as appropriate.
Consider the following example:
LibError ret = doWork();
if(ret != INFO::OK) { warnUser(ret); return ret; }
This can be replaced by:
CHECK_ERR(doWork());
This provides a visible sign that the code handles errors,
automatically propagates errors back to the caller, and most importantly,
allows warning the user whenever an error occurs.
Thus, no errors can be swept under the carpet by failing to
check return value or catch(...) all exceptions.
When to warn the user?
----------------------
When a function fails, there are 2 places we can raise a warning:
as soon as the error condition is known, or in the higher-level caller.
The former is the WARN_RETURN(ERR::FAIL) approach, while the latter
corresponds to the example above.
We prefer the former because it is easier to ensure that all
possible return paths have been covered: search for all "return ERR::*"
that are not followed by a "// NOWARN" comment. Also, the latter approach
raises the question of where exactly to issue the warning.
Clearly API-level routines must raise the warning, but sometimes they will
want to call each other. Multiple warnings along the call stack ensuing
from the same root cause are not nice.
Note the special case of "validator" functions that e.g. verify the
state of an object: we now discuss pros/cons of just returning errors
without warning, and having their callers take care of that.
+ they typically have many return paths (-> increased code size)
- this is balanced by validators that have many call sites.
- we want all return statements wrapped for consistency and
easily checking if any were forgotten
- adding // NOWARN to each validator return statement would be tedious.
- there is no advantage to checking at the call site; call stack indicates
which caller of the validator failed anyway.
Validator functions should therefore also use WARN_RETURN.
Numbering Scheme
----------------
Each module header defines its own error codes to avoid a full rebuild
whenever a new code is added.
Error codes start at -100000 (warnings are positive, but reserves a
negative value; absolute values are unique). This avoids collisions
with all known error code schemes.
Each header gets 100 possible values; the tens value may be
used to denote groups within that header.
The subsystem is denoted by the ten-thousands digit:
0 lib
1 file
2 res (resource management)
3 sysdep (system-dependent)
4 win (Windows-specific)
To summarize: +/-1SHHCC (S=subsystem, HH=header, CC=code number)
10 lib
00CC lib_errors
03CC path
04CC debug
05CC debug_stl
06CC secure_crt
07CC wchar
11 file
01CC vfs
03CC file
04CC archive
12 res
01CC tex
02CC ogl_shader
13 sysdep
00CC cpu
01CC os_cpu
14 win
00CC whrt
Notes:
- file is called lib_errors.h because 0ad has another errors.cpp and
the MS linker isn't smart enough to deal with object files
of the same name but in different paths.
**/
#ifndef INCLUDED_LIB_ERRORS
#define INCLUDED_LIB_ERRORS
#include "lib/code_annotation.h"
#include "lib/code_generation.h"
// note: this loses compiler type safety (being able to prevent
// return 1 when a LibError is the return value), but allows splitting
// up the error namespace into separate headers.
// Lint's 'strong type' checking can be used to find errors.
typedef long LibError;
// opaque - do not access its fields!
// note: must be defined here because clients instantiate them;
// fields cannot be made private due to POD requirement.
struct LibErrorAssociation
{
LibError err;
// must remain valid until end of program.
const wchar_t* description;
// POSIX errno, or -1
int errno_equivalent;
LibErrorAssociation* next;
};
/**
* associate a LibError with a description and errno equivalent.
* @return dummy integer to allow calling via static initializer.
**/
extern int error_AddAssociation(LibErrorAssociation*);
// associate a LibError with a description and errno equivalent.
// Invoke this at file or function scope.
#define ERROR_ASSOCIATE(err, description, errno_equivalent)\
static LibErrorAssociation UID__ = { err, description, errno_equivalent, NULL };\
static int UID2__ = error_AddAssociation(&UID__)
/**
* generate textual description of an error code.
*
* @param err LibError to be translated. if despite type checking we
* get an invalid enum value, the string will be something like
* "Unknown error (65536, 0x10000)".
* @param buf destination buffer
* @param max_chars size of buffer [characters]
* @return buf (allows using this function in expressions)
**/
LIB_API wchar_t* error_description_r(LibError err, wchar_t* buf, size_t max_chars);
//-----------------------------------------------------------------------------
// conversion to/from other error code definitions.
// note: other conversion routines (e.g. to/from Win32) are implemented in
// the corresponding modules to keep this header portable.
/**
* translate errno to LibError.
*
* should only be called directly after a POSIX function indicates failure;
* errno may otherwise still be set from another error cause.
*
* @param warn_if_failed if set, raise a warning when returning an error
* (i.e. ERR::*, but not INFO::OK). this avoids having to wrap all
* call sites in WARN_ERR etc.
* @return LibError equivalent of errno, or ERR::FAIL if there's no equal.
**/
extern LibError LibError_from_errno(bool warn_if_failed = true);
/**
* translate a POSIX function's return/error indication to LibError.
*
* you should set errno to 0 before calling the POSIX function to
* make sure we do not return any stale errors. typical usage:
* errno = 0;
* int ret = posix_func(..);
* return LibError_from_posix(ret);
*
* @param ret return value of a POSIX function: 0 indicates success,
* -1 is error.
* @param warn_if_failed if set, raise a warning when returning an error
* (i.e. ERR::*, but not INFO::OK). this avoids having to wrap all
* call sites in WARN_ERR etc.
* @return INFO::OK if the POSIX function succeeded, else the LibError
* equivalent of errno, or ERR::FAIL if there's no equal.
**/
extern LibError LibError_from_posix(int ret, bool warn_if_failed = true);
/**
* set errno to the equivalent of a LibError.
*
* used in wposix - underlying functions return LibError but must be
* translated to errno at e.g. the mmap interface level. higher-level code
* that calls mmap will in turn convert back to LibError.
*
* @param err error code to set
**/
extern void LibError_set_errno(LibError err);
//-----------------------------------------------------------------------------
// be careful here. the given expression (e.g. variable or
// function return value) may be a Handle (=i64), so it needs to be
// stored and compared as such. (very large but legitimate Handle values
// casted to int can end up negative)
// all functions using this return LibError (instead of i64) for
// efficiency and simplicity. if the input was negative, it is an
// error code and is therefore known to fit; we still mask with
// UINT_MAX to avoid VC cast-to-smaller-type warnings.
// if expression evaluates to a negative error code, warn user and
// return the number.
#define CHECK_ERR(expression)\
STMT(\
i64 err64__ = (i64)(expression);\
if(err64__ < 0)\
{\
LibError err__ = (LibError)(err64__ & ULONG_MAX);\
DEBUG_WARN_ERR(err__);\
return (LibError)(err__ & ULONG_MAX);\
}\
)
// just pass on errors without any kind of annoying warning
// (useful for functions that can legitimately fail).
#define RETURN_ERR(expression)\
STMT(\
i64 err64__ = (i64)(expression);\
if(err64__ < 0)\
{\
LibError err__ = (LibError)(err64__ & ULONG_MAX);\
return err__;\
}\
)
// if expression evaluates to a negative error code, return 0.
#define RETURN_IF_NOT_CONTINUE(expression)\
STMT(\
i64 err64__ = (i64)(expression);\
if(err64__ != INFO::CB_CONTINUE)\
return err64__;\
)
// return an error and warn about it (replaces debug_warn+return)
#define WARN_RETURN(err)\
STMT(\
DEBUG_WARN_ERR(err);\
return err;\
)
// if expression evaluates to a negative error code, warn user and
// throw that number.
#define THROW_ERR(expression)\
STMT(\
i64 err64__ = (i64)(expression);\
if(err64__ < 0)\
{\
LibError err__ = (LibError)(err64__ & ULONG_MAX);\
DEBUG_WARN_ERR(err__);\
throw err__;\
}\
)
// if expression evaluates to a negative error code, warn user and just return
// (useful for void functions that must bail and complain)
#define WARN_ERR_RETURN(expression)\
STMT(\
i64 err64__ = (i64)(expression);\
if(err64__ < 0)\
{\
LibError err__ = (LibError)(err64__ & ULONG_MAX);\
DEBUG_WARN_ERR(err__);\
return;\
}\
)
// if expression evaluates to a negative error code, warn user
// (this is similar to ENSURE but also works in release mode)
#define WARN_ERR(expression)\
STMT(\
i64 err64__ = (i64)(expression);\
if(err64__ < 0)\
{\
LibError err__ = (LibError)(err64__ & ULONG_MAX);\
DEBUG_WARN_ERR(err__);\
}\
)
// if expression evaluates to a negative error code, return 0.
#define RETURN0_IF_ERR(expression)\
STMT(\
i64 err64__ = (i64)(expression);\
if(err64__ < 0)\
return 0;\
)
// if ok evaluates to false or FALSE, warn user and return -1.
#define WARN_RETURN_IF_FALSE(ok)\
STMT(\
if(!(ok))\
{\
debug_warn(L"FYI: WARN_RETURN_IF_FALSE reports that a function failed. "\
L"Feel free to ignore or suppress this warning.");\
return ERR::FAIL;\
}\
)
// if ok evaluates to false or FALSE, return -1.
#define RETURN_IF_FALSE(ok)\
STMT(\
if(!(ok))\
return ERR::FAIL;\
)
// if ok evaluates to false or FALSE, warn user.
#define WARN_IF_FALSE(ok)\
STMT(\
if(!(ok))\
debug_warn(L"FYI: WARN_IF_FALSE reports that a function failed. "\
L"Feel free to ignore or suppress this warning.");\
)
//-----------------------------------------------------------------------------
namespace INFO
{
const LibError OK = 0;
// note: these values are > 100 to allow multiplexing them with
// coroutine return values, which return completion percentage.
// function is a callback and indicates that it can (but need not
// necessarily) be called again.
const LibError CB_CONTINUE = +100000;
// notify caller that nothing was done.
const LibError SKIPPED = +100001;
// function is incapable of doing the requested task with the given inputs.
// this implies SKIPPED, but also conveys a bit more information.
const LibError CANNOT_HANDLE = +100002;
// function is meant to be called repeatedly, and now indicates that
// all jobs are complete.
const LibError ALL_COMPLETE = +100003;
// (returned e.g. when inserting into container)
const LibError ALREADY_EXISTS = +100004;
}
namespace ERR
{
const LibError FAIL = -1;
// general
const LibError LOGIC = -100010;
const LibError TIMED_OUT = -100011;
const LibError REENTERED = -100012;
const LibError CORRUPTED = -100013;
const LibError VERSION = -100014;
// function arguments
const LibError INVALID_PARAM = -100020;
const LibError INVALID_HANDLE = -100021;
const LibError BUF_SIZE = -100022;
// system limitations
const LibError AGAIN = -100030;
const LibError LIMIT = -100031;
const LibError NO_SYS = -100032;
const LibError NOT_IMPLEMENTED = -100033;
const LibError NOT_SUPPORTED = -100034;
const LibError NO_MEM = -100035;
// these are for cases where we just want a distinct value to display and
// a symbolic name + string would be overkill (e.g. the various
// test cases in a validate() call). they are shared between multiple
// functions; when something fails, the stack trace will show in which
// one it was => these errors are unambiguous.
// there are 3 tiers - 1..9 are used in most functions, 11..19 are
// used in a function that calls another validator and 21..29 are
// for for functions that call 2 other validators (this avoids
// ambiguity as to which error actually happened where)
const LibError _1 = -100101;
const LibError _2 = -100102;
const LibError _3 = -100103;
const LibError _4 = -100104;
const LibError _5 = -100105;
const LibError _6 = -100106;
const LibError _7 = -100107;
const LibError _8 = -100108;
const LibError _9 = -100109;
const LibError _11 = -100111;
const LibError _12 = -100112;
const LibError _13 = -100113;
const LibError _14 = -100114;
const LibError _15 = -100115;
const LibError _16 = -100116;
const LibError _17 = -100117;
const LibError _18 = -100118;
const LibError _19 = -100119;
const LibError _21 = -100121;
const LibError _22 = -100122;
const LibError _23 = -100123;
const LibError _24 = -100124;
const LibError _25 = -100125;
const LibError _26 = -100126;
const LibError _27 = -100127;
const LibError _28 = -100128;
const LibError _29 = -100129;
} // namespace ERR
#endif // #ifndef INCLUDED_LIB_ERRORS

View file

@ -37,13 +37,13 @@ static const ModuleInitState BUSY = INFO::ALREADY_EXISTS; // never returned
static const ModuleInitState INITIALIZED = INFO::SKIPPED;
LibError ModuleInit(volatile ModuleInitState* initState, LibError (*init)())
Status ModuleInit(volatile ModuleInitState* initState, Status (*init)())
{
for(;;)
{
if(cpu_CAS(initState, UNINITIALIZED, BUSY))
{
LibError ret = init();
Status ret = init();
*initState = (ret == INFO::OK)? INITIALIZED : ret;
COMPILER_FENCE;
return ret;
@ -57,12 +57,12 @@ LibError ModuleInit(volatile ModuleInitState* initState, LibError (*init)())
}
ENSURE(latchedInitState == INITIALIZED || latchedInitState < 0);
return (LibError)latchedInitState;
return (Status)latchedInitState;
}
}
LibError ModuleShutdown(volatile ModuleInitState* initState, void (*shutdown)())
Status ModuleShutdown(volatile ModuleInitState* initState, void (*shutdown)())
{
for(;;)
{
@ -85,6 +85,6 @@ LibError ModuleShutdown(volatile ModuleInitState* initState, void (*shutdown)())
return INFO::SKIPPED;
ENSURE(latchedInitState < 0);
return (LibError)latchedInitState;
return (Status)latchedInitState;
}
}

View file

@ -37,11 +37,11 @@ typedef intptr_t ModuleInitState; // intptr_t is required by cpu_CAS
/**
* calls a user-defined init function if initState is zero.
*
* @return INFO::SKIPPED if already initialized, a LibError if the
* @return INFO::SKIPPED if already initialized, a Status if the
* previous invocation failed, or the value returned by the callback.
*
* postcondition: initState is "initialized" if the callback returned
* INFO::OK, otherwise its LibError return value (which prevents
* INFO::OK, otherwise its Status return value (which prevents
* shutdown from being called).
*
* thread-safe: subsequent callers spin until the callback returns
@ -50,15 +50,15 @@ typedef intptr_t ModuleInitState; // intptr_t is required by cpu_CAS
* note that callbacks typically reference static data and thus do not
* require a function argument, but that can later be added if necessary.
**/
LIB_API LibError ModuleInit(volatile ModuleInitState* initState, LibError (*init)());
LIB_API Status ModuleInit(volatile ModuleInitState* initState, Status (*init)());
/**
* calls a user-defined shutdown function if initState is "initialized".
*
* @return INFO::OK if shutdown occurred, INFO::SKIPPED if initState was
* zero (uninitialized), otherwise the LibError returned by ModuleInit.
* zero (uninitialized), otherwise the Status returned by ModuleInit.
*
* postcondition: initState remains set to the LibError, or has been
* postcondition: initState remains set to the Status, or has been
* reset to zero to allow multiple init/shutdown pairs, e.g. in self-tests.
*
* note: there is no provision for reference-counting because that
@ -69,6 +69,6 @@ LIB_API LibError ModuleInit(volatile ModuleInitState* initState, LibError (*init
* cleanup is necessary (e.g. at exit before leak reporting) and
* it is certain that the module is no longer in use.
**/
LIB_API LibError ModuleShutdown(volatile ModuleInitState* initState, void (*shutdown)());
LIB_API Status ModuleShutdown(volatile ModuleInitState* initState, void (*shutdown)());
#endif // #ifndef INCLUDED_MODULE_INIT

View file

@ -448,7 +448,7 @@ GLint ogl_max_tex_units = -1; // limit on GL_TEXTUREn
//
// fails if OpenGL not ready for use.
// gfx_card and gfx_drv_ver are unchanged on failure.
LibError ogl_get_gfx_info()
Status ogl_get_gfx_info()
{
const char* vendor = (const char*)glGetString(GL_VENDOR);
const char* renderer = (const char*)glGetString(GL_RENDERER);

View file

@ -147,8 +147,8 @@ extern GLint ogl_max_tex_units; /// limit on GL_TEXTUREn
* fails if OpenGL not ready for use.
* gfx_card and gfx_drv_ver are unchanged on failure.
*
* @return LibError
* @return Status
**/
extern LibError ogl_get_gfx_info();
extern Status ogl_get_gfx_info();
#endif // #ifndef INCLUDED_OGL

View file

@ -30,9 +30,9 @@
#include <cstring>
#include <cerrno>
ERROR_ASSOCIATE(ERR::PATH_CHARACTER_ILLEGAL, L"illegal path character", -1);
ERROR_ASSOCIATE(ERR::PATH_CHARACTER_UNSAFE, L"unsafe path character", -1);
ERROR_ASSOCIATE(ERR::PATH_NOT_FOUND, L"path not found", -1);
STATUS_DEFINE(ERR, PATH_CHARACTER_ILLEGAL, L"illegal path character", -1);
STATUS_DEFINE(ERR, PATH_CHARACTER_UNSAFE, L"unsafe path character", -1);
STATUS_DEFINE(ERR, PATH_NOT_FOUND, L"path not found", -1);
static bool path_is_dir_sep(wchar_t c)
@ -92,7 +92,7 @@ const wchar_t* path_name_only(const wchar_t* path)
}
/*static*/ LibError Path::Validate(String::value_type c)
/*static*/ Status Path::Validate(String::value_type c)
{
if(c < 32)
return ERR::PATH_CHARACTER_UNSAFE;

View file

@ -45,9 +45,9 @@
namespace ERR
{
const LibError PATH_CHARACTER_ILLEGAL = -100300;
const LibError PATH_CHARACTER_UNSAFE = -100301;
const LibError PATH_NOT_FOUND = -100302;
const Status PATH_CHARACTER_ILLEGAL = -100300;
const Status PATH_CHARACTER_UNSAFE = -100301;
const Status PATH_NOT_FOUND = -100302;
}
/**
@ -179,7 +179,7 @@ public:
return ret;
}
static LibError Validate(String::value_type c);
static Status Validate(String::value_type c);
private:
String path;

View file

@ -0,0 +1,146 @@
#ifndef INCLUDED_POINTER_TYPEDEFS
#define INCLUDED_POINTER_TYPEDEFS
// convenience typedefs for shortening parameter lists.
// naming convention: [const] [restrict] pointer to [const] type
// supported types: void, signed/unsigned 8/16/32/64 integers, float, double, XMM
// NB: `restrict' is not going into C++0x, so use __restrict to maintain compatibility
// with VC2010.
typedef void* pVoid;
typedef void* const cpVoid;
typedef void* __restrict rpVoid;
typedef void* const __restrict crpVoid;
typedef const void* pcVoid;
typedef const void* const cpcVoid;
typedef const void* __restrict rpcVoid;
typedef const void* const __restrict crpcVoid;
typedef int8_t* pI8;
typedef int8_t* const cpI8;
typedef int8_t* __restrict rpI8;
typedef int8_t* const __restrict crpI8;
typedef const int8_t* pcI8;
typedef const int8_t* const cpcI8;
typedef const int8_t* __restrict rpcI8;
typedef const int8_t* const __restrict crpcI8;
typedef int16_t* pI16;
typedef int16_t* const cpI16;
typedef int16_t* __restrict rpI16;
typedef int16_t* const __restrict crpI16;
typedef const int16_t* pcI16;
typedef const int16_t* const cpcI16;
typedef const int16_t* __restrict rpcI16;
typedef const int16_t* const __restrict crpcI16;
typedef int32_t* pI32;
typedef int32_t* const cpI32;
typedef int32_t* __restrict rpI32;
typedef int32_t* const __restrict crpI32;
typedef const int32_t* pcI32;
typedef const int32_t* const cpcI32;
typedef const int32_t* __restrict rpcI32;
typedef const int32_t* const __restrict crpcI32;
typedef int64_t* pI64;
typedef int64_t* const cpI64;
typedef int64_t* __restrict rpI64;
typedef int64_t* const __restrict crpI64;
typedef const int64_t* pcI64;
typedef const int64_t* const cpcI64;
typedef const int64_t* __restrict rpcI64;
typedef const int64_t* const __restrict crpcI64;
typedef uint8_t* pU8;
typedef uint8_t* const cpU8;
typedef uint8_t* __restrict rpU8;
typedef uint8_t* const __restrict crpU8;
typedef const uint8_t* pcU8;
typedef const uint8_t* const cpcU8;
typedef const uint8_t* __restrict rpcU8;
typedef const uint8_t* const __restrict crpcU8;
typedef uint16_t* pU16;
typedef uint16_t* const cpU16;
typedef uint16_t* __restrict rpU16;
typedef uint16_t* const __restrict crpU16;
typedef const uint16_t* pcU16;
typedef const uint16_t* const cpcU16;
typedef const uint16_t* __restrict rpcU16;
typedef const uint16_t* const __restrict crpcU16;
typedef uint32_t* pU32;
typedef uint32_t* const cpU32;
typedef uint32_t* __restrict rpU32;
typedef uint32_t* const __restrict crpU32;
typedef const uint32_t* pcU32;
typedef const uint32_t* const cpcU32;
typedef const uint32_t* __restrict rpcU32;
typedef const uint32_t* const __restrict crpcU32;
typedef uint64_t* pU64;
typedef uint64_t* const cpU64;
typedef uint64_t* __restrict rpU64;
typedef uint64_t* const __restrict crpU64;
typedef const uint64_t* pcU64;
typedef const uint64_t* const cpcU64;
typedef const uint64_t* __restrict rpcU64;
typedef const uint64_t* const __restrict crpcU64;
typedef float* pFloat;
typedef float* const cpFloat;
typedef float* __restrict rpFloat;
typedef float* const __restrict crpFloat;
typedef const float* pcFloat;
typedef const float* const cpcFloat;
typedef const float* __restrict rpcFloat;
typedef const float* const __restrict crpcFloat;
typedef double* pDouble;
typedef double* const cpDouble;
typedef double* __restrict rpDouble;
typedef double* const __restrict crpDouble;
typedef const double* pcDouble;
typedef const double* const cpcDouble;
typedef const double* __restrict rpcDouble;
typedef const double* const __restrict crpcDouble;
typedef __m128* pM128;
typedef __m128* const cpM128;
typedef __m128* __restrict rpM128;
typedef __m128* const __restrict crpM128;
typedef const __m128* pcM128;
typedef const __m128* const cpcM128;
typedef const __m128* __restrict rpcM128;
typedef const __m128* const __restrict crpcM128;
typedef __m128i* pM128I;
typedef __m128i* const cpM128I;
typedef __m128i* __restrict rpM128I;
typedef __m128i* const __restrict crpM128I;
typedef const __m128i* pcM128I;
typedef const __m128i* const cpcM128I;
typedef const __m128i* __restrict rpcM128I;
typedef const __m128i* const __restrict crpcM128I;
typedef __m128d* pM128D;
typedef __m128d* const cpM128D;
typedef __m128d* __restrict rpM128D;
typedef __m128d* const __restrict crpM128D;
typedef const __m128d* pcM128D;
typedef const __m128d* const cpcM128D;
typedef const __m128d* __restrict rpcM128D;
typedef const __m128d* const __restrict crpcM128D;
typedef __m64* pM64;
typedef __m64* const cpM64;
typedef __m64* __restrict rpM64;
typedef __m64* const __restrict crpM64;
typedef const __m64* pcM64;
typedef const __m64* const cpcM64;
typedef const __m64* __restrict rpcM64;
typedef const __m64* const __restrict crpcM64;
#endif // #ifndef INCLUDED_POINTER_TYPEDEFS

View file

@ -56,7 +56,7 @@ size_t rand(size_t min_inclusive, size_t max_exclusive)
// huge interval or min >= max
if(range == 0 || range > XRAND_MAX)
{
WARN_ERR(ERR::INVALID_PARAM);
WARN_IF_ERR(ERR::INVALID_PARAM);
return 0;
}

View file

@ -46,7 +46,7 @@
#endif
static LibError load_sys_cursor(const PIVFS& vfs, const VfsPath& pathname, int hx, int hy, sys_cursor* cursor)
static Status load_sys_cursor(const PIVFS& vfs, const VfsPath& pathname, int hx, int hy, sys_cursor* cursor)
{
#if !ALLOW_SYS_CURSOR
UNUSED2(vfs);
@ -58,19 +58,19 @@ static LibError load_sys_cursor(const PIVFS& vfs, const VfsPath& pathname, int h
return ERR::FAIL;
#else
shared_ptr<u8> file; size_t fileSize;
RETURN_ERR(vfs->LoadFile(pathname, file, fileSize));
RETURN_STATUS_IF_ERR(vfs->LoadFile(pathname, file, fileSize));
ScopedTex t;
RETURN_ERR(tex_decode(file, fileSize, &t));
RETURN_STATUS_IF_ERR(tex_decode(file, fileSize, &t));
// convert to required BGRA format.
const size_t flags = (t.flags | TEX_BGR) & ~TEX_DXT;
RETURN_ERR(tex_transform_to(&t, flags));
RETURN_STATUS_IF_ERR(tex_transform_to(&t, flags));
void* bgra_img = tex_get_data(&t);
if(!bgra_img)
WARN_RETURN(ERR::FAIL);
RETURN_ERR(sys_cursor_create((int)t.w, (int)t.h, bgra_img, hx, hy, cursor));
RETURN_STATUS_IF_ERR(sys_cursor_create((int)t.w, (int)t.h, bgra_img, hx, hy, cursor));
return INFO::OK;
#endif
}
@ -86,10 +86,10 @@ class GLCursor
int hotspotx, hotspoty;
public:
LibError create(const PIVFS& vfs, const VfsPath& pathname, int hotspotx_, int hotspoty_)
Status create(const PIVFS& vfs, const VfsPath& pathname, int hotspotx_, int hotspoty_)
{
ht = ogl_tex_load(vfs, pathname);
RETURN_ERR(ht);
RETURN_STATUS_IF_ERR(ht);
size_t width, height;
(void)ogl_tex_get_size(ht, &width, &height, 0);
@ -127,7 +127,7 @@ public:
glEnd();
}
LibError validate() const
Status validate() const
{
const GLint A = 128; // no cursor is expected to get this big
if(w > A || h > A || hotspotx > A || hotspoty > A)
@ -185,7 +185,7 @@ static void Cursor_dtor(Cursor* c)
}
}
static LibError Cursor_reload(Cursor* c, const PIVFS& vfs, const VfsPath& name, Handle)
static Status Cursor_reload(Cursor* c, const PIVFS& vfs, const VfsPath& name, Handle)
{
const VfsPath pathname(VfsPath(L"art/textures/cursors") / name);
@ -195,7 +195,7 @@ static LibError Cursor_reload(Cursor* c, const PIVFS& vfs, const VfsPath& name,
{
const VfsPath pathnameHotspot = pathname.ChangeExtension(L".txt");
shared_ptr<u8> buf; size_t size;
RETURN_ERR(vfs->LoadFile(pathnameHotspot, buf, size));
RETURN_STATUS_IF_ERR(vfs->LoadFile(pathnameHotspot, buf, size));
std::wstringstream s(std::wstring((const wchar_t*)buf.get(), size));
s >> hotspotx >> hotspoty;
}
@ -219,7 +219,7 @@ static LibError Cursor_reload(Cursor* c, const PIVFS& vfs, const VfsPath& name,
return INFO::OK;
}
static LibError Cursor_validate(const Cursor* c)
static Status Cursor_validate(const Cursor* c)
{
switch(c->kind)
{
@ -232,7 +232,7 @@ static LibError Cursor_validate(const Cursor* c)
break;
case CK_OpenGL:
RETURN_ERR(c->gl_cursor.validate());
RETURN_STATUS_IF_ERR(c->gl_cursor.validate());
break;
default:
@ -243,7 +243,7 @@ static LibError Cursor_validate(const Cursor* c)
return INFO::OK;
}
static LibError Cursor_to_string(const Cursor* c, wchar_t* buf)
static Status Cursor_to_string(const Cursor* c, wchar_t* buf)
{
const wchar_t* type;
switch(c->kind)
@ -282,13 +282,13 @@ static Handle cursor_load(const PIVFS& vfs, const VfsPath& name)
return h_alloc(H_Cursor, vfs, name, 0);
}
static LibError cursor_free(Handle& h)
static Status cursor_free(Handle& h)
{
return h_free(h, H_Cursor);
}
LibError cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y)
Status cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y)
{
// hide the cursor
if(!name)
@ -299,7 +299,7 @@ LibError cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y)
Handle hc = cursor_load(vfs, name);
RETURN_ERR(hc); // silently ignore failures
RETURN_STATUS_IF_ERR(hc); // silently ignore failures
H_DEREF(hc, Cursor, c);

View file

@ -43,6 +43,6 @@
* Uses a hardware mouse cursor where available, otherwise a
* portable OpenGL implementation.
**/
extern LibError cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y);
extern Status cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y);
#endif // #ifndef INCLUDED_GRAPHICS_CURSOR

View file

@ -40,11 +40,11 @@
extern PIVFS vfs;
ERROR_ASSOCIATE(ERR::SHDR_CREATE, L"Shader creation failed", -1);
ERROR_ASSOCIATE(ERR::SHDR_COMPILE, L"Shader compile failed", -1);
ERROR_ASSOCIATE(ERR::SHDR_NO_SHADER, L"Invalid shader reference", -1);
ERROR_ASSOCIATE(ERR::SHDR_LINK, L"Shader linking failed", -1);
ERROR_ASSOCIATE(ERR::SHDR_NO_PROGRAM, L"Invalid shader program reference", -1);
STATUS_DEFINE(ERR, SHDR_CREATE, L"Shader creation failed", -1);
STATUS_DEFINE(ERR, SHDR_COMPILE, L"Shader compile failed", -1);
STATUS_DEFINE(ERR, SHDR_NO_SHADER, L"Invalid shader reference", -1);
STATUS_DEFINE(ERR, SHDR_LINK, L"Shader linking failed", -1);
STATUS_DEFINE(ERR, SHDR_NO_PROGRAM, L"Invalid shader program reference", -1);
// Convert a shader object type into a descriptive string.
@ -109,15 +109,15 @@ TIMER_ADD_CLIENT(tc_linkProgram);
// have absolutely no effect on a program object that contains these shaders
// when the program object is already linked.
// So, how can we inform the "parent object" (i.e. the program object) of our change?
static LibError Ogl_Shader_reload(Ogl_Shader* shdr, const PIVFS& vfs, const VfsPath& pathname, Handle UNUSED(h))
static Status Ogl_Shader_reload(Ogl_Shader* shdr, const PIVFS& vfs, const VfsPath& pathname, Handle UNUSED(h))
{
LibError err = ERR::FAIL;
Status err = ERR::FAIL;
if (shdr->id)
return INFO::OK;
shared_ptr<u8> file; size_t file_size;
RETURN_ERR(vfs->LoadFile(pathname, file, file_size));
RETURN_STATUS_IF_ERR(vfs->LoadFile(pathname, file, file_size));
ogl_WarnIfError();
@ -204,13 +204,13 @@ static void Ogl_Shader_dtor(Ogl_Shader* shdr)
}
}
static LibError Ogl_Shader_validate(const Ogl_Shader* UNUSED(shdr))
static Status Ogl_Shader_validate(const Ogl_Shader* UNUSED(shdr))
{
// TODO
return INFO::OK;
}
static LibError Ogl_Shader_to_string(const Ogl_Shader* shdr, wchar_t* buf)
static Status Ogl_Shader_to_string(const Ogl_Shader* shdr, wchar_t* buf)
{
swprintf_s(buf, H_STRING_LEN, L"Ogl_Shader %p", shdr);
return INFO::OK;
@ -237,7 +237,7 @@ void ogl_shader_free(Handle& h)
}
// Attach a shader to the given OpenGL program.
LibError ogl_shader_attach(GLhandleARB program, Handle& h)
Status ogl_shader_attach(GLhandleARB program, Handle& h)
{
H_DEREF(h, Ogl_Shader, shdr);
@ -272,7 +272,7 @@ static void Ogl_Program_init(Ogl_Program* UNUSED(p), va_list UNUSED(args))
// Load the shader associated with one Shader element,
// and attach it to our program object.
static LibError do_load_shader(
static Status do_load_shader(
Ogl_Program* p, const VfsPath& pathname, Handle UNUSED(h),
const CXeromyces& XeroFile, const XMBElement& Shader)
{
@ -305,7 +305,7 @@ static LibError do_load_shader(
}
Handle hshader = ogl_shader_load(g_VFS, pathnameShader.FromUTF8(), shadertype);
RETURN_ERR(hshader);
RETURN_STATUS_IF_ERR(hshader);
ogl_shader_attach(p->id, hshader);
@ -320,7 +320,7 @@ static LibError do_load_shader(
// Reload the program object from the source file.
static LibError Ogl_Program_reload(Ogl_Program* p, const PIVFS& vfs, const VfsPath& pathname, Handle h)
static Status Ogl_Program_reload(Ogl_Program* p, const PIVFS& vfs, const VfsPath& pathname, Handle h)
{
if (p->id)
return INFO::OK;
@ -380,7 +380,7 @@ static LibError Ogl_Program_reload(Ogl_Program* p, const PIVFS& vfs, const VfsPa
WARN_RETURN(ERR::CORRUPTED);
}
RETURN_ERR(do_load_shader(p, pathname, h, XeroFile, Shader));
RETURN_STATUS_IF_ERR(do_load_shader(p, pathname, h, XeroFile, Shader));
}
}
else
@ -427,13 +427,13 @@ static void Ogl_Program_dtor(Ogl_Program* p)
}
}
static LibError Ogl_Program_validate(const Ogl_Program* UNUSED(p))
static Status Ogl_Program_validate(const Ogl_Program* UNUSED(p))
{
// TODO
return INFO::OK;
}
static LibError Ogl_Program_to_string(const Ogl_Program* p, wchar_t* buf)
static Status Ogl_Program_to_string(const Ogl_Program* p, wchar_t* buf)
{
swprintf_s(buf, H_STRING_LEN, L"Ogl_Program %p", p);
return INFO::OK;
@ -459,7 +459,7 @@ void ogl_program_free(Handle& h)
// Activate the program (glUseProgramObjectARB).
// h may be 0, in which case program objects are disabled.
LibError ogl_program_use(Handle h)
Status ogl_program_use(Handle h)
{
if (!h)
{

View file

@ -35,11 +35,11 @@
namespace ERR
{
const LibError SHDR_CREATE = -120200;
const LibError SHDR_COMPILE = -120201;
const LibError SHDR_NO_SHADER = -120202;
const LibError SHDR_LINK = -120203;
const LibError SHDR_NO_PROGRAM = -120204;
const Status SHDR_CREATE = -120200;
const Status SHDR_COMPILE = -120201;
const Status SHDR_NO_SHADER = -120202;
const Status SHDR_LINK = -120203;
const Status SHDR_NO_PROGRAM = -120204;
}
/*
@ -69,7 +69,7 @@ void ogl_shader_free(Handle& h);
/**
* Attach a shader to the given OpenGL program.
**/
LibError ogl_shader_attach(GLhandleARB program, Handle& h);
Status ogl_shader_attach(GLhandleARB program, Handle& h);
/*
@ -97,7 +97,7 @@ void ogl_program_free(Handle& h);
*
* @param h may be 0, in which case program objects are disabled.
**/
LibError ogl_program_use(Handle h);
Status ogl_program_use(Handle h);
/**
* Query uniform information

View file

@ -426,7 +426,7 @@ static void OglTex_dtor(OglTex* ot)
ot->flags &= ~OT_IS_UPLOADED;
}
static LibError OglTex_reload(OglTex* ot, const PIVFS& vfs, const VfsPath& pathname, Handle h)
static Status OglTex_reload(OglTex* ot, const PIVFS& vfs, const VfsPath& pathname, Handle h)
{
// we're reusing a freed but still in-memory OglTex object
if(ot->flags & OT_IS_UPLOADED)
@ -437,7 +437,7 @@ static LibError OglTex_reload(OglTex* ot, const PIVFS& vfs, const VfsPath& pathn
if(!(ot->flags & OT_TEX_VALID))
{
shared_ptr<u8> file; size_t fileSize;
RETURN_ERR(vfs->LoadFile(pathname, file, fileSize));
RETURN_STATUS_IF_ERR(vfs->LoadFile(pathname, file, fileSize));
if(tex_decode(file, fileSize, &ot->t) >= 0)
ot->flags |= OT_TEX_VALID;
}
@ -452,11 +452,11 @@ static LibError OglTex_reload(OglTex* ot, const PIVFS& vfs, const VfsPath& pathn
return INFO::OK;
}
static LibError OglTex_validate(const OglTex* ot)
static Status OglTex_validate(const OglTex* ot)
{
if(ot->flags & OT_TEX_VALID)
{
RETURN_ERR(tex_validate(&ot->t));
RETURN_STATUS_IF_ERR(tex_validate(&ot->t));
// width, height
// (note: this is done here because tex.cpp doesn't impose any
@ -497,7 +497,7 @@ static LibError OglTex_validate(const OglTex* ot)
return INFO::OK;
}
static LibError OglTex_to_string(const OglTex* ot, wchar_t* buf)
static Status OglTex_to_string(const OglTex* ot, wchar_t* buf)
{
swprintf_s(buf, H_STRING_LEN, L"OglTex id=%d flags=%lx", ot->id, ot->flags);
return INFO::OK;
@ -550,7 +550,7 @@ Handle ogl_tex_wrap(Tex* t, const PIVFS& vfs, const VfsPath& pathname, size_t fl
// free all resources associated with the texture and make further
// use of it impossible. (subject to refcount)
LibError ogl_tex_free(Handle& ht)
Status ogl_tex_free(Handle& ht)
{
return h_free(ht, H_OglTex);
}
@ -602,7 +602,7 @@ static void warn_if_uploaded(Handle ht, const OglTex* ot)
// must be called before uploading (raises a warning if called afterwards).
// filter is as defined by OpenGL; it is applied for both minification and
// magnification (for rationale and details, see OglTexState)
LibError ogl_tex_set_filter(Handle ht, GLint filter)
Status ogl_tex_set_filter(Handle ht, GLint filter)
{
H_DEREF(ht, OglTex, ot);
@ -622,7 +622,7 @@ LibError ogl_tex_set_filter(Handle ht, GLint filter)
// must be called before uploading (raises a warning if called afterwards).
// wrap is as defined by OpenGL and applies to both S and T coordinates
// (rationale: see OglTexState).
LibError ogl_tex_set_wrap(Handle ht, GLint wrap)
Status ogl_tex_set_wrap(Handle ht, GLint wrap)
{
H_DEREF(ht, OglTex, ot);
@ -640,7 +640,7 @@ LibError ogl_tex_set_wrap(Handle ht, GLint wrap)
// override default anisotropy for this texture.
// must be called before uploading (raises a warning if called afterwards).
LibError ogl_tex_set_anisotropy(Handle ht, GLfloat anisotropy)
Status ogl_tex_set_anisotropy(Handle ht, GLfloat anisotropy)
{
H_DEREF(ht, OglTex, ot);
@ -747,7 +747,7 @@ static void detect_gl_upload_caps()
// whether mipmaps are needed and the quality settings).
// returns 0 to indicate success; otherwise, caller must disable
// mipmapping by switching filter to e.g. GL_LINEAR.
static LibError get_mipmaps(Tex* t, GLint filter, int q_flags, int* plevels_to_skip)
static Status get_mipmaps(Tex* t, GLint filter, int q_flags, int* plevels_to_skip)
{
// decisions:
// .. does filter call for uploading mipmaps?
@ -788,7 +788,7 @@ static LibError get_mipmaps(Tex* t, GLint filter, int q_flags, int* plevels_to_s
// we will generate mipmaps in software.
else
{
RETURN_ERR(tex_transform_to(t, t->flags|TEX_MIPMAPS));
RETURN_STATUS_IF_ERR(tex_transform_to(t, t->flags|TEX_MIPMAPS));
*plevels_to_skip = 0; // t contains mipmaps
}
@ -857,7 +857,7 @@ static void upload_impl(Tex* t, GLenum fmt, GLint int_fmt, int levels_to_skip)
// side effects:
// - enables texturing on TMU 0 and binds the texture to it;
// - frees the texel data! see ogl_tex_get_data.
LibError ogl_tex_upload(const Handle ht, GLenum fmt_ovr, int q_flags_ovr, GLint int_fmt_ovr)
Status ogl_tex_upload(const Handle ht, GLenum fmt_ovr, int q_flags_ovr, GLint int_fmt_ovr)
{
ONCE(detect_gl_upload_caps());
@ -889,7 +889,7 @@ LibError ogl_tex_upload(const Handle ht, GLenum fmt_ovr, int q_flags_ovr, GLint
{
// (note: we know ht is valid due to H_DEREF, but ogl_tex_bind can
// fail in debug builds if OglTex.id isn't a valid texture name)
RETURN_ERR(ogl_tex_bind(ht, ot->tmu));
RETURN_STATUS_IF_ERR(ogl_tex_bind(ht, ot->tmu));
int levels_to_skip;
if(get_mipmaps(t, ot->state.filter, ot->q_flags, &levels_to_skip) < 0)
// error => disable mipmapping
@ -927,7 +927,7 @@ LibError ogl_tex_upload(const Handle ht, GLenum fmt_ovr, int q_flags_ovr, GLint
// retrieve texture dimensions and bits per pixel.
// all params are optional and filled if non-NULL.
LibError ogl_tex_get_size(Handle ht, size_t* w, size_t* h, size_t* bpp)
Status ogl_tex_get_size(Handle ht, size_t* w, size_t* h, size_t* bpp)
{
H_DEREF(ht, OglTex, ot);
@ -944,7 +944,7 @@ LibError ogl_tex_get_size(Handle ht, size_t* w, size_t* h, size_t* bpp)
// retrieve TexFlags and the corresponding OpenGL format.
// the latter is determined during ogl_tex_upload and is 0 before that.
// all params are optional and filled if non-NULL.
LibError ogl_tex_get_format(Handle ht, size_t* flags, GLenum* fmt)
Status ogl_tex_get_format(Handle ht, size_t* flags, GLenum* fmt)
{
H_DEREF(ht, OglTex, ot);
@ -966,7 +966,7 @@ LibError ogl_tex_get_format(Handle ht, size_t* flags, GLenum* fmt)
// the function doesn't fail (negative return value) by design.
// if you still need to get at the data, add a reference before
// uploading it or read directly from OpenGL (discouraged).
LibError ogl_tex_get_data(Handle ht, u8** p)
Status ogl_tex_get_data(Handle ht, u8** p)
{
H_DEREF(ht, OglTex, ot);
@ -975,7 +975,7 @@ LibError ogl_tex_get_data(Handle ht, u8** p)
}
// retrieve colour of 1x1 mipmap level
extern LibError ogl_tex_get_average_colour(Handle ht, u32* p)
extern Status ogl_tex_get_average_colour(Handle ht, u32* p)
{
H_DEREF(ht, OglTex, ot);
warn_if_uploaded(ht, ot);
@ -999,7 +999,7 @@ extern LibError ogl_tex_get_average_colour(Handle ht, u32* p)
// - assumes multitexturing is available.
// - not necessary before calling ogl_tex_upload!
// - on error, the unit's texture state is unchanged; see implementation.
LibError ogl_tex_bind(Handle ht, size_t unit)
Status ogl_tex_bind(Handle ht, size_t unit)
{
// note: there are many call sites of glActiveTextureARB, so caching
// those and ignoring redundant sets isn't feasible.
@ -1031,20 +1031,20 @@ LibError ogl_tex_bind(Handle ht, size_t unit)
// apply the specified transforms (as in tex_transform) to the image.
// must be called before uploading (raises a warning if called afterwards).
LibError ogl_tex_transform(Handle ht, size_t transforms)
Status ogl_tex_transform(Handle ht, size_t transforms)
{
H_DEREF(ht, OglTex, ot);
LibError ret = tex_transform(&ot->t, transforms);
Status ret = tex_transform(&ot->t, transforms);
return ret;
}
// change the pixel format to that specified by <new_flags>.
// (note: this is equivalent to ogl_tex_transform(ht, ht_flags^new_flags).
LibError ogl_tex_transform_to(Handle ht, size_t new_flags)
Status ogl_tex_transform_to(Handle ht, size_t new_flags)
{
H_DEREF(ht, OglTex, ot);
LibError ret = tex_transform_to(&ot->t, new_flags);
Status ret = tex_transform_to(&ot->t, new_flags);
return ret;
}

View file

@ -219,7 +219,7 @@ extern void ogl_tex_set_defaults(int q_flags, GLint filter);
* @param vfs
* @param pathname
* @param flags h_alloc flags.
* @return Handle to texture or negative LibError
* @return Handle to texture or negative Status
* for a list of supported formats, see tex.h's tex_load.
*/
extern Handle ogl_tex_load(const PIVFS& vfs, const VfsPath& pathname, size_t flags = 0);
@ -229,7 +229,7 @@ extern Handle ogl_tex_load(const PIVFS& vfs, const VfsPath& pathname, size_t fla
* loaded and is still in memory.
*
* @param pathname fn VFS filename of texture.
* @return Handle to texture or negative LibError
* @return Handle to texture or negative Status
*/
extern Handle ogl_tex_find(const VfsPath& pathname);
@ -244,7 +244,7 @@ extern Handle ogl_tex_find(const VfsPath& pathname);
* but would allow h_filename to return meaningful info for
* purposes of debugging.
* @param flags
* @return Handle to texture or negative LibError
* @return Handle to texture or negative Status
*
* note: because we cannot guarantee that callers will pass distinct
* "filenames", caching is disabled for the created object. this avoids
@ -260,9 +260,9 @@ extern Handle ogl_tex_wrap(Tex* t, const PIVFS& vfs, const VfsPath& pathname, si
* its associated resources are freed and further use made impossible.
*
* @param ht Texture handle.
* @return LibError
* @return Status
*/
extern LibError ogl_tex_free(Handle& ht);
extern Status ogl_tex_free(Handle& ht);
//
@ -279,11 +279,11 @@ extern LibError ogl_tex_free(Handle& ht);
* @param ht Texture handle
* @param filter OpenGL minification and magnification filter
* (rationale: see {@link OglTexState})
* @return LibError
* @return Status
*
* Must be called before uploading (raises a warning if called afterwards).
*/
extern LibError ogl_tex_set_filter(Handle ht, GLint filter);
extern Status ogl_tex_set_filter(Handle ht, GLint filter);
/**
* Override default wrap mode (GL_REPEAT) for this texture.
@ -291,11 +291,11 @@ extern LibError ogl_tex_set_filter(Handle ht, GLint filter);
* @param ht Texture handle
* @param wrap OpenGL wrap mode (for both S and T coordinates)
* (rationale: see {@link OglTexState})
* @return LibError
* @return Status
*
* Must be called before uploading (raises a warning if called afterwards).
*/
extern LibError ogl_tex_set_wrap(Handle ht, GLint wrap);
extern Status ogl_tex_set_wrap(Handle ht, GLint wrap);
/**
* Override default maximum anisotropic filtering for this texture.
@ -303,11 +303,11 @@ extern LibError ogl_tex_set_wrap(Handle ht, GLint wrap);
* @param ht Texture handle
* @param anisotropy Anisotropy value (must not be less than 1.0; should
* usually be a power of two)
* @return LibError
* @return Status
*
* Must be called before uploading (raises a warning if called afterwards).
*/
extern LibError ogl_tex_set_anisotropy(Handle ht, GLfloat anisotropy);
extern Status ogl_tex_set_anisotropy(Handle ht, GLfloat anisotropy);
//
@ -346,13 +346,13 @@ extern void ogl_tex_override(OglTexOverrides what, OglTexAllow allow);
* OglTexQualityFlags
* @param int_fmt_ovr optional override for OpenGL internal format
* (e.g. GL_RGB8), which is decided from fmt / q_flags.
* @return LibError.
* @return Status.
*
* Side Effects:
* - enables texturing on TMU 0 and binds the texture to it;
* - frees the texel data! see ogl_tex_get_data.
*/
extern LibError ogl_tex_upload(const Handle ht, GLenum fmt_ovr = 0, int q_flags_ovr = 0, GLint int_fmt_ovr = 0);
extern Status ogl_tex_upload(const Handle ht, GLenum fmt_ovr = 0, int q_flags_ovr = 0, GLint int_fmt_ovr = 0);
//
@ -366,9 +366,9 @@ extern LibError ogl_tex_upload(const Handle ht, GLenum fmt_ovr = 0, int q_flags_
* @param w optional; will be filled with width
* @param h optional; will be filled with height
* @param bpp optional; will be filled with bits per pixel
* @return LibError
* @return Status
*/
extern LibError ogl_tex_get_size(Handle ht, size_t* w, size_t* h, size_t* bpp);
extern Status ogl_tex_get_size(Handle ht, size_t* w, size_t* h, size_t* bpp);
/**
* Retrieve pixel format of the texture.
@ -377,16 +377,16 @@ extern LibError ogl_tex_get_size(Handle ht, size_t* w, size_t* h, size_t* bpp);
* @param flags optional; will be filled with TexFlags
* @param fmt optional; will be filled with GL format
* (it is determined during ogl_tex_upload and 0 before then)
* @return LibError
* @return Status
*/
extern LibError ogl_tex_get_format(Handle ht, size_t* flags, GLenum* fmt);
extern Status ogl_tex_get_format(Handle ht, size_t* flags, GLenum* fmt);
/**
* Retrieve pixel data of the texture.
*
* @param ht Texture handle
* @param p will be filled with pointer to texels.
* @return LibError
* @return Status
*
* Note: this memory is freed after a successful ogl_tex_upload for
* this texture. After that, the pointer we retrieve is NULL but
@ -394,7 +394,7 @@ extern LibError ogl_tex_get_format(Handle ht, size_t* flags, GLenum* fmt);
* If you still need to get at the data, add a reference before
* uploading it or read directly from OpenGL (discouraged).
*/
extern LibError ogl_tex_get_data(Handle ht, u8** p);
extern Status ogl_tex_get_data(Handle ht, u8** p);
/**
* Retrieve ARGB value of 1x1 mipmap level of the texture,
@ -402,11 +402,11 @@ extern LibError ogl_tex_get_data(Handle ht, u8** p);
*
* @param ht Texture handle
* @param p will be filled with ARGB value (or 0 if texture does not have mipmaps)
* @return LibError
* @return Status
*
* Must be called before uploading (raises a warning if called afterwards).
*/
extern LibError ogl_tex_get_average_colour(Handle ht, u32* p);
extern Status ogl_tex_get_average_colour(Handle ht, u32* p);
//
@ -419,7 +419,7 @@ extern LibError ogl_tex_get_average_colour(Handle ht, u32* p);
*
* @param ht Texture handle. If 0, texturing is disabled on this unit.
* @param unit Texture Mapping Unit number, typically 0 for the first.
* @return LibError
* @return Status
*
* Side Effects:
* - changes the active texture unit;
@ -430,33 +430,33 @@ extern LibError ogl_tex_get_average_colour(Handle ht, u32* p);
* - not necessary before calling ogl_tex_upload!
* - on error, the unit's texture state is unchanged; see implementation.
*/
extern LibError ogl_tex_bind(Handle ht, size_t unit = 0);
extern Status ogl_tex_bind(Handle ht, size_t unit = 0);
/**
* (partially) Transform pixel format of the texture.
*
* @param ht Texture handle.
* @param flags the TexFlags that are to be @em changed.
* @return LibError
* @return Status
* @see tex_transform
*
* Must be called before uploading (raises a warning if called afterwards).
*/
extern LibError ogl_tex_transform(Handle ht, size_t flags);
extern Status ogl_tex_transform(Handle ht, size_t flags);
/**
* Transform pixel format of the texture.
*
* @param ht Texture handle.
* @param new_flags Flags desired new TexFlags indicating pixel format.
* @return LibError
* @return Status
* @see tex_transform
*
* Must be called before uploading (raises a warning if called afterwards).
*
* Note: this is equivalent to ogl_tex_transform(ht, ht_flags^new_flags).
*/
extern LibError ogl_tex_transform_to(Handle ht, size_t new_flags);
extern Status ogl_tex_transform_to(Handle ht, size_t new_flags);
/**
* Return whether native S3TC texture compression support is available.

View file

@ -72,7 +72,7 @@ static void UniFont_dtor(UniFont* f)
// basename is e.g. "console"; the files are "fonts/console.fnt" and "fonts/console.png"
// [10..70ms]
static LibError UniFont_reload(UniFont* f, const PIVFS& vfs, const VfsPath& basename, Handle UNUSED(h))
static Status UniFont_reload(UniFont* f, const PIVFS& vfs, const VfsPath& basename, Handle UNUSED(h))
{
// already loaded
if(f->ht > 0)
@ -85,7 +85,7 @@ static LibError UniFont_reload(UniFont* f, const PIVFS& vfs, const VfsPath& base
// Read font definition file into a stringstream
shared_ptr<u8> buf; size_t size;
const VfsPath fntName(basename.ChangeExtension(L".fnt"));
RETURN_ERR(vfs->LoadFile(path / fntName, buf, size)); // [cumulative for 12: 36ms]
RETURN_STATUS_IF_ERR(vfs->LoadFile(path / fntName, buf, size)); // [cumulative for 12: 36ms]
std::istringstream FNTStream(std::string((const char*)buf.get(), size));
int Version;
@ -151,13 +151,13 @@ static LibError UniFont_reload(UniFont* f, const PIVFS& vfs, const VfsPath& base
// [cumulative for 12: 20ms]
const VfsPath imgName(basename.ChangeExtension(L".png"));
Handle ht = ogl_tex_load(vfs, path / imgName);
RETURN_ERR(ht);
RETURN_STATUS_IF_ERR(ht);
(void)ogl_tex_set_filter(ht, GL_NEAREST);
// override is necessary because the GL format is chosen as LUMINANCE,
// but we want ALPHA. there is no way of knowing what format
// 8bpp textures are in - we could adopt a naming convention and
// add some TEX_ flags, but that's overkill.
LibError err = ogl_tex_upload(ht, fmt_ovr);
Status err = ogl_tex_upload(ht, fmt_ovr);
if(err < 0)
{
(void)ogl_tex_free(ht);
@ -169,7 +169,7 @@ static LibError UniFont_reload(UniFont* f, const PIVFS& vfs, const VfsPath& base
return INFO::OK;
}
static LibError UniFont_validate(const UniFont* f)
static Status UniFont_validate(const UniFont* f)
{
if(f->ht < 0)
WARN_RETURN(ERR::_1);
@ -182,7 +182,7 @@ static LibError UniFont_validate(const UniFont* f)
return INFO::OK;
}
static LibError UniFont_to_string(const UniFont* f, wchar_t* buf)
static Status UniFont_to_string(const UniFont* f, wchar_t* buf)
{
if (f->ht) // not true if this is called after dtor (which it is)
{
@ -201,7 +201,7 @@ Handle unifont_load(const PIVFS& vfs, const VfsPath& pathname, size_t flags)
}
LibError unifont_unload(Handle& h)
Status unifont_unload(Handle& h)
{
H_DEREF(h, UniFont, f);
@ -214,7 +214,7 @@ LibError unifont_unload(Handle& h)
}
LibError unifont_bind(const Handle h)
Status unifont_bind(const Handle h)
{
H_DEREF(h, UniFont, f);
@ -349,7 +349,7 @@ void glwprintf(const wchar_t* fmt, ...)
}
LibError unifont_stringsize(const Handle h, const wchar_t* text, int& width, int& height)
Status unifont_stringsize(const Handle h, const wchar_t* text, int& width, int& height)
{
H_DEREF(h, UniFont, f);

View file

@ -46,14 +46,14 @@ extern Handle unifont_load(const PIVFS& vfs, const VfsPath& pathname, size_t fla
* Release a handle to a previously loaded font
* (subject to reference counting).
**/
extern LibError unifont_unload(Handle& h);
extern Status unifont_unload(Handle& h);
/**
* Use a font for all subsequent glwprintf() calls.
*
* Must be called before any glwprintf().
**/
extern LibError unifont_bind(Handle h);
extern Status unifont_bind(Handle h);
/**
* Output text at current OpenGL modelview pos.
@ -90,7 +90,7 @@ extern void glvwprintf(const wchar_t* fmt, va_list args) VWPRINTF_ARGS(1);
*
* note: This is intended for the GUI (hence Unicode).
**/
LibError unifont_stringsize(const Handle h, const wchar_t* text, int& width, int& height);
Status unifont_stringsize(const Handle h, const wchar_t* text, int& width, int& height);
/**
* @return height [pixels] of the font.

View file

@ -273,7 +273,7 @@ static HDATA* h_data_tag_type(const Handle h, const H_Type type)
// idx and hd are undefined if we fail.
// called by h_alloc only.
static LibError alloc_idx(ssize_t& idx, HDATA*& hd)
static Status alloc_idx(ssize_t& idx, HDATA*& hd)
{
// we already know the first free entry
if(first_free != -1)
@ -326,7 +326,7 @@ have_idx:;
}
static LibError free_idx(ssize_t idx)
static Status free_idx(ssize_t idx)
{
if(first_free == -1 || idx < first_free)
first_free = idx;
@ -424,7 +424,7 @@ static void warn_if_invalid(HDATA* hd)
// the others have no invariants we could check.
// have the resource validate its user_data
LibError err = vtbl->validate(hd->user);
Status err = vtbl->validate(hd->user);
ENSURE(err == INFO::OK);
// make sure empty space in control block isn't touched
@ -439,7 +439,7 @@ static void warn_if_invalid(HDATA* hd)
}
static LibError type_validate(H_Type type)
static Status type_validate(H_Type type)
{
if(!type)
WARN_RETURN(ERR::INVALID_PARAM);
@ -498,9 +498,9 @@ static Handle reuse_existing_handle(uintptr_t key, H_Type type, size_t flags)
}
static LibError call_init_and_reload(Handle h, H_Type type, HDATA* hd, const PIVFS& vfs, const VfsPath& pathname, va_list* init_args)
static Status call_init_and_reload(Handle h, H_Type type, HDATA* hd, const PIVFS& vfs, const VfsPath& pathname, va_list* init_args)
{
LibError err = INFO::OK;
Status err = INFO::OK;
H_VTbl* vtbl = type; // exact same thing but for clarity
// init
@ -531,7 +531,7 @@ static Handle alloc_new_handle(H_Type type, const PIVFS& vfs, const VfsPath& pat
{
ssize_t idx;
HDATA* hd;
RETURN_ERR(alloc_idx(idx, hd));
RETURN_STATUS_IF_ERR(alloc_idx(idx, hd));
// (don't want to do this before the add-reference exit,
// so as not to waste tags for often allocated handles.)
@ -552,7 +552,7 @@ static Handle alloc_new_handle(H_Type type, const PIVFS& vfs, const VfsPath& pat
if(key && !hd->unique)
key_add(key, h);
LibError err = call_init_and_reload(h, type, hd, vfs, pathname, init_args);
Status err = call_init_and_reload(h, type, hd, vfs, pathname, init_args);
if(err < 0)
goto fail;
@ -561,7 +561,7 @@ static Handle alloc_new_handle(H_Type type, const PIVFS& vfs, const VfsPath& pat
fail:
// reload failed; free the handle
hd->keep_open = 0; // disallow caching (since contents are invalid)
(void)h_free(h, type); // (h_free already does WARN_ERR)
(void)h_free(h, type); // (h_free already does WARN_IF_ERR)
// note: since some uses will always fail (e.g. loading sounds if
// g_Quickstart), do not complain here.
@ -572,13 +572,13 @@ fail:
// any further params are passed to type's init routine
Handle h_alloc(H_Type type, const PIVFS& vfs, const VfsPath& pathname, size_t flags, ...)
{
RETURN_ERR(type_validate(type));
RETURN_STATUS_IF_ERR(type_validate(type));
const uintptr_t key = fnv_hash(pathname.string().c_str(), pathname.string().length()*sizeof(pathname.string()[0]));
// see if we can reuse an existing handle
Handle h = reuse_existing_handle(key, type, flags);
RETURN_ERR(h);
RETURN_STATUS_IF_ERR(h);
// .. successfully reused the handle; refcount increased
if(h > 0)
return h;
@ -587,14 +587,14 @@ Handle h_alloc(H_Type type, const PIVFS& vfs, const VfsPath& pathname, size_t fl
va_start(args, flags);
h = alloc_new_handle(type, vfs, pathname, key, flags, &args);
va_end(args);
return h; // alloc_new_handle already does CHECK_ERR
return h; // alloc_new_handle already does WARN_RETURN_STATUS_IF_ERR
}
//-----------------------------------------------------------------------------
// currently cannot fail.
static LibError h_free_idx(ssize_t idx, HDATA* hd)
static Status h_free_idx(ssize_t idx, HDATA* hd)
{
// only decrement if refcount not already 0.
if(hd->refs > 0)
@ -638,7 +638,7 @@ static LibError h_free_idx(ssize_t idx, HDATA* hd)
}
LibError h_free(Handle& h, H_Type type)
Status h_free(Handle& h, H_Type type)
{
ssize_t idx = h_idx(h);
HDATA* hd = h_data_tag_type(h, type);
@ -699,7 +699,7 @@ VfsPath h_filename(const Handle h)
// TODO: what if iterating through all handles is too slow?
LibError h_reload(const PIVFS& vfs, const VfsPath& pathname)
Status h_reload(const PIVFS& vfs, const VfsPath& pathname)
{
const u32 key = fnv_hash(pathname.string().c_str(), pathname.string().length()*sizeof(pathname.string()[0]));
@ -715,7 +715,7 @@ LibError h_reload(const PIVFS& vfs, const VfsPath& pathname)
hd->type->dtor(hd->user);
}
LibError ret = INFO::OK;
Status ret = INFO::OK;
// now reload all affected handles
for(ssize_t i = 0; i <= last_in_use; i++)
@ -726,7 +726,7 @@ LibError h_reload(const PIVFS& vfs, const VfsPath& pathname)
Handle h = handle(i, hd->tag);
LibError err = hd->type->reload(hd->user, vfs, hd->pathname, h);
Status err = hd->type->reload(hd->user, vfs, hd->pathname, h);
// don't stop if an error is encountered - try to reload them all.
if(err < 0)
{
@ -755,7 +755,7 @@ Handle h_find(H_Type type, uintptr_t key)
// to later close the object.
// this is used when reinitializing the sound engine -
// at that point, all (cached) OpenAL resources must be freed.
LibError h_force_free(Handle h, H_Type type)
Status h_force_free(Handle h, H_Type type)
{
// require valid index; ignore tag; type checked below.
HDATA* hd = h_data_no_tag(h);
@ -807,7 +807,7 @@ int h_get_refcnt(Handle h)
static ModuleInitState initState;
static LibError Init()
static Status Init()
{
return INFO::OK;
}

View file

@ -133,7 +133,7 @@ reload:
does all initialization of the resource that requires its source file.
called after init; also after dtor every time the file is reloaded.
static LibError Type_reload(Res1* r, const VfsPath& pathname, Handle);
static Status Type_reload(Res1* r, const VfsPath& pathname, Handle);
{
// already loaded; done
if(r->data)
@ -191,7 +191,7 @@ makes sure the resource control block is in a valid state. returns 0 if
all is well, or a negative error code.
called automatically when the Handle is dereferenced or freed.
static LibError Type_validate(const Res1* r);
static Status Type_validate(const Res1* r);
{
const int permissible_flags = 0x01;
if(debug_IsPointerBogus(r->data))
@ -209,7 +209,7 @@ Handle res1_load(const VfsPath& pathname, int my_flags)
return h_alloc(H_Res1, pathname, 0, my_flags);
}
LibError res1_free(Handle& h)
Status res1_free(Handle& h)
{
// control block is automatically zeroed after this.
return h_free(h, H_Res1);
@ -296,10 +296,10 @@ but- has to handle variable params, a bit ugly
struct H_VTbl
{
void (*init)(void* user, va_list);
LibError (*reload)(void* user, const PIVFS& vfs, const VfsPath& pathname, Handle);
Status (*reload)(void* user, const PIVFS& vfs, const VfsPath& pathname, Handle);
void (*dtor)(void* user);
LibError (*validate)(const void* user);
LibError (*to_string)(const void* user, wchar_t* buf);
Status (*validate)(const void* user);
Status (*to_string)(const void* user, wchar_t* buf);
size_t user_size;
const wchar_t* name;
};
@ -309,17 +309,17 @@ typedef H_VTbl* H_Type;
#define H_TYPE_DEFINE(type)\
/* forward decls */\
static void type##_init(type*, va_list);\
static LibError type##_reload(type*, const PIVFS&, const VfsPath&, Handle);\
static Status type##_reload(type*, const PIVFS&, const VfsPath&, Handle);\
static void type##_dtor(type*);\
static LibError type##_validate(const type*);\
static LibError type##_to_string(const type*, wchar_t* buf);\
static Status type##_validate(const type*);\
static Status type##_to_string(const type*, wchar_t* buf);\
static H_VTbl V_##type =\
{\
(void (*)(void*, va_list))type##_init,\
(LibError (*)(void*, const PIVFS&, const VfsPath&, Handle))type##_reload,\
(Status (*)(void*, const PIVFS&, const VfsPath&, Handle))type##_reload,\
(void (*)(void*))type##_dtor,\
(LibError (*)(const void*))type##_validate,\
(LibError (*)(const void*, wchar_t*))type##_to_string,\
(Status (*)(const void*))type##_validate,\
(Status (*)(const void*, wchar_t*))type##_to_string,\
sizeof(type), /* control block size */\
WIDEN(#type) /* name */\
};\
@ -344,7 +344,7 @@ typedef H_VTbl* H_Type;
/* h already indicates an error - return immediately to pass back*/\
/* that specific error, rather than only ERR::INVALID_HANDLE*/\
if(h < 0)\
WARN_RETURN((LibError)h);\
WARN_RETURN((Status)h);\
type* const var = H_USER_DATA(h, type);\
if(!var)\
WARN_RETURN(ERR::INVALID_HANDLE);
@ -395,7 +395,7 @@ const size_t H_STRING_LEN = 256;
// dtor is associated with type and called when the object is freed.
// handle data is initialized to 0; optionally, a pointer to it is returned.
extern Handle h_alloc(H_Type type, const PIVFS& vfs, const VfsPath& pathname, size_t flags = 0, ...);
extern LibError h_free(Handle& h, H_Type type);
extern Status h_free(Handle& h, H_Type type);
// find and return a handle by key (typically filename hash)
@ -413,7 +413,7 @@ extern void* h_user_data(Handle h, H_Type type);
extern VfsPath h_filename(Handle h);
extern LibError h_reload(const PIVFS& vfs, const VfsPath& pathname);
extern Status h_reload(const PIVFS& vfs, const VfsPath& pathname);
// force the resource to be freed immediately, even if cached.
// tag is not checked - this allows the first Handle returned
@ -421,7 +421,7 @@ extern LibError h_reload(const PIVFS& vfs, const VfsPath& pathname);
// to later close the object.
// this is used when reinitializing the sound engine -
// at that point, all (cached) OpenAL resources must be freed.
extern LibError h_force_free(Handle h, H_Type type);
extern Status h_force_free(Handle h, H_Type type);
// increment Handle <h>'s reference count.
// only meant to be used for objects that free a Handle in their dtor,

View file

@ -9,7 +9,7 @@
#include "lib/file/file_system_util.h"
static LibError LibErrorFromVorbis(int err)
static Status LibErrorFromVorbis(int err)
{
switch(err)
{
@ -196,7 +196,7 @@ public:
{
}
LibError Open()
Status Open()
{
ov_callbacks callbacks;
callbacks.read_func = Adapter::Read;
@ -225,7 +225,7 @@ public:
return info->rate;
}
virtual LibError GetNextChunk(u8* buffer, size_t size)
virtual Status GetNextChunk(u8* buffer, size_t size)
{
// we may have to call ov_read multiple times because it
// treats the buffer size "as a limit and not a request"
@ -238,14 +238,14 @@ public:
int bitstream; // unused
const int ret = ov_read(&vf, (char*)buffer+bytesRead, int(size-bytesRead), isBigEndian, wordSize, isSigned, &bitstream);
if(ret == 0) // EOF
return (LibError)bytesRead;
return (Status)bytesRead;
else if(ret < 0)
WARN_RETURN(LibErrorFromVorbis(ret));
else // success
{
bytesRead += ret;
if(bytesRead == size)
return (LibError)bytesRead;
return (Status)bytesRead;
}
}
}
@ -259,25 +259,25 @@ private:
//-----------------------------------------------------------------------------
LibError OpenOggStream(const OsPath& pathname, OggStreamPtr& stream)
Status OpenOggStream(const OsPath& pathname, OggStreamPtr& stream)
{
PFile file(new File);
RETURN_ERR(file->Open(pathname, L'r'));
RETURN_STATUS_IF_ERR(file->Open(pathname, L'r'));
shared_ptr<OggStreamImpl<VorbisFileAdapter> > tmp(new OggStreamImpl<VorbisFileAdapter>(VorbisFileAdapter(file)));
RETURN_ERR(tmp->Open());
RETURN_STATUS_IF_ERR(tmp->Open());
stream = tmp;
return INFO::OK;
}
LibError OpenOggNonstream(const PIVFS& vfs, const VfsPath& pathname, OggStreamPtr& stream)
Status OpenOggNonstream(const PIVFS& vfs, const VfsPath& pathname, OggStreamPtr& stream)
{
shared_ptr<u8> contents;
size_t size;
RETURN_ERR(vfs->LoadFile(pathname, contents, size));
RETURN_STATUS_IF_ERR(vfs->LoadFile(pathname, contents, size));
shared_ptr<OggStreamImpl<VorbisBufferAdapter> > tmp(new OggStreamImpl<VorbisBufferAdapter>(VorbisBufferAdapter(contents, size)));
RETURN_ERR(tmp->Open());
RETURN_STATUS_IF_ERR(tmp->Open());
stream = tmp;
return INFO::OK;
}

View file

@ -12,19 +12,19 @@ public:
virtual ALsizei SamplingRate() = 0;
/**
* @return bytes read (<= size) or a (negative) LibError
* @return bytes read (<= size) or a (negative) Status
**/
virtual LibError GetNextChunk(u8* buffer, size_t size) = 0;
virtual Status GetNextChunk(u8* buffer, size_t size) = 0;
};
typedef shared_ptr<OggStream> OggStreamPtr;
extern LibError OpenOggStream(const OsPath& pathname, OggStreamPtr& stream);
extern Status OpenOggStream(const OsPath& pathname, OggStreamPtr& stream);
/**
* A non-streaming OggStream (reading the whole file in advance)
* that can cope with archived/compressed files.
*/
extern LibError OpenOggNonstream(const PIVFS& vfs, const VfsPath& pathname, OggStreamPtr& stream);
extern Status OpenOggNonstream(const PIVFS& vfs, const VfsPath& pathname, OggStreamPtr& stream);
#endif // INCLUDED_OGG

View file

@ -98,11 +98,11 @@ static bool al_initialized = false;
// used by snd_dev_set to reset OpenAL after device has been changed.
static LibError al_reinit();
static Status al_reinit();
// used by al_shutdown to free all VSrc and SndData objects, respectively,
// so that they release their OpenAL sources and buffers.
static LibError list_free_all();
static Status list_free_all();
static void hsd_list_free_all();
@ -147,7 +147,7 @@ static const char* alc_dev_name = 0;
* tell OpenAL to use the specified device in future.
*
* @param alc_new_dev_name Device name.
* @return LibError
* @return Status
*
* name = 0 reverts to OpenAL's default choice, which will also
* be used if this routine is never called.
@ -163,7 +163,7 @@ static const char* alc_dev_name = 0;
* re-initialize with the new device. that's fairly time-consuming,
* so preferably call this routine before sounds are loaded.
*/
LibError snd_dev_set(const char* alc_new_dev_name)
Status snd_dev_set(const char* alc_new_dev_name)
{
// requesting a specific device
if(alc_new_dev_name)
@ -216,11 +216,11 @@ static void alc_shutdown()
/**
* Ready OpenAL for use by setting up a device and context.
*
* @return LibError
* @return Status
*/
static LibError alc_init()
static Status alc_init()
{
LibError ret = INFO::OK;
Status ret = INFO::OK;
#if WIN_LOADLIBRARY_HACK
HMODULE dlls[3];
@ -329,9 +329,9 @@ static void al_listener_latch()
*
* @param gain Modifier: must be non-negative;
* 1 -> unattenuated, 0.5 -> -6 dB, 0 -> silence.
* @return LibError
* @return Status
*/
LibError snd_set_master_gain(float gain)
Status snd_set_master_gain(float gain)
{
if(gain < 0)
WARN_RETURN(ERR::INVALID_PARAM);
@ -572,9 +572,9 @@ static void al_src_free(ALuint al_src)
* implementation- defined ceiling anyway.
*
* @param limit max. number of sources
* @return LibError
* @return Status
*/
LibError snd_set_max_voices(size_t limit)
Status snd_set_max_voices(size_t limit)
{
// valid if cap is legit (less than what we allocated in al_src_init),
// or if al_src_init hasn't been called yet. note: we accept anything
@ -604,15 +604,15 @@ LibError snd_set_max_voices(size_t limit)
* master OpenAL init; makes sure all subsystems are ready for use.
* called from each snd_open; no harm if called more than once.
*
* @return LibError
* @return Status
*/
static LibError al_init()
static Status al_init()
{
// only take action on first call, OR when re-initializing.
if(al_initialized)
return INFO::OK;
RETURN_ERR(alc_init());
RETURN_STATUS_IF_ERR(alc_init());
al_initialized = true;
@ -659,9 +659,9 @@ static void al_shutdown()
/**
* re-initialize OpenAL. currently only required for changing devices.
*
* @return LibError
* @return Status
*/
static LibError al_reinit()
static Status al_reinit()
{
// not yet initialized. settings have been saved, and will be
// applied by the component init routines called from al_init.
@ -681,9 +681,9 @@ static bool snd_disabled = false;
* extra layer on top of al_init that allows 'disabling' sound.
* called from each snd_open.
*
* @return LibError from al_init, or ERR::AGAIN if sound disabled
* @return Status from al_init, or ERR::AGAIN if sound disabled
*/
static LibError snd_init()
static Status snd_init()
{
// (note: each VSrc_reload and therefore snd_open will fail)
if(snd_disabled)
@ -693,7 +693,7 @@ static LibError snd_init()
}
LibError snd_disable(bool disabled)
Status snd_disable(bool disabled)
{
snd_disabled = disabled;
@ -733,12 +733,12 @@ static const char* devs;
*
* may be called each time the device list is needed.
*
* @return LibError; always successful unless the requisite device
* @return Status; always successful unless the requisite device
* enumeration extension isn't available. in the latter case,
* a "cannot enum device" message should be presented to the user,
* and snd_dev_set need not be called; OpenAL will use its default device.
*/
LibError snd_dev_prepare_enum()
Status snd_dev_prepare_enum()
{
if(alcIsExtensionPresent(0, (alcString)"ALC_ENUMERATION_EXT") != AL_TRUE)
WARN_RETURN(ERR::NO_SYS);
@ -897,25 +897,25 @@ static void SndData_dtor(SndData* sd)
sd->ogg.reset();
}
static LibError SndData_reload(SndData* sd, const PIVFS& vfs, const VfsPath& pathname, Handle hsd)
static Status SndData_reload(SndData* sd, const PIVFS& vfs, const VfsPath& pathname, Handle hsd)
{
#if 0 // HACK: streaming disabled because it breaks archives
// (OGG streaming requires a real POSIX pathname - see OpenOggStream)
fs::wpath real_pathname;
RETURN_ERR(vfs->GetRealPath(pathname, real_pathname));
RETURN_STATUS_IF_ERR(vfs->GetRealPath(pathname, real_pathname));
// currently only supports OGG; WAV is no longer supported. writing our own loader is infeasible
// due to a seriously watered down spec with many incompatible variants.
// pulling in an external library (e.g. freealut) is deemed not worth the
// effort - OGG should be better in all cases.
RETURN_ERR(OpenOggStream(real_pathname, sd->ogg));
RETURN_STATUS_IF_ERR(OpenOggStream(real_pathname, sd->ogg));
const size_t size = fs::file_size(real_pathname);
#else
RETURN_ERR(OpenOggNonstream(vfs, pathname, sd->ogg));
RETURN_STATUS_IF_ERR(OpenOggNonstream(vfs, pathname, sd->ogg));
FileInfo fileInfo;
RETURN_ERR(vfs->GetFileInfo(pathname, &fileInfo));
RETURN_STATUS_IF_ERR(vfs->GetFileInfo(pathname, &fileInfo));
const size_t size = fileInfo.Size();
#endif
@ -930,8 +930,8 @@ static LibError SndData_reload(SndData* sd, const PIVFS& vfs, const VfsPath& pat
if(sd->type == SD_CLIP)
{
std::vector<u8> data(50*MiB); // max. size of any clip (anything larger should be streamed)
const LibError ret = sd->ogg->GetNextChunk(&data[0], data.size());
RETURN_ERR(ret);
const Status ret = sd->ogg->GetNextChunk(&data[0], data.size());
RETURN_STATUS_IF_ERR(ret);
const size_t size = (size_t)ret;
ENSURE(size != 0); // must have read something
ENSURE(size != data.size()); // shouldn't be limited by buffer size
@ -949,7 +949,7 @@ static LibError SndData_reload(SndData* sd, const PIVFS& vfs, const VfsPath& pat
return INFO::OK;
}
static LibError SndData_validate(const SndData* sd)
static Status SndData_validate(const SndData* sd)
{
if(sd->al_fmt == 0)
WARN_RETURN(ERR::_11);
@ -971,7 +971,7 @@ static LibError SndData_validate(const SndData* sd)
}
static LibError SndData_to_string(const SndData* sd, wchar_t* buf)
static Status SndData_to_string(const SndData* sd, wchar_t* buf)
{
const wchar_t* type = (sd->type == SD_CLIP)? L"clip" : L"stream";
swprintf_s(buf, H_STRING_LEN, L"%ls; al_buf=%d", type, sd->al_buf);
@ -982,7 +982,7 @@ static LibError SndData_to_string(const SndData* sd, wchar_t* buf)
/**
* open and return a handle to a sound file's data.
*
* @return Handle or LibError on failure
* @return Handle or Status on failure
*/
static Handle snd_data_load(const PIVFS& vfs, const VfsPath& pathname)
{
@ -993,9 +993,9 @@ static Handle snd_data_load(const PIVFS& vfs, const VfsPath& pathname)
* Free the sound.
*
* @param hsd Handle to SndData; set to 0 afterwards.
* @return LibError
* @return Status
*/
static LibError snd_data_free(Handle& hsd)
static Status snd_data_free(Handle& hsd)
{
return h_free(hsd, H_SndData);
}
@ -1008,11 +1008,11 @@ static LibError snd_data_free(Handle& hsd)
*
* @param hsd Handle to SndData.
* @param al_buf buffer name.
* @return LibError, most commonly:
* @return Status, most commonly:
* INFO::CB_CONTINUE = buffer has been returned; more are expected to be available.
* INFO::OK = buffer has been returned but is the last one (EOF).
*/
static LibError snd_data_buf_get(Handle hsd, ALuint& al_buf)
static Status snd_data_buf_get(Handle hsd, ALuint& al_buf)
{
H_DEREF(hsd, SndData, sd);
if(sd->type == SD_CLIP)
@ -1024,8 +1024,8 @@ static LibError snd_data_buf_get(Handle hsd, ALuint& al_buf)
if(!sd->ogg)
WARN_RETURN(ERR::INVALID_HANDLE);
u8 data[maxBufferSize];
const LibError ret = sd->ogg->GetNextChunk(data, maxBufferSize);
RETURN_ERR(ret);
const Status ret = sd->ogg->GetNextChunk(data, maxBufferSize);
RETURN_STATUS_IF_ERR(ret);
const size_t size = (size_t)ret;
al_buf = al_buf_alloc(data, (ALsizei)size, sd->al_fmt, sd->al_freq);
@ -1038,9 +1038,9 @@ static LibError snd_data_buf_get(Handle hsd, ALuint& al_buf)
*
* @param hsd Handle to SndData.
* @param al_buf buffer name
* @return LibError
* @return Status
*/
static LibError snd_data_buf_free(Handle hsd, ALuint al_buf)
static Status snd_data_buf_free(Handle hsd, ALuint al_buf)
{
H_DEREF(hsd, SndData, sd);
@ -1265,7 +1265,7 @@ static void VSrc_init(VSrc* vs, va_list UNUSED(args))
}
static void list_remove(VSrc* vs);
static LibError vsrc_reclaim(VSrc* vs);
static Status vsrc_reclaim(VSrc* vs);
static void VSrc_dtor(VSrc* vs)
{
@ -1281,16 +1281,16 @@ static void VSrc_dtor(VSrc* vs)
(void)snd_data_free(vs->hsd);
}
static LibError VSrc_reload(VSrc* vs, const PIVFS& vfs, const VfsPath& pathname, Handle hvs)
static Status VSrc_reload(VSrc* vs, const PIVFS& vfs, const VfsPath& pathname, Handle hvs)
{
// cannot wait till play(), need to init here:
// must load OpenAL so that snd_data_load can check for OGG extension.
LibError err = snd_init();
Status err = snd_init();
// .. don't complain if sound is disabled; fail silently.
if(err == ERR::AGAIN)
return err;
// .. catch genuine errors during init.
RETURN_ERR(err);
RETURN_STATUS_IF_ERR(err);
VfsPath dataPathname;
@ -1299,7 +1299,7 @@ static LibError VSrc_reload(VSrc* vs, const PIVFS& vfs, const VfsPath& pathname,
if(pathname.Extension() == L".txt")
{
shared_ptr<u8> buf; size_t size;
RETURN_ERR(vfs->LoadFile(pathname, buf, size));
RETURN_STATUS_IF_ERR(vfs->LoadFile(pathname, buf, size));
std::wistringstream def(std::wstring((wchar_t*)buf.get(), (int)size));
def >> dataPathname;
@ -1322,7 +1322,7 @@ static LibError VSrc_reload(VSrc* vs, const PIVFS& vfs, const VfsPath& pathname,
vsrc_reclaim(vs);
vs->hsd = snd_data_load(vfs, dataPathname);
RETURN_ERR(vs->hsd);
RETURN_STATUS_IF_ERR(vs->hsd);
return INFO::OK;
}
@ -1332,7 +1332,7 @@ static bool IsValidBoolean(ALboolean b)
return (b == AL_FALSE || b == AL_TRUE);
}
static LibError VSrc_validate(const VSrc* vs)
static Status VSrc_validate(const VSrc* vs)
{
// al_src can legitimately be 0 (if vs is low-pri)
if(vs->flags & ~VS_ALL_FLAGS)
@ -1348,7 +1348,7 @@ static LibError VSrc_validate(const VSrc* vs)
return INFO::OK;
}
static LibError VSrc_to_string(const VSrc* vs, wchar_t* buf)
static Status VSrc_to_string(const VSrc* vs, wchar_t* buf)
{
swprintf_s(buf, H_STRING_LEN, L"al_src = %d", vs->al_src);
return INFO::OK;
@ -1363,7 +1363,7 @@ static LibError VSrc_to_string(const VSrc* vs, wchar_t* buf)
* sound file name and its gain (0.0 .. 1.0).
* otherwise, it is taken to be the sound file name and
* gain is set to the default of 1.0 (no attenuation).
* @return Handle or LibError on failure
* @return Handle or Status on failure
*/
Handle snd_open(const PIVFS& vfs, const VfsPath& pathname)
{
@ -1379,9 +1379,9 @@ Handle snd_open(const PIVFS& vfs, const VfsPath& pathname)
* this is provided for completeness only.
*
* @param hvs Handle to VSrc. will be set to 0 afterwards.
* @return LibError
* @return Status
*/
LibError snd_free(Handle& hvs)
Status snd_free(Handle& hvs)
{
if(!hvs)
return INFO::OK;
@ -1499,7 +1499,7 @@ static void vsrc_free(VSrc* vs)
snd_free(vs->hvs);
}
static LibError list_free_all()
static Status list_free_all()
{
list_foreach(vsrc_free);
return INFO::OK;
@ -1612,7 +1612,7 @@ public:
{
}
LibError operator()(VSrc* vs) const
Status operator()(VSrc* vs) const
{
if(!vs->HasSource())
return INFO::OK;
@ -1649,8 +1649,8 @@ public:
{
// get next buffer
ALuint al_buf;
LibError ret = snd_data_buf_get(vs->hsd, al_buf);
RETURN_ERR(ret);
Status ret = snd_data_buf_get(vs->hsd, al_buf);
RETURN_STATUS_IF_ERR(ret);
if(ret == INFO::OK) // no further buffers will be forthcoming
vs->flags |= VS_EOF;
@ -1676,9 +1676,9 @@ private:
* Try to give the VSrc an AL source so that it can (re)start playing.
* called by snd_play and voice management.
*
* @return LibError (ERR::FAIL if no AL source is available)
* @return Status (ERR::FAIL if no AL source is available)
*/
static LibError vsrc_grant(VSrc* vs)
static Status vsrc_grant(VSrc* vs)
{
if(vs->HasSource()) // already playing
return INFO::OK;
@ -1709,7 +1709,7 @@ static LibError vsrc_grant(VSrc* vs)
* called when closing the VSrc, or when voice management decides
* this VSrc must yield to others of higher priority.
*/
static LibError vsrc_reclaim(VSrc* vs)
static Status vsrc_reclaim(VSrc* vs)
{
if(!vs->HasSource())
return ERR::FAIL; // NOWARN
@ -1761,9 +1761,9 @@ static LibError vsrc_reclaim(VSrc* vs)
* @param static_pri (min 0 .. max 1, default 0) indicates which sounds are
* considered more important; this is attenuated by distance to the
* listener (see snd_update).
* @return LibError
* @return Status
*/
LibError snd_play(Handle hvs, float static_pri)
Status snd_play(Handle hvs, float static_pri)
{
H_DEREF(hvs, VSrc, vs);
@ -1792,9 +1792,9 @@ LibError snd_play(Handle hvs, float static_pri)
* @param x,y,z coordinates (interpretation: see below)
* @param relative if true, (x,y,z) is treated as relative to the listener;
* otherwise, it is the position in world coordinates (default).
* @return LibError
* @return Status
*/
LibError snd_set_pos(Handle hvs, float x, float y, float z, bool relative)
Status snd_set_pos(Handle hvs, float x, float y, float z, bool relative)
{
H_DEREF(hvs, VSrc, vs);
@ -1816,9 +1816,9 @@ LibError snd_set_pos(Handle hvs, float x, float y, float z, bool relative)
* @param hvs Handle to VSrc
* @param gain modifier; must be non-negative;
* 1 -> unattenuated, 0.5 -> -6 dB, 0 -> silence.
* @return LibError
* @return Status
*/
LibError snd_set_gain(Handle hvs, float gain)
Status snd_set_gain(Handle hvs, float gain)
{
H_DEREF(hvs, VSrc, vs);
@ -1847,9 +1847,9 @@ LibError snd_set_gain(Handle hvs, float gain)
* @param hvs Handle to VSrc
* @param pitch shift: 1.0 means no change; each doubling/halving equals a
* pitch shift of +/-12 semitones (one octave). zero is invalid.
* @return LibError
* @return Status
*/
LibError snd_set_pitch(Handle hvs, float pitch)
Status snd_set_pitch(Handle hvs, float pitch)
{
H_DEREF(hvs, VSrc, vs);
@ -1878,7 +1878,7 @@ LibError snd_set_pitch(Handle hvs, float pitch)
*
* @param hvs Handle to VSrc
*/
LibError snd_set_loop(Handle hvs, bool loop)
Status snd_set_loop(Handle hvs, bool loop)
{
H_DEREF(hvs, VSrc, vs);
@ -1916,9 +1916,9 @@ LibError snd_set_loop(Handle hvs, bool loop)
* http://www.transom.org/tools/editing_mixing/200309.stupidfadetricks.html
* you can also pass FT_ABORT to stop fading (if in progress) and
* set gain to the final_gain parameter passed here.
* @return LibError
* @return Status
*/
LibError snd_fade(Handle hvs, float initial_gain, float final_gain,
Status snd_fade(Handle hvs, float initial_gain, float final_gain,
float length, FadeType type)
{
H_DEREF(hvs, VSrc, vs);
@ -2026,7 +2026,7 @@ static void reclaim(VSrc* vs)
* update voice management, i.e. recalculate priority and assign AL sources.
* no-op if OpenAL not yet initialized.
*/
static LibError vm_update()
static Status vm_update()
{
list_prune_removed();
@ -2056,9 +2056,9 @@ static LibError vm_update()
* world isn't initialized yet.
* @param dir view direction
* @param up up vector
* @return LibError
* @return Status
*/
LibError snd_update(const float* pos, const float* dir, const float* up)
Status snd_update(const float* pos, const float* dir, const float* up)
{
// there's no sense in updating anything if we weren't initialized
// yet (most notably, if sound is disabled). we check for this to

View file

@ -99,11 +99,11 @@ terminology
* snd_dev_next).
* may be called each time the device list is needed.
*
* @return LibError; fails iff the requisite OpenAL extension isn't available.
* @return Status; fails iff the requisite OpenAL extension isn't available.
* in that case, a "cannot enum device" message should be displayed, but
* snd_dev_set need not be called; OpenAL will use its default device.
**/
extern LibError snd_dev_prepare_enum();
extern Status snd_dev_prepare_enum();
/**
* get next device name in list.
@ -137,9 +137,9 @@ extern const char* snd_dev_next();
* re-initialize with the new device. that's fairly time-consuming,
* so preferably call this routine before sounds are loaded.
*
* @return LibError (the status returned by OpenAL re-init)
* @return Status (the status returned by OpenAL re-init)
**/
extern LibError snd_dev_set(const char* alc_new_dev_name);
extern Status snd_dev_set(const char* alc_new_dev_name);
/**
* Set maximum number of voices to play simultaneously;
@ -147,9 +147,9 @@ extern LibError snd_dev_set(const char* alc_new_dev_name);
*
* @param limit Maximum number of voices. Ignored if higher than
* an implementation-defined limit anyway.
* @return LibError
* @return Status
**/
extern LibError snd_set_max_voices(size_t limit);
extern Status snd_set_max_voices(size_t limit);
/**
* set amplitude modifier, which is effectively applied to all sounds.
@ -157,9 +157,9 @@ extern LibError snd_set_max_voices(size_t limit);
*
* @param gain amplitude modifier. must be non-negative;
* 1 -> unattenuated, 0.5 -> -6 dB, 0 -> silence.
* @return LibError
* @return Status
**/
extern LibError snd_set_master_gain(float gain);
extern Status snd_set_master_gain(float gain);
//
@ -176,7 +176,7 @@ extern LibError snd_set_master_gain(float gain);
* its gain (0.0 .. 1.0).
* Otherwise, it is taken to be the sound file name and
* gain is set to the default of 1.0 (no attenuation).
* @return Handle or LibError
* @return Handle or Status
**/
extern Handle snd_open(const PIVFS& vfs, const VfsPath& pathname);
@ -187,9 +187,9 @@ extern Handle snd_open(const PIVFS& vfs, const VfsPath& pathname);
* this API is provided for completeness only.
*
* @param hvs Handle to sound instance. Zeroed afterwards.
* @return LibError
* @return Status
**/
extern LibError snd_free(Handle& hvs);
extern Status snd_free(Handle& hvs);
/**
* Start playing the sound.
@ -206,9 +206,9 @@ extern LibError snd_free(Handle& hvs);
* voices are available). the static priority is attenuated by
* distance to the listener; see snd_update.
*
* @return LibError
* @return Status
**/
extern LibError snd_play(Handle hvs, float static_pri = 0.0f);
extern Status snd_play(Handle hvs, float static_pri = 0.0f);
/**
* Change 3d position of the sound source.
@ -220,9 +220,9 @@ extern LibError snd_play(Handle hvs, float static_pri = 0.0f);
* @param x,y,z
* @param relative treat (x,y,z) as relative to the listener;
* if false (the default), it is the position in world coordinates.
* @return LibError
* @return Status
**/
extern LibError snd_set_pos(Handle hvs, float x, float y, float z, bool relative = false);
extern Status snd_set_pos(Handle hvs, float x, float y, float z, bool relative = false);
/**
* change gain (amplitude modifier) of the sound source.
@ -233,9 +233,9 @@ extern LibError snd_set_pos(Handle hvs, float x, float y, float z, bool relative
*
* @param gain amplitude modifier. must be non-negative;
* 1 -\> unattenuated, 0.5 -\> -6 dB, 0 -\> silence.
* @return LibError
* @return Status
**/
extern LibError snd_set_gain(Handle hs, float gain);
extern Status snd_set_gain(Handle hs, float gain);
/**
* change pitch shift of the sound source.
@ -245,9 +245,9 @@ extern LibError snd_set_gain(Handle hs, float gain);
*
* @param pitch shift: 1.0 means no change; each doubling/halving equals a
* pitch shift of +/-12 semitones (one octave). zero is invalid.
* @return LibError
* @return Status
**/
extern LibError snd_set_pitch(Handle hs, float pitch);
extern Status snd_set_pitch(Handle hs, float pitch);
/**
* Enable/disable looping on the sound source.
@ -264,9 +264,9 @@ extern LibError snd_set_pitch(Handle hs, float pitch);
*
* @param hvs Handle to the sound.
* @param loop Boolean to enable/disable lopping on the sound.
* @return LibError
* @return Status
**/
extern LibError snd_set_loop(Handle hvs, bool loop);
extern Status snd_set_loop(Handle hvs, bool loop);
/// types of fade in/out operations
enum FadeType
@ -312,9 +312,9 @@ enum FadeType
* It is safe to start another fade on the same sound source while
* one is already in progress; the old one will be discarded.
*
* @return LibError
* @return Status
**/
extern LibError snd_fade(Handle hvs, float initial_gain, float final_gain,
extern Status snd_fade(Handle hvs, float initial_gain, float final_gain,
float length, FadeType type);
@ -338,9 +338,9 @@ extern LibError snd_fade(Handle hvs, float initial_gain, float final_gain,
* will be applied and subsequent sound load / play requests will work.
*
* @param disabled
* @return LibError
* @return Status
**/
extern LibError snd_disable(bool disabled);
extern Status snd_disable(bool disabled);
/**
* Perform housekeeping (e.g. streaming); call once a frame.
@ -351,9 +351,9 @@ extern LibError snd_disable(bool disabled);
* @param pos listener's position
* @param dir listener view direction
* @param up listener's local up vector
* @return LibError
* @return Status
**/
extern LibError snd_update(const float* pos, const float* dir, const float* up);
extern Status snd_update(const float* pos, const float* dir, const float* up);
/**
* find out if a sound is still playing

View file

@ -35,7 +35,7 @@
// we were included from wsecure_crt.cpp; skip all stuff that
// must only be done once.
#ifndef WSECURE_CRT
ERROR_ASSOCIATE(ERR::STRING_NOT_TERMINATED, L"Invalid string (no 0 terminator found in buffer)", -1);
STATUS_DEFINE(ERR, STRING_NOT_TERMINATED, L"Invalid string (no 0 terminator found in buffer)", -1);
#endif

View file

@ -29,11 +29,11 @@
#include <stdarg.h>
#include "lib/lib_errors.h"
#include "lib/status.h"
namespace ERR
{
const LibError STRING_NOT_TERMINATED = -100600;
const Status STRING_NOT_TERMINATED = -100600;
}
// if the platform lacks a secure CRT implementation, we'll provide one.

View file

@ -182,7 +182,7 @@ extern bool self_test_active;
// for convenience, to avoid having to include all of these manually
#include "lib/lib_errors.h"
#include "lib/status.h"
#include "lib/os_path.h"
#include "lib/posix/posix.h"

170
source/lib/status.cpp Normal file
View file

@ -0,0 +1,170 @@
/* Copyright (c) 2011 Wildfire Games
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* error handling system: defines status codes, translates them to/from
* other schemes (e.g. errno), associates them with descriptive text,
* simplifies propagating errors / checking if functions failed.
*/
#include "precompiled.h"
#include "lib/status.h"
#include <cstring>
#include <cstdio>
#include "lib/posix/posix_errno.h"
// linked list (most recent first)
// note: no memory is allocated, all nodes are static instances.
//
// rationale: don't use a std::map. we don't care about lookup speed,
// dynamic allocation would be ugly, and returning a local static object
// from a function doesn't work, either (the compiler generates calls to
// atexit, which leads to disaster since we're sometimes called before
// the CRT has initialized)
static StatusDefinition* definitions;
int StatusAddDefinition(StatusDefinition* def)
{
// insert at front of list
def->next = definitions;
definitions = def;
return 0; // stored in dummy variable
}
static const StatusDefinition* DefinitionFromStatus(Status status)
{
for(const StatusDefinition* def = definitions; def; def = def->next)
{
if(def->status == status)
return def;
}
return 0;
}
static const StatusDefinition* DefinitionFromErrno(int errno_equivalent)
{
for(const StatusDefinition* def = definitions; def; def = def->next)
{
if(def->errno_equivalent == errno_equivalent)
return def;
}
return 0;
}
wchar_t* StatusDescription(Status status, wchar_t* buf, size_t max_chars)
{
const StatusDefinition* def = DefinitionFromStatus(status);
if(def)
{
wcscpy_s(buf, max_chars, def->description);
return buf;
}
swprintf_s(buf, max_chars, L"Unknown error (%d, 0x%X)", (int)status, (unsigned int)status);
return buf;
}
int ErrnoFromStatus(Status status)
{
const StatusDefinition* def = DefinitionFromStatus(status);
if(def && def->errno_equivalent != -1)
return def->errno_equivalent;
// the set of errnos in wposix.h doesn't have an "unknown error".
// we use this one as a default because it's not expected to come up often.
return EPERM;
}
Status StatusFromErrno()
{
const StatusDefinition* def = DefinitionFromErrno(errno);
return def? def->status : ERR::FAIL;
}
//-----------------------------------------------------------------------------
// INFO::OK doesn't really need a string because calling StatusDescription(0)
// should never happen, but we'll play it safe.
STATUS_DEFINE(INFO, OK, L"(but return value was 0 which indicates success)", -1);
STATUS_DEFINE(ERR, FAIL, L"Function failed (no details available)", -1);
STATUS_DEFINE(INFO, CB_CONTINUE, L"Continue (not an error)", -1);
STATUS_DEFINE(INFO, SKIPPED, L"Skipped (not an error)", -1);
STATUS_DEFINE(INFO, CANNOT_HANDLE, L"Cannot handle (not an error)", -1);
STATUS_DEFINE(INFO, ALL_COMPLETE, L"All complete (not an error)", -1);
STATUS_DEFINE(INFO, ALREADY_EXISTS, L"Already exists (not an error)", -1);
STATUS_DEFINE(ERR, LOGIC, L"Logic error in code", -1);
STATUS_DEFINE(ERR, TIMED_OUT, L"Timed out", -1);
STATUS_DEFINE(ERR, REENTERED, L"Single-call function was reentered", -1);
STATUS_DEFINE(ERR, CORRUPTED, L"File/memory data is corrupted", -1);
STATUS_DEFINE(ERR, VERSION, L"Version mismatch", -1);
STATUS_DEFINE(ERR, INVALID_PARAM, L"Invalid function argument", EINVAL);
STATUS_DEFINE(ERR, INVALID_HANDLE, L"Invalid Handle (argument)", -1);
STATUS_DEFINE(ERR, BUF_SIZE, L"Buffer argument too small", -1);
STATUS_DEFINE(ERR, AGAIN, L"Try again later", -1);
STATUS_DEFINE(ERR, LIMIT, L"Fixed limit exceeded", -1);
STATUS_DEFINE(ERR, NO_SYS, L"OS doesn't provide a required API", -1);
STATUS_DEFINE(ERR, NOT_IMPLEMENTED, L"Feature currently not implemented", ENOSYS);
STATUS_DEFINE(ERR, NOT_SUPPORTED, L"Feature isn't and won't be supported", -1);
STATUS_DEFINE(ERR, NO_MEM, L"Not enough memory", ENOMEM);
STATUS_DEFINE(ERR, _1, L"Case 1", -1);
STATUS_DEFINE(ERR, _2, L"Case 2", -1);
STATUS_DEFINE(ERR, _3, L"Case 3", -1);
STATUS_DEFINE(ERR, _4, L"Case 4", -1);
STATUS_DEFINE(ERR, _5, L"Case 5", -1);
STATUS_DEFINE(ERR, _6, L"Case 6", -1);
STATUS_DEFINE(ERR, _7, L"Case 7", -1);
STATUS_DEFINE(ERR, _8, L"Case 8", -1);
STATUS_DEFINE(ERR, _9, L"Case 9", -1);
STATUS_DEFINE(ERR, _11, L"Case 11", -1);
STATUS_DEFINE(ERR, _12, L"Case 12", -1);
STATUS_DEFINE(ERR, _13, L"Case 13", -1);
STATUS_DEFINE(ERR, _14, L"Case 14", -1);
STATUS_DEFINE(ERR, _15, L"Case 15", -1);
STATUS_DEFINE(ERR, _16, L"Case 16", -1);
STATUS_DEFINE(ERR, _17, L"Case 17", -1);
STATUS_DEFINE(ERR, _18, L"Case 18", -1);
STATUS_DEFINE(ERR, _19, L"Case 19", -1);
STATUS_DEFINE(ERR, _21, L"Case 21", -1);
STATUS_DEFINE(ERR, _22, L"Case 22", -1);
STATUS_DEFINE(ERR, _23, L"Case 23", -1);
STATUS_DEFINE(ERR, _24, L"Case 24", -1);
STATUS_DEFINE(ERR, _25, L"Case 25", -1);
STATUS_DEFINE(ERR, _26, L"Case 26", -1);
STATUS_DEFINE(ERR, _27, L"Case 27", -1);
STATUS_DEFINE(ERR, _28, L"Case 28", -1);
STATUS_DEFINE(ERR, _29, L"Case 29", -1);

430
source/lib/status.h Normal file
View file

@ -0,0 +1,430 @@
/* Copyright (c) 2010 Wildfire Games
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* error handling system: defines status codes, translates them to/from
* other schemes (e.g. errno), associates them with descriptive text,
* simplifies propagating errors / checking if functions failed.
*/
/**
Error handling system
Why Error Codes?
----------------
To convey information about what failed, the alternatives are unique
integral codes and direct pointers to descriptive text. Both occupy the
same amount of space, but codes are easier to internationalize.
Method of Propagating Errors
----------------------------
When a low-level function has failed, this must be conveyed to the
higher-level application logic across several functions on the call stack.
There are two alternatives:
1) check at each call site whether a function failed;
if so, return to the caller.
2) throw an exception.
We will discuss the advantages and disadvantages of exceptions,
which are the opposites of call site checking.
- performance: they shouldn't be used in time-critical code.
- predictability: exceptions can come up almost anywhere,
so it is hard to say what execution path will be taken.
- interoperability: not compatible with other languages.
+ readability: cleans up code by separating application logic and
error handling. however, this is also a disadvantage because it
may be difficult to see at a glance if a piece of code does
error checking at all.
+ visibility: errors are more likely to be seen than relying on
callers to check return codes; less reliant on discipline.
Both have their place. Our recommendation is to throw error code
exceptions when checking call sites and propagating errors becomes tedious.
However, inter-module boundaries should always return error codes for
interoperability with other languages.
Simplifying Call-Site Checking
------------------------------
As mentioned above, this approach requires discipline. We provide
"enforcer" macros to simplify this task by propagating errors to
the calling function.
Consider the following example:
Status status = doWork();
if(status != INFO::OK)
return status;
This can be replaced by:
RETURN_STATUS_IF_ERR(doWork());
This provides a visible sign that the code handles errors but
reduces clutter.
When to warn the user?
----------------------
When a function fails, there are 2 places we can raise a warning:
as soon as the error condition is known, or higher on the call stack.
We prefer the former because it is easier to ensure that all
possible return paths have been covered: search for all "return ERR::*"
or "return StatusFrom*" that are not followed by a "// NOWARN" comment.
The latter approach also risks multiple warnings along the
call stack for the same error.
Note the special case of "validator" functions that e.g. verify the
state of an object: we now discuss pros/cons of just returning errors
without warning, and having their callers take care of that.
+ they typically have many return paths (-> increased code size)
- this is balanced by validators that have many call sites.
- we want all return statements wrapped for consistency and
easily checking if any were forgotten
- adding // NOWARN to each validator return statement would be tedious.
- there is no advantage to checking at the call site; the call stack
indicates which caller of the validator failed anyway.
Validator functions should therefore also use WARN_RETURN.
Numbering Scheme
----------------
Each module header defines its own error codes to avoid a full rebuild
whenever a new code is added.
Error codes start at -100000 (warnings are positive, but the
corresponding negative value should not be used to avoid confusion).
This scheme avoids collisions with all other known error codes.
Each header gets 100 possible values; the tens value may be
used to denote groups within that header.
The subsystem is denoted by the ten-thousands digit:
0 general
1 file
2 res (resource management)
3 sysdep (system-dependent)
4 win (Windows-specific)
To summarize: +/-1SHHCC (S=subsystem, HH=header, CC=code number)
10 general
00CC misc
03CC path
04CC debug
05CC debug_stl
06CC secure_crt
07CC wchar
11 file
01CC vfs
03CC file
04CC archive
12 res
01CC tex
02CC ogl_shader
13 sysdep
00CC cpu
01CC os_cpu
14 win
00CC whrt
**/
#ifndef INCLUDED_STATUS
#define INCLUDED_STATUS
#include "lib/lib_api.h"
// an integral type allows defining error codes in individual headers,
// but is not as type-safe as an enum. use Lint's 'strong type' checking
// to catch errors such as Status Func() { return 1; }.
// this must be signed and 64-bit because some functions may multiplex
// file offsets/sizes and Status in their return value.
typedef i64 Status;
// opaque - do not access its fields!
// note: must be defined here because clients instantiate them;
// fields cannot be made private due to POD requirements.
struct StatusDefinition // POD
{
Status status;
// must remain valid until end of program.
const wchar_t* description;
StatusDefinition* next;
int errno_equivalent; // (-1 if there is none)
};
/**
* associating a Status with a description and errno equivalent.
* @return dummy integer to allow calling via static initializer.
**/
LIB_API int StatusAddDefinition(StatusDefinition*);
// associate a Status with a description and errno equivalent.
// Invoke this at file or function scope.
#define STATUS_DEFINE(namespaceName, identifier, description, errno_equivalent)\
static StatusDefinition identifier##_def = { namespaceName::identifier, description, NULL, errno_equivalent };\
static int identifier##_dummy = StatusAddDefinition(&identifier##_def)
/**
* generate textual description of a Status.
*
* @param buf destination buffer (allows generating strings with
* the code's numerical value if no definition is found)
* @param max_chars size of buffer [characters]
* @return buf (allows using this function in expressions)
**/
LIB_API wchar_t* StatusDescription(Status status, wchar_t* buf, size_t max_chars);
//-----------------------------------------------------------------------------
// conversion to/from other error code definitions.
// note: other conversion routines (e.g. to/from Win32) are implemented in
// the corresponding modules to keep this header portable.
/**
* @return the errno equivalent of a Status.
*
* used in wposix - underlying functions return Status but must be
* translated to errno at e.g. the mmap interface level. higher-level code
* that calls mmap will in turn convert back to Status.
**/
extern int ErrnoFromStatus(Status status);
/**
* @return Status equivalent of errno, or ERR::FAIL if there's no equivalent.
* should only be called directly after a POSIX function indicates failure;
* errno may otherwise still be set from another error cause.
**/
extern Status StatusFromErrno();
//-----------------------------------------------------------------------------
// warn and return a status. use when an error is first detected to
// begin propagating it to callers.
#define WARN_RETURN(status)\
do\
{\
DEBUG_WARN_ERR(status);\
return status;\
}\
while(0)
// warn if expression is negative, i.e. an error.
// (this macro is more convenient than ENSURE)
#define WARN_IF_ERR(expression)\
do\
{\
const Status status_ = (expression);\
if(status_ < 0)\
DEBUG_WARN_ERR(status_);\
}\
while(0)
// return expression if it is negative, i.e. pass on errors to
// the caller. use when failures are common/expected.
#define RETURN_STATUS_IF_ERR(expression)\
do\
{\
const Status status_ = (expression);\
if(status_ < 0)\
return status_;\
}\
while(0)
// warn and return expression if it is negative.
// use if a function doesn't raise warnings when it returns errors.
#define WARN_RETURN_STATUS_IF_ERR(expression)\
do\
{\
const Status status_ = (expression);\
if(status_ < 0)\
{\
DEBUG_WARN_ERR(status_);\
return status_;\
}\
}\
while(0)
// warn and throw expression if it is negative. use to propagate
// errors from within constructors.
#define THROW_STATUS_IF_ERR(expression)\
do\
{\
const Status status_ = (expression);\
if(status_ < 0)\
{\
DEBUG_WARN_ERR(status_);\
throw status_;\
}\
}\
while(0)
// return 0 if expression is negative. use in functions that return pointers.
#define RETURN_0_IF_ERR(expression)\
do\
{\
const Status status_ = (expression);\
if(status_ < 0)\
return 0;\
}\
while(0)
// return expression if it evaluates to something other than
// INFO::CB_CONTINUE. use when invoking callbacks.
#define RETURN_IF_NOT_CONTINUE(expression)\
do\
{\
const Status status_ = (expression);\
if(status_ != INFO::CB_CONTINUE)\
return status_;\
}\
while(0)
// warn if expression is false, i.e. zero.
#define WARN_IF_FALSE(expression)\
do\
{\
if(!(expression))\
debug_warn(L"FYI: WARN_IF_FALSE reports that a function failed. Feel free to ignore or suppress this warning.");\
}\
while(0)
// warn and return 0 if expression is false, i.e. zero.
#define WARN_RETURN_0_IF_FALSE(expression)\
do\
{\
if(!(expression))\
{\
debug_warn(L"FYI: WARN_RETURN_0_IF_FALSE reports that a function failed. Feel free to ignore or suppress this warning.");\
return 0;\
}\
}\
while(0)
//-----------------------------------------------------------------------------
namespace INFO
{
const Status OK = 0;
// note: these values are > 100 to allow multiplexing them with
// coroutine return values, which return completion percentage.
// function is a callback and indicates that it can (but need not
// necessarily) be called again.
const Status CB_CONTINUE = +100000;
// notify caller that nothing was done.
const Status SKIPPED = +100001;
// function is incapable of doing the requested task with the given inputs.
// this implies SKIPPED, but also conveys a bit more information.
const Status CANNOT_HANDLE = +100002;
// function is meant to be called repeatedly, and now indicates that
// all jobs are complete.
const Status ALL_COMPLETE = +100003;
// (returned e.g. when inserting into container)
const Status ALREADY_EXISTS = +100004;
} // namespace INFO
namespace ERR
{
const Status FAIL = -1;
// general
const Status LOGIC = -100010;
const Status TIMED_OUT = -100011;
const Status REENTERED = -100012;
const Status CORRUPTED = -100013;
const Status VERSION = -100014;
// function arguments
const Status INVALID_PARAM = -100020;
const Status INVALID_HANDLE = -100021;
const Status BUF_SIZE = -100022;
// system limitations
const Status AGAIN = -100030;
const Status LIMIT = -100031;
const Status NO_SYS = -100032;
const Status NOT_IMPLEMENTED = -100033;
const Status NOT_SUPPORTED = -100034;
const Status NO_MEM = -100035;
// these are for cases where we just want a distinct value to display and
// a symbolic name + string would be overkill (e.g. the various
// test cases in a validate() call). they are shared between multiple
// functions; when something fails, the stack trace will show in which
// one it was => these errors are unambiguous.
// there are 3 tiers - 1..9 are used in most functions, 11..19 are
// used in a function that calls another validator and 21..29 are
// for for functions that call 2 other validators (this avoids
// ambiguity as to which error actually happened where)
const Status _1 = -100101;
const Status _2 = -100102;
const Status _3 = -100103;
const Status _4 = -100104;
const Status _5 = -100105;
const Status _6 = -100106;
const Status _7 = -100107;
const Status _8 = -100108;
const Status _9 = -100109;
const Status _11 = -100111;
const Status _12 = -100112;
const Status _13 = -100113;
const Status _14 = -100114;
const Status _15 = -100115;
const Status _16 = -100116;
const Status _17 = -100117;
const Status _18 = -100118;
const Status _19 = -100119;
const Status _21 = -100121;
const Status _22 = -100122;
const Status _23 = -100123;
const Status _24 = -100124;
const Status _25 = -100125;
const Status _26 = -100126;
const Status _27 = -100127;
const Status _28 = -100128;
const Status _29 = -100129;
} // namespace ERR
#endif // #ifndef INCLUDED_STATUS

View file

@ -95,7 +95,7 @@ static bool IsCall(void* ret_addr, void*& target)
return false;
}
LibError ia32_GetCallTarget(void* ret_addr, void*& target)
Status ia32_GetCallTarget(void* ret_addr, void*& target)
{
if(IsCall(ret_addr, target))
{

View file

@ -41,6 +41,6 @@
*
* this function is used for walking the call stack.
**/
LIB_API LibError ia32_GetCallTarget(void* ret_addr, void*& target);
LIB_API Status ia32_GetCallTarget(void* ret_addr, void*& target);
#endif // #ifndef INCLUDED_IA32

View file

@ -602,7 +602,7 @@ static void DetectCacheAndTLB(size_t& descriptorFlags)
} // namespace CPUID2
static LibError DetectCacheAndTLB()
static Status DetectCacheAndTLB()
{
// ensure all cache entries are initialized (DetectCache* might not set them all)
for(size_t idxLevel = 0; idxLevel < x86_x64_Cache::maxLevels; idxLevel++)

View file

@ -147,7 +147,7 @@ static bool AreApicIdsUnique(u8* apicIds, size_t numIds)
static u8 apicIdStorage[os_cpu_MaxProcessors];
static const u8* apicIds; // = apicIdStorage, or 0 if IDs invalid
static LibError InitApicIds()
static Status InitApicIds()
{
struct StoreEachProcessorsApicId
{
@ -218,7 +218,7 @@ struct CpuTopology // POD
static CpuTopology cpuTopology;
static ModuleInitState cpuInitState;
static LibError InitCpuTopology()
static Status InitCpuTopology()
{
const size_t maxLogicalPerCore = MaxLogicalPerCore();
const size_t maxCoresPerPackage = MaxCoresPerPackage();
@ -511,7 +511,7 @@ struct CacheTopology // POD
static CacheTopology cacheTopology;
static ModuleInitState cacheInitState;
static LibError InitCacheTopology()
static Status InitCacheTopology()
{
const u8* apicIds = ApicIds();
DetermineCachesProcessorMask(apicIds, cacheTopology.cachesProcessorMask, cacheTopology.numCaches);

View file

@ -88,7 +88,7 @@ static void cpuid(x86_x64_CpuidRegs* regs)
static u32 cpuid_maxFunction;
static u32 cpuid_maxExtendedFunction;
static LibError InitCpuid()
static Status InitCpuid()
{
x86_x64_CpuidRegs regs = { 0 };
@ -128,7 +128,7 @@ static u32 caps[4];
static ModuleInitState capsInitState;
static LibError InitCaps()
static Status InitCaps()
{
x86_x64_CpuidRegs regs = { 0 };
regs.eax = 1;
@ -177,7 +177,7 @@ void x86_x64_caps(u32* d0, u32* d1, u32* d2, u32* d3)
static x86_x64_Vendors vendor;
static LibError InitVendor()
static Status InitVendor()
{
x86_x64_CpuidRegs regs = { 0 };
regs.eax = 0;
@ -220,7 +220,7 @@ static size_t model;
static size_t family;
static ModuleInitState signatureInitState;
static LibError InitSignature()
static Status InitSignature()
{
x86_x64_CpuidRegs regs = { 0 };
regs.eax = 1;
@ -287,7 +287,7 @@ private:
// 3 calls x 4 registers x 4 bytes = 48 + 0-terminator
static char identifierString[48+1];
static LibError InitIdentifierString()
static Status InitIdentifierString()
{
// get brand string (if available)
char* pos = identifierString;

View file

@ -21,7 +21,7 @@
*/
// "copy" text into the clipboard. replaces previous contents.
extern LibError sys_clipboard_set(const wchar_t* text);
extern Status sys_clipboard_set(const wchar_t* text);
// allow "pasting" from clipboard. returns the current contents if they
// can be represented as text, otherwise 0.
@ -31,4 +31,4 @@ extern wchar_t* sys_clipboard_get();
// frees memory used by <copy>, which must have been returned by
// sys_clipboard_get. see note above.
extern LibError sys_clipboard_free(wchar_t* copy);
extern Status sys_clipboard_free(wchar_t* copy);

View file

@ -27,9 +27,9 @@
#include "precompiled.h"
#include "lib/sysdep/cpu.h"
ERROR_ASSOCIATE(ERR::CPU_FEATURE_MISSING, L"This CPU doesn't support a required feature", -1);
ERROR_ASSOCIATE(ERR::CPU_UNKNOWN_OPCODE, L"Disassembly failed", -1);
ERROR_ASSOCIATE(ERR::CPU_UNKNOWN_VENDOR, L"CPU vendor unknown", -1);
STATUS_DEFINE(ERR, CPU_FEATURE_MISSING, L"This CPU doesn't support a required feature", -1);
STATUS_DEFINE(ERR, CPU_UNKNOWN_OPCODE, L"Disassembly failed", -1);
STATUS_DEFINE(ERR, CPU_UNKNOWN_VENDOR, L"CPU vendor unknown", -1);
// ensure the actual pointer size matches expectations on the most common

View file

@ -32,9 +32,9 @@
namespace ERR
{
const LibError CPU_FEATURE_MISSING = -130000;
const LibError CPU_UNKNOWN_OPCODE = -130001;
const LibError CPU_UNKNOWN_VENDOR = -130002;
const Status CPU_FEATURE_MISSING = -130000;
const Status CPU_UNKNOWN_OPCODE = -130001;
const Status CPU_UNKNOWN_VENDOR = -130002;
}

View file

@ -41,7 +41,7 @@ typedef void* sys_cursor;
* @param cursor Is 0 if the return code indicates failure, otherwise
* a valid cursor that must be sys_cursor_free-ed when no longer needed.
**/
extern LibError sys_cursor_create(int w, int h, void* bgra_img, int hx, int hy, sys_cursor* cursor);
extern Status sys_cursor_create(int w, int h, void* bgra_img, int hx, int hy, sys_cursor* cursor);
/**
* Create a transparent cursor (used to hide the system cursor).
@ -49,26 +49,26 @@ extern LibError sys_cursor_create(int w, int h, void* bgra_img, int hx, int hy,
* @param cursor is 0 if the return code indicates failure, otherwise
* a valid cursor that must be sys_cursor_free-ed when no longer needed.
**/
extern LibError sys_cursor_create_empty(sys_cursor* cursor);
extern Status sys_cursor_create_empty(sys_cursor* cursor);
/**
* override the current system cursor.
*
* @param cursor can be 0 to restore the default.
**/
extern LibError sys_cursor_set(sys_cursor cursor);
extern Status sys_cursor_set(sys_cursor cursor);
/**
* destroy the indicated cursor and frees its resources.
*
* @param cursor if currently in use, the default cursor is restored first.
**/
extern LibError sys_cursor_free(sys_cursor cursor);
extern Status sys_cursor_free(sys_cursor cursor);
/**
* reset any cached cursor data.
* on some systems, this is needed when resetting the SDL video subsystem.
**/
extern LibError sys_cursor_reset();
extern Status sys_cursor_reset();
#endif // #ifndef INCLUDED_SYSDEP_CURSOR

View file

@ -49,7 +49,7 @@ typedef shared_ptr<DirWatch> PDirWatch;
* convenient to store PDirWatch there instead of creating a second
* tree structure here.
**/
LIB_API LibError dir_watch_Add(const OsPath& path, PDirWatch& dirWatch);
LIB_API Status dir_watch_Add(const OsPath& path, PDirWatch& dirWatch);
class DirWatchNotification
{
@ -87,7 +87,7 @@ typedef std::vector<DirWatchNotification> DirWatchNotifications;
* return all pending directory watch notifications.
*
* @param notifications receives any pending notifications in unspecified order.
* @return LibError (INFO::OK doesn't imply notifications were returned)
* @return Status (INFO::OK doesn't imply notifications were returned)
*
* note: the run time of this function is independent of the number of
* directory watches and number of files.
@ -96,6 +96,6 @@ typedef std::vector<DirWatchNotification> DirWatchNotifications;
* typically want to receive change notifications at a single point,
* rather than deal with the complexity of asynchronous notifications.
**/
LIB_API LibError dir_watch_Poll(DirWatchNotifications& notifications);
LIB_API Status dir_watch_Poll(DirWatchNotifications& notifications);
#endif // #ifndef INCLUDED_DIR_WATCH

Some files were not shown because too many files have changed in this diff Show more