mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
add hash table api
This commit is contained in:
parent
a72d3f6844
commit
33c9ce0f7b
7 changed files with 382 additions and 5 deletions
|
@ -47,6 +47,8 @@ void Cvar_Progs_Init (struct progs_s *pr);
|
|||
|
||||
void File_Progs_Init (struct progs_s *pr);
|
||||
|
||||
void Hash_Progs_Init (struct progs_s *pr);
|
||||
|
||||
void InputLine_Progs_Init (struct progs_s *pr);
|
||||
void InputLine_Progs_SetDraw (struct progs_s *pr,
|
||||
void (*draw)(struct inputline_s*));
|
||||
|
|
|
@ -10,5 +10,6 @@ libQFgamecode_builtins_la_SOURCES= pr_cmds.c
|
|||
|
||||
libQFcsqc_la_LDFLAGS= -version-info 1:0:0
|
||||
libQFcsqc_la_SOURCES=\
|
||||
bi_cbuf.c bi_cmd.c bi_cvar.c bi_file.c bi_init.c bi_inputline.c \
|
||||
bi_cbuf.c bi_cmd.c bi_cvar.c bi_file.c bi_hash.c bi_init.c \
|
||||
bi_inputline.c \
|
||||
bi_qfile.c bi_qfs.c bi_string.c bi_strhash.c
|
||||
|
|
328
libs/gamecode/builtins/bi_hash.c
Normal file
328
libs/gamecode/builtins/bi_hash.c
Normal file
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
bi_hash.c
|
||||
|
||||
QuakeC hash table api
|
||||
|
||||
Copyright (C) 2002 Bill Currie
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2003/4/7
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
static __attribute__ ((unused)) const char rcsid[] =
|
||||
"$Id$";
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "QF/csqc.h"
|
||||
#include "QF/hash.h"
|
||||
#include "QF/progs.h"
|
||||
|
||||
typedef struct bi_hashtab_s {
|
||||
struct bi_hashtab_s *next;
|
||||
struct bi_hashtab_s **prev;
|
||||
progs_t *pr;
|
||||
hashtab_t *tab;
|
||||
func_t gk;
|
||||
func_t gh;
|
||||
func_t cmp;
|
||||
func_t f;
|
||||
pointer_t ud;
|
||||
} bi_hashtab_t;
|
||||
|
||||
typedef struct {
|
||||
bi_hashtab_t *tabs;
|
||||
} hash_resources_t;
|
||||
|
||||
static const char *
|
||||
bi_get_key (void *key, void *_ht)
|
||||
{
|
||||
bi_hashtab_t *ht = (bi_hashtab_t *)_ht;
|
||||
P_INT (ht->pr, 0) = (long) (key);
|
||||
P_INT (ht->pr, 1) = ht->ud;
|
||||
PR_ExecuteProgram (ht->pr, ht->gk);
|
||||
return G_STRING (ht->pr, OFS_RETURN);
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
bi_get_hash (void *key, void *_ht)
|
||||
{
|
||||
bi_hashtab_t *ht = (bi_hashtab_t *)_ht;
|
||||
P_INT (ht->pr, 0) = (long) (key);
|
||||
P_INT (ht->pr, 1) = ht->ud;
|
||||
PR_ExecuteProgram (ht->pr, ht->gh);
|
||||
return R_INT (ht->pr);
|
||||
}
|
||||
|
||||
static int
|
||||
bi_compare (void *key1, void *key2, void *_ht)
|
||||
{
|
||||
bi_hashtab_t *ht = (bi_hashtab_t *)_ht;
|
||||
P_INT (ht->pr, 0) = (long) (key1);
|
||||
P_INT (ht->pr, 1) = (long) (key2);
|
||||
P_INT (ht->pr, 2) = ht->ud;
|
||||
PR_ExecuteProgram (ht->pr, ht->cmp);
|
||||
return R_INT (ht->pr);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_free (void *key, void *_ht)
|
||||
{
|
||||
bi_hashtab_t *ht = (bi_hashtab_t *)_ht;
|
||||
P_INT (ht->pr, 0) = (long) (key);
|
||||
P_INT (ht->pr, 1) = ht->ud;
|
||||
PR_ExecuteProgram (ht->pr, ht->f);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Hash_NewTable (progs_t *pr)
|
||||
{
|
||||
hash_resources_t *res = PR_Resources_Find (pr, "Hash");
|
||||
int tsize = P_INT (pr, 0);
|
||||
const char *(*gk)(void*,void*);
|
||||
void (*f)(void*,void*);
|
||||
bi_hashtab_t *ht;
|
||||
|
||||
ht = PR_Zone_Malloc (pr, sizeof (bi_hashtab_t));
|
||||
ht->pr = pr;
|
||||
ht->gk = P_FUNCTION (pr, 1);
|
||||
ht->f = P_FUNCTION (pr, 2);
|
||||
ht->ud = P_INT (pr, 3); // don't convert pointer for speed reasons
|
||||
|
||||
ht->next = res->tabs;
|
||||
ht->prev = &res->tabs;
|
||||
if (ht->next)
|
||||
ht->next->prev = &ht->next;
|
||||
|
||||
gk = ht->gk ? bi_get_key : 0;
|
||||
f = ht->f ? bi_free : 0;
|
||||
ht->tab = Hash_NewTable (tsize, gk, f, ht);
|
||||
RETURN_POINTER (pr, ht);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Hash_SetHashCompare (progs_t *pr)
|
||||
{
|
||||
bi_hashtab_t *ht = &G_STRUCT (pr, bi_hashtab_t, 0);
|
||||
unsigned long (*gh)(void*,void*);
|
||||
int (*cmp)(void*,void*,void*);
|
||||
|
||||
ht->gh = P_FUNCTION (pr, 1);
|
||||
ht->cmp = P_FUNCTION (pr, 2);
|
||||
gh = ht->gh ? bi_get_hash : 0;
|
||||
cmp = ht->cmp ? bi_compare : 0;
|
||||
Hash_SetHashCompare (ht->tab, gh, cmp);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Hash_DelTable (progs_t *pr)
|
||||
{
|
||||
bi_hashtab_t *ht = &G_STRUCT (pr, bi_hashtab_t, 0);
|
||||
|
||||
Hash_DelTable (ht->tab);
|
||||
*ht->prev = ht->next;
|
||||
PR_Zone_Free (pr, ht);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Hash_FlushTable (progs_t *pr)
|
||||
{
|
||||
bi_hashtab_t *ht = &G_STRUCT (pr, bi_hashtab_t, 0);
|
||||
|
||||
Hash_FlushTable (ht->tab);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Hash_Add (progs_t *pr)
|
||||
{
|
||||
bi_hashtab_t *ht = &G_STRUCT (pr, bi_hashtab_t, 0);
|
||||
|
||||
R_INT (pr) = Hash_Add (ht->tab, (void *) P_INT (pr, 1));
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Hash_AddElement (progs_t *pr)
|
||||
{
|
||||
bi_hashtab_t *ht = &G_STRUCT (pr, bi_hashtab_t, 0);
|
||||
|
||||
R_INT (pr) = Hash_Add (ht->tab, (void *) P_INT (pr, 1));
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Hash_Find (progs_t *pr)
|
||||
{
|
||||
bi_hashtab_t *ht = &G_STRUCT (pr, bi_hashtab_t, 0);
|
||||
|
||||
R_INT (pr) = (long) Hash_Find (ht->tab, P_STRING (pr, 1));
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Hash_FindElement (progs_t *pr)
|
||||
{
|
||||
bi_hashtab_t *ht = &G_STRUCT (pr, bi_hashtab_t, 0);
|
||||
|
||||
R_INT (pr) = (long) Hash_FindElement (ht->tab, (void *) P_INT (pr, 1));
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Hash_FindList (progs_t *pr)
|
||||
{
|
||||
bi_hashtab_t *ht = &G_STRUCT (pr, bi_hashtab_t, 0);
|
||||
void **list, **l;
|
||||
pr_type_t *pr_list;
|
||||
int count;
|
||||
|
||||
list = Hash_FindList (ht->tab, P_STRING (pr, 1));
|
||||
for (count = 1, l = list; *l; l++)
|
||||
count++;
|
||||
pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t));
|
||||
for (count = 0, l = list; *l; l++)
|
||||
pr_list[count++].integer_var = (long) *l;
|
||||
free (list);
|
||||
RETURN_POINTER (pr, pr_list);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Hash_FindElementList (progs_t *pr)
|
||||
{
|
||||
bi_hashtab_t *ht = &G_STRUCT (pr, bi_hashtab_t, 0);
|
||||
void **list, **l;
|
||||
pr_type_t *pr_list;
|
||||
int count;
|
||||
|
||||
list = Hash_FindElementList (ht->tab, (void *) P_INT (pr, 1));
|
||||
for (count = 1, l = list; *l; l++)
|
||||
count++;
|
||||
pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t));
|
||||
for (count = 0, l = list; *l; l++)
|
||||
pr_list[count++].integer_var = (long) *l;
|
||||
free (list);
|
||||
RETURN_POINTER (pr, pr_list);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Hash_Del (progs_t *pr)
|
||||
{
|
||||
bi_hashtab_t *ht = &G_STRUCT (pr, bi_hashtab_t, 0);
|
||||
|
||||
R_INT (pr) = (long) Hash_Del (ht->tab, P_STRING (pr, 1));
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Hash_DelElement (progs_t *pr)
|
||||
{
|
||||
bi_hashtab_t *ht = &G_STRUCT (pr, bi_hashtab_t, 0);
|
||||
|
||||
R_INT (pr) = (long) Hash_DelElement (ht->tab, (void *) P_INT (pr, 1));
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Hash_Free (progs_t *pr)
|
||||
{
|
||||
bi_hashtab_t *ht = &G_STRUCT (pr, bi_hashtab_t, 0);
|
||||
|
||||
Hash_Free (ht->tab, (void *) P_INT (pr, 1));
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Hash_String (progs_t *pr)
|
||||
{
|
||||
R_INT (pr) = Hash_String (P_STRING (pr, 0));
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Hash_Buffer (progs_t *pr)
|
||||
{
|
||||
R_INT (pr) = Hash_Buffer (P_POINTER (pr, 0), P_INT (pr, 1));
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Hash_GetList (progs_t *pr)
|
||||
{
|
||||
bi_hashtab_t *ht = &G_STRUCT (pr, bi_hashtab_t, 0);
|
||||
void **list, **l;
|
||||
pr_type_t *pr_list;
|
||||
int count;
|
||||
|
||||
list = Hash_GetList (ht->tab);
|
||||
for (count = 1, l = list; *l; l++)
|
||||
count++;
|
||||
pr_list = PR_Zone_Malloc (pr, count * sizeof (pr_type_t));
|
||||
for (count = 0, l = list; *l; l++)
|
||||
pr_list[count++].integer_var = (long) *l;
|
||||
free (list);
|
||||
RETURN_POINTER (pr, pr_list);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Hash_Stats (progs_t *pr)
|
||||
{
|
||||
bi_hashtab_t *ht = &G_STRUCT (pr, bi_hashtab_t, 0);
|
||||
|
||||
Hash_Stats (ht->tab);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_hash_clear (progs_t *pr, void *data)
|
||||
{
|
||||
hash_resources_t *res = (hash_resources_t *) data;
|
||||
bi_hashtab_t *ht;
|
||||
|
||||
for (ht = res->tabs; ht; ht = ht->next)
|
||||
Hash_DelTable (ht->tab);
|
||||
res->tabs = 0;
|
||||
}
|
||||
|
||||
void
|
||||
Hash_Progs_Init (progs_t *pr)
|
||||
{
|
||||
hash_resources_t *res = malloc (sizeof (hash_resources_t));
|
||||
res->tabs = 0;
|
||||
|
||||
PR_Resources_Register (pr, "Hash", res, bi_hash_clear);
|
||||
PR_AddBuiltin (pr, "Hash_NewTable", bi_Hash_NewTable, -1);
|
||||
PR_AddBuiltin (pr, "Hash_SetHashCompare", bi_Hash_SetHashCompare, -1);
|
||||
PR_AddBuiltin (pr, "Hash_DelTable", bi_Hash_DelTable, -1);
|
||||
PR_AddBuiltin (pr, "Hash_FlushTable", bi_Hash_FlushTable, -1);
|
||||
PR_AddBuiltin (pr, "Hash_Add", bi_Hash_Add, -1);
|
||||
PR_AddBuiltin (pr, "Hash_AddElement", bi_Hash_AddElement, -1);
|
||||
PR_AddBuiltin (pr, "Hash_Find", bi_Hash_Find, -1);
|
||||
PR_AddBuiltin (pr, "Hash_FindElement", bi_Hash_FindElement, -1);
|
||||
PR_AddBuiltin (pr, "Hash_FindList", bi_Hash_FindList, -1);
|
||||
PR_AddBuiltin (pr, "Hash_FindElementList", bi_Hash_FindElementList, -1);
|
||||
PR_AddBuiltin (pr, "Hash_Del", bi_Hash_Del, -1);
|
||||
PR_AddBuiltin (pr, "Hash_DelElement", bi_Hash_DelElement, -1);
|
||||
PR_AddBuiltin (pr, "Hash_Free", bi_Hash_Free, -1);
|
||||
PR_AddBuiltin (pr, "Hash_String", bi_Hash_String, -1);
|
||||
PR_AddBuiltin (pr, "Hash_Buffer", bi_Hash_Buffer, -1);
|
||||
PR_AddBuiltin (pr, "Hash_GetList", bi_Hash_GetList, -1);
|
||||
PR_AddBuiltin (pr, "Hash_Stats", bi_Hash_Stats, -1);
|
||||
}
|
|
@ -35,8 +35,10 @@ static __attribute__ ((unused)) const char rcsid[] =
|
|||
#include "QF/progs.h"
|
||||
|
||||
static void (*const cbuf_progs_init)(progs_t *) = Cbuf_Progs_Init;
|
||||
static void (*const cvar_progs_init)(progs_t *) = Cvar_Progs_Init;
|
||||
static void (*const cmd_progs_init)(progs_t *) = Cmd_Progs_Init;
|
||||
static void (*const cvar_progs_init)(progs_t *) = Cvar_Progs_Init;
|
||||
static void (*const file_progs_init)(progs_t *) = File_Progs_Init;
|
||||
static void (*const hash_progs_init)(progs_t *) = Hash_Progs_Init;
|
||||
static void (*const inputline_progs_init)(progs_t *) = InputLine_Progs_Init;
|
||||
static void (*const qfile_progs_init)(progs_t *, int) = QFile_Progs_Init;
|
||||
static void (*const qfs_progs_init)(progs_t *) = QFS_Progs_Init;
|
||||
|
|
25
ruamoko/include/hash.h
Normal file
25
ruamoko/include/hash.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef __ruamoko_hash_h
|
||||
#define __ruamoko_hash_h
|
||||
|
||||
struct _hashtab_t = {};
|
||||
typedef _hashtab_t [] hashtab_t;
|
||||
|
||||
hashtab_t () Hash_NewTable;
|
||||
void () Hash_SetHashCompare;
|
||||
void () Hash_DelTable;
|
||||
void () Hash_FlushTable;
|
||||
integer () Hash_Add;
|
||||
integer () Hash_AddElement;
|
||||
(void []) () Hash_Find;
|
||||
(void []) () Hash_FindElement;
|
||||
(void [][]) () Hash_FindList;
|
||||
(void [][]) () Hash_FindElementList;
|
||||
(void []) () Hash_Del;
|
||||
(void []) () Hash_DelElement;
|
||||
void () Hash_Free;
|
||||
integer () Hash_String;
|
||||
integer () Hash_Buffer;
|
||||
(void [][]) () Hash_GetList;
|
||||
void () Hash_Stats;
|
||||
|
||||
#endif __ruamoko_hash_h
|
|
@ -27,9 +27,9 @@ EXTRA_LIBRARIES= $(ruamoko_libs)
|
|||
$(QFCC) $(QCFLAGS) $(QCPPFLAGS) -c -o $@ $<
|
||||
|
||||
libr_a_SOURCES=\
|
||||
crudefile.r debug.r entities.r infokey.r math.r message.r nq_message.r \
|
||||
physics.r qfile.r qw_message.r qw_physics.r qw_sys.r sound.r string.r \
|
||||
system.r Object.r Array.r Entity.r Point.r Size.r Rect.r
|
||||
crudefile.r debug.r hash.r entities.r infokey.r math.r message.r \
|
||||
nq_message.r physics.r qfile.r qw_message.r qw_physics.r qw_sys.r sound.r \
|
||||
string.r system.r Object.r Array.r Entity.r Point.r Size.r Rect.r
|
||||
libr_a_AR=$(PAK) -cf
|
||||
|
||||
libgui_a_SOURCES=\
|
||||
|
|
19
ruamoko/lib/hash.r
Normal file
19
ruamoko/lib/hash.r
Normal file
|
@ -0,0 +1,19 @@
|
|||
#include "hash.h"
|
||||
|
||||
hashtab_t () Hash_NewTable = #0;
|
||||
void () Hash_SetHashCompare = #0;
|
||||
void () Hash_DelTable = #0;
|
||||
void () Hash_FlushTable = #0;
|
||||
integer () Hash_Add = #0;
|
||||
integer () Hash_AddElement = #0;
|
||||
(void []) () Hash_Find = #0;
|
||||
(void []) () Hash_FindElement = #0;
|
||||
(void [][]) () Hash_FindList = #0;
|
||||
(void [][]) () Hash_FindElementList = #0;
|
||||
(void []) () Hash_Del = #0;
|
||||
(void []) () Hash_DelElement = #0;
|
||||
void () Hash_Free = #0;
|
||||
integer () Hash_String = #0;
|
||||
integer () Hash_Buffer = #0;
|
||||
(void [][]) () Hash_GetList = #0;
|
||||
void () Hash_Stats = #0;
|
Loading…
Reference in a new issue