cvars and cvar alias now use a hash table for lookups. commands and aliases

coming soon :)
This commit is contained in:
Bill Currie 2001-01-04 19:10:38 +00:00
parent 365ece328b
commit 381f5b6df4
9 changed files with 249 additions and 18 deletions

View file

@ -97,5 +97,8 @@
/* Define this if fnmatch is prototyped in fnmatch.h */
#undef HAVE_FNMATCH_PROTO
/* Define this to something appropriate for declaring 0 length arrays */
#undef ZERO_LENGTH_ARRAY
@BOTTOM@
#endif // __config_h_

View file

@ -152,6 +152,13 @@ AC_TRY_COMPILE(
AC_MSG_RESULT(no)
)
AC_MSG_CHECKING(for zero length array syntax)
AC_TRY_COMPILE(
[],
[int foo[0];],
AC_DEFINE(ZERO_LENGTH_ARRAY,0) AC_MSG_RESULT([0]),
AC_DEFINE(ZERO_LENGTH_ARRAY,) AC_MSG_RESULT([])
)
dnl ==================================================================
dnl Checks for library functions.

View file

@ -118,6 +118,7 @@ void Cvar_WriteVariables (QFile *f);
// Returns a pointer to the Cvar, NULL if not found
cvar_t *Cvar_FindVar (char *var_name);
void Cvar_Init_Hash (void);
void Cvar_Init();
void Cvar_Shutdown();

54
include/hash.h Normal file
View file

@ -0,0 +1,54 @@
/*
hash.h
hash tables
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 2000 Marcus Sundberg <mackan@stacken.kth.se>
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
$Id$
*/
#ifndef __hash_h
#define __hash_h
#include <stdlib.h> // should be sys/types.h, but bc is stupid
typedef struct hashlink_s {
struct hashlink_s *next;
struct hashlink_s **prev;
void *data;
} hashlink_t;
typedef struct hashtab_s {
size_t tab_size;
char *(*get_key)(void*);
void (*free_ele)(void*);
hashlink_t *tab[ZERO_LENGTH_ARRAY];
} hashtab_t;
hashtab_t *Hash_NewTable (int tsize, char *(*gk)(void*), void (*f)(void*));
void Hash_DelTable (hashtab_t *tab);
int Hash_Add (hashtab_t *tab, void *ele);
void *Hash_Find (hashtab_t *tab, const char *key);
int Hash_Del (hashtab_t *tab, const char *key);
#endif // __hash_h

View file

@ -45,7 +45,8 @@ noinst_LIBRARIES= libqfcd.a libqfjs.a libqfsnd.a libqfsys_cl.a libqfsys_sv.a
if ASM_ARCH
math_ASM = math.S sys_x86.S
endif
common_SOURCES= buildnum.c checksum.c cmd.c com.c crc.c cvar.c info.c link.c \
common_SOURCES= buildnum.c checksum.c cmd.c com.c crc.c cvar.c hash.c \
info.c link.c \
locs.c mathlib.c mdfour.c model.c model_brush.c msg.c \
net_chan.c net_com.c net_udp.c pmove.c pmovetst.c qargs.c \
qendian.c quakefs.c quakeio.c sizebuf.c va.c zone.c \

View file

@ -1641,6 +1641,7 @@ Host_Init (void)
Sys_Error ("Only %4.1f megs of memory reported, can't execute game",
host_parms.memsize / (float) 0x100000);
Cvar_Init_Hash ();
Memory_Init (host_parms.membase, host_parms.memsize);
Cvar_Init ();
Sys_Init_Cvars ();

View file

@ -45,6 +45,7 @@
#include "commdef.h"
#include "cvar.h"
#include "console.h"
#include "hash.h"
#include "qargs.h"
#include "cmd.h"
#include "commdef.h"
@ -53,6 +54,8 @@ cvar_t *cvar_vars;
char *cvar_null_string = "";
extern cvar_t *developer;
cvar_alias_t *calias_vars;
hashtab_t *cvar_hash;
hashtab_t *calias_hash;
/*
============
@ -62,13 +65,7 @@ Cvar_FindVar
cvar_t *
Cvar_FindVar (char *var_name)
{
cvar_t *var;
for (var = cvar_vars; var; var = var->next)
if (!strcmp (var_name, var->name))
return var;
return NULL;
return (cvar_t*)Hash_Find (cvar_hash, var_name);
}
cvar_t *
@ -76,10 +73,10 @@ Cvar_FindAlias (char *alias_name)
{
cvar_alias_t *alias;
for (alias = calias_vars; alias; alias = alias->next)
if (!strcmp (alias_name, alias->name))
return alias->cvar;
return NULL;
alias = (cvar_alias_t*)Hash_Find (calias_hash, alias_name);
if (alias)
return alias->cvar;
return 0;
}
void
@ -104,6 +101,7 @@ Cvar_Alias_Get (char *name, cvar_t *cvar)
calias_vars = alias;
alias->name = strdup (name);
alias->cvar = cvar;
Hash_Add (calias_hash, alias);
}
}
@ -206,8 +204,7 @@ Cvar_Set (cvar_t *var, char *value)
free (var->string); // free the old value string
var->string = malloc (strlen (value) + 1);
strcpy (var->string, value);
var->string = strdup (value);
var->value = atof (var->string);
var->int_val = atoi (var->string);
@ -228,8 +225,7 @@ Cvar_SetROM (cvar_t *var, char *value)
free (var->string); // free the old value string
var->string = malloc (strlen (value) + 1);
strcpy (var->string, value);
var->string = strdup (value);
var->value = atof (var->string);
var->int_val = atoi (var->string);
@ -430,6 +426,44 @@ Cvar_CvarList_f (void)
Con_Printf ("------------\n%d variables\n", i);
}
static void
cvar_free (void *c)
{
cvar_t *cvar = (cvar_t*)c;
free (cvar->name);
free (cvar->string);
free (cvar);
}
static char *
cvar_get_key (void *c)
{
cvar_t *cvar = (cvar_t*)c;
return cvar->name;
}
static void
calias_free (void *c)
{
cvar_alias_t *calias = (cvar_alias_t*)c;
free (calias->name);
free (calias);
}
static char *
calias_get_key (void *c)
{
cvar_alias_t *calias = (cvar_alias_t*)c;
return calias->name;
}
void
Cvar_Init_Hash (void)
{
cvar_hash = Hash_NewTable (1021, cvar_get_key, cvar_free);
calias_hash = Hash_NewTable (1021, calias_get_key, calias_free);
}
void
Cvar_Init (void)
{
@ -486,12 +520,12 @@ Cvar_Get (char *name, char *string, int cvarflags, char *description)
v->next = cvar_vars;
cvar_vars = v;
v->name = strdup (name);
v->string = malloc (strlen (string) + 1);
strcpy (v->string, string);
v->string = strdup (string);
v->flags = cvarflags;
v->description = description;
v->value = atof (v->string);
v->int_val = atoi (v->string);
Hash_Add (cvar_hash, v);
} else {
// Cvar does exist, so we update the flags and return.
v->flags &= ~CVAR_USER_CREATED;

129
source/hash.c Normal file
View file

@ -0,0 +1,129 @@
/*
hash.h
hash tables
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 2000 Marcus Sundberg <mackan@stacken.kth.se>
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
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "compat.h"
#include "hash.h"
static unsigned long
hash (const char *str)
{
unsigned long h = 0;
while (*str) {
h = (h << 4) + (unsigned char)*str++;
if (h&0xf0000000)
h = (h ^ (h >> 24)) & 0xfffffff;
}
return h;
}
hashtab_t *
Hash_NewTable (int tsize, char *(*gk)(void*), void (*f)(void*))
{
hashtab_t *tab = calloc (1, (size_t)&((hashtab_t*)0)->tab[tsize]);
if (!tab)
return 0;
tab->tab_size = tsize;
tab->get_key = gk;
tab->free_ele = f;
return tab;
}
void
Hash_DelTable (hashtab_t *tab)
{
int i;
for (i = 0; i < tab->tab_size; i++) {
while (tab->tab[i]) {
hashlink_t *t = tab->tab[i]->next;
if (tab->free_ele)
tab->free_ele (&tab->tab[i]->data);
free (tab->tab[i]);
tab->tab[i] = t;
}
}
free (tab);
}
int
Hash_Add (hashtab_t *tab, void *ele)
{
unsigned long h = hash (tab->get_key(ele));
size_t ind = h % tab->tab_size;
hashlink_t *lnk = malloc (sizeof (hashlink_t));
if (!lnk)
return -1;
if (tab->tab[ind])
tab->tab[ind]->prev = &lnk->next;
lnk->next = tab->tab[ind];
lnk->prev = &tab->tab[ind];
lnk->data = ele;
tab->tab[ind] = lnk;
return 0;
}
void *
Hash_Find (hashtab_t *tab, const char *key)
{
unsigned long h = hash (key);
size_t ind = h % tab->tab_size;
hashlink_t *lnk = tab->tab[ind];
while (lnk) {
if (strequal (key, tab->get_key (lnk->data)))
return lnk->data;
lnk = lnk->next;
}
return 0;
}
int
Hash_Del (hashtab_t *tab, const char *key)
{
unsigned long h = hash (key);
size_t ind = h % tab->tab_size;
hashlink_t *lnk = tab->tab[ind];
while (lnk) {
if (strequal (key, tab->get_key (lnk->data))) {
if (lnk->next)
lnk->next->prev = lnk->prev;
*lnk->prev = lnk->next;
free (lnk);
return 0;
}
lnk = lnk->next;
}
return -1;
}

View file

@ -1867,6 +1867,7 @@ SV_Init (void)
SV_Error ("Only %4.1f megs of memory reported, can't execute game",
host_parms.memsize / (float) 0x100000);
Cvar_Init_Hash ();
Memory_Init (host_parms.membase, host_parms.memsize);
Cvar_Init ();
Sys_Init_Cvars ();