Skip to content
Snippets Groups Projects
Commit 9a7752b9 authored by Nicolas Léveillé's avatar Nicolas Léveillé
Browse files

Finish porting hammer's library to windows

We port registry by importing the (public domain) openbsd implementation
of the tfind/tsearch POSIX binary tree search functions.

These are only necessary when building on non-posix platforms
parent 206f5044
No related branches found
No related tags found
No related merge requests found
......@@ -15,10 +15,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <search.h>
#include <stdlib.h>
#include "hammer.h"
#include "internal.h"
#include "tsearch.h"
#if defined(_MSC_VER)
#define h_strdup _strdup
#else
#define h_strdup strdup
#endif
typedef struct Entry_ {
const char* name;
......@@ -58,7 +64,7 @@ HTokenType h_allocate_token_type(const char* name) {
return probe->value;
} else {
// new value
probe->name = strdup(probe->name); // drop ownership of name
probe->name = h_strdup(probe->name); // drop ownership of name
probe->value = tt_next++;
if ((probe->value - TT_START) >= tt_by_id_sz) {
if (tt_by_id_sz == 0) {
......
#if defined(_MSC_VER)
/* find or insert datum into search tree */
void *tsearch(const void *vkey, void **vrootp,
int (*compar)(const void *, const void *));
/* delete node with given key */
void * tdelete(const void *vkey, void **vrootp,
int (*compar)(const void *, const void *));
/* Walk the nodes of a tree */
void twalk(const void *vroot, void (*action)(const void *, VISIT, int));
#else
#include <search.h>
#endif
/* $OpenBSD: tsearch.c,v 1.9 2015/08/20 21:49:29 deraadt Exp $ */
/*
* Tree search generalized from Knuth (6.2.2) Algorithm T just like
* the AT&T man page says.
*
* The node_t structure is for internal use only
*
* Written by reading the System V Interface Definition, not the code.
*
* Totally public domain.
*/
#include <stdlib.h>
#include "tsearch.h"
typedef struct node_t {
char *key;
struct node_t *left, *right;
} node;
/* find or insert datum into search tree */
void *
tsearch(const void *vkey, void **vrootp,
int (*compar)(const void *, const void *))
{
node *q;
char *key = (char *)vkey;
node **rootp = (node **)vrootp;
if (rootp == (struct node_t **)0)
return ((void *)0);
while (*rootp != (struct node_t *)0) { /* Knuth's T1: */
int r;
if ((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */
return ((void *)*rootp); /* we found it! */
rootp = (r < 0) ?
&(*rootp)->left : /* T3: follow left branch */
&(*rootp)->right; /* T4: follow right branch */
}
q = malloc(sizeof(node)); /* T5: key not found */
if (q != (struct node_t *)0) { /* make new node */
*rootp = q; /* link new node to old */
q->key = key; /* initialize new node */
q->left = q->right = (struct node_t *)0;
}
return ((void *)q);
}
/* delete node with given key */
void *
tdelete(const void *vkey, void **vrootp,
int (*compar)(const void *, const void *))
{
node **rootp = (node **)vrootp;
char *key = (char *)vkey;
node *p = (node *)1;
node *q;
node *r;
int cmp;
if (rootp == (struct node_t **)0 || *rootp == (struct node_t *)0)
return ((struct node_t *)0);
while ((cmp = (*compar)(key, (*rootp)->key)) != 0) {
p = *rootp;
rootp = (cmp < 0) ?
&(*rootp)->left : /* follow left branch */
&(*rootp)->right; /* follow right branch */
if (*rootp == (struct node_t *)0)
return ((void *)0); /* key not found */
}
r = (*rootp)->right; /* D1: */
if ((q = (*rootp)->left) == (struct node_t *)0) /* Left (struct node_t *)0? */
q = r;
else if (r != (struct node_t *)0) { /* Right link is null? */
if (r->left == (struct node_t *)0) { /* D2: Find successor */
r->left = q;
q = r;
} else { /* D3: Find (struct node_t *)0 link */
for (q = r->left; q->left != (struct node_t *)0; q = r->left)
r = q;
r->left = q->right;
q->left = (*rootp)->left;
q->right = (*rootp)->right;
}
}
free((struct node_t *) *rootp); /* D4: Free node */
*rootp = q; /* link parent to new node */
return(p);
}
/* Walk the nodes of a tree */
static void
trecurse(node *root, void (*action)(const void *, VISIT, int), int level)
{
if (root->left == (struct node_t *)0 && root->right == (struct node_t *)0)
(*action)(root, leaf, level);
else {
(*action)(root, preorder, level);
if (root->left != (struct node_t *)0)
trecurse(root->left, action, level + 1);
(*action)(root, postorder, level);
if (root->right != (struct node_t *)0)
trecurse(root->right, action, level + 1);
(*action)(root, endorder, level);
}
}
/* Walk the nodes of a tree */
void
twalk(const void *vroot, void (*action)(const void *, VISIT, int))
{
node *root = (node *)vroot;
if (root != (node *)0 && action != (void (*)(const void *, VISIT, int))0)
trecurse(root, action, 0);
}
/* $OpenBSD: tfind.c,v 1.6 2014/03/16 18:38:30 guenther Exp $ */
/* find a node, or return 0 */
void *
tfind(const void *vkey, void * const *vrootp,
int (*compar)(const void *, const void *))
{
char *key = (char *)vkey;
node **rootp = (node **)vrootp;
if (rootp == (struct node_t **)0)
return ((struct node_t *)0);
while (*rootp != (struct node_t *)0) { /* T1: */
int r;
if ((r = (*compar)(key, (*rootp)->key)) == 0) /* T2: */
return (*rootp); /* key found */
rootp = (r < 0) ?
&(*rootp)->left : /* T3: follow left branch */
&(*rootp)->right; /* T4: follow right branch */
}
return (node *)0;
}
#ifndef HAMMER_TSEARCH__H
#define HAMMER_TSEARCH__H
#if defined(_MSC_VER)
typedef enum { preorder, postorder, endorder, leaf } VISIT;
/* find or insert datum into search tree */
void *tsearch(const void *vkey, void **vrootp,
int (*compar)(const void *, const void *));
/* delete node with given key */
void * tdelete(const void *vkey, void **vrootp,
int (*compar)(const void *, const void *));
/* Walk the nodes of a tree */
void twalk(const void *vroot, void (*action)(const void *, VISIT, int));
/* find a node, or return 0 */
void *tfind(const void *vkey, void * const *vrootp,
int (*compar)(const void *, const void *));
#else
#include <search.h>
#endif
#endif /* HAMMER_TSEARCH__H */
......@@ -9,7 +9,9 @@ desugar.c
glue.c
hammer.c
pprint.c
registry.c
system_allocator.c
tsearch.c
parsers/action.c
parsers/and.c
parsers/attr_bool.c
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment