1
0
mirror of git://projects.qi-hardware.com/wernermisc.git synced 2024-11-22 12:56:15 +02:00
wernermisc/qpkg/id.c

130 lines
2.0 KiB
C

#include <string.h>
#include "util.h"
#include "id.h"
#define NODE2ID(n) ((struct id *) n)
static struct id *free_id = NULL;
int comp_id(const struct id *a, const struct id *b)
{
int len = a->len < b->len ? a->len : b->len;
int cmp;
cmp = memcmp(a->s, b->s, len);
if (cmp)
return cmp;
return a->len < b->len ? -1 : a->len > b->len;
}
struct tree *make_tree(int (*comp)(const struct id *a, const struct id *b))
{
struct tree *tree;
tree = alloc_type(struct tree);
tree->comp = comp;
tree->root = NULL;
return tree;
}
static struct node *add_node(struct tree *tree, struct node *node)
{
struct node **p, *last;
int cmp;
p = &tree->root;
last = NULL;
while (*p) {
last = *p;
cmp = tree->comp(NODE2ID(node), NODE2ID(*p));
if (cmp < 0)
p = &(*p)->left;
else if (cmp > 0)
p = &(*p)->right;
else
return *p;
}
*p = node;
node->up = last;
node->left = node->right = NULL;
return NULL;
}
struct id *make_id(struct tree *tree, const char *s, size_t len)
{
struct id *id;
struct node *node;
if (!free_id)
free_id = alloc_type(struct id);
id = free_id;
id->s = s;
id->len = len;
id->value = NULL;
node = add_node(tree, &id->node);
if (node)
return NODE2ID(node);
free_id = NULL;
return id;
}
const struct id *find_id(const struct tree *tree, const char *s, size_t len)
{
struct id id = {
.s = s,
.len = len
};
const struct node *n = tree->root;
int cmp;
while (n) {
cmp = tree->comp(&id, NODE2ID(n));
if (cmp < 0)
n = n->left;
else if (cmp > 0)
n = n->right;
else
return NODE2ID(n);
}
return NULL;
}
const struct id *first_id(const struct tree *tree)
{
const struct node *n = tree->root;
if (!n)
return NULL;
while (n->left)
n = n->left;
return NODE2ID(n);
}
const struct id *next_id(const struct id *id)
{
const struct node *n = &id->node;
if (n->right) {
n = n->right;
while (n->left)
n = n->left;
return NODE2ID(n);
}
while (n->up) {
if (n == n->up->left)
return NODE2ID(n->up);
n = n->up;
}
return NULL;
}