forked from abiggerhammer/hammer
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
245 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
/* $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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#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 */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters