mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-07-04 05:55:47 -07:00
lib.h: have CHECK|RETURN_ERR etc. store+compare as i64 (safer). document details.
h_mgr.h: debug_warn if H_DEREF fails have vfs / res functions only CHECK_ERR (i.e. complain) once per call sequence. made sure vfs_load and vfs_open debug_warn and everything else just passes on the error. This was SVN commit r2482.
This commit is contained in:
parent
24da4d7c7d
commit
5754128dec
7 changed files with 53 additions and 40 deletions
|
|
@ -96,52 +96,56 @@ STMT(\
|
|||
)
|
||||
|
||||
|
||||
// note: UINT_MAX is necessary when testing a Handle value and
|
||||
// also returning Handle. the negative value (error return)
|
||||
// is guaranteed to fit into an int, but we need to "mask"
|
||||
// it to avoid VC cast-to-smaller-type warnings.
|
||||
// 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 int (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.
|
||||
|
||||
#ifdef _WIN32
|
||||
#define CHECK_ERR(func)\
|
||||
#define CHECK_ERR(expression)\
|
||||
STMT(\
|
||||
int err__ = (int)((func) & UINT_MAX);\
|
||||
i64 err__ = (i64)(expression);\
|
||||
if(err__ < 0)\
|
||||
{\
|
||||
debug_assert(0 && "FYI: CHECK_ERR reports that a function failed."\
|
||||
"feel free to ignore or suppress this warning.");\
|
||||
return err__;\
|
||||
debug_warn("FYI: CHECK_ERR reports that a function failed."\
|
||||
"feel free to ignore or suppress this warning.");\
|
||||
return (int)(err__ & UINT_MAX);\
|
||||
}\
|
||||
)
|
||||
#else
|
||||
#define CHECK_ERR(func)\
|
||||
#define CHECK_ERR(expression)\
|
||||
STMT(\
|
||||
int err__ = (int)((func) & UINT_MAX);\
|
||||
i64 err__ = (i64)(expression);\
|
||||
if(err__ < 0)\
|
||||
{\
|
||||
debug_printf("%s:%d: FYI: CHECK_ERR reports that a function failed."\
|
||||
"feel free to ignore or suppress this warning.\n", __FILE__, __LINE__);\
|
||||
return err__;\
|
||||
return (int)(err__ & UINT_MAX);\
|
||||
}\
|
||||
)
|
||||
#endif
|
||||
|
||||
// just pass on errors without any kind of annoying warning
|
||||
// (useful for functions that can legitimately fail, e.g. vfs_exists).
|
||||
#define RETURN_ERR(func)\
|
||||
#define RETURN_ERR(expression)\
|
||||
STMT(\
|
||||
int err__ = (int)((func) & UINT_MAX);\
|
||||
i64 err__ = (i64)(expression);\
|
||||
if(err__ < 0)\
|
||||
return err__;\
|
||||
return (int)(err__ & UINT_MAX);\
|
||||
)
|
||||
|
||||
#define THROW_ERR(func)\
|
||||
#define THROW_ERR(expression)\
|
||||
STMT(\
|
||||
int err__ = (int)((func) & UINT_MAX);\
|
||||
i64 err__ = (i64)(expression);\
|
||||
if(err__ < 0)\
|
||||
{\
|
||||
debug_assert(0 && "FYI: CHECK_ERR reports that a function failed."\
|
||||
"feel free to ignore or suppress this warning.");\
|
||||
throw err__;\
|
||||
debug_warn("FYI: CHECK_ERR reports that a function failed."\
|
||||
"feel free to ignore or suppress this warning.");\
|
||||
throw (int)(err__ & UINT_MAX);\
|
||||
}\
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ static int Cursor_reload(Cursor* c, const char* name, Handle)
|
|||
void* p;
|
||||
size_t size;
|
||||
Handle hm = vfs_load(filename, p, size);
|
||||
CHECK_ERR(hm);
|
||||
RETURN_ERR(hm);
|
||||
|
||||
std::stringstream s(std::string((const char*)p, size));
|
||||
s >> hotspotx >> hotspoty;
|
||||
|
|
|
|||
|
|
@ -135,7 +135,10 @@ typedef H_VTbl* H_Type;
|
|||
/* don't use STMT - var decl must be visible to "caller" */\
|
||||
type* const var = H_USER_DATA(h, type);\
|
||||
if(!var)\
|
||||
return ERR_INVALID_HANDLE;
|
||||
{\
|
||||
debug_warn("H_DEREF failed");\
|
||||
return ERR_INVALID_HANDLE;\
|
||||
}
|
||||
|
||||
|
||||
// all functions check the passed tag (part of the handle) and type against
|
||||
|
|
|
|||
|
|
@ -986,7 +986,7 @@ static int SndData_reload(SndData* sd, const char* fn, Handle hsd)
|
|||
|
||||
void* file;
|
||||
size_t file_size;
|
||||
CHECK_ERR(vfs_load(fn, file, file_size));
|
||||
RETURN_ERR(vfs_load(fn, file, file_size));
|
||||
|
||||
ALvoid* al_data = file;
|
||||
ALsizei al_size = (ALsizei)file_size;
|
||||
|
|
@ -1473,7 +1473,7 @@ static int VSrc_reload(VSrc* vs, const char* fn, Handle hvs)
|
|||
{
|
||||
void* def_file;
|
||||
size_t def_size;
|
||||
CHECK_ERR(vfs_load(fn, def_file, def_size));
|
||||
RETURN_ERR(vfs_load(fn, def_file, def_size));
|
||||
std::istringstream def(std::string((char*)def_file, (int)def_size));
|
||||
mem_free(def_file);
|
||||
|
||||
|
|
|
|||
|
|
@ -1709,7 +1709,7 @@ int tex_load(const char* fn, TexInfo* t)
|
|||
// load file
|
||||
void* p; size_t size; // unused
|
||||
Handle hm = vfs_load(fn, p, size);
|
||||
CHECK_ERR(hm); // (need handle below; can't test return value directly)
|
||||
RETURN_ERR(hm); // (need handle below; can't test return value directly)
|
||||
int ret = tex_load_mem(hm, fn, t);
|
||||
mem_free_h(hm);
|
||||
if(ret < 0)
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ static int UniFont_reload(UniFont* f, const char* fn, Handle UNUSEDPARAM(h))
|
|||
// // return ERR_FILE_NOT_FOUND;
|
||||
|
||||
Handle hm = vfs_load(fnt_fn, RawFNT, FNTSize);
|
||||
CHECK_ERR(hm);
|
||||
RETURN_ERR(hm);
|
||||
|
||||
// Get the data in a nicer object
|
||||
std::istringstream FNTStream (std::string((const char*)RawFNT, (int)FNTSize));
|
||||
|
|
|
|||
|
|
@ -1036,6 +1036,8 @@ ssize_t vfs_size(Handle hf)
|
|||
// open the file for synchronous or asynchronous IO. write access is
|
||||
// requested via FILE_WRITE flag, and is not possible for files in archives.
|
||||
// file_flags: default 0
|
||||
//
|
||||
// on failure, a debug_warn is generated and a negative error code returned.
|
||||
Handle vfs_open(const char* v_fn, uint file_flags)
|
||||
{
|
||||
// keeping files open doesn't make sense in most cases (because the
|
||||
|
|
@ -1044,25 +1046,26 @@ Handle vfs_open(const char* v_fn, uint file_flags)
|
|||
if(file_flags & FILE_CACHE)
|
||||
res_flags = 0;
|
||||
|
||||
Handle h = h_alloc(H_VFile, v_fn, res_flags, file_flags);
|
||||
Handle hf = h_alloc(H_VFile, v_fn, res_flags, file_flags);
|
||||
// pass file flags to init
|
||||
|
||||
#ifdef PARANOIA
|
||||
debug_printf("vfs_open fn=%s %llx\n", v_fn, h);
|
||||
debug_printf("vfs_open fn=%s %llx\n", v_fn, hf);
|
||||
#endif
|
||||
|
||||
return h;
|
||||
CHECK_ERR(hf);
|
||||
return hf;
|
||||
}
|
||||
|
||||
|
||||
// close the handle to a file.
|
||||
int vfs_close(Handle& h)
|
||||
int vfs_close(Handle& hf)
|
||||
{
|
||||
#ifdef PARANOIA
|
||||
debug_printf("vfs_close %llx\n", h);
|
||||
debug_printf("vfs_close %llx\n", hf);
|
||||
#endif
|
||||
|
||||
return h_free(h, H_VFile);
|
||||
return h_free(hf, H_VFile);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1152,6 +1155,8 @@ static ssize_t vfs_timed_io(const Handle hf, const size_t size, void** p, FileIO
|
|||
// in addition to the regular file cache, the entire buffer is kept in memory
|
||||
// if flags & FILE_CACHE.
|
||||
//
|
||||
// on failure, a debug_warn is generated and a negative error code returned.
|
||||
//
|
||||
// note: we need the Handle return value for Tex.hm - the data pointer
|
||||
// must be protected against being accidentally free-d in that case.
|
||||
Handle vfs_load(const char* v_fn, void*& p, size_t& size, uint flags /* default 0 */)
|
||||
|
|
@ -1163,9 +1168,10 @@ debug_printf("vfs_load v_fn=%s\n", v_fn);
|
|||
p = 0; size = 0; // zeroed in case vfs_open or H_DEREF fails
|
||||
|
||||
Handle hf = vfs_open(v_fn, flags);
|
||||
CHECK_ERR(hf);
|
||||
// note: if we skip this and have H_DEREF report the error,
|
||||
// we get "invalid handle" instead of vfs_open's error code.
|
||||
RETURN_ERR(hf);
|
||||
// necessary because if we skip this and have H_DEREF report the
|
||||
// error, we get "invalid handle" instead of vfs_open's error code.
|
||||
// don't CHECK_ERR because vfs_open already did.
|
||||
|
||||
H_DEREF(hf, VFile, vf);
|
||||
|
||||
|
|
@ -1223,9 +1229,7 @@ ret:
|
|||
if(hm <= 0)
|
||||
p = 0, size = 0;
|
||||
|
||||
if (hm == 0)
|
||||
debug_printf("hm == 0!!\n");
|
||||
|
||||
CHECK_ERR(hm);
|
||||
return hm;
|
||||
}
|
||||
|
||||
|
|
@ -1236,8 +1240,10 @@ ret:
|
|||
int vfs_store(const char* v_fn, void* p, const size_t size, uint flags /* default 0 */)
|
||||
{
|
||||
Handle hf = vfs_open(v_fn, flags|FILE_WRITE);
|
||||
if(hf <= 0)
|
||||
return (int)hf; // error code
|
||||
RETURN_ERR(hf);
|
||||
// necessary because if we skip this and have H_DEREF report the
|
||||
// error, we get "invalid handle" instead of vfs_open's error code.
|
||||
// don't CHECK_ERR because vfs_open already did.
|
||||
H_DEREF(hf, VFile, vf);
|
||||
const int ret = vfs_io(hf, size, &p);
|
||||
vfs_close(hf);
|
||||
|
|
|
|||
Loading…
Reference in a new issue