⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 varstore.c

📁 htp是一个HTML预处理器。页面可以用htp扩展的类HTML的宏编写。这可以简化维护一个一致外观的Web页面集.
💻 C
字号:
/*//// varstore.c//// Variable store functions (implemented with a simple hash table)//// Copyright (c) 1995-96 Jim Nelson.  Permission to distribute// granted by the author.  No warranties are made on the fitness of this// source code.//*/#include "htp.h"/* statistics for performance measurement */#if DEBUGuint variableLookups = 0;uint variableCacheHits = 0;uint variableStringCompares = 0;uint variableMissedStringCompares = 0;uint variableHashCalcs = 0;#endif/* !! dont primes contribute to a more evenly distributed hash table? *//* need to check Knuth ... */#define HASH_TABLE_SIZE             (53)/*// generates an index into the hash table from the string*/uint StringToHashTableIndex(const char *name){    uint hash;    uint ctr;    if(name == NULL)    {        return 0;    }    #if DEBUG    variableHashCalcs++;    #endif    hash = 0;    ctr = 0;    while(*name != NUL)    {        /* uppercase the chars before hashing because names are case-insensitive */        /* shift left to give a broader distribution in the hash table */        hash += (uint) toupper(*name++) << (ctr++ & 0x03);    }    return (hash % HASH_TABLE_SIZE);}BOOL InitializeVariableStore(VARSTORE *varstore){    assert(varstore != NULL);    /* allocate the hash table */    varstore->variableHashTable = AllocMemory(sizeof(VARIABLE *) * HASH_TABLE_SIZE);    if(varstore->variableHashTable == NULL)    {        DEBUG_PRINT(("out of memory trying to allocate variable hash table"));        return FALSE;    }    memset(varstore->variableHashTable, 0, sizeof(VARIABLE *) * HASH_TABLE_SIZE);    /* initialize the rest of the store */    varstore->parent = NULL;    varstore->child = NULL;    varstore->lastVariable = NULL;    return TRUE;}void DestroyVariableStore(VARSTORE *varstore){    /* destroy all children as well ... this function doesn't simply "unlink" */    /* the current store from the linked list */    while(varstore != NULL)    {        /* unlink from parent */        if(varstore->parent != NULL)        {            varstore->parent->child = NULL;            varstore->parent = NULL;        }        /* destroy all variables in this store */        ClearVariableList(varstore);        /* free the hash table memory */        FreeMemory(varstore->variableHashTable);        varstore->variableHashTable = NULL;        /* destroy all child scopes as well */        varstore = varstore->child;    }}BOOL StoreVariable(VARSTORE *varstore, const char *name, const char *value,    uint type, uint flag, void *param, VAR_DESTRUCTOR destructor){    VARIABLE *variable;    VARIABLE *ptr;    uint index;    assert(varstore != NULL);    assert(name != NULL);    /* remove any variable with the same name in the store */    RemoveVariable(varstore, name);    /* allocate space for the variable structure */    if((variable = AllocMemory(sizeof(VARIABLE))) == NULL)    {        DEBUG_PRINT(("unable to allocate memory for new variable"));        return FALSE;    }    /* copy in the variable's name */    StringCopy(variable->name, name, MAX_VARNAME_LEN);    /* copy in the variable's value, if any */    if(value != NULL)    {        StringCopy(variable->value, value, MAX_VARVALUE_LEN);    }    /* set flags and destructor pointer */    variable->type = type;    variable->flag = flag;    variable->param = param;    variable->destructor = destructor;    variable->next = NULL;    /* insert into the hash table */    index = StringToHashTableIndex(name);    ptr = varstore->variableHashTable[index];    varstore->variableHashTable[index] = variable;    if(ptr != NULL)    {        /* the slot has been previously hashed to a different variable, */        /* inserted new item at beginning of list, add rest to end */        variable->next = ptr;    }    /* put this new variable into the last-used cache */    varstore->lastVariable = variable;    return TRUE;}   static VARIABLE *FindVariable(VARSTORE *varstore, const char *name){    VARIABLE *ptr;    assert(varstore != NULL);    assert(name != NULL);    #if DEBUG    variableLookups++;    #endif    /* check the last referenced variable first */    if(varstore->lastVariable != NULL)    {        #if DEBUG        variableStringCompares++;        #endif        if(stricmp(varstore->lastVariable->name, name) == 0)        {            #if DEBUG            variableCacheHits++;            #endif            return varstore->lastVariable;        }        #if DEBUG        variableMissedStringCompares++;        #endif    }    ptr = varstore->variableHashTable[StringToHashTableIndex(name)];    while(ptr != NULL)    {        #if DEBUG        variableStringCompares++;        #endif        if(stricmp(ptr->name, name) == 0)        {            /* cache this variable for next time */            varstore->lastVariable = ptr;            return ptr;        }        #if DEBUG        variableMissedStringCompares++;        #endif        ptr = ptr->next;    }    /* check all parent stores as well */    if(varstore->parent != NULL)    {        return FindVariable(varstore->parent, name);    }    return NULL;}   const char *GetVariableValue(VARSTORE *varstore, const char *name){    VARIABLE *variable;    if(name != NULL)    {        if((variable = FindVariable(varstore, name)) != NULL)        {            return variable->value;        }    }    return NULL;}   uint GetVariableType(VARSTORE *varstore, const char *name){    VARIABLE *variable;    if(name != NULL)    {        if((variable = FindVariable(varstore, name)) != NULL)        {            return variable->type;        }    }    return VAR_TYPE_UNKNOWN;}uint GetVariableFlag(VARSTORE *varstore, const char *name){    VARIABLE *variable;    if(name != NULL)    {        if((variable = FindVariable(varstore, name)) != NULL)        {            return variable->flag;        }    }    return VAR_FLAG_UNKNOWN;}   static void DestroyVariable(VARSTORE *varstore, VARIABLE *variable){    /* if the variable has a destructor callback, do it */    if(variable->destructor != NULL)    {        variable->destructor(variable->name, variable->value, variable->type,            variable->flag, variable->param);    }    /* if this is the last referenced variable, uncache it */    if(varstore->lastVariable == variable)    {        varstore->lastVariable = NULL;    }    /* free the structure */    FreeMemory(variable);}void ClearVariableList(VARSTORE *varstore){    VARIABLE *ptr;    VARIABLE *next;    uint ctr;    assert(varstore != NULL);    /* have to walk the entire hash table to destroy each item */    for(ctr = 0; ctr < HASH_TABLE_SIZE; ctr++)    {        ptr = varstore->variableHashTable[ctr];        while(ptr != NULL)        {            next = ptr->next;            DestroyVariable(varstore, ptr);            ptr = next;        }        varstore->variableHashTable[ctr] = NULL;    }}   BOOL RemoveVariable(VARSTORE *varstore, const char *name){    VARIABLE *ptr;    VARIABLE *prev;    uint index;    assert(varstore != NULL);    if(name == NULL)    {        return FALSE;    }    index = StringToHashTableIndex(name);    prev = NULL;    ptr = varstore->variableHashTable[index];    while(ptr != NULL)    {        #if DEBUG        variableStringCompares++;        #endif        if(stricmp(ptr->name, name) == 0)        {            /* found the variable */            /* unlink from the list */            if(prev != NULL)            {                prev->next = ptr->next;            }            else            {                varstore->variableHashTable[index] = ptr->next;            }            /* destroy the variable structure */            DestroyVariable(varstore, ptr);            return TRUE;        }        prev = ptr;        ptr = ptr->next;    }    return FALSE;}BOOL VariableExists(VARSTORE *varstore, const char *name){    return (FindVariable(varstore, name) != NULL) ? TRUE : FALSE;}void *GetVariableParam(VARSTORE *varstore, const char *name){    VARIABLE *var;    if(name != NULL)    {        if((var = FindVariable(varstore, name)) != NULL)        {            return var->param;        }    }    return NULL;}static VARSTORE *FindTopmostContext(VARSTORE *varstore){    VARSTORE *ptr;    assert(varstore != NULL);    ptr = varstore;    while(ptr->child != NULL)    {        assert(ptr->child->parent == ptr);        ptr = ptr->child;    }    return ptr;}void PushVariableStoreContext(VARSTORE *parent, VARSTORE *varstore){    VARSTORE *ptr;    assert(parent != NULL);    assert(varstore != NULL);    assert(varstore->parent == NULL);    ptr = FindTopmostContext(parent);    ptr->child = varstore;    varstore->parent = ptr;    varstore->child = NULL;}VARSTORE *PopVariableStoreContext(VARSTORE *varstore){    VARSTORE *ptr;    assert(varstore != NULL);    ptr = FindTopmostContext(varstore);    /* unlink from parent and return current context */    ptr->parent->child = NULL;    ptr->parent = NULL;    return ptr;}VARSTORE *PeekVariableStoreContext(VARSTORE *varstore){    return FindTopmostContext(varstore);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -