diff options
author | Ben Cheng <bccheng@google.com> | 2012-03-13 23:04:57 -0700 |
---|---|---|
committer | Ben Cheng <bccheng@google.com> | 2012-03-20 12:54:55 -0700 |
commit | 21eab513e7eec280a7a8bcb9482a1a8b61e59442 (patch) | |
tree | 28ba8f7977161897ebddf533fb8e09755a6f35d7 /libc/bionic/tdelete.c | |
parent | adb6989786dcc7248d51a3a5a76221b93951f84a (diff) | |
download | android_bionic-21eab513e7eec280a7a8bcb9482a1a8b61e59442.tar.gz android_bionic-21eab513e7eec280a7a8bcb9482a1a8b61e59442.tar.bz2 android_bionic-21eab513e7eec280a7a8bcb9482a1a8b61e59442.zip |
New additions/bug fixes required/found when porting perf.
New functions:
tfind
tsearch
tdelete
twalk
tdestroy (GNU extension)
Bug fix: the current implementation for realpath would crash
if the second argument (resolved_path) is NULL.
New headers:
ar.h
search.h
Change-Id: Ib6c1e42fc186a6d597a6e5a9692b16acaa155804
Diffstat (limited to 'libc/bionic/tdelete.c')
-rw-r--r-- | libc/bionic/tdelete.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/libc/bionic/tdelete.c b/libc/bionic/tdelete.c new file mode 100644 index 000000000..b64b47a2a --- /dev/null +++ b/libc/bionic/tdelete.c @@ -0,0 +1,71 @@ +/* $NetBSD: tdelete.c,v 1.2 1999/09/16 11:45:37 lukem 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, lint doesn't grok it. + * + * Written by reading the System V Interface Definition, not the code. + * + * Totally public domain. + */ + +#include <sys/cdefs.h> +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: tdelete.c,v 1.2 1999/09/16 11:45:37 lukem Exp $"); +#endif /* LIBC_SCCS and not lint */ +#endif +__FBSDID("$FreeBSD: release/9.0.0/lib/libc/stdlib/tdelete.c 108694 2003-01-05 02:43:18Z tjr $"); + +#define _SEARCH_PRIVATE +#include <search.h> +#include <stdlib.h> + + +/* + * delete node with given key + * + * vkey: key to be deleted + * vrootp: address of the root of the tree + * compar: function to carry out node comparisons + */ +void * +tdelete(const void * __restrict vkey, void ** __restrict vrootp, + int (*compar)(const void *, const void *)) +{ + node_t **rootp = (node_t **)vrootp; + node_t *p, *q, *r; + int cmp; + + if (rootp == NULL || (p = *rootp) == NULL) + return NULL; + + while ((cmp = (*compar)(vkey, (*rootp)->key)) != 0) { + p = *rootp; + rootp = (cmp < 0) ? + &(*rootp)->llink : /* follow llink branch */ + &(*rootp)->rlink; /* follow rlink branch */ + if (*rootp == NULL) + return NULL; /* key not found */ + } + r = (*rootp)->rlink; /* D1: */ + if ((q = (*rootp)->llink) == NULL) /* Left NULL? */ + q = r; + else if (r != NULL) { /* Right link is NULL? */ + if (r->llink == NULL) { /* D2: Find successor */ + r->llink = q; + q = r; + } else { /* D3: Find NULL link */ + for (q = r->llink; q->llink != NULL; q = r->llink) + r = q; + r->llink = q->rlink; + q->llink = (*rootp)->llink; + q->rlink = (*rootp)->rlink; + } + } + free(*rootp); /* D4: Free node */ + *rootp = q; /* link parent to new node */ + return p; +} |