[gamecode] Make PR_RESMAP macros more function-like

I never liked that some of the macros needed the type as a parameter
(yay typeof and __auto_type) or those that returned a value hid the
return statement so they couldn't be used in assignments.
This commit is contained in:
Bill Currie 2021-03-21 21:26:36 +09:00
parent 003910612a
commit 56cf181a11
14 changed files with 136 additions and 131 deletions

View file

@ -1532,46 +1532,44 @@ void *PR_Resources_Find (progs_t *pr, const char *name);
/** Allocate a new resource from the resource map.
\param type The type of the resource. Must match the \c type parameter
used for PR_RESMAP.
\param map The resource map.
\return A pointer to the new resource, or null if no more could
be allocated.
*/
#define PR_RESNEW(type,map) \
type *t; \
\
if (!map._free) { \
int i, size; \
map._size++; \
size = map._size * sizeof (type *); \
map._map = realloc (map._map, size); \
if (!map._map) \
return 0; \
map._free = calloc (1024, sizeof (type)); \
if (!map._free) \
return 0; \
map._map[map._size - 1] = map._free; \
for (i = 0; i < 1023; i++) \
*(type **) &map._free[i] = &map._free[i + 1]; \
*(type **) &map._free[i] = 0; \
} \
t = map._free; \
map._free = *(type **) t; \
memset (t, 0, sizeof (type)); \
return t
#define PR_RESNEW(map) \
({ \
if (!map._free) { \
int i, size; \
map._size++; \
size = map._size * sizeof (map._free); \
map._map = realloc (map._map, size); \
if (!map._map) \
return 0; \
map._free = calloc (1024, sizeof (*map._free)); \
if (!map._free) \
return 0; \
map._map[map._size - 1] = map._free; \
for (i = 0; i < 1023; i++) \
*(typeof (map._free) *) &map._free[i] = &map._free[i + 1]; \
*(typeof (map._free) *) &map._free[i] = 0; \
} \
__auto_type t = map._free; \
map._free = *(typeof (map._free) *) t; \
memset (t, 0, sizeof (*map._free)); \
t; \
})
/** Free a resource returning it to the resource map.
\param type The type of the resource. Must match the \c type parameter
used for PR_RESMAP.
\param map The resource map.
\param t Pointer to the resource to be freed.
*/
#define PR_RESFREE(type,map,t) \
memset (t, 0, sizeof (type)); \
*(type **) t = map._free; \
map._free = t
#define PR_RESFREE(map,t) \
do { \
memset (t, 0, sizeof (*map._free)); \
*(typeof (map._free) *) t = map._free; \
map._free = t; \
} while (0)
/** Free all resources in the resource map.
@ -1580,24 +1578,24 @@ void *PR_Resources_Find (progs_t *pr, const char *name);
A reset resource map is guaranteed to allocate elements sequentially.
\param type The type of the resource. Must match the \c type parameter
used for PR_RESMAP.
\param map The resource map.
*/
#define PR_RESRESET(type,map) \
unsigned i, j; \
if (!map._size) \
return; \
for (i = 0; i < map._size; i++) { \
map._free = map._map[i]; \
for (j = 0; j < 1023; j++) \
*(type **) &map._free[j] = &map._free[j + 1]; \
if (i < map._size - 1) \
*(type **) &map._free[j] = &map._map[i + 1][0]; \
else \
*(type **) &map._free[j] = 0; \
} \
map._free = map._map[0];
#define PR_RESRESET(map) \
do { \
unsigned i, j; \
if (!map._size) \
return; \
for (i = 0; i < map._size; i++) { \
map._free = map._map[i]; \
for (j = 0; j < 1023; j++) \
*(typeof (map._free) *) &map._free[j] = &map._free[j + 1]; \
if (i < map._size - 1) \
*(typeof (map._free) *) &map._free[j] = &map._map[i + 1][0];\
else \
*(typeof (map._free) *) &map._free[j] = 0; \
} \
map._free = map._map[0]; \
} while (0)
/** Retrieve a resource from the resource map using a handle.
@ -1606,12 +1604,14 @@ void *PR_Resources_Find (progs_t *pr, const char *name);
\return A pointer to the resource, or NULL if the handle is
invalid.
*/
#define PR_RESGET(map,col) \
unsigned row = ~col / 1024; \
col = ~col % 1024; \
if (row >= map._size) \
return 0; \
return &map._map[row][col]
#define PR_RESGET(map,col) \
({ \
unsigned row = ~col / 1024; \
col = ~col % 1024; \
if (row >= map._size) \
return 0; \
&map._map[row][col]; \
})
/** Convert a resource pointer to a handle.
@ -1619,14 +1619,19 @@ void *PR_Resources_Find (progs_t *pr, const char *name);
\param ptr The resource pointer.
\return The handle or 0 if the pointer is invalid.
*/
#define PR_RESINDEX(map,ptr) \
unsigned i; \
for (i = 0; i < map._size; i++) { \
long d = ptr - map._map[i]; \
if (d >= 0 && d < 1024) \
return ~(i * 1024 + d); \
} \
return 0
#define PR_RESINDEX(map,ptr) \
({ \
unsigned i; \
unsigned index = 0; \
for (i = 0; i < map._size; i++) { \
long d = ptr - map._map[i]; \
if (d >= 0 && d < 1024) { \
index = ~(i * 1024 + d); \
break; \
} \
} \
index; \
})
///@}
///@}

View file

@ -62,31 +62,31 @@ typedef struct {
static il_data_t *
il_data_new (il_resources_t *res)
{
PR_RESNEW (il_data_t, res->line_map);
return PR_RESNEW (res->line_map);
}
static void
il_data_free (il_resources_t *res, il_data_t *line)
{
PR_RESFREE (il_data_t, res->line_map, line);
PR_RESFREE (res->line_map, line);
}
static void
il_data_reset (il_resources_t *res)
{
PR_RESRESET (il_data_t, res->line_map);
PR_RESRESET (res->line_map);
}
static inline il_data_t *
il_data_get (il_resources_t *res, unsigned index)
{
PR_RESGET (res->line_map, index);
return PR_RESGET (res->line_map, index);
}
static inline int __attribute__((pure))
il_data_index (il_resources_t *res, il_data_t *line)
{
PR_RESINDEX (res->line_map, line);
return PR_RESINDEX (res->line_map, line);
}
static void

View file

@ -373,7 +373,7 @@ pr_debug_clear (progs_t *pr, void *data)
Hash_FlushTable (res->file_hash);
Hash_FlushTable (res->debug_syms);
Hash_FlushTable (res->compunits);
PR_RESRESET (compunit_t, res->compmap);
PR_RESRESET (res->compmap);
res->debug = 0;
res->auxfunctions = 0;
if (res->auxfunction_map)
@ -461,7 +461,7 @@ byteswap_def (pr_def_t *def)
static compunit_t *
new_compunit (prdeb_resources_t *res)
{
PR_RESNEW (compunit_t, res->compmap);
return PR_RESNEW (res->compmap);
}
static void

View file

@ -64,31 +64,31 @@ typedef struct {
static bi_hashtab_t *
table_new (hash_resources_t *res)
{
PR_RESNEW (bi_hashtab_t, res->table_map);
return PR_RESNEW (res->table_map);
}
static void
table_free (hash_resources_t *res, bi_hashtab_t *table)
{
PR_RESFREE (bi_hashtab_t, res->table_map, table);
PR_RESFREE (res->table_map, table);
}
static void
table_reset (hash_resources_t *res)
{
PR_RESRESET (bi_hashtab_t, res->table_map);
PR_RESRESET (res->table_map);
}
static inline bi_hashtab_t *
table_get (hash_resources_t *res, int index)
{
PR_RESGET(res->table_map, index);
return PR_RESGET(res->table_map, index);
}
static inline int __attribute__((pure))
table_index (hash_resources_t *res, bi_hashtab_t *table)
{
PR_RESINDEX(res->table_map, table);
return PR_RESINDEX(res->table_map, table);
}
static const char *

View file

@ -58,32 +58,32 @@ typedef struct {
static msgbuf_t *
msgbuf_new (msgbuf_resources_t *res)
{
PR_RESNEW (msgbuf_t, res->msgbuf_map);
return PR_RESNEW (res->msgbuf_map);
}
static void
msgbuf_free (progs_t *pr, msgbuf_resources_t *res, msgbuf_t *msgbuf)
{
PR_Zone_Free (pr, msgbuf->sizebuf.data);
PR_RESFREE (msgbuf_t, res->msgbuf_map, msgbuf);
PR_RESFREE (res->msgbuf_map, msgbuf);
}
static void
msgbuf_reset (msgbuf_resources_t *res)
{
PR_RESRESET (msgbuf_t, res->msgbuf_map);
PR_RESRESET (res->msgbuf_map);
}
static inline msgbuf_t *
msgbuf_get (msgbuf_resources_t *res, int index)
{
PR_RESGET(res->msgbuf_map, index);
return PR_RESGET(res->msgbuf_map, index);
}
static inline int __attribute__((pure))
msgbuf_index (msgbuf_resources_t *res, msgbuf_t *msgbuf)
{
PR_RESINDEX(res->msgbuf_map, msgbuf);
return PR_RESINDEX(res->msgbuf_map, msgbuf);
}
static void

View file

@ -93,25 +93,25 @@ typedef struct probj_resources_s {
static dtable_t *
dtable_new (probj_t *probj)
{
PR_RESNEW (dtable_t, probj->dtables);
return PR_RESNEW (probj->dtables);
}
static void
dtable_reset (probj_t *probj)
{
PR_RESRESET (dtable_t, probj->dtables);
PR_RESRESET (probj->dtables);
}
static inline dtable_t *
dtable_get (probj_t *probj, int index)
{
PR_RESGET (probj->dtables, index);
return PR_RESGET (probj->dtables, index);
}
static inline int __attribute__((pure))
dtable_index (probj_t *probj, dtable_t *dtable)
{
PR_RESINDEX (probj->dtables, dtable);
return PR_RESINDEX (probj->dtables, dtable);
}
static always_inline dtable_t * __attribute__((pure))

View file

@ -63,31 +63,31 @@ typedef struct {
static bi_plist_t *
plist_new (plist_resources_t *res)
{
PR_RESNEW (bi_plist_t, res->plist_map);
return PR_RESNEW (res->plist_map);
}
static void
plist_free (plist_resources_t *res, bi_plist_t *plist)
{
PR_RESFREE (bi_plist_t, res->plist_map, plist);
PR_RESFREE (res->plist_map, plist);
}
static void
plist_reset (plist_resources_t *res)
{
PR_RESRESET (bi_plist_t, res->plist_map);
PR_RESRESET (res->plist_map);
}
static inline bi_plist_t *
plist_get (plist_resources_t *res, unsigned index)
{
PR_RESGET(res->plist_map, index);
return PR_RESGET(res->plist_map, index);
}
static inline int __attribute__((pure))
plist_index (plist_resources_t *res, bi_plist_t *plist)
{
PR_RESINDEX(res->plist_map, plist);
return PR_RESINDEX(res->plist_map, plist);
}
static void

View file

@ -56,31 +56,31 @@ typedef struct {
static qfile_t *
handle_new (qfile_resources_t *res)
{
PR_RESNEW (qfile_t, res->handle_map);
return PR_RESNEW (res->handle_map);
}
static void
handle_free (qfile_resources_t *res, qfile_t *handle)
{
PR_RESFREE (qfile_t, res->handle_map, handle);
PR_RESFREE (res->handle_map, handle);
}
static void
handle_reset (qfile_resources_t *res)
{
PR_RESRESET (qfile_t, res->handle_map);
PR_RESRESET (res->handle_map);
}
static inline qfile_t *
handle_get (qfile_resources_t *res, int index)
{
PR_RESGET(res->handle_map, index);
return PR_RESGET(res->handle_map, index);
}
static inline int __attribute__((pure))
handle_index (qfile_resources_t *res, qfile_t *handle)
{
PR_RESINDEX(res->handle_map, handle);
return PR_RESINDEX(res->handle_map, handle);
}
static void

View file

@ -57,31 +57,31 @@ typedef struct {
static rua_script_t *
script_new (script_resources_t *res)
{
PR_RESNEW (rua_script_t, res->scripts);
return PR_RESNEW (res->scripts);
}
static void
script_free (script_resources_t *res, rua_script_t *script)
{
PR_RESFREE (rua_script_t, res->scripts, script);
PR_RESFREE (res->scripts, script);
}
static void
script_reset (script_resources_t *res)
{
PR_RESRESET (rua_script_t, res->scripts);
PR_RESRESET (res->scripts);
}
static inline rua_script_t *
script_get (script_resources_t *res, int index)
{
PR_RESGET(res->scripts, index);
return PR_RESGET(res->scripts, index);
}
static inline int __attribute__((pure))
script_index (script_resources_t *res, rua_script_t *script)
{
PR_RESINDEX(res->scripts, script);
return PR_RESINDEX(res->scripts, script);
}
static void

View file

@ -77,61 +77,61 @@ typedef struct {
static bi_set_t *
res_set_new (set_resources_t *res)
{
PR_RESNEW (bi_set_t, res->set_map);
return PR_RESNEW (res->set_map);
}
static void
res_set_free (set_resources_t *res, bi_set_t *set)
{
PR_RESFREE (bi_set_t, res->set_map, set);
PR_RESFREE (res->set_map, set);
}
static void
res_set_reset (set_resources_t *res)
{
PR_RESRESET (bi_set_t, res->set_map);
PR_RESRESET (res->set_map);
}
static inline bi_set_t *
res_set_get (set_resources_t *res, int index)
{
PR_RESGET(res->set_map, index);
return PR_RESGET(res->set_map, index);
}
static inline int __attribute__((pure))
res_set_index (set_resources_t *res, bi_set_t *set)
{
PR_RESINDEX(res->set_map, set);
return PR_RESINDEX(res->set_map, set);
}
static bi_set_iter_t *
res_set_iter_new (set_resources_t *res)
{
PR_RESNEW (bi_set_iter_t, res->set_iter_map);
return PR_RESNEW (res->set_iter_map);
}
static void
res_set_iter_free (set_resources_t *res, bi_set_iter_t *set_iter)
{
PR_RESFREE (bi_set_iter_t, res->set_iter_map, set_iter);
PR_RESFREE (res->set_iter_map, set_iter);
}
static void
res_set_iter_reset (set_resources_t *res)
{
PR_RESRESET (bi_set_iter_t, res->set_iter_map);
PR_RESRESET (res->set_iter_map);
}
static inline bi_set_iter_t *
res_set_iter_get (set_resources_t *res, int index)
{
PR_RESGET(res->set_iter_map, index);
return PR_RESGET(res->set_iter_map, index);
}
static inline int __attribute__((pure))
res_set_iter_index (set_resources_t *res, bi_set_iter_t *set_iter)
{
PR_RESINDEX(res->set_iter_map, set_iter);
return PR_RESINDEX(res->set_iter_map, set_iter);
}
static bi_set_t *

View file

@ -68,7 +68,7 @@ typedef struct {
static qpic_res_t *
qpic_new (draw_resources_t *res)
{
PR_RESNEW (qpic_res_t, res->qpic_map);
return PR_RESNEW (res->qpic_map);
}
static void
@ -86,25 +86,25 @@ static void
qpic_free (draw_resources_t *res, qpic_res_t *qp)
{
bi_draw_free_qpic (qp);
PR_RESFREE (qpic_res_t, res->qpic_map, qp);
PR_RESFREE (res->qpic_map, qp);
}
static void
qpic_reset (draw_resources_t *res)
{
PR_RESRESET (qpic_res_t, res->qpic_map);
PR_RESRESET (res->qpic_map);
}
static inline qpic_res_t *
qpic_get (draw_resources_t *res, int index)
{
PR_RESGET (res->qpic_map, index);
return PR_RESGET (res->qpic_map, index);
}
static inline int __attribute__((pure))
qpic_index (draw_resources_t *res, qpic_res_t *qp)
{
PR_RESINDEX (res->qpic_map, qp);
return PR_RESINDEX (res->qpic_map, qp);
}
static qpic_res_t *

View file

@ -127,31 +127,31 @@ static const char *qwaq_command_names[]= {
static window_t *
window_new (qwaq_resources_t *res)
{
PR_RESNEW (window_t, res->window_map);
return PR_RESNEW (res->window_map);
}
static void
window_free (qwaq_resources_t *res, window_t *win)
{
PR_RESFREE (window_t, res->window_map, win);
PR_RESFREE (res->window_map, win);
}
static void
window_reset (qwaq_resources_t *res)
{
PR_RESRESET (window_t, res->window_map);
PR_RESRESET (res->window_map);
}
static inline window_t *
window_get (qwaq_resources_t *res, unsigned index)
{
PR_RESGET(res->window_map, index);
return PR_RESGET(res->window_map, index);
}
static inline int __attribute__((pure))
window_index (qwaq_resources_t *res, window_t *win)
{
PR_RESINDEX (res->window_map, win);
return PR_RESINDEX (res->window_map, win);
}
static always_inline window_t * __attribute__((pure))
@ -173,31 +173,31 @@ get_window (qwaq_resources_t *res, const char *name, int handle)
static panel_t *
panel_new (qwaq_resources_t *res)
{
PR_RESNEW (panel_t, res->panel_map);
return PR_RESNEW (res->panel_map);
}
static void
panel_free (qwaq_resources_t *res, panel_t *win)
{
PR_RESFREE (panel_t, res->panel_map, win);
PR_RESFREE (res->panel_map, win);
}
static void
panel_reset (qwaq_resources_t *res)
{
PR_RESRESET (panel_t, res->panel_map);
PR_RESRESET (res->panel_map);
}
static inline panel_t *
panel_get (qwaq_resources_t *res, unsigned index)
{
PR_RESGET(res->panel_map, index);
return PR_RESGET(res->panel_map, index);
}
static inline int __attribute__((pure))
panel_index (qwaq_resources_t *res, panel_t *win)
{
PR_RESINDEX (res->panel_map, win);
return PR_RESINDEX (res->panel_map, win);
}
static always_inline panel_t * __attribute__((pure))

View file

@ -73,31 +73,31 @@ typedef struct qwaq_debug_s {
static qwaq_target_t *
target_new (qwaq_debug_t *debug)
{
PR_RESNEW (qwaq_target_t, debug->targets);
return PR_RESNEW (debug->targets);
}
static void
target_free (qwaq_debug_t *debug, qwaq_target_t *target)
{
PR_RESFREE (qwaq_target_t, debug->targets, target);
PR_RESFREE (debug->targets, target);
}
static void
target_reset (qwaq_debug_t *debug)
{
PR_RESRESET (qwaq_target_t, debug->targets);
PR_RESRESET (debug->targets);
}
static inline qwaq_target_t *
target_get (qwaq_debug_t *debug, unsigned index)
{
PR_RESGET (debug->targets, index);
return PR_RESGET (debug->targets, index);
}
static inline int __attribute__((pure))
target_index (qwaq_debug_t *debug, qwaq_target_t *target)
{
PR_RESINDEX (debug->targets, target);
return PR_RESINDEX (debug->targets, target);
}
static always_inline qwaq_target_t * __attribute__((pure))

View file

@ -31,31 +31,31 @@ typedef struct qwaq_ebresources_s {
static editbuffer_t *
editbuffer_new (qwaq_ebresources_t *res)
{
PR_RESNEW (editbuffer_t, res->buffers);
return PR_RESNEW (res->buffers);
}
static void
editbuffer_free (qwaq_ebresources_t *res, editbuffer_t *buffer)
{
PR_RESFREE (editbuffer_t, res->buffers, buffer);
PR_RESFREE (res->buffers, buffer);
}
static void
editbuffer_reset (qwaq_ebresources_t *res)
{
PR_RESRESET (editbuffer_t, res->buffers);
PR_RESRESET (res->buffers);
}
static inline editbuffer_t *
editbuffer_get (qwaq_ebresources_t *res, unsigned index)
{
PR_RESGET (res->buffers, index);
return PR_RESGET (res->buffers, index);
}
static inline int __attribute__((pure))
editbuffer_index (qwaq_ebresources_t *res, editbuffer_t *buffer)
{
PR_RESINDEX (res->buffers, buffer);
return PR_RESINDEX (res->buffers, buffer);
}
static always_inline editbuffer_t * __attribute__((pure))