Browse Source

Add tsearch functions from libc-5.3.12.

Manuel Novoa III 23 years ago
parent
commit
dd3bc2a852
3 changed files with 234 additions and 1 deletions
  1. 1 1
      libc/misc/Makefile
  2. 43 0
      libc/misc/tsearch/Makefile
  3. 190 0
      libc/misc/tsearch/tsearch.c

+ 1 - 1
libc/misc/Makefile

@@ -25,7 +25,7 @@ include $(TOPDIR)Rules.mak
 LIBC=$(TOPDIR)libc.a
 
 
-DIRS = assert crypt ctype fnmatch glob internals lsearch mntent syslog shm time utmp
+DIRS = assert crypt ctype fnmatch glob internals lsearch mntent syslog shm time utmp tsearch
 
 # regex bombs out with an internal compiler error using m68k-pic-coff-gcc.
 ifneq ($(TARGET_ARCH),m68k)

+ 43 - 0
libc/misc/tsearch/Makefile

@@ -0,0 +1,43 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000 by Lineo, inc.
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Library General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Derived in part from the Linux-8086 C library, the GNU C Library, and several
+# other sundry sources.  Files within this library are copyright by their
+# respective copyright holders.
+
+TOPDIR=../../
+include $(TOPDIR)Rules.mak
+LIBC=$(TOPDIR)libc.a
+
+MSRC=tsearch.c
+MOBJ=tsearch.o tfind.o tdelete.o twalk.o
+
+all: $(MOBJ) $(LIBC)
+
+$(LIBC): ar-target
+
+ar-target: $(OBJS)
+	$(AR) $(ARFLAGS) $(LIBC) $(OBJS)
+
+$(MOBJ): $(MSRC)
+	$(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
+	$(STRIPTOOL) -x -R .note -R .comment $*.o
+
+clean:
+	rm -f *.[oa] *~ core
+

+ 190 - 0
libc/misc/tsearch/tsearch.c

@@ -0,0 +1,190 @@
+/* Copyright (C) 1994 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/*
+ * 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.
+ */
+/*LINTLIBRARY*/
+
+#include <search.h>
+#include <stdlib.h>
+
+/* This routine is not very bad. It makes many assumptions about
+ * the compiler. It assumpts that the first field in node must be
+ * the "key" field, which points to the datum. It is a very trick
+ * stuff. H.J.
+ */
+
+typedef struct node_t
+{
+    void	*key;
+    struct node_t *left, *right;
+} node;
+
+#ifdef L_tsearch
+/* find or insert datum into search tree.
+char 	*key;			 key to be located
+register node	**rootp;	 address of tree root
+int	(*compar)();		 ordering function
+*/
+
+void *tsearch(__const void *key, void **vrootp, __compar_fn_t compar)
+{
+    register node *q;
+    register node **rootp = (node **) vrootp;
+
+    if (rootp == (struct node_t **)0)
+	return ((struct node_t *)0);
+    while (*rootp != (struct node_t *)0)	/* Knuth's T1: */
+    {
+	int r;
+
+	if ((r = (*compar)(key, (*rootp)->key)) == 0)	/* T2: */
+	    return (*rootp);		/* we found it! */
+	rootp = (r < 0) ?
+	    &(*rootp)->left :		/* T3: follow left branch */
+	    &(*rootp)->right;		/* T4: follow right branch */
+    }
+    q = (node *) 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 = (void *)key;			/* initialize new node */
+	q->left = q->right = (struct node_t *)0;
+    }
+    return (q);
+}
+#endif
+
+#ifdef L_tfind
+void *tfind(__const void *key, void * __const *vrootp, __compar_fn_t compar)
+{
+    register node **rootp = (node **) vrootp;
+
+    if (rootp == (struct node_t **)0)
+	return ((struct node_t *)0);
+    while (*rootp != (struct node_t *)0)	/* Knuth's T1: */
+    {
+	int r;
+
+	if ((r = (*compar)(key, (*rootp)->key)) == 0)	/* T2: */
+	    return (*rootp);		/* we found it! */
+	rootp = (r < 0) ?
+	    &(*rootp)->left :		/* T3: follow left branch */
+	    &(*rootp)->right;		/* T4: follow right branch */
+    }
+    return NULL;
+}
+#endif
+
+#ifdef L_tdelete
+/* delete node with given key
+char	*key;			key to be deleted
+register node	**rootp;	address of the root of tree
+int	(*compar)();		comparison function
+*/
+void *tdelete(__const void *key, void ** vrootp, __compar_fn_t compar)
+{
+    node *p;
+    register node *q;
+    register node *r;
+    int cmp;
+    register node **rootp = (node **) vrootp;
+
+    if (rootp == (struct node_t **)0 || (p = *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 ((struct node_t *)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);
+}
+#endif
+
+#ifdef L_twalk
+/* Walk the nodes of a tree
+register node	*root;		Root of the tree to be walked
+register void	(*action)();	Function to be called at each node
+register int	level;
+*/
+static void trecurse(__const void *vroot, __action_fn_t action, int level)
+{
+    register node *root = (node *) vroot;
+
+    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);
+    }
+}
+
+/* void twalk(root, action)		Walk the nodes of a tree 
+node	*root;			Root of the tree to be walked
+void	(*action)();		Function to be called at each node
+PTR
+*/
+void twalk(__const void *vroot, __action_fn_t action)
+{
+    register __const node *root = (node *) vroot;
+
+    if (root != (node *)0 && action != (__action_fn_t) 0)
+	trecurse(root, action, 0);
+}
+#endif
+
+/* tsearch.c ends here */