projects
/
oweals
/
u-boot.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
command: Remove the cmd_tbl_t typedef
[oweals/u-boot.git]
/
lib
/
hashtable.c
diff --git
a/lib/hashtable.c
b/lib/hashtable.c
index 50ff40a397431aac6abc5742352f6b63625f274a..e3be563565174fadb1fb434d56ca50e6cce17195 100644
(file)
--- a/
lib/hashtable.c
+++ b/
lib/hashtable.c
@@
-14,6
+14,7
@@
#include <errno.h>
#include <malloc.h>
#include <errno.h>
#include <malloc.h>
+#include <sort.h>
#ifdef USE_HOSTCC /* HOST build */
# include <string.h>
#ifdef USE_HOSTCC /* HOST build */
# include <string.h>
@@
-40,6
+41,9
@@
#define CONFIG_ENV_MAX_ENTRIES 512
#endif
#define CONFIG_ENV_MAX_ENTRIES 512
#endif
+#define USED_FREE 0
+#define USED_DELETED -1
+
#include <env_callback.h>
#include <env_flags.h>
#include <search.h>
#include <env_callback.h>
#include <env_flags.h>
#include <search.h>
@@
-56,14
+60,14
@@
* which describes the current status.
*/
* which describes the current status.
*/
-
typedef struct _ENTRY
{
+
struct env_entry_node
{
int used;
int used;
-
ENTRY
entry;
-}
_ENTRY
;
+
struct env_entry
entry;
+};
-static void _hdelete(const char *key, struct hsearch_data *htab,
ENTRY *ep,
- int idx);
+static void _hdelete(const char *key, struct hsearch_data *htab,
+
struct env_entry *ep,
int idx);
/*
* hcreate()
/*
* hcreate()
@@
-117,7
+121,8
@@
int hcreate_r(size_t nel, struct hsearch_data *htab)
htab->filled = 0;
/* allocate memory and zero out */
htab->filled = 0;
/* allocate memory and zero out */
- htab->table = (_ENTRY *) calloc(htab->size + 1, sizeof(_ENTRY));
+ htab->table = (struct env_entry_node *)calloc(htab->size + 1,
+ sizeof(struct env_entry_node));
if (htab->table == NULL)
return 0;
if (htab->table == NULL)
return 0;
@@
-148,7
+153,7
@@
void hdestroy_r(struct hsearch_data *htab)
/* free used memory */
for (i = 1; i <= htab->size; ++i) {
if (htab->table[i].used > 0) {
/* free used memory */
for (i = 1; i <= htab->size; ++i) {
if (htab->table[i].used > 0) {
-
ENTRY
*ep = &htab->table[i].entry;
+
struct env_entry
*ep = &htab->table[i].entry;
free((void *)ep->key);
free(ep->data);
free((void *)ep->key);
free(ep->data);
@@
-190,14
+195,14
@@
void hdestroy_r(struct hsearch_data *htab)
* data any more.
* - The standard implementation does not provide a way to update an
* existing entry. This version will create a new entry or update an
* data any more.
* - The standard implementation does not provide a way to update an
* existing entry. This version will create a new entry or update an
- * existing one when both "action == ENTER" and "item.data != NULL".
+ * existing one when both "action == EN
V_EN
TER" and "item.data != NULL".
* - Instead of returning 1 on success, we return the index into the
* internal hash table, which is also guaranteed to be positive.
* This allows us direct access to the found hash table slot for
* example for functions like hdelete().
*/
* - Instead of returning 1 on success, we return the index into the
* internal hash table, which is also guaranteed to be positive.
* This allows us direct access to the found hash table slot for
* example for functions like hdelete().
*/
-int hmatch_r(const char *match, int last_idx,
ENTRY **
retval,
+int hmatch_r(const char *match, int last_idx,
struct env_entry **
retval,
struct hsearch_data *htab)
{
unsigned int idx;
struct hsearch_data *htab)
{
unsigned int idx;
@@
-217,18
+222,30
@@
int hmatch_r(const char *match, int last_idx, ENTRY ** retval,
return 0;
}
return 0;
}
+static int
+do_callback(const struct env_entry *e, const char *name, const char *value,
+ enum env_op op, int flags)
+{
+#ifndef CONFIG_SPL_BUILD
+ if (e->callback)
+ return e->callback(name, value, op, flags);
+#endif
+ return 0;
+}
+
/*
* Compare an existing entry with the desired key, and overwrite if the action
/*
* Compare an existing entry with the desired key, and overwrite if the action
- * is ENTER. This is simply a helper function for hsearch_r().
+ * is EN
V_EN
TER. This is simply a helper function for hsearch_r().
*/
*/
-static inline int _compare_and_overwrite_entry(ENTRY item, ACTION action,
- ENTRY **retval, struct hsearch_data *htab, int flag,
- unsigned int hval, unsigned int idx)
+static inline int _compare_and_overwrite_entry(struct env_entry item,
+ enum env_action action, struct env_entry **retval,
+ struct hsearch_data *htab, int flag, unsigned int hval,
+ unsigned int idx)
{
if (htab->table[idx].used == hval
&& strcmp(item.key, htab->table[idx].entry.key) == 0) {
/* Overwrite existing value? */
{
if (htab->table[idx].used == hval
&& strcmp(item.key, htab->table[idx].entry.key) == 0) {
/* Overwrite existing value? */
- if (
(action == ENTER) && (item.data != NULL)
) {
+ if (
action == ENV_ENTER && item.data
) {
/* check for permission */
if (htab->change_ok != NULL && htab->change_ok(
&htab->table[idx].entry, item.data,
/* check for permission */
if (htab->change_ok != NULL && htab->change_ok(
&htab->table[idx].entry, item.data,
@@
-241,9
+258,8
@@
static inline int _compare_and_overwrite_entry(ENTRY item, ACTION action,
}
/* If there is a callback, call it */
}
/* If there is a callback, call it */
- if (htab->table[idx].entry.callback &&
- htab->table[idx].entry.callback(item.key,
- item.data, env_op_overwrite, flag)) {
+ if (do_callback(&htab->table[idx].entry, item.key,
+ item.data, env_op_overwrite, flag)) {
debug("callback() rejected setting variable "
"%s, skipping it!\n", item.key);
__set_errno(EINVAL);
debug("callback() rejected setting variable "
"%s, skipping it!\n", item.key);
__set_errno(EINVAL);
@@
-267,8
+283,8
@@
static inline int _compare_and_overwrite_entry(ENTRY item, ACTION action,
return -1;
}
return -1;
}
-int hsearch_r(
ENTRY item, ACTION action, ENTRY ** retval
,
- struct hsearch_data *htab, int flag)
+int hsearch_r(
struct env_entry item, enum env_action action
,
+ struct
env_entry **retval, struct
hsearch_data *htab, int flag)
{
unsigned int hval;
unsigned int count;
{
unsigned int hval;
unsigned int count;
@@
-303,7
+319,7
@@
int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
*/
unsigned hval2;
*/
unsigned hval2;
- if (htab->table[idx].used ==
-1
+ if (htab->table[idx].used ==
USED_DELETED
&& !first_deleted)
first_deleted = idx;
&& !first_deleted)
first_deleted = idx;
@@
-335,17
+351,21
@@
int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
if (idx == hval)
break;
if (idx == hval)
break;
+ if (htab->table[idx].used == USED_DELETED
+ && !first_deleted)
+ first_deleted = idx;
+
/* If entry is found use it. */
ret = _compare_and_overwrite_entry(item, action, retval,
htab, flag, hval, idx);
if (ret != -1)
return ret;
}
/* If entry is found use it. */
ret = _compare_and_overwrite_entry(item, action, retval,
htab, flag, hval, idx);
if (ret != -1)
return ret;
}
- while (htab->table[idx].used);
+ while (htab->table[idx].used
!= USED_FREE
);
}
/* An empty bucket has been found. */
}
/* An empty bucket has been found. */
- if (action == ENTER) {
+ if (action == EN
V_EN
TER) {
/*
* If table is full and another entry should be
* entered return with error.
/*
* If table is full and another entry should be
* entered return with error.
@@
-392,9
+412,8
@@
int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
}
/* If there is a callback, call it */
}
/* If there is a callback, call it */
- if (htab->table[idx].entry.callback &&
- htab->table[idx].entry.callback(item.key, item.data,
- env_op_create, flag)) {
+ if (do_callback(&htab->table[idx].entry, item.key, item.data,
+ env_op_create, flag)) {
debug("callback() rejected setting variable "
"%s, skipping it!\n", item.key);
_hdelete(item.key, htab, &htab->table[idx].entry, idx);
debug("callback() rejected setting variable "
"%s, skipping it!\n", item.key);
_hdelete(item.key, htab, &htab->table[idx].entry, idx);
@@
-424,30
+443,29
@@
int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
* do that.
*/
* do that.
*/
-static void _hdelete(const char *key, struct hsearch_data *htab,
ENTRY *ep,
- int idx)
+static void _hdelete(const char *key, struct hsearch_data *htab,
+
struct env_entry *ep,
int idx)
{
{
- /* free used
ENTRY
*/
+ /* free used
entry
*/
debug("hdelete: DELETING key \"%s\"\n", key);
free((void *)ep->key);
free(ep->data);
debug("hdelete: DELETING key \"%s\"\n", key);
free((void *)ep->key);
free(ep->data);
- ep->callback = NULL;
ep->flags = 0;
ep->flags = 0;
- htab->table[idx].used =
-1
;
+ htab->table[idx].used =
USED_DELETED
;
--htab->filled;
}
int hdelete_r(const char *key, struct hsearch_data *htab, int flag)
{
--htab->filled;
}
int hdelete_r(const char *key, struct hsearch_data *htab, int flag)
{
-
ENTRY
e, *ep;
+
struct env_entry
e, *ep;
int idx;
debug("hdelete: DELETE key \"%s\"\n", key);
e.key = (char *)key;
int idx;
debug("hdelete: DELETE key \"%s\"\n", key);
e.key = (char *)key;
- idx = hsearch_r(e, FIND, &ep, htab, 0);
+ idx = hsearch_r(e,
ENV_
FIND, &ep, htab, 0);
if (idx == 0) {
__set_errno(ESRCH);
return 0; /* not found */
if (idx == 0) {
__set_errno(ESRCH);
return 0; /* not found */
@@
-463,8
+481,8
@@
int hdelete_r(const char *key, struct hsearch_data *htab, int flag)
}
/* If there is a callback, call it */
}
/* If there is a callback, call it */
- if (
htab->table[idx].entry.callback &&
-
htab->table[idx].entry.callback(key, NULL,
env_op_delete, flag)) {
+ if (
do_callback(&htab->table[idx].entry, key, NULL,
+
env_op_delete, flag)) {
debug("callback() rejected deleting variable "
"%s, skipping it!\n", key);
__set_errno(EINVAL);
debug("callback() rejected deleting variable "
"%s, skipping it!\n", key);
__set_errno(EINVAL);
@@
-521,8
+539,8
@@
int hdelete_r(const char *key, struct hsearch_data *htab, int flag)
static int cmpkey(const void *p1, const void *p2)
{
static int cmpkey(const void *p1, const void *p2)
{
-
ENTRY *e1 = *(ENTRY **)
p1;
-
ENTRY *e2 = *(ENTRY **)
p2;
+
struct env_entry *e1 = *(struct env_entry **)
p1;
+
struct env_entry *e2 = *(struct env_entry **)
p2;
return (strcmp(e1->key, e2->key));
}
return (strcmp(e1->key, e2->key));
}
@@
-556,8
+574,8
@@
static int match_string(int flag, const char *str, const char *pat, void *priv)
return 0;
}
return 0;
}
-static int match_entry(
ENTRY *ep, int flag
,
-
int argc, char *
const argv[])
+static int match_entry(
struct env_entry *ep, int flag, int argc
,
+
char *
const argv[])
{
int arg;
void *priv = NULL;
{
int arg;
void *priv = NULL;
@@
-587,9
+605,9
@@
static int match_entry(ENTRY *ep, int flag,
ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag,
char **resp, size_t size,
ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag,
char **resp, size_t size,
- int argc, char *
const argv[])
+ int argc, char *const argv[])
{
{
-
ENTRY
*list[htab->size];
+
struct env_entry
*list[htab->size];
char *res, *p;
size_t totlen;
int i, n;
char *res, *p;
size_t totlen;
int i, n;
@@
-610,7
+628,7
@@
ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag,
for (i = 1, n = 0, totlen = 0; i <= htab->size; ++i) {
if (htab->table[i].used > 0) {
for (i = 1, n = 0, totlen = 0; i <= htab->size; ++i) {
if (htab->table[i].used > 0) {
-
ENTRY
*ep = &htab->table[i].entry;
+
struct env_entry
*ep = &htab->table[i].entry;
int found = match_entry(ep, flag, argc, argv);
if ((argc > 0) && (found == 0))
int found = match_entry(ep, flag, argc, argv);
if ((argc > 0) && (found == 0))
@@
-650,7
+668,7
@@
ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag,
#endif
/* Sort list by keys */
#endif
/* Sort list by keys */
- qsort(list, n, sizeof(
ENTRY
*), cmpkey);
+ qsort(list, n, sizeof(
struct env_entry
*), cmpkey);
/* Check if the user supplied buffer size is sufficient */
if (size) {
/* Check if the user supplied buffer size is sufficient */
if (size) {
@@
-862,7
+880,7
@@
int himport_r(struct hsearch_data *htab,
}
/* Parse environment; allow for '\0' and 'sep' as separators */
do {
}
/* Parse environment; allow for '\0' and 'sep' as separators */
do {
-
ENTRY
e, *rv;
+
struct env_entry
e, *rv;
/* skip leading white space */
while (isblank(*dp))
/* skip leading white space */
while (isblank(*dp))
@@
-922,7
+940,7
@@
int himport_r(struct hsearch_data *htab,
e.key = name;
e.data = value;
e.key = name;
e.data = value;
- hsearch_r(e, ENTER, &rv, htab, flag);
+ hsearch_r(e, EN
V_EN
TER, &rv, htab, flag);
if (rv == NULL)
printf("himport_r: can't insert \"%s=%s\" into hash table\n",
name, value);
if (rv == NULL)
printf("himport_r: can't insert \"%s=%s\" into hash table\n",
name, value);
@@
-969,7
+987,7
@@
end:
* Walk all of the entries in the hash, calling the callback for each one.
* this allows some generic operation to be performed on each element.
*/
* Walk all of the entries in the hash, calling the callback for each one.
* this allows some generic operation to be performed on each element.
*/
-int hwalk_r(struct hsearch_data *htab, int (*callback)(
ENTRY *
))
+int hwalk_r(struct hsearch_data *htab, int (*callback)(
struct env_entry *entry
))
{
int i;
int retval;
{
int i;
int retval;