forked from KolibriOS/kolibrios
Add one more clink's dependency
git-svn-id: svn://kolibrios.org@8601 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
2b98571951
commit
0b8e3382ef
21
programs/develop/clink/cdict/LICENSE
Normal file
21
programs/develop/clink/cdict/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 Magomed Kostoev
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
88
programs/develop/clink/cdict/README.md
Normal file
88
programs/develop/clink/cdict/README.md
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# CDict - a simple dictionary implementation in C
|
||||||
|
## Ready to use!
|
||||||
|
|
||||||
|
It may be used out of the box with key and value of type `CStr` (which is `char *` - zero-terminated string). Once it instantiated in some file using `CDICT_INST` definition:
|
||||||
|
|
||||||
|
```C
|
||||||
|
#define CDICT_INST
|
||||||
|
#include "cdict.h"
|
||||||
|
```
|
||||||
|
|
||||||
|
It may be then declared just using `#include`:
|
||||||
|
|
||||||
|
```C
|
||||||
|
#include "cdict.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
CDict_CStr_CStr dict;
|
||||||
|
if (!cdict_CStr_CStr_init(&dict)) {
|
||||||
|
printf("CDict returned error #%d", dict.error_code);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
cdict_CStr_CStr_add_vv(&dict, "key_a", "value_a", CDICT_REPLACE_EXIST);
|
||||||
|
printf("[key_a] = \"%s\"\n", cdict_CStr_CStr_get_v(&dict, "key_a"));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Easy to configure!
|
||||||
|
|
||||||
|
If you want to create a dictionary for other key types you should provide your own keys hashing and comparsion functions, in such case the instantiation of the library will look like this:
|
||||||
|
|
||||||
|
```C
|
||||||
|
#define CDICT_INST
|
||||||
|
#define CDICT_KEY_T MyType
|
||||||
|
#define CDICT_HASH_FN(pkey) my_hash(pkey)
|
||||||
|
#define CDICT_CMP_FN(pkey0, pkey1) my_cmp(pkey0, pkey1)
|
||||||
|
#include "cdict.h"
|
||||||
|
|
||||||
|
int my_cmp(MyType *pkey0, MyType *pkey1) {
|
||||||
|
// Return `whatever_negative` if `key0 < key1`, `0` if `key0 == key1` and `whatever_positive` if `key0 > key1`
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long my_hash(MyType *key) {
|
||||||
|
// Return the hash of the key
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Then to use the new dictionary you only need to define key type before the header inclusion:
|
||||||
|
|
||||||
|
```C
|
||||||
|
#define CDICT_KEY_T MyType
|
||||||
|
#include "cdict.h"
|
||||||
|
|
||||||
|
// ...
|
||||||
|
CDict_MyType_CStr dict;
|
||||||
|
cdict_MyType_CStr_init(&dict);
|
||||||
|
// ...
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to specify the type of values - just define the type:
|
||||||
|
|
||||||
|
```C
|
||||||
|
#define CDICT_VAL_T MyValueType
|
||||||
|
```
|
||||||
|
|
||||||
|
And so on.
|
||||||
|
|
||||||
|
## Dependency-free!
|
||||||
|
|
||||||
|
Every single used dependency may be redefined:
|
||||||
|
|
||||||
|
```C
|
||||||
|
#define CDICT_ASSERT_FN(x) my_assert(x);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Flexible!
|
||||||
|
|
||||||
|
May define user data to be used in overriden functions (for example - custom allocators):
|
||||||
|
|
||||||
|
```C
|
||||||
|
#define CDICT_USER_DATA_T UserData
|
||||||
|
#define CDICT_HASHTAB_ITEM_ALLOC_FN(cdict, size) item_alloc(cdict, size)
|
||||||
|
#define CDICT_HASHTAB_ITEM_FREE_FN(cdict, ptr) item_free(cdict, ptr)
|
||||||
|
#define CDICT_HASHTAB_ALLOC_FN(cdict, size) hashtab_alloc(cdict, size)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Checkout
|
||||||
|
|
||||||
|
[The library](cdict.h).
|
350
programs/develop/clink/cdict/cdict.h
Normal file
350
programs/develop/clink/cdict/cdict.h
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
// Copyright (c) 2020 Magomed Kostoev
|
||||||
|
//
|
||||||
|
// You may use, distribute and modify this code under the terms of the MIT license.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the MIT license with this file. If not, please visit
|
||||||
|
// https://opensource.org/licenses/MIT or boppan.org/MIT for full license details.
|
||||||
|
|
||||||
|
// cdict.h - simple dictionaty implementation in C.
|
||||||
|
//
|
||||||
|
// Uses hash table with fixed (but configurable) size. Functions named using given type names:
|
||||||
|
// cdict_<CDICT_KEY_T>_<CDICT_VAL_T>_<name>.
|
||||||
|
//
|
||||||
|
// See configuration below (in public "Input macros" section), also:
|
||||||
|
// CDICT_INST: Instantiate the functions if defined.
|
||||||
|
//
|
||||||
|
// Minimal definitions for declaration: CDICT_KEY_T, CDICT_VAL_T
|
||||||
|
// Minimal definitions for instantiation: CDICT_INST, CDICT_KEY_T, CDICT_VAL_T, CDICT_HASH_FN,
|
||||||
|
// CDICT_CMP_FN
|
||||||
|
//
|
||||||
|
// WARNING: All used definitions will be undefined on header exit.
|
||||||
|
//
|
||||||
|
// Dependencies:
|
||||||
|
// <stddef.h> or another source of size_t
|
||||||
|
// <stdlib.h> or another source of malloc, and calloc
|
||||||
|
// <assert.h> or another source of assert
|
||||||
|
|
||||||
|
//
|
||||||
|
// Internal macros for external declarations
|
||||||
|
//
|
||||||
|
|
||||||
|
#define CDICT_CAT2_IMPL(x, y) x ## _ ## y
|
||||||
|
#define CDICT_CAT2(x, y) CDICT_CAT2_IMPL(x, y)
|
||||||
|
|
||||||
|
/// Creates method name according to CDICT_KEY_T and CDICT_VAL_T
|
||||||
|
#define CDICT_FUN(name) CDICT_CAT2(cdict, CDICT_CAT2(CDICT_KEY_T, CDICT_CAT2(CDICT_VAL_T, name)))
|
||||||
|
|
||||||
|
#define cdict_init CDICT_FUN(init)
|
||||||
|
#define cdict_init_ud CDICT_FUN(init_ud)
|
||||||
|
#define cdict_init_pud CDICT_FUN(init_pud)
|
||||||
|
#define cdict_add_pp CDICT_FUN(add_pp)
|
||||||
|
#define cdict_add_vv CDICT_FUN(add_vv)
|
||||||
|
#define cdict_get_p CDICT_FUN(get_p)
|
||||||
|
#define cdict_get_v CDICT_FUN(get_v)
|
||||||
|
#define cdict_error_message CDICT_FUN(error_message)
|
||||||
|
|
||||||
|
#define cdict_hash CDICT_FUN(hash)
|
||||||
|
#define cdict_keycmp CDICT_FUN(keycmp)
|
||||||
|
#define cdict_chain_begin CDICT_FUN(begin)
|
||||||
|
#define cdict_chain_next CDICT_FUN(next)
|
||||||
|
|
||||||
|
#define CDictItem CDICT_CAT2(CDictItem, CDICT_CAT2(CDICT_KEY_T, CDICT_VAL_T))
|
||||||
|
#define CDictItem_s CDICT_CAT2(CDictItem_s, CDICT_CAT2(CDICT_KEY_T, CDICT_VAL_T))
|
||||||
|
#define CDict CDICT_CAT2(CDict, CDICT_CAT2(CDICT_KEY_T, CDICT_VAL_T))
|
||||||
|
|
||||||
|
//
|
||||||
|
// Input macros
|
||||||
|
//
|
||||||
|
|
||||||
|
/// Type of the dictionary's keys, named type only - used in functions names, default: CStr
|
||||||
|
#ifndef CDICT_KEY_T
|
||||||
|
typedef char *CStr;
|
||||||
|
#define CDICT_CSTR_IS_THERE
|
||||||
|
#define CDICT_KEY_T CStr
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Type of the dictionary's values, named type only - used in functions names, default: CStr
|
||||||
|
#ifndef CDICT_VAL_T
|
||||||
|
#ifndef CDICT_CSTR_IS_THERE
|
||||||
|
typedef char *CStr;
|
||||||
|
#endif
|
||||||
|
#define CDICT_VAL_T CStr
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Type of user data
|
||||||
|
#ifndef CDICT_USER_DATA_T
|
||||||
|
#define CDICT_USER_DATA_T void *
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Public interface
|
||||||
|
//
|
||||||
|
|
||||||
|
#define CDICT_NO_CHECK 0
|
||||||
|
#define CDICT_REPLACE_EXIST 1
|
||||||
|
#define CDICT_LEAVE_EXIST 2
|
||||||
|
|
||||||
|
#define CDICT_ERR_SUCCESS 0
|
||||||
|
#define CDICT_ERR_OUT_OF_MEMORY 1
|
||||||
|
#define CDICT_ERR_THIS_IS_NULL 2
|
||||||
|
#define CDICT_ERR_HASH_TABLE_IS_NULL 3
|
||||||
|
#define CDICT_ERR_PKEY0_IS_NULL 4
|
||||||
|
#define CDICT_ERR_PKEY1_IS_NULL 5
|
||||||
|
#define CDICT_ERR_PKEY_IS_NULL 6
|
||||||
|
#define CDICT_ERR_PVAL_IS_NULL 7
|
||||||
|
|
||||||
|
typedef struct CDictItem_s {
|
||||||
|
struct CDictItem_s *next_collision;
|
||||||
|
CDICT_KEY_T key;
|
||||||
|
CDICT_VAL_T val;
|
||||||
|
} CDictItem;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
CDictItem **hash_table;
|
||||||
|
CDICT_USER_DATA_T user_data;
|
||||||
|
int error_code;
|
||||||
|
} CDict;
|
||||||
|
|
||||||
|
/// Initializes dictionary structure
|
||||||
|
int cdict_init(CDict *s);
|
||||||
|
|
||||||
|
/// Initializes dictionary structure with non-standard user data
|
||||||
|
int cdict_init_ud(CDict *s, CDICT_USER_DATA_T user_data);
|
||||||
|
|
||||||
|
/// Initializes dictionary structure with non-standard user data
|
||||||
|
int cdict_init_pud(CDict *s, CDICT_USER_DATA_T *user_data);
|
||||||
|
|
||||||
|
/// Inserts a value by key (receives pointers to val and key)
|
||||||
|
CDictItem *cdict_add_pp(CDict *s, CDICT_KEY_T *pkey, CDICT_VAL_T *pval, int if_exists);
|
||||||
|
|
||||||
|
/// Inserts a value by key (receives values of val and key)
|
||||||
|
CDictItem *cdict_add_vv(CDict *s, CDICT_KEY_T key, CDICT_VAL_T val, int if_exists);
|
||||||
|
|
||||||
|
/// Gives a value by key (receives a pointer to key)
|
||||||
|
CDICT_VAL_T cdict_get_p(CDict *s, CDICT_KEY_T *pkey);
|
||||||
|
|
||||||
|
/// Gives a vaule by key (receives a value of key)
|
||||||
|
CDICT_VAL_T cdict_get_v(CDict *s, CDICT_KEY_T key);
|
||||||
|
|
||||||
|
#ifdef CDICT_INST
|
||||||
|
|
||||||
|
//
|
||||||
|
// Input macros (instantiation edition)
|
||||||
|
//
|
||||||
|
|
||||||
|
/// The value returned on some error
|
||||||
|
#ifndef CDICT_VAL_DEFAULT
|
||||||
|
#define CDICT_VAL_DEFAULT (CDICT_VAL_T){ 0 }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Hashing function for the key type
|
||||||
|
#ifndef CDICT_HASH_FN
|
||||||
|
#include <string.h>
|
||||||
|
#define CDICT_HASH_FN(pkey) strlen(*pkey) ^ (*pkey)[0]
|
||||||
|
#else
|
||||||
|
#define CDICT_HASH_FN_OVERRIDEN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Ammount of pointers to elements in hash table
|
||||||
|
#ifndef CDICT_HASHTAB_SZ
|
||||||
|
#define CDICT_HASHTAB_SZ 1024
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Hash table allocator MUST return zeroed buffer
|
||||||
|
#ifndef CDICT_HASHTAB_ALLOC_FN
|
||||||
|
#include <stdlib.h>
|
||||||
|
#define CDICT_HASHTAB_ALLOC_FN(cdict, size) calloc(1, size)
|
||||||
|
#else
|
||||||
|
#define CDICT_HASHTAB_ALLOCATORS_OVERRIDDEN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// New hash table items allocator (should be just a function call)
|
||||||
|
#ifndef CDICT_HASHTAB_ITEM_ALLOC_FN
|
||||||
|
#include <stdlib.h>
|
||||||
|
#define CDICT_HASHTAB_ITEM_ALLOC_FN(cdict, size) malloc(size)
|
||||||
|
#define CDICT_HASHTAB_ITEM_FREE_FN(cdict, ptr) free(ptr)
|
||||||
|
#else
|
||||||
|
#ifndef CDICT_HASHTAB_ITEM_FREE_FN
|
||||||
|
#error "CDICT_HASHTAB_ITEM_FREE_FN should be defiend along with CDICT_HASHTAB_ITEM_ALLOC_FN"
|
||||||
|
#endif
|
||||||
|
#define CDICT_HASHTAB_ITEM_ALLOCATORS_OVERRIDDEN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CDICT_HASHTAB_ITEM_ALLOCATORS_OVERRIDDEN
|
||||||
|
#error "FUCK!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Replacement for assert from <assert.h>
|
||||||
|
#ifndef CDICT_ASSERT_FN
|
||||||
|
#include <assert.h>
|
||||||
|
#define CDICT_ASSERT_FN(x) if (!x) { printf(__FILE__":%d: Disasserted", __LINE__); } assert(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Function for comparsion of keys, return should be the same as memcmp
|
||||||
|
#ifndef CDICT_CMP_FN
|
||||||
|
#include <string.h>
|
||||||
|
#define CDICT_CMP_FN(pkey0, pkey1) strcmp(*pkey0, *pkey1)
|
||||||
|
#else
|
||||||
|
#define CDICT_CMP_FN_OVERRIDDEN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Internal macros (instantiation edition)
|
||||||
|
//
|
||||||
|
|
||||||
|
#define CDICT_ASSERT(x) ({ CDICT_ASSERT_FN(x); x; })
|
||||||
|
// Should write the error code into strucure, but should not rewrite it's already set
|
||||||
|
#define CDICT_IF_NULL_SET_ERR_RETURN(x, ec, res) if (x == NULL) { \
|
||||||
|
if (s->error_code == CDICT_ERR_SUCCESS) s->error_code = ec; \
|
||||||
|
return res; \
|
||||||
|
}
|
||||||
|
#define CDICT_IF_NULL_RETURN(x, res) if (x == NULL) return res
|
||||||
|
|
||||||
|
//
|
||||||
|
// Predeclarations
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifdef CDICT_HASHTAB_ITEM_ALLOCATORS_OVERRIDDEN
|
||||||
|
void *CDICT_HASHTAB_ITEM_ALLOC_FN(CDict *s, size_t size);
|
||||||
|
void CDICT_HASHTAB_ITEM_FREE_FN(CDict *s, CDictItem *ptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CDICT_HASHTAB_ALLOCATORS_OVERRIDDEN
|
||||||
|
void *CDICT_HASHTAB_ALLOC_FN(CDict *s, size_t size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CDICT_HASH_FN_OVERRIDEN
|
||||||
|
unsigned long CDICT_HASH_FN(CDICT_KEY_T *pkey);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CDICT_CMP_FN_OVERRIDDEN
|
||||||
|
int CDICT_CMP_FN(CDICT_KEY_T *pkey0, CDICT_KEY_T *pkey1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// The code
|
||||||
|
//
|
||||||
|
|
||||||
|
static size_t cdict_hash(CDICT_KEY_T *pkey) {
|
||||||
|
return CDICT_HASH_FN(CDICT_ASSERT(pkey)) & (CDICT_HASHTAB_SZ - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cdict_keycmp(CDICT_KEY_T *pkey0, CDICT_KEY_T *pkey1) {
|
||||||
|
return CDICT_CMP_FN(CDICT_ASSERT(pkey0), CDICT_ASSERT(pkey1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static CDictItem **cdict_chain_begin(CDict *s, CDICT_KEY_T *pkey) {
|
||||||
|
CDICT_ASSERT(s);
|
||||||
|
size_t hash = cdict_hash(CDICT_ASSERT(pkey));
|
||||||
|
CDICT_IF_NULL_SET_ERR_RETURN(s->hash_table, CDICT_ERR_HASH_TABLE_IS_NULL, NULL);
|
||||||
|
return &s->hash_table[hash];
|
||||||
|
}
|
||||||
|
|
||||||
|
static CDictItem **cdict_chain_next(CDictItem **ppit) {
|
||||||
|
CDICT_ASSERT(ppit);
|
||||||
|
CDICT_ASSERT(*ppit);
|
||||||
|
return &(*ppit)->next_collision;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cdict_init(CDict *s) {
|
||||||
|
return cdict_init_pud(s, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cdict_init_ud(CDict *s, CDICT_USER_DATA_T user_data) {
|
||||||
|
return cdict_init_pud(s, &user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cdict_init_pud(CDict *s, CDICT_USER_DATA_T *user_data) {
|
||||||
|
CDICT_IF_NULL_RETURN(s, 0);
|
||||||
|
s->user_data = user_data ? *user_data : (CDICT_USER_DATA_T){ 0 };
|
||||||
|
s->error_code = CDICT_ERR_SUCCESS;
|
||||||
|
s->hash_table = CDICT_HASHTAB_ALLOC_FN(s, sizeof(*s->hash_table) * CDICT_HASHTAB_SZ);
|
||||||
|
CDICT_IF_NULL_SET_ERR_RETURN(s->hash_table, CDICT_ERR_OUT_OF_MEMORY, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CDictItem *cdict_add_pp(CDict *s, CDICT_KEY_T *pkey, CDICT_VAL_T *pval, int if_exists) {
|
||||||
|
CDICT_IF_NULL_RETURN(s, NULL);
|
||||||
|
CDICT_IF_NULL_SET_ERR_RETURN(pkey, CDICT_ERR_PKEY_IS_NULL, NULL);
|
||||||
|
CDICT_IF_NULL_SET_ERR_RETURN(pval, CDICT_ERR_PVAL_IS_NULL, NULL);
|
||||||
|
CDictItem *next_collision = NULL;
|
||||||
|
CDictItem **ppit = cdict_chain_begin(s, pkey);
|
||||||
|
CDICT_IF_NULL_RETURN(ppit, NULL);
|
||||||
|
while (*ppit) {
|
||||||
|
int exists = if_exists == CDICT_NO_CHECK ? 0 : !cdict_keycmp(pkey, &(*ppit)->key);
|
||||||
|
if (exists) {
|
||||||
|
if (if_exists == CDICT_LEAVE_EXIST) {
|
||||||
|
return *ppit;
|
||||||
|
} else if (if_exists == CDICT_REPLACE_EXIST) {
|
||||||
|
next_collision = (*ppit)->next_collision;
|
||||||
|
CDICT_HASHTAB_ITEM_FREE_FN(s, *ppit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ppit = cdict_chain_next(ppit);
|
||||||
|
}
|
||||||
|
*ppit = CDICT_HASHTAB_ITEM_ALLOC_FN(s, sizeof(**ppit));
|
||||||
|
CDictItem *pit = *ppit;
|
||||||
|
pit->key = *pkey;
|
||||||
|
pit->val = *pval;
|
||||||
|
pit->next_collision = next_collision;
|
||||||
|
return pit;
|
||||||
|
}
|
||||||
|
|
||||||
|
CDictItem *cdict_add_vv(CDict *s, CDICT_KEY_T key, CDICT_VAL_T val, int if_exists) {
|
||||||
|
return cdict_add_pp(s, &key, &val, if_exists);
|
||||||
|
}
|
||||||
|
|
||||||
|
CDICT_VAL_T cdict_get_p(CDict *s, CDICT_KEY_T *pkey) {
|
||||||
|
CDICT_IF_NULL_RETURN(s, CDICT_VAL_DEFAULT);
|
||||||
|
CDICT_IF_NULL_SET_ERR_RETURN(pkey, CDICT_ERR_PKEY_IS_NULL, CDICT_VAL_DEFAULT);
|
||||||
|
CDictItem **ppit = cdict_chain_begin(s, pkey);
|
||||||
|
CDICT_IF_NULL_RETURN(ppit, CDICT_VAL_DEFAULT);
|
||||||
|
while (*ppit) {
|
||||||
|
if (!cdict_keycmp(pkey, &(*ppit)->key)) {
|
||||||
|
return (*ppit)->val;
|
||||||
|
}
|
||||||
|
ppit = cdict_chain_next(ppit);
|
||||||
|
}
|
||||||
|
return CDICT_VAL_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
CDICT_VAL_T cdict_get_v(CDict *s, CDICT_KEY_T key) {
|
||||||
|
return cdict_get_p(s, &key);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef CDICT_CAT2_IMPL
|
||||||
|
#undef CDICT_CAT2
|
||||||
|
#undef CDICT_FUN
|
||||||
|
|
||||||
|
#undef cdict_init
|
||||||
|
#undef cdict_init_ud
|
||||||
|
#undef cdict_init_pud
|
||||||
|
#undef cdict_add_pp
|
||||||
|
#undef cdict_add_vv
|
||||||
|
#undef cdict_get_p
|
||||||
|
#undef cdict_get_v
|
||||||
|
|
||||||
|
#undef CDICT_KEY_T
|
||||||
|
#undef CDICT_VAL_T
|
||||||
|
#undef CDICT_USER_DATA_T
|
||||||
|
|
||||||
|
#ifdef CDICT_INST
|
||||||
|
#undef CDICT_INST
|
||||||
|
#undef CDICT_HASH_FN
|
||||||
|
#undef CDICT_HASHTAB_SZ
|
||||||
|
#undef CDICT_HASHTAB_ALLOC_FN
|
||||||
|
#undef CDICT_HASHTAB_ITEM_ALLOC_FN
|
||||||
|
#undef CDICT_HASHTAB_ITEM_FREE_FN
|
||||||
|
#undef CDICT_ASSERT_FN
|
||||||
|
#undef CDICT_CMP_FN
|
||||||
|
#undef CDICT_ASSERT
|
||||||
|
#undef CDICT_IF_NULL_RETURN
|
||||||
|
#undef CDICT_IF_NULL_SET_ERR_RETURN
|
||||||
|
#undef CDICT_HASHTAB_ITEM_ALLOCATORS_OVERRIDDEN
|
||||||
|
#undef CDICT_HASHTAB_ALLOCATORS_OVERRIDDEN
|
||||||
|
#undef CDICT_HASH_FN_OVERRIDEN
|
||||||
|
#undef CDICT_CMP_FN_OVERRIDDEN
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user