summaryrefslogtreecommitdiff
path: root/source4/lib/adt_tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/adt_tree.c')
-rw-r--r--source4/lib/adt_tree.c464
1 files changed, 0 insertions, 464 deletions
diff --git a/source4/lib/adt_tree.c b/source4/lib/adt_tree.c
deleted file mode 100644
index 0bc224ec23..0000000000
--- a/source4/lib/adt_tree.c
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * Generic Abstract Data Types
- * Copyright (C) Gerald Carter 2002.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-
-/**************************************************************************
- Initialize the tree's root. The cmp_fn is a callback function used
- for comparision of two children
- *************************************************************************/
-
-static BOOL trim_tree_keypath( char *path, char **base, char **new_path )
-{
- char *p;
-
- *new_path = *base = NULL;
-
- if ( !path )
- return False;
-
- *base = path;
-
- p = strchr( path, '/' );
-
- if ( p ) {
- *p = '\0';
- *new_path = p+1;
- }
-
- return True;
-}
-
-
-/**************************************************************************
- Initialize the tree's root. The cmp_fn is a callback function used
- for comparision of two children
- *************************************************************************/
-
-SORTED_TREE* sorted_tree_init( void *data_p,
- int (cmp_fn)(void*, void*),
- void (free_fn)(void*) )
-{
- SORTED_TREE *tree = NULL;
-
- if ( !(tree = (SORTED_TREE*)malloc( sizeof(SORTED_TREE) )) )
- return NULL;
-
- ZERO_STRUCTP( tree );
-
- tree->compare = cmp_fn;
- tree->free = free_fn;
-
- if ( !(tree->root = (TREE_NODE*)malloc( sizeof(TREE_NODE) )) ) {
- SAFE_FREE( tree );
- return NULL;
- }
-
- ZERO_STRUCTP( tree->root );
- tree->root->data_p = data_p;
-
- return tree;
-}
-
-
-/**************************************************************************
- Delete a tree and free all allocated memory
- *************************************************************************/
-
-static void sorted_tree_destroy_children( TREE_NODE *root )
-{
- int i;
-
- if ( !root )
- return;
-
- for ( i=0; i<root->num_children; i++ )
- {
- sorted_tree_destroy_children( root->children[i] );
- }
-
- SAFE_FREE( root->children );
- SAFE_FREE( root->key );
-
- return;
-}
-
-/**************************************************************************
- Delete a tree and free all allocated memory
- *************************************************************************/
-
-void sorted_tree_destroy( SORTED_TREE *tree )
-{
- if ( tree->root )
- sorted_tree_destroy_children( tree->root );
-
- if ( tree->free )
- tree->free( tree->root );
-
- SAFE_FREE( tree );
-}
-
-/**************************************************************************
- Find the next child given a key string
- *************************************************************************/
-
-static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key )
-{
- TREE_NODE *infant = NULL;
- TREE_NODE **siblings;
- int i;
-
- if ( !(infant = (TREE_NODE*)malloc( sizeof(TREE_NODE) )) )
- return NULL;
-
- ZERO_STRUCTP( infant );
-
- infant->key = strdup( key );
- infant->parent = node;
-
- siblings = Realloc( node->children, sizeof(TREE_NODE*)*(node->num_children+1) );
-
- if ( siblings )
- node->children = siblings;
-
- node->num_children++;
-
- /* first child */
-
- if ( node->num_children == 1 ) {
- DEBUG(11,("sorted_tree_birth_child: First child of node [%s]! [%s]\n",
- node->key ? node->key : "NULL", infant->key ));
- node->children[0] = infant;
- }
- else
- {
- /*
- * multiple siblings .... (at least 2 children)
- *
- * work from the end of the list forward
- * The last child is not set at this point
- * Insert the new infanct in ascending order
- * from left to right
- */
-
- for ( i = node->num_children-1; i>=1; i-- )
- {
- DEBUG(11,("sorted_tree_birth_child: Looking for crib; infant -> [%s], child -> [%s]\n",
- infant->key, node->children[i-1]->key));
-
- /* the strings should never match assuming that we
- have called sorted_tree_find_child() first */
-
- if ( StrCaseCmp( infant->key, node->children[i-1]->key ) > 0 ) {
- DEBUG(11,("sorted_tree_birth_child: storing infant in i == [%d]\n",
- i));
- node->children[i] = infant;
- break;
- }
-
- /* bump everything towards the end on slot */
-
- node->children[i] = node->children[i-1];
- }
-
- DEBUG(11,("sorted_tree_birth_child: Exiting loop (i == [%d])\n", i ));
-
- /* if we haven't found the correct slot yet, the child
- will be first in the list */
-
- if ( i == 0 )
- node->children[0] = infant;
- }
-
- return infant;
-}
-
-/**************************************************************************
- Find the next child given a key string
- *************************************************************************/
-
-static TREE_NODE* sorted_tree_find_child( TREE_NODE *node, char* key )
-{
- TREE_NODE *next = NULL;
- int i, result;
-
- if ( !node ) {
- DEBUG(0,("sorted_tree_find_child: NULL node passed into function!\n"));
- return NULL;
- }
-
- if ( !key ) {
- DEBUG(0,("sorted_tree_find_child: NULL key string passed into function!\n"));
- return NULL;
- }
-
- for ( i=0; i<node->num_children; i++ )
- {
- DEBUG(11,("sorted_tree_find_child: child key => [%s]\n",
- node->children[i]->key));
-
- result = StrCaseCmp( node->children[i]->key, key );
-
- if ( result == 0 )
- next = node->children[i];
-
- /* if result > 0 then we've gone to far because
- the list of children is sorted by key name
- If result == 0, then we have a match */
-
- if ( result > 0 )
- break;
- }
-
- DEBUG(11,("sorted_tree_find_child: %s [%s]\n",
- next ? "Found" : "Did not find", key ));
-
- return next;
-}
-
-/**************************************************************************
- Add a new node into the tree given a key path and a blob of data
- *************************************************************************/
-
-BOOL sorted_tree_add( SORTED_TREE *tree, const char *path, void *data_p )
-{
- char *str, *base, *path2;
- TREE_NODE *current, *next;
- BOOL ret = True;
-
- DEBUG(8,("sorted_tree_add: Enter\n"));
-
- if ( !path || *path != '/' ) {
- DEBUG(0,("sorted_tree_add: Attempt to add a node with a bad path [%s]\n",
- path ? path : "NULL" ));
- return False;
- }
-
- if ( !tree ) {
- DEBUG(0,("sorted_tree_add: Attempt to add a node to an uninitialized tree!\n"));
- return False;
- }
-
- /* move past the first '/' */
-
- path++;
- path2 = strdup( path );
- if ( !path2 ) {
- DEBUG(0,("sorted_tree_add: strdup() failed on string [%s]!?!?!\n", path));
- return False;
- }
-
-
- /*
- * this works sort of like a 'mkdir -p' call, possibly
- * creating an entire path to the new node at once
- * The path should be of the form /<key1>/<key2>/...
- */
-
- base = path2;
- str = path2;
- current = tree->root;
-
- do {
- /* break off the remaining part of the path */
-
- str = strchr( str, '/' );
- if ( str )
- *str = '\0';
-
- /* iterate to the next child--birth it if necessary */
-
- next = sorted_tree_find_child( current, base );
- if ( !next ) {
- next = sorted_tree_birth_child( current, base );
- if ( !next ) {
- DEBUG(0,("sorted_tree_add: Failed to create new child!\n"));
- ret = False;
- goto done;
- }
- }
- current = next;
-
- /* setup the next part of the path */
-
- base = str;
- if ( base ) {
- *base = '/';
- base++;
- str = base;
- }
-
- } while ( base != NULL );
-
- current->data_p = data_p;
-
- DEBUG(10,("sorted_tree_add: Successfully added node [%s] to tree\n",
- path ));
-
- DEBUG(8,("sorted_tree_add: Exit\n"));
-
-done:
- SAFE_FREE( path2 );
- return ret;
-}
-
-
-/**************************************************************************
- Recursive routine to print out all children of a TREE_NODE
- *************************************************************************/
-
-static void sorted_tree_print_children( TREE_NODE *node, int debug, const char *path )
-{
- int i;
- int num_children;
- pstring path2;
-
- if ( !node )
- return;
-
-
- if ( node->key )
- DEBUG(debug,("%s: [%s] (%s)\n", path ? path : "NULL", node->key,
- node->data_p ? "data" : "NULL" ));
-
- *path2 = '\0';
- if ( path )
- pstrcpy( path2, path );
- pstrcat( path2, node->key ? node->key : "NULL" );
- pstrcat( path2, "/" );
-
- num_children = node->num_children;
- for ( i=0; i<num_children; i++ )
- sorted_tree_print_children( node->children[i], debug, path2 );
-
-
-}
-
-/**************************************************************************
- Dump the kys for a tree to the log file
- *************************************************************************/
-
-void sorted_tree_print_keys( SORTED_TREE *tree, int debug )
-{
- int i;
- int num_children = tree->root->num_children;
-
- if ( tree->root->key )
- DEBUG(debug,("ROOT/: [%s] (%s)\n", tree->root->key,
- tree->root->data_p ? "data" : "NULL" ));
-
- for ( i=0; i<num_children; i++ ) {
- sorted_tree_print_children( tree->root->children[i], debug,
- tree->root->key ? tree->root->key : "ROOT/" );
- }
-
-}
-
-/**************************************************************************
- return the data_p for for the node in tree matching the key string
- The key string is the full path. We must break it apart and walk
- the tree
- *************************************************************************/
-
-void* sorted_tree_find( SORTED_TREE *tree, char *key )
-{
- char *keystr, *base, *str, *p;
- TREE_NODE *current;
- void *result = NULL;
-
- DEBUG(10,("sorted_tree_find: Enter [%s]\n", key ? key : "NULL" ));
-
- /* sanity checks first */
-
- if ( !key ) {
- DEBUG(0,("sorted_tree_find: Attempt to search tree using NULL search string!\n"));
- return NULL;
- }
-
- if ( !tree ) {
- DEBUG(0,("sorted_tree_find: Attempt to search an uninitialized tree using string [%s]!\n",
- key ? key : "NULL" ));
- return NULL;
- }
-
- if ( !tree->root )
- return NULL;
-
- /* make a copy to play with */
-
- if ( *key == '/' )
- keystr = strdup( key+1 );
- else
- keystr = strdup( key );
-
- if ( !keystr ) {
- DEBUG(0,("sorted_tree_find: strdup() failed on string [%s]!?!?!\n", key));
- return NULL;
- }
-
- /* start breaking the path apart */
-
- p = keystr;
- current = tree->root;
-
- if ( tree->root->data_p )
- result = tree->root->data_p;
-
- do
- {
- /* break off the remaining part of the path */
-
- trim_tree_keypath( p, &base, &str );
-
- DEBUG(11,("sorted_tree_find: [loop] base => [%s], new_path => [%s]\n",
- base, str));
-
- /* iterate to the next child */
-
- current = sorted_tree_find_child( current, base );
-
- /*
- * the idea is that the data_p for a parent should
- * be inherited by all children, but allow it to be
- * overridden farther down
- */
-
- if ( current && current->data_p )
- result = current->data_p;
-
- /* reset the path pointer 'p' to the remaining part of the key string */
-
- p = str;
-
- } while ( str && current );
-
- /* result should be the data_p from the lowest match node in the tree */
- if ( result )
- DEBUG(11,("sorted_tree_find: Found data_p!\n"));
-
- SAFE_FREE( keystr );
-
- DEBUG(10,("sorted_tree_find: Exit\n"));
-
- return result;
-}
-
-