RIP BOOL. Convert BOOL -> bool. I found a few interesting
[kai/samba.git] / source / lib / adt_tree.c
index bd857e205ac150dfcc944e569b7991b3cd676ade..ef72ba3e70c517c07141d6915632fc3b13b3c870 100644 (file)
@@ -5,7 +5,7 @@
  *
  *  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
+ *  the Free Software Foundation; either version 3 of the License, or
  *  (at your option) any later version.
  *  
  *  This program is distributed in the hope that it will be useful,
  *  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.
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "includes.h"
+#include "adt_tree.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 )
+static bool trim_tree_keypath( char *path, char **base, char **new_path )
 {
        char *p;
        
@@ -53,88 +51,43 @@ static BOOL trim_tree_keypath( char *path, char **base, char **new_path )
  for comparision of two children
  *************************************************************************/
 
-SORTED_TREE* sorted_tree_init( void *data_p,
-                               int (cmp_fn)(void*, void*),
-                               void (free_fn)(void*) )
+ SORTED_TREE* pathtree_init( void *data_p, int (cmp_fn)(void*, void*) )
 {
        SORTED_TREE *tree = NULL;
        
-       if ( !(tree = (SORTED_TREE*)malloc( sizeof(SORTED_TREE) )) )
+       if ( !(tree = TALLOC_ZERO_P(NULL, SORTED_TREE)) )
                return NULL;
                
-       ZERO_STRUCTP( tree );
-       
        tree->compare = cmp_fn;
-       tree->free_func    = free_fn;
        
-       if ( !(tree->root = (TREE_NODE*)malloc( sizeof(TREE_NODE) )) ) {
-               SAFE_FREE( tree );
+       if ( !(tree->root = TALLOC_ZERO_P(tree, TREE_NODE)) ) {
+               TALLOC_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_func )
-               tree->free_func( 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 )
+static TREE_NODE* pathtree_birth_child( TREE_NODE *node, char* key )
 {
        TREE_NODE *infant = NULL;
        TREE_NODE **siblings;
        int i;
        
-       if ( !(infant = (TREE_NODE*)malloc( sizeof(TREE_NODE) )) )
+       if ( !(infant = TALLOC_ZERO_P( node, TREE_NODE)) )
                return NULL;
        
-       ZERO_STRUCTP( infant );
-               
-       infant->key = strdup( key );
+       infant->key = talloc_strdup( infant, key );
        infant->parent = node;
        
-       siblings = Realloc( node->children, sizeof(TREE_NODE*)*(node->num_children+1) );
+       siblings = TALLOC_REALLOC_ARRAY( node, node->children, TREE_NODE *, node->num_children+1 );
        
        if ( siblings )
                node->children = siblings;
@@ -144,7 +97,7 @@ static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key )
        /* first child */
        
        if ( node->num_children == 1 ) {
-               DEBUG(11,("sorted_tree_birth_child: First child of node [%s]! [%s]\n", 
+               DEBUG(11,("pathtree_birth_child: First child of node [%s]! [%s]\n", 
                        node->key ? node->key : "NULL", infant->key ));
                node->children[0] = infant;
        }
@@ -161,14 +114,14 @@ static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key )
        
                for ( i = node->num_children-1; i>=1; i-- )
                {
-                       DEBUG(11,("sorted_tree_birth_child: Looking for crib; infant -> [%s], child -> [%s]\n",
+                       DEBUG(11,("pathtree_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 */
+                          have called pathtree_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", 
+                               DEBUG(11,("pathtree_birth_child: storing infant in i == [%d]\n", 
                                        i));
                                node->children[i] = infant;
                                break;
@@ -179,7 +132,7 @@ static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key )
                        node->children[i] = node->children[i-1];
                }
 
-               DEBUG(11,("sorted_tree_birth_child: Exiting loop (i == [%d])\n", i ));
+               DEBUG(11,("pathtree_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 */
@@ -195,24 +148,24 @@ static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key )
  Find the next child given a key string
  *************************************************************************/
 
-static TREE_NODE* sorted_tree_find_child( TREE_NODE *node, char* key )
+static TREE_NODE* pathtree_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"));
+               DEBUG(0,("pathtree_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"));
+               DEBUG(0,("pathtree_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",
+               DEBUG(11,("pathtree_find_child: child key => [%s]\n",
                        node->children[i]->key));
                        
                result = StrCaseCmp( node->children[i]->key, key );
@@ -228,7 +181,7 @@ static TREE_NODE* sorted_tree_find_child( TREE_NODE *node, char* key )
                        break;
        }
 
-       DEBUG(11,("sorted_tree_find_child: %s [%s]\n",
+       DEBUG(11,("pathtree_find_child: %s [%s]\n",
                next ? "Found" : "Did not find", key ));        
        
        return next;
@@ -238,31 +191,31 @@ static TREE_NODE* sorted_tree_find_child( TREE_NODE *node, char* key )
  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 )
+ bool pathtree_add( SORTED_TREE *tree, const char *path, void *data_p )
 {
        char *str, *base, *path2;
        TREE_NODE *current, *next;
-       BOOL ret = True;
+       bool ret = True;
        
-       DEBUG(8,("sorted_tree_add: Enter\n"));
+       DEBUG(8,("pathtree_add: Enter\n"));
                
        if ( !path || *path != '/' ) {
-               DEBUG(0,("sorted_tree_add: Attempt to add a node with a bad path [%s]\n",
+               DEBUG(0,("pathtree_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"));
+               DEBUG(0,("pathtree_add: Attempt to add a node to an uninitialized tree!\n"));
                return False;
        }
        
        /* move past the first '/' */
        
        path++; 
-       path2 = strdup( path );
+       path2 = SMB_STRDUP( path );
        if ( !path2 ) {
-               DEBUG(0,("sorted_tree_add: strdup() failed on string [%s]!?!?!\n", path));
+               DEBUG(0,("pathtree_add: strdup() failed on string [%s]!?!?!\n", path));
                return False;
        }
        
@@ -286,11 +239,11 @@ BOOL sorted_tree_add( SORTED_TREE *tree, const char *path, void *data_p )
                        
                /* iterate to the next child--birth it if necessary */
                
-               next = sorted_tree_find_child( current, base );
+               next = pathtree_find_child( current, base );
                if ( !next ) {
-                       next = sorted_tree_birth_child( current, base );
+                       next = pathtree_birth_child( current, base );
                        if ( !next ) {
-                               DEBUG(0,("sorted_tree_add: Failed to create new child!\n"));
+                               DEBUG(0,("pathtree_add: Failed to create new child!\n"));
                                ret =  False;
                                goto done;
                        }
@@ -310,10 +263,10 @@ BOOL sorted_tree_add( SORTED_TREE *tree, const char *path, void *data_p )
        
        current->data_p = data_p;
        
-       DEBUG(10,("sorted_tree_add: Successfully added node [%s] to tree\n",
+       DEBUG(10,("pathtree_add: Successfully added node [%s] to tree\n",
                path ));
 
-       DEBUG(8,("sorted_tree_add: Exit\n"));
+       DEBUG(8,("pathtree_add: Exit\n"));
 
 done:
        SAFE_FREE( path2 );
@@ -325,76 +278,88 @@ done:
  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 )
+static void pathtree_print_children(TALLOC_CTX *ctx,
+                               TREE_NODE *node,
+                               int debug,
+                               const char *path )
 {
        int i;
        int num_children;
-       pstring path2;
-       
+       char *path2 = NULL;
+
        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 );
-       
+       if ( path ) {
+               path2 = talloc_strdup(ctx, path);
+               if (!path2) {
+                       return;
+               }
+       }
 
+       path2 = talloc_asprintf(ctx,
+                       "%s%s/",
+                       path ? path : "",
+                       node->key ? node->key : "NULL");
+       if (!path2) {
+               return;
+       }
+
+       num_children = node->num_children;
+       for ( i=0; i<num_children; i++ ) {
+               pathtree_print_children(ctx, 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 )
+ void pathtree_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, 
+               TALLOC_CTX *ctx = talloc_stackframe();
+               pathtree_print_children(ctx, tree->root->children[i], debug,
                        tree->root->key ? tree->root->key : "ROOT/" );
+               TALLOC_FREE(ctx);
        }
-       
+
 }
 
 /**************************************************************************
  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 key string is the full path.  We must break it apart and walk
  the tree
  *************************************************************************/
 
-void* sorted_tree_find( SORTED_TREE *tree, char *key )
+ void* pathtree_find( SORTED_TREE *tree, char *key )
 {
-       char *keystr, *base, *str, *p;
+       char *keystr, *base = NULL, *str = NULL, *p;
        TREE_NODE *current;
        void *result = NULL;
        
-       DEBUG(10,("sorted_tree_find: Enter [%s]\n", key ? key : "NULL" ));
+       DEBUG(10,("pathtree_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"));
+               DEBUG(0,("pathtree_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",
+               DEBUG(0,("pathtree_find: Attempt to search an uninitialized tree using string [%s]!\n",
                        key ? key : "NULL" ));
                return NULL;
        }
@@ -405,12 +370,12 @@ void* sorted_tree_find( SORTED_TREE *tree, char *key )
        /* make a copy to play with */
        
        if ( *key == '/' )
-               keystr = strdup( key+1 );
+               keystr = SMB_STRDUP( key+1 );
        else
-               keystr = strdup( key );
+               keystr = SMB_STRDUP( key );
        
        if ( !keystr ) {
-               DEBUG(0,("sorted_tree_find: strdup() failed on string [%s]!?!?!\n", key));
+               DEBUG(0,("pathtree_find: strdup() failed on string [%s]!?!?!\n", key));
                return NULL;
        }
 
@@ -428,12 +393,13 @@ void* sorted_tree_find( SORTED_TREE *tree, char *key )
 
                trim_tree_keypath( p, &base, &str );
                        
-               DEBUG(11,("sorted_tree_find: [loop] base => [%s], new_path => [%s]\n", 
-                       base, str));
+               DEBUG(11,("pathtree_find: [loop] base => [%s], new_path => [%s]\n", 
+                       base ? base : "",
+                       str ? str : ""));
 
                /* iterate to the next child */
                
-               current = sorted_tree_find_child( current, base );
+               current = pathtree_find_child( current, base );
        
                /* 
                 * the idea is that the data_p for a parent should 
@@ -452,11 +418,11 @@ void* sorted_tree_find( SORTED_TREE *tree, char *key )
        
        /* 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"));
+               DEBUG(11,("pathtree_find: Found data_p!\n"));
        
        SAFE_FREE( keystr );
        
-       DEBUG(10,("sorted_tree_find: Exit\n"));
+       DEBUG(10,("pathtree_find: Exit\n"));
        
        return result;
 }