libnode/lib/libnode.c
2003-01-17 08:06:57 +00:00

4876 lines
165 KiB
C
Raw Blame History

/*---------------------------------------------------------------------------------*/
/* $RCSfile: libnode.c,v $ */
/*---------------------------------------------------------------------------------*/
/* $Revision: 2.8 $ */
/* $Name: $ */
/* $Date: 2003/01/17 08:06:57 $ */
/* $Author: agibert $ */
/*---------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------*/
/* This file is part of LibNode */
/* */
/* LibNode is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU Lesser General Public Licence as published by */
/* the Free Software Foundation; either version 2.1 of the License, or */
/* (at your option) any later version. */
/* */
/* LibNode 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 Lesser General Public License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with Foobar; if not, write to the Free Software */
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*---------------------------------------------------------------------------------*/
#define _LIBNODE_C_
#include <libnode.h>
#ifdef _LIBVER_SUPPORT
VER_INFO_EXPORT (libnode,"$Revision: 2.8 $", "$Name: $",__FILE__,"$Author: agibert $")
#endif
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* Node Manager Template */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
NDT_Status ND_Default_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list Args)
{
NDT_Command_Name Command_Name;
switch( Command)
{
case NDD_CMD_MANAGER_VERSION:
{
NDT_Version_Name *Version_Name_Ptr = (NDT_Version_Name *)va_arg( Args, NDT_Version_Name *);
Command_Name = "NDD_CMD_MANAGER_VERSION";
*Version_Name_Ptr = "$Revision: 2.8 $ $Name: $ $Date: 2003/01/17 08:06:57 $ $Author: agibert $";
return( NDS_OK);
}
case NDD_CMD_INDEX_GET:
{
/*
NDT_Index_Id *Reply_Index_Id_Ptr = (NDT_Index_Id *)va_arg( Args, NDT_Index_Id *);
NDT_Command *Reply_Command_Ptr = (NDT_Command *)va_arg( Args, NDT_Command *);
NDT_Command Cmd = (NDT_Command)va_arg( Args, NDT_Command);
void *Value_ptr = (void *)va_arg( Args, void *);
*/
NDT_Index_Id *Reply_Index_Id_Ptr = (NDT_Index_Id *)va_arg( Args, NDT_Index_Id *);
NDT_Command *Reply_Command_Ptr = (NDT_Command *)va_arg( Args, NDT_Command *);
NDT_Command Cmd = (NDT_Command)va_arg( Args, NDT_Command);
void *Value_ptr = (void *)va_arg( Args, void *);
Command_Name = "NDD_CMD_INDEX_GET";
switch(Cmd)
{
/*
case NDT_CMD_SOME_USER_CMD:
{
*Reply_Index_Id_Ptr = 0;
*Reply_Command_Ptr = NDD_CMD_SOME_OTHER_CMD;
break;
}
...
*/
default:
{
*Reply_Index_Id_Ptr = Index_Id;
*Reply_Command_Ptr = Cmd;
break;
}
}
return( NDS_OK);
}
case NDD_CMD_VALUE_ALLOC:
{
/*
void **Value_Ptr_Ptr = (void **)va_arg( Args, void **);
va_list user_args = (va_list)va_arg( Args, va_list);
user_type user_data = (user_type)va_arg( user_args, user_type);
... = (...)va_arg( user_args, ...);
*/
Command_Name = "NDD_CMD_VALUE_ALLOC";
/*
if( ( *Value_Ptr_Ptr = (void *)malloc( sizeof(void))) == NULL)
{
return(NDS_ERRMEM);
}
else
{
...
return( NDS_OK);
}
*/
}
case NDD_CMD_VALUE_FREE:
{
/*
void *Value_Ptr = (void *)va_arg( Args, void *);
va_list user_args = (va_list)va_arg( Args, va_list);
user_type user_data = (user_type)va_arg( user_args, user_type);
... = (...)va_arg( user_args, ...);
*/
Command_Name = "NDD_CMD_VALUE_FREE";
/*
free( Value_Ptr);
return( NDS_OK);
*/
}
case NDD_CMD_VALUE_COMP:
{
/*
void *Value1_Ptr = (void *)va_arg( Args, void *);
void *Value2_Ptr = (void *)va_arg( Args, void *);
va_list user_args = (va_list)va_arg( Args, va_list);
user_type user_data = (user_type)va_arg( user_args, user_type);
... = (...)va_arg( user_args, ...);
*/
Command_Name = "NDD_CMD_VALUE_COMP";
/*
switch( Index_Id)
{
case 0:
{
int rc;
rc = strcmp( Value1_Ptr->..., Value2_Ptr->...);
if( rc < 0)
{
return(NDS_LOWER);
}
else
{
if( rc > 0)
{
return(NDS_GREATER);
}
else
{
return(NDS_EQUAL);
}
}
}
case 1:
{
int val1 = atoi(Value1_Ptr->...);
int val2 = atoi(Value2_Ptr->...);
if( val1 < val2)
{
return(NDS_LOWER);
}
else
{
if( val1 > val2)
{
return(NDS_GREATER);
}
else
{
return(NDS_EQUAL);
}
}
}
case 2:
{
...
}
default:
{
printf( "Unknown COMP idx (%d) !\n", Index_Id);
return( NDS_KO);
}
}
return( NDS_OK);
*/
}
case NDD_CMD_VALUE_ADD:
{
/*
void *Value_Ptr = (void *)va_arg( Args, void *);
va_list user_args = (va_list)va_arg( Args, va_list);
user_type user_data = (user_type)va_arg( user_args, user_type);
... = (...)va_arg( user_args, ...);
*/
Command_Name = "NDD_CMD_VALUE_ADD";
/*
return( NDS_OK);
*/
}
case NDD_CMD_VALUE_REMOVE:
{
/*
void *Value_Ptr = (void *)va_arg( Args, void *);
va_list user_args = (va_list)va_arg( Args, va_list);
user_type user_data = (user_type)va_arg( user_args, user_type);
... = (...)va_arg( user_args, ...);
*/
Command_Name = "NDD_CMD_VALUE_REMOVE";
/*
return( NDS_OK);
*/
}
case NDD_CMD_VALUE_PRINT:
{
/*
NDT_Node *Next_Node_Ptr = (NDT_Node *)va_arg( Args, NDT_Node *);
va_list lib_args = (va_list)va_arg( Args, va_list);
FILE *Out = (FILE *)va_arg( lib_args, FILE *);
NDT_Recursive_Mode Recursive_Mode = (NDT_Recursive_Mode)va_arg( lib_args, NDT_Recursive_Mode);
NDT_Recursive_Depth Recursive_Depth = (NDT_Recursive_Depth)va_arg( lib_args, NDT_Recursive_Depth);
NDT_Recursive_Offset Recursive_Offset = (NDT_Recursive_Offset)va_arg( lib_args, NDT_Recursive_Offset);
va_list user_args = (va_list)va_arg( lib_args, va_list);
user_type user_data = (user_type)va_arg( user_args, user_type);
... = (...)va_arg( user_args, ...);
void *Value_Ptr = Node_Ptr->Value;
*/
Command_Name = "NDD_CMD_VALUE_PRINT";
/*
fprintf( Out, "...\n", Value_Ptr->..., ...);
return( NDS_OK);
*/
}
case NDD_CMD_INFO_PRINT:
{
/*
NDT_Node *Next_Node_Ptr = (NDT_Node *)va_arg( Args, NDT_Node *);
va_list lib_args = (va_list)va_arg( Args, va_list);
FILE *Out = (FILE *)va_arg( lib_args, FILE *);
NDT_Recursive_Mode Recursive_Mode = (NDT_Recursive_Mode)va_arg( lib_args, NDT_Recursive_Mode);
NDT_Recursive_Depth Recursive_Depth = (NDT_Recursive_Depth)va_arg( lib_args, NDT_Recursive_Depth);
NDT_Recursive_Offset Recursive_Offset = (NDT_Recursive_Offset)va_arg( lib_args, NDT_Recursive_Offset);
va_list user_args = (va_list)va_arg( lib_args, va_list);
user_type user_data = (user_type)va_arg( user_args, user_type);
... = (...)va_arg( user_args, ...);
void *Value_Ptr = Node_Ptr->Value;
*/
Command_Name = "NDD_CMD_INFO_PRINT";
/*
return( NDS_OK);
*/
}
case NDD_CMD_USER_TRAVERSE:
{
/*
NDT_Node *Next_Node_Ptr = (NDT_Node *)va_arg( Args, NDT_Node *);
va_list user_args = (va_list)va_arg( Args, va_list);
user_type user_data = (user_type)va_arg( user_args, user_type);
... = (...)va_arg( user_args, ...);
void *Value_Ptr = Node_Ptr->Value;
*/
Command_Name = "NDD_CMD_USER_TRAVERSE";
/*
return( NDS_OK);
*/
}
default:
{
printf( "Default_Manager() called with an undefined command %d\n", Command);
return(NDS_ERRAPI);
}
}
printf( "Default_Manager() called with command %d (%s)\n", Command, Command_Name);
return(NDS_OK);
}
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* FONCTIONS PUBLIQUES */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* FONCTIONS OPTIMISEES (ND_MODE = 1) */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* Initialisation du contexte de la librairie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Library_Open_I( int Debug_Mode)
{
if( Debug_Mode == NDD_TRUE) ND_Library_Stderr_Set_I( stderr);
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Initialisation du contexte de la librairie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Library_Open_C( int Debug_Mode)
{
return ND_Library_Open_I( Debug_Mode);
}
/*------------------------------------------------------------------------------*/
/* Fermeture du contexte de la librairie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Library_Close_I( void)
{
struct Symbol * Symbol, * Next_Symbol;
/* D<>sallocation de la table des symboles locale */
Symbol = Symbol_Table;
while (Symbol)
{
Next_Symbol = Symbol->Next;
free (Symbol->Name);
free (Symbol);
Symbol = Next_Symbol;
}
Symbol_Table = NULL;
return NDS_OK;
}
/*------------------------------------------------------------------------------*/
/* Fermeture du contexte de la librairie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Library_Close_C( void)
{
return ND_Library_Close_I();
}
/*------------------------------------------------------------------------------*/
/* D<>finition de la sortie standard des messages d'erreur de la librairie */
/*------------------------------------------------------------------------------*/
/* (I) Out : flux de sortie de l'affichage des messages d'erreur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Library_Stderr_Set_I( FILE *Out)
{
ND_stderr = Out;
return NDS_OK;
}
/*------------------------------------------------------------------------------*/
/* D<>finition de la sortie standard des messages d'erreur de la librairie */
/*------------------------------------------------------------------------------*/
/* (I) Out : flux de sortie de l'affichage des messages d'erreur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Library_Stderr_Set_C( FILE *Out)
{
return ND_Library_Stderr_Set_I( Out);
}
/*------------------------------------------------------------------------------*/
/* Cr<43>ation d'une nouvelle structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (O) Root: adresse d'un pointeur sur la racine de la nouvelle structure */
/* (I) Type: type de la structure.de donn<6E>es (liste ou arbre binaire) */
/* (I) Allocator: pointeur vers la fonction d'allocation */
/* (I) Desallocator: pointeur vers la fonction de d<>sallocation */
/* (I) Data : pointeur de donn<6E>es utiles <20> l'allocateur */
/* (I) Own_Value : indique si la structure est propri<72>taire de ses valeurs */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Open_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Index_Type Type)
{
NDT_Status status;
NDT_Node *node_ptr;
if( ( Root_Ptr->Index_Open_Count == 0) && ( Index_Id != NDD_INDEX_PRIMARY))
{
sprintf( ND_Error_Msg, "Error ND_Index_Open_I: fist opened index should be the primary");
ND_Error_Print();
return(NDS_ERRAPI);
}
if( ( status = ND_Index_Clear( Root_Ptr, Index_Id)) != NDS_OK)
{
sprintf( ND_Error_Msg, "Error ND_Index_Open_I: Index cleaning error");
ND_Error_Print();
return( NDS_KO);
}
Root_Ptr->Index_Tab[Index_Id].Type = Type & NDD_INDEX_STATUS_RMSK | NDD_INDEX_STATUS_OPENED ;
Root_Ptr->Index_Open_Count++;
if( Index_Id != NDD_INDEX_PRIMARY)
{
if( ( status = ND_Index_Node_First_Get_I( &node_ptr, Root_Ptr, NDD_INDEX_PRIMARY)) != NDS_OK)
{
sprintf( ND_Error_Msg, "Error ND_Index_Open_I: can't get first primary index node");
ND_Error_Print();
return( NDS_KO);
}
while( node_ptr != NULL)
{
if( ( status = ND_Index_Value_Add_I( Root_Ptr, Index_Id, node_ptr->Value)) != NDS_OK)
{
sprintf( ND_Error_Msg, "Error ND_Index_Open_I: can't add value");
ND_Error_Print();
return( NDS_KO);
}
if( ( status = ND_Index_Node_Next_Get_I( &node_ptr, node_ptr)) != NDS_OK)
{
sprintf( ND_Error_Msg, "Error ND_Index_Open_I: can't get next node");
ND_Error_Print();
return( NDS_KO);
}
}
}
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Cr<43>ation d'une nouvelle structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (O) Root: adresse d'un pointeur sur la racine de la nouvelle structure */
/* (I) Type: type de la structure.de donn<6E>es (liste ou arbre binaire) */
/* (I) Allocator: pointeur vers la fonction d'allocation */
/* (I) Desallocator: pointeur vers la fonction de d<>sallocation */
/* (I) Data : pointeur de donn<6E>es utiles <20> l'allocateur */
/* (I) Own_Value : indique si la structure est propri<72>taire de ses valeurs */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Open_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Index_Type Type)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Open_C: structure root is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
if( !ND_INDEX_STATUS_CLOSED_IS( Root_Ptr, Index_Id))
{
sprintf( ND_Error_Msg, "Error ND_Index_Open_C: index is not closed");
ND_Error_Print();
return(NDS_ERRAPI);
}
return( ND_Index_Open_I( Root_Ptr, Index_Id, Type));
}
/*------------------------------------------------------------------------------*/
/* Cr<43>ation d'une nouvelle structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (O) Root: adresse d'un pointeur sur la racine de la nouvelle structure */
/* (I) Type: type de la structure.de donn<6E>es (liste ou arbre binaire) */
/* (I) Allocator: pointeur vers la fonction d'allocation */
/* (I) Desallocator: pointeur vers la fonction de d<>sallocation */
/* (I) Data : pointeur de donn<6E>es utiles <20> l'allocateur */
/* (I) Own_Value : indique si la structure est propri<72>taire de ses valeurs */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Open_I( NDT_Root **Root_Ptr_Ptr, NDT_Index_Nb Index_Nb, NDT_Index_Type *Type_Ptr, NDT_Manager_Name Manager_Name, NDT_Manager *Manager_Ptr,
NDT_Allocator_Name Allocator_Name, NDT_Allocator *Allocator_Ptr, NDT_Desallocator_Name Desallocator_Name, NDT_Desallocator *Desallocator_Ptr, short Own_Value, void *Data)
{
NDT_Status status;
// const char *Real_Allocator, *Real_Desallocator; // Win32
NDT_Manager_Name Real_Manager_Name;
NDT_Manager *Real_Manager_Ptr;
NDT_Allocator_Name Real_Allocator_Name;
NDT_Allocator *Real_Allocator_Ptr;
NDT_Desallocator_Name Real_Desallocator_Name;
NDT_Desallocator *Real_Desallocator_Ptr;
/* Valeurs par d<>faut des fonctions d'allocation et de d<>sallocation */
if( Manager_Ptr)
{
Real_Manager_Name = Manager_Name;
Real_Manager_Ptr = Manager_Ptr;
}
else
{
Real_Manager_Name = "ND_Default_Manager";
Real_Manager_Ptr = ND_Default_Manager;
}
if( Allocator_Ptr)
{
Real_Allocator_Name = Allocator_Name;
Real_Allocator_Ptr = Allocator_Ptr;
}
else
{
Real_Allocator_Name = "ND_Default_Allocator";
Real_Allocator_Ptr = ND_Default_Allocator;
}
if( Desallocator_Ptr)
{
Real_Desallocator_Name = Desallocator_Name;
Real_Desallocator_Ptr = Desallocator_Ptr;
}
else
{
Real_Desallocator_Name = "ND_Default_Desallocator";
Real_Desallocator_Ptr = ND_Default_Desallocator;
}
status = ND_Node_Root_Alloc( Root_Ptr_Ptr, Index_Nb, Type_Ptr, Real_Manager_Name, Real_Manager_Ptr, Real_Allocator_Name, Real_Allocator_Ptr, Real_Desallocator_Name, Real_Desallocator_Ptr, Own_Value, Data);
if( ND_ERROR( status)) return( status);
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Cr<43>ation d'une nouvelle structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (O) Root: adresse d'un pointeur sur la racine de la nouvelle structure */
/* (I) Type: type de la structure.de donn<6E>es (liste ou arbre binaire) */
/* (I) Allocator: pointeur vers la fonction d'allocation */
/* (I) Desallocator: pointeur vers la fonction de d<>sallocation */
/* (I) Data : pointeur de donn<6E>es utiles <20> l'allocateur */
/* (I) Own_Value : indique si la structure est propri<72>taire de ses valeurs */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Open_C( NDT_Root **Root_Ptr_Ptr, NDT_Index_Nb Index_Nb, NDT_Index_Type *Type_Ptr, NDT_Manager_Name Manager_Name, NDT_Manager *Manager_Ptr,
NDT_Allocator_Name Allocator_Name, NDT_Allocator *Allocator_Ptr, NDT_Desallocator_Name Desallocator_Name, NDT_Desallocator *Desallocator_Ptr, short Own_Value, void *Data_Ptr)
{
return ND_DataStruct_Open_I( Root_Ptr_Ptr, Index_Nb, Type_Ptr, Manager_Name, Manager_Ptr, Allocator_Name, Allocator_Ptr, Desallocator_Name, Desallocator_Ptr, Own_Value, Data_Ptr);
}
/*------------------------------------------------------------------------------*/
/* Destruction d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (O) Root: pointeur sur la racine de la structure de donn<6E>es <20> d<>truire */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Close_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
{
NDT_Status status;
if( ( Root_Ptr->Index_Open_Count != 1) && ( Index_Id == NDD_INDEX_PRIMARY))
{
sprintf( ND_Error_Msg, "Error ND_Index_Close_I: the primary should be the last closed");
ND_Error_Print();
return(NDS_ERRAPI);
}
status = ND_Index_Flush_I( Root_Ptr, Index_Id);
if( ND_ERROR( status)) return( status);
Root_Ptr->Index_Tab[ Index_Id].Type = Root_Ptr->Index_Tab[ Index_Id].Type & NDD_INDEX_STATUS_RMSK | NDD_INDEX_STATUS_CLOSED;
Root_Ptr->Index_Open_Count--;
return(NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Destruction d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (O) Root: pointeur sur la racine de la structure de donn<6E>es <20> d<>truire */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Close_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Close_C: structure root is null");
ND_Error_Print();
return( NDS_ERRAPI);
}
if( !ND_INDEX_STATUS_OPENED_IS( Root_Ptr, Index_Id))
{
sprintf( ND_Error_Msg, "Error ND_Index_Close_C: index is not opened");
ND_Error_Print();
return(NDS_ERRAPI);
}
return( ND_Index_Close_I( Root_Ptr, Index_Id));
}
/*------------------------------------------------------------------------------*/
/* Destruction d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (O) Root: pointeur sur la racine de la structure de donn<6E>es <20> d<>truire */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Close_I( NDT_Root *Root_Ptr)
{
NDT_Status status;
status = ND_DataStruct_Flush_I( Root_Ptr);
if( ND_ERROR( status)) return( status);
return( ND_Node_Root_Free( Root_Ptr));
}
/*------------------------------------------------------------------------------*/
/* Destruction d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (O) Root: pointeur sur la racine de la structure de donn<6E>es <20> d<>truire */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Close_C( NDT_Root *Root_Ptr)
{
if (!Root_Ptr)
{
sprintf (ND_Error_Msg, "Error ND_DataStruct_Close : structure root is null");
ND_Error_Print();
return( NDS_ERRAPI);
}
return( ND_DataStruct_Close_I( Root_Ptr));
}
/*------------------------------------------------------------------------------*/
/* (O) Root: pointeur sur la racine de la structure de donn<6E>es <20> d<>truire */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Flush_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
{
NDT_Status status;
NDT_Node *Node_Ptr, *Next_Node_Ptr;
ND_Index_Node_First_Get_I( &Node_Ptr, Root_Ptr, Index_Id);
while( Node_Ptr)
{
Next_Node_Ptr = NULL;
ND_Index_Node_Next_Get_I( &Next_Node_Ptr, Node_Ptr);
if( Index_Id == NDD_INDEX_PRIMARY)
{
status = ND_Manager_Exec_I( Root_Ptr, Index_Id, Node_Ptr, NDD_CMD_VALUE_FREE, Node_Ptr->Value);
if( ND_ERROR( status)) return( status);
}
else
{
status = ND_Manager_Exec_I( Root_Ptr, Index_Id, Node_Ptr, NDD_CMD_VALUE_REMOVE, Node_Ptr->Value);
if( ND_ERROR( status)) return( status);
}
status = ND_Index_Node_Remove_I( Node_Ptr);
if( ND_ERROR( status)) return( status);
status = ND_Node_Free( Root_Ptr, Node_Ptr);
if (ND_ERROR( status)) return( status);
Node_Ptr = Next_Node_Ptr;
}
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Destruction d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (O) Root: pointeur sur la racine de la structure de donn<6E>es <20> d<>truire */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Flush_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Close : structure root is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
return( ND_Index_Flush_I( Root_Ptr, Index_Id));
}
/*------------------------------------------------------------------------------*/
/* Destruction d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (O) Root: pointeur sur la racine de la structure de donn<6E>es <20> d<>truire */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Flush_I( NDT_Root *Root_Ptr)
{
NDT_Status status;
NDT_Index_Id index_id;
for( index_id = ( Root_Ptr->Index_Nb - 1); index_id >= 0 ; index_id--)
{
status = ND_Index_Flush_I( Root_Ptr, index_id);
if( ND_ERROR( status)) return( status);
}
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Destruction d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (O) Root: pointeur sur la racine de la structure de donn<6E>es <20> d<>truire */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Flush_C( NDT_Root *Root_Ptr)
{
if (!Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Flush : structure root is null");
ND_Error_Print();
return( NDS_ERRAPI);
}
return ND_DataStruct_Flush_I( Root_Ptr);
}
/*------------------------------------------------------------------------------*/
/* Function de r<>paration d'une structure : */
/* - v<>rifie que tous les noeuds sont correctement li<6C>s les uns aux autres */
/* - corrige les informations statistiques de la racine */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure */
/* (O) Nb_Detected : pointeur sur le nombre d'erreurs d<>tect<63>es */
/* (O) Nb_Corrected : pointeur sur le nombre d'erreurs corrig<69>es */
/* (I) Out : flux de sortie du rapport */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Check_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Detected_Nb_Ptr, int *Corrected_Nb_Ptr, FILE *Out)
{
*Detected_Nb_Ptr = 0;
*Corrected_Nb_Ptr = 0;
if( ND_INDEX_STATUS_OPENED_IS( Root_Ptr, Index_Id))
{
if( ND_INDEX_TYPE_LIST_IS( Root_Ptr, Index_Id))
{
ND_List_Check( Root_Ptr, Index_Id, Detected_Nb_Ptr, Corrected_Nb_Ptr, Out);
}
else if( ND_INDEX_TYPE_TREE_IS( Root_Ptr, Index_Id))
{
ND_Tree_Check( Root_Ptr, Index_Id, Detected_Nb_Ptr, Corrected_Nb_Ptr, Out);
}
else
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Check : unknown structure type (%d) in structure (%p:%d)\n", Root_Ptr->Index_Tab[Index_Id].Type, Root_Ptr, Index_Id);
ND_Error_Print();
(*Detected_Nb_Ptr)++;
return( NDS_OK);
}
/* Affichage du r<>sultat de la proc<6F>dure de v<>rification */
if( *Detected_Nb_Ptr == 0)
{
fprintf( Out, "No error detected in the node structure (%p:%d)\n", Root_Ptr, Index_Id);
}
else
{
fprintf( Out, "%d/%d error(s) corrected in the node structure (%p:%d)\n", *Corrected_Nb_Ptr, *Detected_Nb_Ptr, Root_Ptr, Index_Id);
}
}
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Function de r<>paration d'une structure : */
/* - v<>rifie que tous les noeuds sont correctement li<6C>s les uns aux autres */
/* - corrige les informations statistiques de la racine */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure */
/* (O) Nb_Detected : pointeur sur le nombre d'erreurs d<>tect<63>es */
/* (O) Nb_Corrected : pointeur sur le nombre d'erreurs corrig<69>es */
/* (I) Out : flux de sortie du rapport */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Check_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Check : structure root is null");
ND_Error_Print();
(*Nb_Detected_Ptr)++;
return(NDS_ERRAPI);
}
if( !Out)
{
sprintf( ND_Error_Msg, "Error ND_Index_Check : the stream descriptor is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
return ND_Index_Check_I( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out);
}
/*------------------------------------------------------------------------------*/
/* Function de r<>paration d'une structure : */
/* - v<>rifie que tous les noeuds sont correctement li<6C>s les uns aux autres */
/* - corrige les informations statistiques de la racine */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure */
/* (O) Nb_Detected : pointeur sur le nombre d'erreurs d<>tect<63>es */
/* (O) Nb_Corrected : pointeur sur le nombre d'erreurs corrig<69>es */
/* (I) Out : flux de sortie du rapport */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Check_I( NDT_Root *Root_Ptr, int *Error_Detected_Nb_Ptr, int *Error_Corrected_Nb_Ptr, FILE *Out)
{
NDT_Status status;
NDT_Index_Id index_id;
int index_error_detected_nb, index_error_corrected_nb;
for( index_id = 0; index_id < Root_Ptr->Index_Nb; index_id++)
{
status = ND_Index_Check_I( Root_Ptr, index_id, &index_error_detected_nb, &index_error_corrected_nb, Out);
if( ND_ERROR(status)) return(status);
*Error_Detected_Nb_Ptr = *Error_Detected_Nb_Ptr + index_error_detected_nb;
*Error_Corrected_Nb_Ptr = *Error_Corrected_Nb_Ptr + index_error_corrected_nb;
}
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Function de r<>paration d'une structure : */
/* - v<>rifie que tous les noeuds sont correctement li<6C>s les uns aux autres */
/* - corrige les informations statistiques de la racine */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure */
/* (O) Nb_Detected : pointeur sur le nombre d'erreurs d<>tect<63>es */
/* (O) Nb_Corrected : pointeur sur le nombre d'erreurs corrig<69>es */
/* (I) Out : flux de sortie du rapport */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Check_C( NDT_Root *Root_Ptr, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Check : structure root is null");
ND_Error_Print();
(*Nb_Detected_Ptr)++;
return NDS_ERRAPI;
}
if( !Out)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Check : the stream descriptor is null");
ND_Error_Print();
return NDS_ERRAPI;
}
return ND_DataStruct_Check_I( Root_Ptr, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out);
}
/*------------------------------------------------------------------------------*/
/* Conversion d'une structure de donn<6E>es d'un type en un autre */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> convertir */
/* (I) Target_Type : type de structure cible */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Convert_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Index_Type Target_Type)
{
NDT_Status rc;
if( ND_INDEX_STATUS_OPENED_IS( Root_Ptr, Index_Id))
{
switch( Root_Ptr->Index_Tab[Index_Id].Type & NDD_INDEX_TYPE_MSK)
{
case NDD_INDEX_TYPE_LIST:
{
switch( Target_Type & ( NDD_INDEX_TYPE_MSK | NDD_INDEX_SUBTYPE_MSK))
{
case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_SORTED):
{
rc = ND_List_Sort( Root_Ptr, Index_Id);
if( ND_ERROR( rc)) return( rc);
Root_Ptr->Index_Tab[Index_Id].Type = Target_Type;
return( rc);
}
case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_FIFO):
case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_LIFO):
{
Root_Ptr->Index_Tab[Index_Id].Type = Target_Type;
return( NDS_OK);
}
case( NDD_INDEX_TYPE_TREE | NDD_INDEX_SUBTYPE_BALANCED):
case( NDD_INDEX_TYPE_TREE | NDD_INDEX_SUBTYPE_UNBALANCED):
{
rc = ND_List_Sort( Root_Ptr, Index_Id);
if( rc != NDS_OK) return( rc);
rc = ND_Tree_Make( Root_Ptr, Index_Id);
if( ND_ERROR( rc)) return( rc);
Root_Ptr->Index_Tab[Index_Id].Type = Target_Type;
return( rc);
}
default:
{
return( NDS_KO);
}
}
break;
}
case NDD_INDEX_TYPE_TREE:
{
switch( Target_Type & ( NDD_INDEX_TYPE_MSK | NDD_INDEX_SUBTYPE_MSK))
{
case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_SORTED):
case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_FIFO):
case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_LIFO):
{
rc = ND_List_Make( Root_Ptr, Index_Id);
if( ND_ERROR( rc)) return( rc);
Root_Ptr->Index_Tab[Index_Id].Type = Target_Type;
return( rc);
}
default:
{
return( NDS_KO);
}
}
break;
}
default:
{
sprintf (ND_Error_Msg, "Error ND_DataStruct_Reorg : unknown structure type (%d)", Root_Ptr->Index_Tab[Index_Id].Type);
ND_Error_Print ();
return NDS_ERRAPI;
}
}
}
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Conversion d'une structure de donn<6E>es d'un type en un autre */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> convertir */
/* (I) Target_Type : type de structure cible */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Convert_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Index_Type Target_Type)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Convert : structure root is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
return ND_Index_Convert_I( Root_Ptr, Index_Id, Target_Type);
}
/*------------------------------------------------------------------------------*/
/* Conversion d'une structure de donn<6E>es d'un type en un autre */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> convertir */
/* (I) Target_Type : type de structure cible */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Convert_I( NDT_Root *Root_Ptr, NDT_Index_Type *Target_Type_Ptr)
{
NDT_Status rc;
NDT_Index_Nb idx;
for( idx = 0; idx < Root_Ptr->Index_Nb; idx++)
{
rc = ND_Index_Convert_I( Root_Ptr, idx, Target_Type_Ptr[idx]);
if( ND_ERROR(rc)) return rc;
}
return(NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Conversion d'une structure de donn<6E>es d'un type en un autre */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> convertir */
/* (I) Target_Type : type de structure cible */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Convert_C( NDT_Root *Root_Ptr, NDT_Index_Type *Target_Type_Ptr)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Convert : structure root is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
if( !Target_Type_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Convert : target type ptr is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
return ND_DataStruct_Convert_I( Root_Ptr, Target_Type_Ptr);
}
/*------------------------------------------------------------------------------*/
/* R<>organisation d'une structure de donn<6E>es */
/* - ordonnancement d'une liste non ordonn<6E>e */
/* - r<>quilibrage d'un arbre non auto-<2D>quilibr<62> */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> supprimer */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Reorg_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
{
NDT_Status status;
if( ND_INDEX_STATUS_OPENED_IS( Root_Ptr, Index_Id))
{
if( ( status = ND_INDEX_TYPE_LIST_IS( Root_Ptr, Index_Id)))
{
if ( !ND_INDEX_SUBTYPE_SORTED_IS( Root_Ptr, Index_Id))
{
if( ( status = ND_List_Sort( Root_Ptr, Index_Id)) != NDS_OK)
{
return( status);
}
}
}
else
{
if( ND_INDEX_TYPE_TREE_IS( Root_Ptr, Index_Id))
{
if( ( status = ND_Tree_Equalize( Root_Ptr, Index_Id)) != NDS_OK)
{
return( status);
}
}
else
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Reorg : unknown structure type (%d) in structure (%p:%d)\n", Root_Ptr->Index_Tab[Index_Id].Type, Root_Ptr, Index_Id);
ND_Error_Print();
return(NDS_ERRAPI);
}
}
}
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* R<>organisation d'une structure de donn<6E>es */
/* - ordonnancement d'une liste non ordonn<6E>e */
/* - r<>quilibrage d'un arbre non auto-<2D>quilibr<62> */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> supprimer */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Reorg_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Reorg : structure root is null");
ND_Error_Print ();
return NDS_ERRAPI;
}
return ND_Index_Reorg_I( Root_Ptr, Index_Id);
}
/*------------------------------------------------------------------------------*/
/* R<>organisation d'une structure de donn<6E>es */
/* - ordonnancement d'une liste non ordonn<6E>e */
/* - r<>quilibrage d'un arbre non auto-<2D>quilibr<62> */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> supprimer */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Reorg_I( NDT_Root *Root_Ptr)
{
NDT_Status status;
NDT_Index_Id index_id;
for( index_id = 0; index_id < Root_Ptr->Index_Nb; index_id++)
{
status = ND_Index_Reorg_I( Root_Ptr, index_id);
if( ND_ERROR( status)) return status;
}
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* R<>organisation d'une structure de donn<6E>es */
/* - ordonnancement d'une liste non ordonn<6E>e */
/* - r<>quilibrage d'un arbre non auto-<2D>quilibr<62> */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> supprimer */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Reorg_C( NDT_Root *Root_Ptr)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Reorg : structure root is null");
ND_Error_Print ();
return NDS_ERRAPI;
}
return ND_DataStruct_Reorg_I( Root_Ptr);
}
/*------------------------------------------------------------------------------*/
/* Parcours de tous les noeuds d'une structure de donn<6E>es et ex<65>cution d'une */
/* commande sur chacun d'eux */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> parcourir */
/* (I) Command : Commande <20> ex<65>cuter sur chaque noeud travers<72> */
/* (I) Data : pointeur de donn<6E>es utilisateur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Traverse_VI( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Command Command, va_list Args)
{
NDT_Status rc;
NDT_Node *Node_Ptr, *Next_Node_Ptr;
ND_Index_Node_First_Get_I( &Node_Ptr, Root_Ptr, Index_Id);
while( Node_Ptr)
{
Next_Node_Ptr = NULL;
ND_Index_Node_Next_Get_I( &Next_Node_Ptr, Node_Ptr);
switch (Command)
{
case NDD_CMD_VALUE_REMOVE:
case NDD_CMD_VALUE_FREE:
{
rc = ND_Manager_Exec_I( Root_Ptr, Index_Id, Node_Ptr, Command, Node_Ptr->Value, Args);
if (ND_ERROR( rc)) return rc;
rc = ND_Index_Node_Remove_I( Node_Ptr);
if( ND_ERROR( rc)) return rc;
rc = ND_Node_Free( Root_Ptr, Node_Ptr);
if (ND_ERROR(rc)) return rc;
break;
}
default:
{
rc = ND_Manager_Exec_I( Root_Ptr, Index_Id, Node_Ptr, Command, Next_Node_Ptr, Args);
if (ND_ERROR( rc)) return rc;
break;
}
}
Node_Ptr = Next_Node_Ptr;
}
return NDS_OK;
}
/*------------------------------------------------------------------------------*/
/* Parcours de tous les noeuds d'une structure de donn<6E>es et ex<65>cution d'une */
/* commande sur chacun d'eux */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> parcourir */
/* (I) Command : Commande <20> ex<65>cuter sur chaque noeud travers<72> */
/* (I) Data : pointeur de donn<6E>es utilisateur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Traverse_VC( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Command Command, va_list Args)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Traverse_VC : structure root is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
return ND_Index_Traverse_VI( Root_Ptr, Index_Id, Command, Args);
}
/*------------------------------------------------------------------------------*/
/* Parcours de tous les noeuds d'une structure de donn<6E>es et ex<65>cution d'une */
/* commande sur chacun d'eux */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> parcourir */
/* (I) Command : Commande <20> ex<65>cuter sur chaque noeud travers<72> */
/* (I) Data : pointeur de donn<6E>es utilisateur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Traverse_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Command Command, ...)
{
NDT_Status status;
va_list args;
NDT_Node *Node_Ptr, *Next_Node_Ptr;
va_start( args, Command);
ND_Index_Node_First_Get_I( &Node_Ptr, Root_Ptr, Index_Id);
status = NDS_OK;
while( Node_Ptr)
{
Next_Node_Ptr = NULL;
ND_Index_Node_Next_Get_I( &Next_Node_Ptr, Node_Ptr);
switch (Command)
{
case NDD_CMD_VALUE_REMOVE:
case NDD_CMD_VALUE_FREE:
{
status = ND_Manager_Exec_I( Root_Ptr, Index_Id, Node_Ptr, Command, Node_Ptr->Value, args);
if( ND_ERROR( status)) return( status);
status = ND_Index_Node_Remove_I( Node_Ptr);
if( ND_ERROR( status)) return( status);
status = ND_Node_Free( Root_Ptr, Node_Ptr);
if (ND_ERROR( status)) return( status);
break;
}
default:
{
status = ND_Manager_Exec_I( Root_Ptr, Index_Id, Node_Ptr, Command, Next_Node_Ptr, args);
if( ND_ERROR( status)) return( status);
break;
}
}
Node_Ptr = Next_Node_Ptr;
}
va_end( args);
return( status);
}
/*------------------------------------------------------------------------------*/
/* Parcours de tous les noeuds d'une structure de donn<6E>es et ex<65>cution d'une */
/* commande sur chacun d'eux */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> parcourir */
/* (I) Command : Commande <20> ex<65>cuter sur chaque noeud travers<72> */
/* (I) Data : pointeur de donn<6E>es utilisateur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Traverse_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Command Command, ...)
{
NDT_Status status;
va_list args;
va_start( args, Command);
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Traverse_C : structure root is null");
ND_Error_Print();
return( NDS_ERRAPI);
}
status = ND_Index_Traverse_VI( Root_Ptr, Index_Id, Command, args);
va_end( args);
return( status);
}
/*------------------------------------------------------------------------------*/
/* Parcours de tous les noeuds d'une structure de donn<6E>es et ex<65>cution d'une */
/* commande sur chacun d'eux */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> parcourir */
/* (I) Command : Commande <20> ex<65>cuter sur chaque noeud travers<72> */
/* (I) Data : pointeur de donn<6E>es utilisateur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Traverse_VI( NDT_Root *Root_Ptr, NDT_Command Command, va_list Args)
{
NDT_Status status;
NDT_Index_Id new_index;
NDT_Command new_cmd;
status = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_UNKNOWN, NULL, NDD_CMD_INDEX_GET, &new_index, &new_cmd, Command, NULL);
if( ND_ERROR(status)) return( status);
return( ND_Index_Traverse_VI( Root_Ptr, (NDT_Index_Id)(( new_index == NDD_INDEX_UNKNOWN) ? NDD_INDEX_PRIMARY : new_index), new_cmd, Args));
}
/*------------------------------------------------------------------------------*/
/* Parcours de tous les noeuds d'une structure de donn<6E>es et ex<65>cution d'une */
/* commande sur chacun d'eux */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> parcourir */
/* (I) Command : Commande <20> ex<65>cuter sur chaque noeud travers<72> */
/* (I) Data : pointeur de donn<6E>es utilisateur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Traverse_VC( NDT_Root *Root_Ptr, NDT_Command Command, va_list Args)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Traverse_VC : structure root is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
return ND_DataStruct_Traverse_VI( Root_Ptr, Command, Args);
}
/*------------------------------------------------------------------------------*/
/* Parcours de tous les noeuds d'une structure de donn<6E>es et ex<65>cution d'une */
/* commande sur chacun d'eux */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> parcourir */
/* (I) Command : Commande <20> ex<65>cuter sur chaque noeud travers<72> */
/* (I) Data : pointeur de donn<6E>es utilisateur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Traverse_I( NDT_Root *Root_Ptr, NDT_Command Command, ...)
{
NDT_Status status;
va_list args;
NDT_Index_Id new_index;
NDT_Command new_cmd;
va_start( args, Command);
status = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_UNKNOWN, NULL, NDD_CMD_INDEX_GET, &new_index, &new_cmd, Command, NULL);
if( ND_ERROR( status)) return( status);
status = ND_Index_Traverse_VI( Root_Ptr, (NDT_Index_Id)(( new_index == NDD_INDEX_UNKNOWN) ? NDD_INDEX_PRIMARY : new_index), new_cmd, args);
va_end( args);
return( status);
}
/*------------------------------------------------------------------------------*/
/* Parcours de tous les noeuds d'une structure de donn<6E>es et ex<65>cution d'une */
/* commande sur chacun d'eux */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> parcourir */
/* (I) Command : Commande <20> ex<65>cuter sur chaque noeud travers<72> */
/* (I) Data : pointeur de donn<6E>es utilisateur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Traverse_C( NDT_Root *Root_Ptr, NDT_Command Command, ...)
{
NDT_Status status;
va_list args;
va_start( args, Command);
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Traverse_C : structure root is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
status = ND_DataStruct_Traverse_VI( Root_Ptr, Command, args);
va_end( args);
return( status);
}
/*------------------------------------------------------------------------------*/
/* Affichage d'informations sur une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root: pointeur sur la racine de la structure de donn<6E>es */
/* (I) Out : flux de sortie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Info_Print_I( FILE *Out, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset)
{
NDT_Status status;
char offset[255];
if( ND_RECURSIVE_PARENT_IS( Recursive_Mode))
{
memset( offset, ' ', Recursive_Offset * ND_RECURSIVE_PRINT_OFFSET);
offset[Recursive_Offset * ND_RECURSIVE_PRINT_OFFSET] = '\0';
printf( "%s Index Id: (%d)\tType: (%#06x) [%s:%s:%s]\tNode Nb: (%d)\tHead: (%s%p)\tTail: (%s%p)\n%s Min Depth: (%d)\tMax Depth: (%d)\tMax Dif: (%d)\tNb Equ: (%d)\tSave: (%s%p)\n\n",
offset, Index_Id, Root_Ptr->Index_Tab[Index_Id].Type, ND_INDEX_STATUS_ASCII_GET( Root_Ptr, Index_Id), ND_INDEX_TYPE_ASCII_GET( Root_Ptr, Index_Id), ND_INDEX_SUBTYPE_ASCII_GET( Root_Ptr, Index_Id),
Root_Ptr->Index_Tab[Index_Id].Node_Number,
NDD_PRINTF_PTR_PREFIX, Root_Ptr->Index_Tab[Index_Id].Head, NDD_PRINTF_PTR_PREFIX, Root_Ptr->Index_Tab[Index_Id].Tail,
offset, Root_Ptr->Index_Tab[Index_Id].Min_Depth, Root_Ptr->Index_Tab[Index_Id].Max_Depth, Root_Ptr->Index_Tab[Index_Id].Max_Dif, Root_Ptr->Index_Tab[Index_Id].Nb_Equ,
NDD_PRINTF_PTR_PREFIX, Root_Ptr->Index_Tab[Index_Id].Save);
}
if( ND_RECURSIVE_CHILD_IS(Recursive_Mode))
{
status = ND_Index_Traverse_I( Root_Ptr, Index_Id, NDD_CMD_INFO_PRINT, Out, NDD_RECURSIVE_MODE_PARENT_CHILD, Recursive_Depth, Recursive_Offset);
}
else
{
status = NDS_OK;
}
return( status);
}
/*------------------------------------------------------------------------------*/
/* Affichage d'informations sur une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root: pointeur sur la racine de la structure de donn<6E>es */
/* (I) Out : flux de sortie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Info_Print_C( FILE *Out, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Info_Print : structure root is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
if( !Out)
{
sprintf( ND_Error_Msg, "Error ND_Index_Info_Print : the stream descriptor is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
return( ND_Index_Info_Print_I( Out, Root_Ptr, Index_Id, Recursive_Mode, Recursive_Depth, Recursive_Offset));
}
/*------------------------------------------------------------------------------*/
/* Affichage d'informations sur une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root: pointeur sur la racine de la structure de donn<6E>es */
/* (I) Out : flux de sortie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Info_Print_I( FILE *Out, NDT_Root *Root_Ptr, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset)
{
NDT_Status status;
NDT_Index_Nb idx;
NDT_Version_Name version_name;
char offset[255];
if( ND_RECURSIVE_PARENT_IS( Recursive_Mode))
{
memset( offset, ' ', Recursive_Offset * ND_RECURSIVE_PRINT_OFFSET);
offset[Recursive_Offset * ND_RECURSIVE_PRINT_OFFSET] = '\0';
status = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_UNKNOWN, NULL, NDD_CMD_MANAGER_VERSION, &version_name);
if( ND_ERROR( status)) return( status);
printf( "%sRoot: (%s%p)\tIndex Nb: (%d)\tIndex Open Count: (%d)\tManager: (%s%p) [%s]\n%sAllocator: (%s%p) [%s]\tDesallocator: (%s%p) [%s]\tUser: (%s%p)\n%sManager Version: [%s]\n\n",
offset, NDD_PRINTF_PTR_PREFIX, Root_Ptr, Root_Ptr->Index_Nb, Root_Ptr->Index_Open_Count, NDD_PRINTF_PTR_PREFIX, Root_Ptr->Manager_Ptr, Root_Ptr->Manager_Name,
offset, NDD_PRINTF_PTR_PREFIX, Root_Ptr->Allocator_Ptr, Root_Ptr->Allocator_Name, NDD_PRINTF_PTR_PREFIX, Root_Ptr->Desallocator_Ptr, Root_Ptr->Desallocator_Name, NDD_PRINTF_PTR_PREFIX, Root_Ptr->User,
offset, version_name);
}
if( ND_RECURSIVE_CHILD_IS( Recursive_Mode))
{
for( idx = NDD_INDEX_PRIMARY; idx < Root_Ptr->Index_Nb; idx++)
{
status = ND_Index_Info_Print_I( Out, Root_Ptr, idx, NDD_RECURSIVE_MODE_PARENT, 0, Recursive_Offset);
if( ND_ERROR( status)) return( status);
}
return( ND_Index_Info_Print_I( Out, Root_Ptr, NDD_INDEX_PRIMARY, NDD_RECURSIVE_MODE_CHILD, Recursive_Depth, Recursive_Offset));
}
else
{
return( NDS_OK);
}
}
/*------------------------------------------------------------------------------*/
/* Affichage d'informations sur une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root: pointeur sur la racine de la structure de donn<6E>es */
/* (I) Out : flux de sortie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Info_Print_C( FILE *Out, NDT_Root *Root_Ptr, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset)
{
if( !Root_Ptr)
{
sprintf (ND_Error_Msg, "Error ND_DataStruct_Info_Print : structure root is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
if( !Out)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Info_Print : the stream descriptor is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
return( ND_DataStruct_Info_Print_I( Out, Root_Ptr, Recursive_Mode, Recursive_Depth, Recursive_Offset));
}
/*------------------------------------------------------------------------------*/
/* Ajout d'une valeur <20> une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es */
/* (I) Value : pointeur sur la valeur <20> ajouter <20> la structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Value_Add_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr)
{
NDT_Status status;
if( ND_INDEX_TYPE_LIST_IS( Root_Ptr, Index_Id))
{
status = ND_List_Value_Add( Root_Ptr, Index_Id, Value_Ptr);
if(ND_ERROR( status)) return( status);
}
else if( ND_INDEX_TYPE_TREE_IS( Root_Ptr, Index_Id))
{
status = ND_Tree_Value_Add( Root_Ptr, Index_Id, Value_Ptr);
if(ND_ERROR( status)) return( status);
}
else
{
sprintf( ND_Error_Msg, "Error ND_Index_Value_Add : unknown structure type (%d)", Root_Ptr->Index_Tab[Index_Id].Type);
ND_Error_Print();
return( NDS_ERRAPI);
}
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Ajout d'une valeur <20> une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es */
/* (I) Value : pointeur sur la valeur <20> ajouter <20> la structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Value_Add_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Value_Add : structure root is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
if( !Value_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Value_Add : the value to add is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
return ND_Index_Value_Add_I( Root_Ptr, Index_Id, Value_Ptr);
}
/*------------------------------------------------------------------------------*/
/* Ajout d'une valeur <20> une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es */
/* (I) Value : pointeur sur la valeur <20> ajouter <20> la structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Value_Add_I( NDT_Root *Root_Ptr, void *Value_Ptr)
{
NDT_Status status;
NDT_Index_Id index_id;
for( index_id = 0; index_id < Root_Ptr->Index_Nb; index_id++)
{
if( ND_INDEX_STATUS_OPENED_IS( Root_Ptr, index_id))
{
status = ND_Index_Value_Add( Root_Ptr, index_id, Value_Ptr);
if( ND_ERROR( status)) return( status);
}
}
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Ajout d'une valeur <20> une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es */
/* (I) Value : pointeur sur la valeur <20> ajouter <20> la structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Value_Add_C( NDT_Root *Root_Ptr, void *Value_Ptr)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Value_Add : structure root is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
if( !Value_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DatatStruct_Value_Add : the value to add is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
return ND_DataStruct_Value_Add_I( Root_Ptr, Value_Ptr);
}
/*------------------------------------------------------------------------------*/
/* Suppression du premier noeud correspondant <20> une valeur donn<6E>e */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es */
/* (I) Reference_Value : pointeur sur la valeur de r<>f<EFBFBD>rence */
/* (I) Removed_Value : adresse d'un pointeur sur la valeur supprim<69>e */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Value_Remove_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr)
{
NDT_Status status;
NDT_Node *node_ptr;
/* Recherche du premier noeud correspondant <20> la valeur de r<>f<EFBFBD>rence */
status = ND_Index_Node_Find_I( &node_ptr, Root_Ptr, Index_Id, Value_Ptr);
if( ND_ERROR( status)) return( status);
if( !node_ptr) return( NDS_OK);
/* manager call */
status = ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_REMOVE, Value_Ptr);
if (ND_ERROR( status)) return( status);
/* Retrait du noeud de la structure */
status = ND_Index_Node_Remove_I( node_ptr);
if( ND_ERROR( status)) return( status);
/* D<>sallocation du noeud */
status = ND_Node_Free( Root_Ptr, node_ptr);
return( status);
}
/*------------------------------------------------------------------------------*/
/* Suppression du premier noeud correspondant <20> une valeur donn<6E>e */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es */
/* (I) Reference_Value : pointeur sur la valeur de r<>f<EFBFBD>rence */
/* (I) Removed_Value : adresse d'un pointeur sur la valeur supprim<69>e */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Value_Remove_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Value_Remove : structure root is null");
ND_Error_Print();
return NDS_ERRAPI;
}
if( !Value_Ptr)
{
sprintf (ND_Error_Msg, "Error ND_Index_Value_Remove : the value is null");
ND_Error_Print ();
return NDS_ERRAPI;
}
return ND_Index_Value_Remove_I( Root_Ptr, Index_Id, Value_Ptr);
}
/*------------------------------------------------------------------------------*/
/* Suppression du premier noeud correspondant <20> une valeur donn<6E>e */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es */
/* (I) Reference_Value : pointeur sur la valeur de r<>f<EFBFBD>rence */
/* (I) Removed_Value : adresse d'un pointeur sur la valeur supprim<69>e */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Value_Remove_I( NDT_Root *Root_Ptr, void *Value_Ptr)
{
NDT_Status status;
NDT_Index_Id index_id;
for( index_id = 0; index_id < Root_Ptr->Index_Nb; index_id++)
{
if( ND_INDEX_STATUS_OPENED_IS( Root_Ptr, index_id))
{
status = ND_Index_Value_Remove_I( Root_Ptr, index_id, Value_Ptr);
if( ND_ERROR( status)) return( status);
}
}
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Suppression du premier noeud correspondant <20> une valeur donn<6E>e */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es */
/* (I) Reference_Value : pointeur sur la valeur de r<>f<EFBFBD>rence */
/* (I) Removed_Value : adresse d'un pointeur sur la valeur supprim<69>e */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Value_Remove_C( NDT_Root *Root_Ptr, void *Value_Ptr)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Value_Remove : structure root is null");
ND_Error_Print();
return NDS_ERRAPI;
}
if( !Value_Ptr)
{
sprintf (ND_Error_Msg, "Error ND_DataStruct_Value_Remove : the value is null");
ND_Error_Print ();
return NDS_ERRAPI;
}
return ND_DataStruct_Value_Remove_I( Root_Ptr, Value_Ptr);
}
/*------------------------------------------------------------------------------*/
/* Affichage d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> afficher */
/* (I) Out : flux de sortie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Value_Print_VI( FILE *Out, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset, va_list Args)
{
NDT_Status status;
status = ND_Index_Traverse_I( Root_Ptr, Index_Id, NDD_CMD_VALUE_PRINT, Out, Recursive_Mode, Recursive_Depth, Recursive_Offset, Args);
return( status);
}
/*------------------------------------------------------------------------------*/
/* Affichage d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> afficher */
/* (I) Out : flux de sortie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Value_Print_I( FILE *Out, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset, ...)
{
NDT_Status status;
va_list user_args;
va_start( user_args, Recursive_Offset);
status = ND_Index_Traverse_I( Root_Ptr, Index_Id, NDD_CMD_VALUE_PRINT, Out, Recursive_Mode, Recursive_Depth, Recursive_Offset, user_args);
va_end( user_args);
return( status);
}
/*------------------------------------------------------------------------------*/
/* Affichage d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> afficher */
/* (I) Out : flux de sortie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Value_Print_C( FILE *Out, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset, ...)
{
NDT_Status status;
va_list user_args;
va_start( user_args, Recursive_Offset);
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Value_Print : structure root is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
if( !Out)
{
sprintf( ND_Error_Msg, "Error ND_Index_Value_Print : the stream descriptor is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
status = ND_Index_Value_Print_VI( Out, Root_Ptr, Index_Id, Recursive_Mode, Recursive_Depth, Recursive_Offset, user_args);
va_end( user_args);
return( status);
}
/*------------------------------------------------------------------------------*/
/* Affichage d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> afficher */
/* (I) Out : flux de sortie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Value_Print_VI( FILE *Out, NDT_Root *Root_Ptr, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset, va_list User_Args)
{
NDT_Status status;
status = ND_DataStruct_Traverse_I( Root_Ptr, NDD_CMD_VALUE_PRINT, Out, Recursive_Mode, Recursive_Depth, Recursive_Offset, User_Args);
return( status);
}
/*------------------------------------------------------------------------------*/
/* Affichage d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> afficher */
/* (I) Out : flux de sortie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Value_Print_I( FILE *Out, NDT_Root *Root_Ptr, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset, ...)
{
NDT_Status status;
va_list user_args;
va_start( user_args, Recursive_Offset);
status = ND_DataStruct_Traverse_I( Root_Ptr, NDD_CMD_VALUE_PRINT, Out, Recursive_Mode, Recursive_Depth, Recursive_Offset, user_args);
va_end( user_args);
return( status);
}
/*------------------------------------------------------------------------------*/
/* Affichage d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es <20> afficher */
/* (I) Out : flux de sortie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Value_Print_C( FILE *Out, NDT_Root *Root_Ptr, NDT_Recursive_Mode Recursive_Mode, NDT_Recursive_Depth Recursive_Depth, NDT_Recursive_Offset Recursive_Offset, ...)
{
NDT_Status status;
va_list user_args;
va_start( user_args, Recursive_Offset);
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Value_Print : structure root is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
if( !Out)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Value_Print : the stream descriptor is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
status = ND_DataStruct_Value_Print_VI( Out, Root_Ptr, Recursive_Mode, Recursive_Depth, Recursive_Offset, user_args);
va_end( user_args);
return( status);
}
/*------------------------------------------------------------------------------*/
/* Ajout d'un noeud <20> une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es */
/* (I) Node : pointeur sur le noeud <20> ajouter */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Node_Add_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr )
{
if( ND_INDEX_TYPE_LIST_IS( Root_Ptr, Index_Id)) return ND_List_Node_Add( Root_Ptr, Index_Id, Node_Ptr);
else if( ND_INDEX_TYPE_TREE_IS( Root_Ptr, Index_Id)) return ND_Tree_Node_Add( Root_Ptr, Index_Id, Node_Ptr);
else
{
sprintf (ND_Error_Msg, "Error ND_Index_Node_Add : unknown structure type (%d)", Root_Ptr->Index_Tab[Index_Id].Type);
ND_Error_Print ();
return(NDS_ERRAPI);
}
return(NDS_KO);
}
/*------------------------------------------------------------------------------*/
/* Ajout d'un noeud <20> une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es */
/* (I) Node : pointeur sur le noeud <20> ajouter */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Node_Add_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr)
{
if( !Root_Ptr)
{
sprintf (ND_Error_Msg, "Error ND_Index_Node_Add : structure root is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
if( !Node_Ptr)
{
sprintf (ND_Error_Msg, "Error ND_Index_Node_Add : the node to add is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
return ND_Index_Node_Add_I( Root_Ptr, Index_Id, Node_Ptr);
}
/*------------------------------------------------------------------------------*/
/* Suppression d'un noeud dans une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Node: pointeur sur le noeud <20> supprimer */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Node_Remove_I( NDT_Node *Node_Ptr)
{
NDT_Root *root_ptr;
NDT_Index_Id index_id;
root_ptr = Node_Ptr->Root;
index_id = Node_Ptr->Index;
if( ND_INDEX_TYPE_LIST_IS( root_ptr, index_id)) return ND_List_Node_Remove( Node_Ptr);
else if( ND_INDEX_TYPE_TREE_IS( root_ptr, index_id))
{
NDT_Node **tmp_ptr_ptr;
/* On r<>cup<75>re l'adresse du lien entre le noeud <20> supprimer et son p<>re */
if( Node_Ptr->Parent)
{
/* Cas g<>n<EFBFBD>ral */
if( Node_Ptr == Node_Ptr->Parent->Left) tmp_ptr_ptr = &(Node_Ptr->Parent->Left);
else tmp_ptr_ptr = &(Node_Ptr->Parent->Right);
}
else
{
/* Cas du noeud racine */
tmp_ptr_ptr = NULL;
}
if( Node_Ptr->Right)
{
NDT_Node *Right_Node_Ptr = Node_Ptr->Right;
NDT_Node *Left_Node_Ptr = Node_Ptr->Left;
NDT_Node *First_Node_Ptr;
/*
On sauve le fils gauche du noeud <20> supprimer dans un pointeur de
sauvegarde pour pouvoir le r<>cup<75>rer au cas o<> la proc<6F>dure serait
interrompue (recovery).
*/
root_ptr->Index_Tab[index_id].Save = Left_Node_Ptr;
/* On remplace le noeud supprim<69> par son sous-arbre droit */
if( !tmp_ptr_ptr) root_ptr->Index_Tab[index_id].Head = root_ptr->Index_Tab[index_id].Tail = Node_Ptr->Right;
else *tmp_ptr_ptr = Node_Ptr->Right;
Right_Node_Ptr->Parent = Node_Ptr->Parent;
/* On attache le sous-arbre gauche au premier noeud du sous-arbre droit */
if( root_ptr->Index_Tab[index_id].Save)
{
First_Node_Ptr = ND_Tree_Node_First_Recursive_Get(Right_Node_Ptr);
First_Node_Ptr->Left = root_ptr->Index_Tab[index_id].Save;
root_ptr->Index_Tab[index_id].Save->Parent = First_Node_Ptr;
root_ptr->Index_Tab[index_id].Save = NULL;
}
}
else
{
/* On remplace le noeud supprim<69> par son sous-arbre gauche */
if( !tmp_ptr_ptr) root_ptr->Index_Tab[index_id].Head = root_ptr->Index_Tab[index_id].Tail = Node_Ptr->Left;
else *tmp_ptr_ptr = Node_Ptr->Left;
if( Node_Ptr->Left) Node_Ptr->Left->Parent = Node_Ptr->Parent;
}
root_ptr->Index_Tab[index_id].Node_Number--;
/* Pas de mise <20> jour des informations de profondeur : trop co<63>teux */
Node_Ptr->Root = NULL;
Node_Ptr->Index = NDD_INDEX_UNKNOWN;
Node_Ptr->Left = NULL;
Node_Ptr->Right = NULL;
Node_Ptr->Parent = NULL;
}
else
{
sprintf (ND_Error_Msg, "Error ND_Index_Node_Remove : unknown structure type (%d)", root_ptr->Index_Tab[index_id].Type);
ND_Error_Print ();
return(NDS_ERRAPI);
}
return(NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Suppression d'un noeud dans une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Node: pointeur sur le noeud <20> supprimer */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Node_Remove_C( NDT_Node *Node_Ptr)
{
if( !Node_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Node_Remove : the node to remove is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
return ND_Index_Node_Remove_I( Node_Ptr);
}
/*------------------------------------------------------------------------------*/
/* R<>cup<75>ration du premier noeud d'une structure */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine dont on cherche le premier noeud */
/* (O) First_Node : adresse du pointeur sur le premier noeud */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Node_First_Get_I( NDT_Node **First_Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
{
*First_Node_Ptr_Ptr = NULL;
if( ND_INDEX_TYPE_LIST_IS(Root_Ptr, Index_Id)) *First_Node_Ptr_Ptr = (Root_Ptr->Index_Tab)[Index_Id].Head;
else if( ND_INDEX_TYPE_TREE_IS(Root_Ptr, Index_Id)) *First_Node_Ptr_Ptr = ND_Tree_Node_First_Recursive_Get( Root_Ptr->Index_Tab[Index_Id].Head);
// if(!*First_Node_Ptr_Ptr) return(NDS_KO);
return(NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* R<>cup<75>ration du premier noeud d'une structure */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine dont on cherche le premier noeud */
/* (O) First_Node : adresse du pointeur sur le premier noeud */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Node_First_Get_C( NDT_Node **First_Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Node_First_Get : structure root is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
return ND_Index_Node_First_Get_I( First_Node_Ptr_Ptr, Root_Ptr, Index_Id);
}
/*------------------------------------------------------------------------------*/
/* R<>cup<75>ration du dernier noeud d'une structure */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine dont on cherche le dernier noeud */
/* (O) Last_Node : adresse du pointeur sur le premier noeud */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Node_Last_Get_I ( NDT_Node **Last_Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
{
*Last_Node_Ptr_Ptr = NULL;
if( ND_INDEX_TYPE_LIST_IS(Root_Ptr, Index_Id)) *Last_Node_Ptr_Ptr = Root_Ptr->Index_Tab[Index_Id].Tail;
else if( ND_INDEX_TYPE_TREE_IS(Root_Ptr, Index_Id)) *Last_Node_Ptr_Ptr = ND_Tree_Node_Last_Recursive_Get( Root_Ptr->Index_Tab[Index_Id].Head);
// if(!*Last_Node_Ptr_Ptr) return(NDS_KO);
return(NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* R<>cup<75>ration du dernier noeud d'une structure */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine dont on cherche le dernier noeud */
/* (O) Last_Node : adresse du pointeur sur le premier noeud */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Node_Last_Get_C( NDT_Node **Last_Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Node_Last_Get : structure root is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
return ND_Index_Node_Last_Get_I( Last_Node_Ptr_Ptr, Root_Ptr, Index_Id);
}
/*------------------------------------------------------------------------------*/
/* R<>cup<75>ration du noeud suivant */
/*------------------------------------------------------------------------------*/
/* (I) Node : pointeur sur le noeud dont on cherche le suivant */
/* (O) Next_Node : adresse du pointeur sur le noeud suivant */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Node_Next_Get_I ( NDT_Node **Next_Node_Ptr_Ptr, NDT_Node *Node_Ptr)
{
if( ND_INDEX_TYPE_LIST_IS( Node_Ptr->Root, Node_Ptr->Index))
{
*Next_Node_Ptr_Ptr = Node_Ptr->Right;
}
else if( ND_INDEX_TYPE_TREE_IS( Node_Ptr->Root, Node_Ptr->Index))
{
if( !Node_Ptr->Right)
{
*Next_Node_Ptr_Ptr = ND_Tree_Parent_Next_Recursive_Get(Node_Ptr);
}
else
{
*Next_Node_Ptr_Ptr = ND_Tree_Node_First_Recursive_Get(Node_Ptr->Right);
}
}
// if(!*Next_Node_Ptr_Ptr) return(NDS_KO);
return(NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* R<>cup<75>ration du noeud suivant */
/*------------------------------------------------------------------------------*/
/* (I) Node : pointeur sur le noeud dont on cherche le suivant */
/* (O) Next_Node : adresse du pointeur sur le noeud suivant */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Node_Next_Get_C( NDT_Node **Next_Node_Ptr_Ptr, NDT_Node *Node_Ptr)
{
if( !Node_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Node_Next_Get : node is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
return ND_Index_Node_Next_Get_I( Next_Node_Ptr_Ptr, Node_Ptr);
}
/*------------------------------------------------------------------------------*/
/* R<>cup<75>ration du noeud pr<70>c<EFBFBD>dant */
/*------------------------------------------------------------------------------*/
/* (I) Node : pointeur sur le noeud dont on cherche le pr<70>c<EFBFBD>dant */
/* (O) Prev_Node : adresse du pointeur sur le noeud suivant */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Node_Previous_Get_I( NDT_Node **Prev_Node_Ptr_Ptr, NDT_Node *Node_Ptr)
{
if( ND_INDEX_TYPE_LIST_IS( Node_Ptr->Root, Node_Ptr->Index)) *Prev_Node_Ptr_Ptr = Node_Ptr->Left;
if( ND_INDEX_TYPE_TREE_IS( Node_Ptr->Root, Node_Ptr->Index))
{
if( !Node_Ptr->Left)
{
*Prev_Node_Ptr_Ptr = ND_Tree_Parent_Previous_Recursive_Get( Node_Ptr);
}
else
{
*Prev_Node_Ptr_Ptr = ND_Tree_Node_Last_Recursive_Get( Node_Ptr->Left);
}
}
// if( !*Prev_Node_Ptr_Ptr) return( NDS_KO);
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* R<>cup<75>ration du noeud pr<70>c<EFBFBD>dant */
/*------------------------------------------------------------------------------*/
/* (I) Node : pointeur sur le noeud dont on cherche le pr<70>c<EFBFBD>dant */
/* (O) Prev_Node : adresse du pointeur sur le noeud suivant */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Node_Previous_Get_C( NDT_Node **Prev_Node_Ptr_Ptr, NDT_Node *Node_Ptr)
{
if( !Node_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Node_Previous_Get : node is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
return ND_Index_Node_Previous_Get_I( Prev_Node_Ptr_Ptr, Node_Ptr);
}
/*------------------------------------------------------------------------------*/
/* Recherche un noeud <20> partir d'une valeur */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de l'abre */
/* (O) Node : adresse du pointeur sur le noeud <20> r<>cuperer */
/* (I) Value : pointeur sur la valeur <20> rechercher */
/* (I) Data : pointeur de donn<6E>es */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Node_Find_VI( NDT_Node **Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr, va_list Args)
{
if( ND_INDEX_TYPE_LIST_IS( Root_Ptr, Index_Id))
{
*Node_Ptr_Ptr = ND_List_Node_Find( Root_Ptr, Index_Id, Value_Ptr, Args);
}
else if ( ND_INDEX_TYPE_TREE_IS( Root_Ptr, Index_Id))
{
*Node_Ptr_Ptr = ND_Tree_Node_Find( Root_Ptr, Index_Id, Value_Ptr, Args);
}
else
{
sprintf (ND_Error_Msg, "Error ND_Index_Node_Find_VI: unknown structure type (%d)", Root_Ptr->Index_Tab[Index_Id].Type);
ND_Error_Print ();
}
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Recherche un noeud <20> partir d'une valeur */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de l'abre */
/* (O) Node : adresse du pointeur sur le noeud <20> r<>cuperer */
/* (I) Value : pointeur sur la valeur <20> rechercher */
/* (I) Data : pointeur de donn<6E>es */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Node_Find_VC( NDT_Node **Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr, va_list Args)
{
NDT_Status status;
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Node_Find_VC: structure root is null");
ND_Error_Print();
return( NDS_ERRAPI);
}
if( !Value_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Node_Find_VC: the value to find is null");
ND_Error_Print();
return( NDS_ERRAPI);
}
status = ND_Index_Node_Find_VI( Node_Ptr_Ptr, Root_Ptr, Index_Id, Value_Ptr, Args);
return( status);
}
/*------------------------------------------------------------------------------*/
/* Recherche un noeud <20> partir d'une valeur */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de l'abre */
/* (O) Node : adresse du pointeur sur le noeud <20> r<>cuperer */
/* (I) Value : pointeur sur la valeur <20> rechercher */
/* (I) Data : pointeur de donn<6E>es */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Node_Find_I( NDT_Node **Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr, ...)
{
va_list user_args;
va_start( user_args, Value_Ptr);
if( ND_INDEX_TYPE_LIST_IS( Root_Ptr, Index_Id))
{
*Node_Ptr_Ptr = ND_List_Node_Find( Root_Ptr, Index_Id, Value_Ptr, user_args);
}
else if ( ND_INDEX_TYPE_TREE_IS( Root_Ptr, Index_Id))
{
*Node_Ptr_Ptr = ND_Tree_Node_Find( Root_Ptr, Index_Id, Value_Ptr, user_args);
}
else
{
sprintf (ND_Error_Msg, "Error ND_Index_Node_Find_I: unknown structure type (%d)", Root_Ptr->Index_Tab[Index_Id].Type);
ND_Error_Print ();
}
va_end( user_args);
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Recherche un noeud <20> partir d'une valeur */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de l'abre */
/* (O) Node : adresse du pointeur sur le noeud <20> r<>cuperer */
/* (I) Value : pointeur sur la valeur <20> rechercher */
/* (I) Data : pointeur de donn<6E>es */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Node_Find_C( NDT_Node **Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr, ...)
{
NDT_Status status;
va_list user_args;
va_start( user_args, Value_Ptr);
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Node_Find_C: structure root is null");
ND_Error_Print();
return( NDS_ERRAPI);
}
if( !Value_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Index_Node_Find_C: the value to find is null");
ND_Error_Print();
return( NDS_ERRAPI);
}
status = ND_Index_Node_Find_VI( Node_Ptr_Ptr, Root_Ptr, Index_Id, Value_Ptr, user_args);
va_end( user_args);
return( status);
}
/*------------------------------------------------------------------------------*/
/* Recherche un noeud <20> partir d'une valeur */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de l'abre */
/* (O) Node : adresse du pointeur sur le noeud <20> r<>cuperer */
/* (I) Value : pointeur sur la valeur <20> rechercher */
/* (I) Data : pointeur de donn<6E>es */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Value_Find_VI( void **Value_Ptr_Ptr, NDT_Root *Root_Ptr, void *Ref_Value_Ptr, va_list Args)
{
NDT_Status status;
NDT_Index_Id new_index;
NDT_Command new_cmd;
NDT_Node *node_ptr;
status = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_UNKNOWN, NULL, NDD_CMD_INDEX_GET, &new_index, &new_cmd, NDD_CMD_VALUE_FIND, Ref_Value_Ptr);
if( ND_ERROR(status)) return( status);
status = ND_Index_Node_Find_VI( &node_ptr, Root_Ptr, new_index, Ref_Value_Ptr, Args);
if( ND_ERROR(status)) return( status);
if( node_ptr != NULL)
{
*Value_Ptr_Ptr = node_ptr->Value;
}
else
{
*Value_Ptr_Ptr = NULL;
}
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Recherche un noeud <20> partir d'une valeur */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de l'abre */
/* (O) Node : adresse du pointeur sur le noeud <20> r<>cuperer */
/* (I) Value : pointeur sur la valeur <20> rechercher */
/* (I) Data : pointeur de donn<6E>es */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Value_Find_VC( void **Value_Ptr_Ptr, NDT_Root *Root_Ptr, void *Ref_Value_Ptr, va_list Args)
{
NDT_Status status;
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Value_Find_VC: structure root is null");
ND_Error_Print();
return( NDS_ERRAPI);
}
if( !Ref_Value_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Value_Find_VC: the ref value to find is null");
ND_Error_Print();
return( NDS_ERRAPI);
}
status = ND_DataStruct_Value_Find_VI( Value_Ptr_Ptr, Root_Ptr, Ref_Value_Ptr, Args);
return( status);
}
/*------------------------------------------------------------------------------*/
/* Recherche un noeud <20> partir d'une valeur */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de l'abre */
/* (O) Node : adresse du pointeur sur le noeud <20> r<>cuperer */
/* (I) Value : pointeur sur la valeur <20> rechercher */
/* (I) Data : pointeur de donn<6E>es */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Value_Find_I( void **Value_Ptr_Ptr, NDT_Root *Root_Ptr, void *Ref_Value_Ptr, ...)
{
NDT_Status status;
va_list user_args;
NDT_Index_Id new_index;
NDT_Command new_cmd;
NDT_Node *node_ptr;
va_start( user_args, Ref_Value_Ptr);
status = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_PRIMARY, NULL, NDD_CMD_INDEX_GET, &new_index, &new_cmd, NDD_CMD_VALUE_FIND, Ref_Value_Ptr);
if( ND_ERROR(status)) return( status);
status = ND_Index_Node_Find_VI( &node_ptr, Root_Ptr, new_index, Ref_Value_Ptr, user_args);
if( ND_ERROR(status)) return( status);
if( node_ptr != NULL)
{
*Value_Ptr_Ptr = node_ptr->Value;
}
else
{
*Value_Ptr_Ptr = NULL;
}
va_end( user_args);
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Recherche un noeud <20> partir d'une valeur */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de l'abre */
/* (O) Node : adresse du pointeur sur le noeud <20> r<>cuperer */
/* (I) Value : pointeur sur la valeur <20> rechercher */
/* (I) Data : pointeur de donn<6E>es */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Value_Find_C( void **Value_Ptr_Ptr, NDT_Root *Root_Ptr, void *Ref_Value_Ptr, ...)
{
NDT_Status status;
va_list user_args;
va_start( user_args, Ref_Value_Ptr);
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Value_Find_C: structure root is null");
ND_Error_Print();
return( NDS_ERRAPI);
}
if( !Ref_Value_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_DataStruct_Value_Find_C: the ref value to find is null");
ND_Error_Print();
return( NDS_ERRAPI);
}
status = ND_DataStruct_Value_Find_VI( Value_Ptr_Ptr, Root_Ptr, Ref_Value_Ptr, user_args);
va_end( user_args);
return(status);
}
/*------------------------------------------------------------------------------*/
/* R<>cup<75>ration de la racine d'une structure */
/*------------------------------------------------------------------------------*/
/* (O) Root : adresse du pointeur sur la racine <20> r<>cup<75>rer */
/* (I) Node : pointeur sur le noeud dont on cherche la racine */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Node_Root_Get_I( NDT_Root **Root_Ptr_Ptr, NDT_Node *Node_Ptr)
{
*Root_Ptr_Ptr = Node_Ptr->Root;
return NDS_OK;
}
/*------------------------------------------------------------------------------*/
/* R<>cup<75>ration de la racine d'une structure */
/*------------------------------------------------------------------------------*/
/* (O) Root : adresse du pointeur sur la racine <20> r<>cup<75>rer */
/* (I) Node : pointeur sur le noeud dont on cherche la racine */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Node_Root_Get_C( NDT_Root **Root_Ptr_Ptr, NDT_Node *Node_Ptr )
{
if( !Node_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Node_Root_Get : node is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
return ND_Node_Root_Get_I( Root_Ptr_Ptr, Node_Ptr);
}
/*------------------------------------------------------------------------------*/
/* Allocation d'une valeur d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es */
/* (O) Value : adresse d'un pointeur sur la valeur <20> allouer */
/* (I) ... : arguments relatifs <20> l'allocation de la valeur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Value_Alloc_I( NDT_Root *Root_Ptr, void **Value_Ptr_Ptr, ...)
{
NDT_Status rc;
va_list user_args;
/* R<>cup<75>ration des arguments pour l'allocation de la valeur */
va_start( user_args, Value_Ptr_Ptr);
/* Appel du manager */
rc = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_UNKNOWN, NULL, NDD_CMD_VALUE_ALLOC, Value_Ptr_Ptr, user_args);
va_end( user_args);
return rc;
}
/*------------------------------------------------------------------------------*/
/* Allocation d'une valeur d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de donn<6E>es */
/* (O) Value : adresse d'un pointeur sur la valeur <20> allouer */
/* (I) ... : arguments relatifs <20> l'allocation de la valeur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Value_Alloc_C( NDT_Root *Root_Ptr, void **Value_Ptr_Ptr, ...)
{
NDT_Status rc;
va_list user_args;
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Value_Alloc : structure root is null");
ND_Error_Print();
return(NDS_ERRAPI);
}
/* R<>cup<75>ration des arguments pour l'allocation de la valeur */
va_start( user_args, Value_Ptr_Ptr);
/* Appel du manager */
rc = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_UNKNOWN, NULL, NDD_CMD_VALUE_ALLOC, Value_Ptr_Ptr, user_args);
va_end( user_args);
return( rc);
}
/*------------------------------------------------------------------------------*/
/* D<>sallocation d'une valeur d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root: pointeur sur la racine de la structure de donn<6E>es */
/* (I) Value: pointeur sur la valeur <20> d<>sallouer */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Value_Free_I( NDT_Root *Root_Ptr, void *Value_Ptr)
{
return ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_UNKNOWN, NULL, NDD_CMD_VALUE_FREE, Value_Ptr);
}
/*------------------------------------------------------------------------------*/
/* D<>sallocation d'une valeur d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root: pointeur sur la racine de la structure de donn<6E>es */
/* (I) Value: pointeur sur la valeur <20> d<>sallouer */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Value_Free_C( NDT_Root *Root_Ptr, void *Value_Ptr)
{
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Value_Free_C : structure root is null");
ND_Error_Print();
return( NDS_ERRAPI);
}
if( !Value_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Value_Free_C : the value to free is null");
ND_Error_Print();
return( NDS_ERRAPI);
}
/* Appel du manager */
return( ND_Value_Free_I( Root_Ptr, Value_Ptr));
}
/*------------------------------------------------------------------------------*/
/* Ex<45>cution d'une fonction Manager dont le nom est pass<73> en param<61>tre */
/*------------------------------------------------------------------------------*/
/* (I) Function : nom de la fonction manager <20> ex<65>cuter */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Manager_Exec_VI( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list Args)
{
NDT_Status status;
NDT_Manager *manager_ptr;
manager_ptr = Root_Ptr->Manager_Ptr; // Win32
status = manager_ptr( Root_Ptr, Index_Id, Node_Ptr, Command, Args);
return( status);
}
/*------------------------------------------------------------------------------*/
/* Ex<45>cution d'une fonction Manager dont le nom est pass<73> en param<61>tre */
/*------------------------------------------------------------------------------*/
/* (I) Function : nom de la fonction manager <20> ex<65>cuter */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Manager_Exec_VC( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list Args)
{
NDT_Status status;
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Manager_Exec_VC : structure root is null");
ND_Error_Print();
return( NDS_ERRAPI);
}
if( !Root_Ptr->Manager_Ptr || !*(Root_Ptr->Manager_Ptr))
{
sprintf( ND_Error_Msg, "Error ND_Manager_Exec_VC : undefined function name");
ND_Error_Print();
return( NDS_ERRAPI);
}
status = ND_Manager_Exec_VI( Root_Ptr, Index_Id, Node_Ptr, Command, Args);
return(status);
}
/*------------------------------------------------------------------------------*/
/* Ex<45>cution d'une fonction Manager dont le nom est pass<73> en param<61>tre */
/*------------------------------------------------------------------------------*/
/* (I) Function : nom de la fonction manager <20> ex<65>cuter */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Manager_Exec_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, ...)
{
NDT_Status status;
va_list args;
NDT_Manager *manager_ptr;
va_start( args, Command);
manager_ptr = Root_Ptr->Manager_Ptr; // Win32
status = manager_ptr( Root_Ptr, Index_Id, Node_Ptr, Command, args);
va_end( args);
return( status);
}
/*------------------------------------------------------------------------------*/
/* Ex<45>cution d'une fonction Manager dont le nom est pass<73> en param<61>tre */
/*------------------------------------------------------------------------------*/
/* (I) Function : nom de la fonction manager <20> ex<65>cuter */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Manager_Exec_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, ...)
{
NDT_Status status;
va_list args;
va_start( args, Command);
if( !Root_Ptr)
{
sprintf( ND_Error_Msg, "Error ND_Manager_Exec_C : structure root is null");
ND_Error_Print();
return( NDS_ERRAPI);
}
if( !Root_Ptr->Manager_Ptr || !*(Root_Ptr->Manager_Ptr))
{
sprintf( ND_Error_Msg, "Error ND_Manager_Exec_C : undefined function name");
ND_Error_Print();
return( NDS_ERRAPI);
}
status = ND_Manager_Exec_VI( Root_Ptr, Index_Id, Node_Ptr, Command, args);
va_end( args);
return(status);
}
/*------------------------------------------------------------------------------*/
/* Ex<45>cution d'une fonction d'allocation dont le nom est pass<73> en param<61>tre */
/*------------------------------------------------------------------------------*/
/* (I) Function : nom de la fonction <20> ex<65>cuter */
/* (O) Ptr : adresse d'un pointeur sur la zone <20> allouer */
/* (I) Size : taille de la zone <20> allouer */
/* (I) Data : donn<6E>es utilisateur utiles <20> l'allocateur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Allocator_Exec_I( NDT_Allocator *Function, void **Ptr_Ptr, size_t Size, void *Data_Ptr)
{
NDT_Allocator *allocator_ptr;
*Ptr_Ptr = NULL;
allocator_ptr = Function;
return allocator_ptr( Size, Ptr_Ptr, Data_Ptr);
}
/*------------------------------------------------------------------------------*/
/* Ex<45>cution d'une fonction d'allocation dont le nom est pass<73> en param<61>tre */
/*------------------------------------------------------------------------------*/
/* (I) Function : nom de la fonction <20> ex<65>cuter */
/* (O) Ptr : adresse d'un pointeur sur la zone <20> allouer */
/* (I) Size : taille de la zone <20> allouer */
/* (I) Data : donn<6E>es utilisateur utiles <20> l'allocateur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Allocator_Exec_C ( NDT_Allocator *Function, void **Ptr_Ptr, size_t Size, void *Data_Ptr)
{
NDT_Allocator *Allocator_Ptr;
*Ptr_Ptr = NULL;
if(!Function || !*Function)
{
sprintf( ND_Error_Msg, "Error ND_Allocator_Exec : undefined function name");
ND_Error_Print ();
return(NDS_ERRAPI);
}
Allocator_Ptr = Function;
if( !Allocator_Ptr) return(NDS_ERRAPI);
return( Allocator_Ptr (Size, Ptr_Ptr, Data_Ptr));
}
/*------------------------------------------------------------------------------*/
/* Ex<45>cution d'une fonction de d<>sallocation dont nom est pass<73> en param<61>tre */
/*------------------------------------------------------------------------------*/
/* (I) Function : nom de la fonction <20> ex<65>cuter */
/* (I) Ptr : adresse de la zone <20> d<>sallouer */
/* (I) Data : donn<6E>es utilisateur utiles <20> l'allocateur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Desallocator_Exec_I( NDT_Desallocator *Function, void *Ptr, void *Data_Ptr)
{
NDT_Desallocator *desallocator_ptr;
desallocator_ptr = Function;
return desallocator_ptr( Ptr, Data_Ptr);
}
/*------------------------------------------------------------------------------*/
/* Ex<45>cution d'une fonction de d<>sallocation dont nom est pass<73> en param<61>tre */
/*------------------------------------------------------------------------------*/
/* (I) Function : nom de la fonction <20> ex<65>cuter */
/* (I) Ptr : adresse de la zone <20> d<>sallouer */
/* (I) Data : donn<6E>es utilisateur utiles <20> l'allocateur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Desallocator_Exec_C( NDT_Desallocator *Function, void *Ptr, void *Data_Ptr)
{
NDT_Desallocator *desallocator_ptr;
if (!Function || !*Function)
{
sprintf (ND_Error_Msg, "Error ND_Desallocator_Exec : undefined function name");
ND_Error_Print ();
return NDS_ERRAPI;
}
desallocator_ptr = Function;
if( !desallocator_ptr) return( NDS_ERRAPI);
return desallocator_ptr( Ptr, Data_Ptr);
}
/*------------------------------------------------------------------------------*/
/* FONCTIONS SECURISEES (ND_MODE = 0) */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* FONCTIONS PRIVEES */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* Recherche d'un symbole */
/*------------------------------------------------------------------------------*/
void * ND_Symbol_Find ( const char * Symbol_Name )
{
struct Symbol * Symbol;
void * Ptr = NULL;
/* Recherche du symbole dans la table des symboles locale */
Symbol = Symbol_Table;
while (Symbol)
{
if (!strcmp (Symbol->Name, Symbol_Name)) return Symbol->Ptr;
else Symbol = Symbol->Next;
}
/* Si le symbole n'a pas <20>t<EFBFBD> trouv<75>e dans la table des symboles locale, on l'y ajoute */
// Ptr = dlsym (RTLD_DEFAULT, (const char *) Symbol_Name);
if (!Ptr)
{
sprintf (ND_Error_Msg, "Error ND_Symbol_Find : unable to find \"%s\"' in symbol table (%s)", Symbol_Name, NULL/*dlerror ()*/);
ND_Error_Print ();
return NULL;
}
Symbol = (struct Symbol *) malloc (sizeof (struct Symbol));
if (Symbol)
{
Symbol->Name = strdup (Symbol_Name);
Symbol->Ptr = Ptr;
Symbol->Next = Symbol_Table;
Symbol_Table = Symbol;
}
return Ptr;
}
/*------------------------------------------------------------------------------*/
/* Allocation d'un noeud */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure */
/* (O) Node : adresse du pointeur sur le nouveau noeud */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Node_Alloc( NDT_Root *Root_Ptr, NDT_Node **Node_Ptr_Ptr )
{
NDT_Status rc;
rc = ND_Allocator_Exec_I( Root_Ptr->Allocator_Ptr, (void **)Node_Ptr_Ptr, sizeof(NDT_Node), Root_Ptr->User);
if( ND_ERROR(rc)) return(rc);
(*Node_Ptr_Ptr)->Root = NULL;
(*Node_Ptr_Ptr)->Index = NDD_INDEX_UNKNOWN;
(*Node_Ptr_Ptr)->Parent = NULL;
(*Node_Ptr_Ptr)->Left = NULL;
(*Node_Ptr_Ptr)->Right = NULL;
(*Node_Ptr_Ptr)->Value = NULL;
return(NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* D<>sallocation d'un noeud */
/*------------------------------------------------------------------------------*/
/* (I) Root: pointeur sur la racine de la structure */
/* (I) Node : pointeur sur le noeud <20> d<>truire */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Node_Free ( NDT_Root *Root_Ptr, NDT_Node *Node_Ptr)
{
return ND_Desallocator_Exec_I( Root_Ptr->Desallocator_Ptr, Node_Ptr, Root_Ptr->User);
}
/*------------------------------------------------------------------------------*/
/* Cr<43>ation d'une nouvelle structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (O) Root: adresse d'un pointeur sur la racine de la nouvelle structure */
/* (I) Type: type de la structure.de donn<6E>es (liste ou arbre binaire) */
/* (I) Allocator: pointeur vers la fonction d'allocation */
/* (I) Desallocator: pointeur vers la fonction de d<>sallocation */
/* (I) Data : pointeur de donn<6E>es utiles <20> l'allocateur */
/* (I) Own_Value : indique si la structure est propri<72>taire de ses valeurs */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Index_Clear( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
{
Root_Ptr->Index_Tab[Index_Id].Type = NDD_INDEX_STATUS_UNKNOWN;
Root_Ptr->Index_Tab[Index_Id].Head = NULL;
Root_Ptr->Index_Tab[Index_Id].Tail = NULL;
Root_Ptr->Index_Tab[Index_Id].Save = NULL;
Root_Ptr->Index_Tab[Index_Id].Max_Dif = DEF_MAX_DIF;
Root_Ptr->Index_Tab[Index_Id].Node_Number = 0;
Root_Ptr->Index_Tab[Index_Id].Max_Depth = 0;
Root_Ptr->Index_Tab[Index_Id].Min_Depth = NDD_HUGE_LONG;
Root_Ptr->Index_Tab[Index_Id].Nb_Equ = 0;
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Allocation d'une racine de structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (O) New_Root: adresse du pointeur sur la nouvelle racine */
/* (I) Type: type de la structure de donn<6E>es */
/* (I) Allocator: pointeur vers la fonction d'allocation */
/* (I) Desallocator: pointeur vers la fonction de d<>sallocation */
/* (I) Data : pointeur de donn<6E>es utiles <20> l'allocateur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Node_Root_Alloc( NDT_Root **Root_Ptr_Ptr, NDT_Index_Nb Index_Nb, NDT_Index_Type *Type_Ptr, char *Manager_Name, NDT_Manager *Manager_Ptr, char *Allocator_Name, NDT_Allocator *Allocator_Ptr, char *Desallocator_Name, NDT_Desallocator *Desallocator_Ptr, short Own_Value, void *Data_Ptr)
{
NDT_Status status;
NDT_Index_Id index_id;
status = ND_Allocator_Exec_I( Allocator_Ptr, (void **)Root_Ptr_Ptr, ( sizeof (NDT_Root) + sizeof(NDT_Index) * (Index_Nb + 1)), Data_Ptr);
if( ND_ERROR(status)) return( status);
if( strlen(Manager_Name) > NDD_MANAGER_NAME_LEN_MAX) return( NDS_ERRAPI);
strcpy( (*Root_Ptr_Ptr)->Manager_Name, Manager_Name);
(*Root_Ptr_Ptr)->Manager_Ptr = Manager_Ptr;
if( strlen(Allocator_Name) > NDD_ALLOCATOR_NAME_LEN_MAX) return( NDS_ERRAPI);
strcpy( (*Root_Ptr_Ptr)->Allocator_Name, Allocator_Name);
(*Root_Ptr_Ptr)->Allocator_Ptr = Allocator_Ptr;
if( strlen(Desallocator_Name) > NDD_DESALLOCATOR_NAME_LEN_MAX) return( NDS_ERRAPI);
strcpy( (*Root_Ptr_Ptr)->Desallocator_Name, Desallocator_Name);
(*Root_Ptr_Ptr)->Desallocator_Ptr = Desallocator_Ptr;
(*Root_Ptr_Ptr)->Own_Value = Own_Value;
(*Root_Ptr_Ptr)->User = Data_Ptr;
(*Root_Ptr_Ptr)->Index_Nb = Index_Nb;
(*Root_Ptr_Ptr)->Index_Open_Count = 0;
for( index_id = 0; index_id < Index_Nb; index_id++)
{
if( ( Type_Ptr[index_id] & NDD_INDEX_STATUS_MSK) == NDD_INDEX_STATUS_OPENED)
{
status = ND_Index_Open_I( *Root_Ptr_Ptr, index_id, Type_Ptr[index_id]);
if( ND_ERROR( status)) return( status);
}
else
{
if( ( status = ND_Index_Clear( *Root_Ptr_Ptr, index_id)) != NDS_OK)
{
sprintf( ND_Error_Msg, "Error ND_Index_Open_I: Index cleaning error");
ND_Error_Print();
return( NDS_KO);
}
(*Root_Ptr_Ptr)->Index_Tab[index_id].Type = NDD_INDEX_STATUS_CLOSED;
}
}
return(NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* D<>sallocation de la racine d'une structure de donn<6E>e */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine <20> d<>truire */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Node_Root_Free( NDT_Root *Root_Ptr)
{
return ND_Desallocator_Exec_I( Root_Ptr->Desallocator_Ptr, Root_Ptr, Root_Ptr->User);
}
/*------------------------------------------------------------------------------*/
/* Ajout d'un noeud <20> une liste cha<68>n<EFBFBD>e */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la liste */
/* (I) New_Node : pointeur sur le noeud <20> ajouter */
/*------------------------------------------------------------------------------*/
NDT_Status ND_List_Node_Add( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *New_Node_Ptr)
{
/* Ajout dans une liste tri<72>e */
if( ND_INDEX_SUBTYPE_SORTED_IS( Root_Ptr, Index_Id))
{
NDT_Node *node_ptr;
NDT_Status rc;
New_Node_Ptr->Root = Root_Ptr;
New_Node_Ptr->Index = Index_Id;
New_Node_Ptr->Parent = New_Node_Ptr->Left = New_Node_Ptr->Right = NULL;
/*
Une liste tri<72>e peut <20>tre orient<6E>e de 2 mani<6E>res :
- FIFO : un noeud sera ins<6E>r<EFBFBD> APRES un noeud de m<>me valeur (par d<>faut)
- FILO : un noeud sera ins<6E>r<EFBFBD> AVANT un noeud de m<>me valeur
*/
if( ND_INDEX_SUBTYPE_LIFO_IS( Root_Ptr, Index_Id))
{
/* Pour une liste tri<72>e orient<6E>e FILO, on parcourt la liste en sens normal */
node_ptr = Root_Ptr->Index_Tab[Index_Id].Head;
while( node_ptr)
{
rc = ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_COMP, New_Node_Ptr->Value, node_ptr->Value, NULL);
if(rc == NDS_GREATER)
node_ptr = node_ptr->Right;
else
{
/* On ins<6E>re avant le noeud courant si le nouveau noeud est de valeur inf<6E>rieure ou <20>gale */
New_Node_Ptr->Left = node_ptr->Left;
New_Node_Ptr->Right = node_ptr;
if(!node_ptr->Left) Root_Ptr->Index_Tab[Index_Id].Head = New_Node_Ptr;
else node_ptr->Left->Right = New_Node_Ptr;
node_ptr->Left = New_Node_Ptr;
node_ptr = NULL;
}
}
/* Insertion en queue de liste si le noeud n'a pas <20>t<EFBFBD> ins<6E>r<EFBFBD> */
if(!New_Node_Ptr->Left && !New_Node_Ptr->Right)
{
if (!Root_Ptr->Index_Tab[Index_Id].Tail) Root_Ptr->Index_Tab[Index_Id].Head = Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr;
else
{
Root_Ptr->Index_Tab[Index_Id].Tail->Right = New_Node_Ptr;
New_Node_Ptr->Left = Root_Ptr->Index_Tab[Index_Id].Tail;
Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr;
}
}
}
else
{
/* Pour une liste tri<72>e orient<6E>e FIFO, on parcourt la liste dans le sens inverse */
node_ptr = Root_Ptr->Index_Tab[Index_Id].Tail;
while( node_ptr)
{
rc = ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_COMP, New_Node_Ptr->Value, node_ptr->Value, NULL);
/* On ins<6E>re apr<70>s le noeud courant si le nouveau noeud est de valeur strictement sup<75>rieure ou <20>gale */
if( rc == NDS_LOWER) node_ptr = node_ptr->Left;
else
{
New_Node_Ptr->Left = node_ptr;
New_Node_Ptr->Right = node_ptr->Right;
if( !node_ptr->Right) Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr;
else node_ptr->Right->Left = New_Node_Ptr;
node_ptr->Right = New_Node_Ptr;
node_ptr = NULL;
}
}
/* Insertion en t<>te de liste si le noeud n'a pas <20>t<EFBFBD> ins<6E>r<EFBFBD> */
if( !New_Node_Ptr->Left && !New_Node_Ptr->Right)
{
if( !Root_Ptr->Index_Tab[Index_Id].Head) Root_Ptr->Index_Tab[Index_Id].Head = Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr;
else
{
Root_Ptr->Index_Tab[Index_Id].Head->Left = New_Node_Ptr;
New_Node_Ptr->Right = Root_Ptr->Index_Tab[Index_Id].Head;
Root_Ptr->Index_Tab[Index_Id].Head = New_Node_Ptr;
}
}
}
Root_Ptr->Index_Tab[Index_Id].Node_Number++;
return( NDS_OK);
}
else
{
/* FIFO = ajout en queue de liste */
if( ND_INDEX_SUBTYPE_FIFO_IS( Root_Ptr, Index_Id))
{
New_Node_Ptr->Root = Root_Ptr;
New_Node_Ptr->Index = Index_Id;
New_Node_Ptr->Parent = NULL;
New_Node_Ptr->Left = Root_Ptr->Index_Tab[Index_Id].Tail;
New_Node_Ptr->Right = NULL;
if( !Root_Ptr->Index_Tab[Index_Id].Head) Root_Ptr->Index_Tab[Index_Id].Head = New_Node_Ptr;
else Root_Ptr->Index_Tab[Index_Id].Tail->Right = New_Node_Ptr;
Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr;
Root_Ptr->Index_Tab[Index_Id].Node_Number++;
return( NDS_OK);
}
/* FILO = ajout en t<>te de liste */
if( ND_INDEX_SUBTYPE_LIFO_IS( Root_Ptr, Index_Id))
{
New_Node_Ptr->Root = Root_Ptr;
New_Node_Ptr->Index = Index_Id;
New_Node_Ptr->Parent = NULL;
New_Node_Ptr->Left = NULL;
New_Node_Ptr->Right = Root_Ptr->Index_Tab[Index_Id].Head;
if( !Root_Ptr->Index_Tab[Index_Id].Tail) Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr;
else Root_Ptr->Index_Tab[Index_Id].Head->Left = New_Node_Ptr;
Root_Ptr->Index_Tab[Index_Id].Head = New_Node_Ptr;
Root_Ptr->Index_Tab[Index_Id].Node_Number++;
return( NDS_OK);
}
}
printf( "ND_List_Node_Add : unknown list type (%d)\n", Root_Ptr->Index_Tab[Index_Id].Type);
return(NDS_ERRAPI);
}
/*------------------------------------------------------------------------------*/
/* Ajout d'une nouvelle valeur <20> une liste */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la liste */
/* (I) Value : pointeur sur la valeur <20> ajouter */
/*------------------------------------------------------------------------------*/
NDT_Status ND_List_Value_Add( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr)
{
NDT_Status rc;
NDT_Node *node_ptr;
rc = ND_Node_Alloc( Root_Ptr, &node_ptr);
if( ND_ERROR(rc)) return(rc);
node_ptr->Value = Value_Ptr;
// return ND_List_Node_Add (Root, Node);
rc = ND_List_Node_Add( Root_Ptr, Index_Id, node_ptr);
if( ND_ERROR(rc))
{
return( rc);
}
else
{
return( ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_ADD, Value_Ptr, NULL));
}
}
/*------------------------------------------------------------------------------*/
/* Ajout d'un noeud <20> un arbre binaire */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de l'arbre */
/* (I) Value : pointeur sur la valeur <20> ajouter */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Tree_Value_Add( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr)
{
NDT_Status rc;
NDT_Node *node_ptr;
rc = ND_Node_Alloc( Root_Ptr, &node_ptr);
if( ND_ERROR(rc)) return(rc);
node_ptr->Value = Value_Ptr;
// return ND_Tree_Node_Add (Root, Node);
rc = ND_Tree_Node_Add( Root_Ptr, Index_Id, node_ptr);
if( ND_ERROR(rc))
{
return( rc);
}
else
{
return ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_ADD, Value_Ptr, NULL);
}
}
/*------------------------------------------------------------------------------*/
/* Recherche une valeur dans une liste et retourne le noeud correspondant */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la liste */
/* (I) Value : pointeur sur la valeur <20> rechercher */
/* (I) Data : pointeur de donn<6E>es */
/*------------------------------------------------------------------------------*/
NDT_Node *ND_List_Node_Find( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr, va_list User_Args)
{
NDT_Node *node_ptr;
NDT_Status rc;
node_ptr = Root_Ptr->Index_Tab[Index_Id].Head;
if( ND_INDEX_SUBTYPE_SORTED_IS( Root_Ptr, Index_Id))
{
/* Pour les listes tri<72>es, la recherche peut <20>tre optimis<69>e */
while( node_ptr)
{
rc = ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_COMP, Value_Ptr, node_ptr->Value, User_Args);
switch (rc)
{
case NDS_EQUAL:
{
return(node_ptr);
}
case NDS_LOWER:
{
/* Ce n'est pas a peine de continuer car on a d<>j<EFBFBD> d<>pass<73> la valeur recherch<63>e */
return(NULL);
}
case NDS_GREATER:
{
node_ptr = node_ptr->Right;
break;
}
}
}
}
else
{
/* Pour les listes non tri<72>es, il faut parcourir toute la liste */
while( node_ptr && ( ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_COMP, Value_Ptr, node_ptr->Value, User_Args) != NDS_EQUAL))
{
node_ptr = node_ptr->Right;
}
}
return node_ptr;
}
/*------------------------------------------------------------------------------*/
/* Recherche un noeud dans un arbre et retourne le pointeur sur le noeud */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de l'abre */
/* (I) Value : pointeur sur la valeur <20> rechercher */
/* (I) Data : pointeur de donn<6E>es */
/*------------------------------------------------------------------------------*/
/*------------------------------ Recursive Kernel ------------------------------*/
NDT_Node *ND_Tree_Node_Recursive_Find( NDT_Node *Node_Ptr, void *Value_Ptr, va_list User_Args)
{
NDT_Status answer;
if( !Node_Ptr) return(NULL);
answer = ND_Manager_Exec_I( Node_Ptr->Root, Node_Ptr->Index, Node_Ptr, NDD_CMD_VALUE_COMP, Value_Ptr, Node_Ptr->Value, User_Args);
/* Noeud trouv<75> */
if( answer == NDS_EQUAL) return(Node_Ptr);
/* Continuation de la recherche par appel r<>cursif */
if( answer == NDS_LOWER) return( ND_Tree_Node_Recursive_Find( Node_Ptr->Left, Value_Ptr, User_Args));
if( answer == NDS_GREATER) return( ND_Tree_Node_Recursive_Find( Node_Ptr->Right, Value_Ptr, User_Args));
return(NULL);
}
/*-------------------------------- main body ---------------------------------*/
NDT_Node *ND_Tree_Node_Find( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr, va_list User_Args)
{
return( ND_Tree_Node_Recursive_Find( Root_Ptr->Index_Tab[Index_Id].Head, Value_Ptr, User_Args));
}
/*------------------------------------------------------------------------------*/
/* Recherche du premier noeud parent situ<74> apr<70>s */
/*------------------------------------------------------------------------------*/
/* (I) Node : pointeur sur le noeud */
/*------------------------------------------------------------------------------*/
NDT_Node *ND_Tree_Parent_Next_Recursive_Get( NDT_Node *Node_Ptr)
{
if( !Node_Ptr->Parent) return( NULL);
if( Node_Ptr == Node_Ptr->Parent->Right) return( ND_Tree_Parent_Next_Recursive_Get( Node_Ptr->Parent));
return( Node_Ptr->Parent);
}
/*------------------------------------------------------------------------------*/
/* Recherche du premier noeud parent situ<74> avant */
/*------------------------------------------------------------------------------*/
/* (I) Node : pointeur sur le noeud */
/*------------------------------------------------------------------------------*/
NDT_Node *ND_Tree_Parent_Previous_Recursive_Get( NDT_Node *Node_Ptr)
{
if( !Node_Ptr->Parent) return( NULL);
if( Node_Ptr == Node_Ptr->Parent->Left) return( ND_Tree_Parent_Previous_Recursive_Get( Node_Ptr->Parent));
return( Node_Ptr->Parent);
}
/*------------------------------------------------------------------------------*/
/* Supprime le noeud d'une liste */
/*------------------------------------------------------------------------------*/
/* (I) Node : pointeur sur le noeud <20> supprimer */
/*------------------------------------------------------------------------------*/
NDT_Status ND_List_Node_Remove( NDT_Node *Node_Ptr)
{
if( !Node_Ptr->Left) Node_Ptr->Root->Index_Tab[Node_Ptr->Index].Head = Node_Ptr->Right;
else Node_Ptr->Left->Right = Node_Ptr->Right;
if( !Node_Ptr->Right) Node_Ptr->Root->Index_Tab[Node_Ptr->Index].Tail = Node_Ptr->Left;
else Node_Ptr->Right->Left = Node_Ptr->Left;
Node_Ptr->Root->Index_Tab[Node_Ptr->Index].Node_Number--;
Node_Ptr->Root = NULL;
Node_Ptr->Index = NDD_INDEX_UNKNOWN;
Node_Ptr->Left = NULL;
Node_Ptr->Right = NULL;
return( NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Conversion d'un arbre en liste cha<68>n<EFBFBD>e */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine du la structure <20> convertir */
/*------------------------------------------------------------------------------*/
/*------------------------------- Recursive Kernel -----------------------------*/
NDT_Status ND_List_Recursive_Make( NDT_Node *Node_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
{
NDT_Node *right_node_ptr;
if( !Node_Ptr) return NDS_OK;
if( ND_List_Recursive_Make( Node_Ptr->Left, Root_Ptr, Index_Id) != NDS_OK) return NDS_KO;
right_node_ptr = Node_Ptr->Right;
if( ND_List_Node_Add( Root_Ptr, Index_Id, Node_Ptr) != NDS_OK) return NDS_KO;
return ND_List_Recursive_Make( right_node_ptr, Root_Ptr, Index_Id);
}
/*--------------------------------- main body --------------------------------*/
NDT_Status ND_List_Make( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
{
NDT_Node *node_ptr;
node_ptr = Root_Ptr->Index_Tab[Index_Id].Head;
Root_Ptr->Index_Tab[Index_Id].Head = NULL;
Root_Ptr->Index_Tab[Index_Id].Tail = NULL;
Root_Ptr->Index_Tab[Index_Id].Max_Dif = DEF_MAX_DIF;
Root_Ptr->Index_Tab[Index_Id].Node_Number = 0;
Root_Ptr->Index_Tab[Index_Id].Max_Depth = 0;
Root_Ptr->Index_Tab[Index_Id].Min_Depth = NDD_HUGE_LONG;
Root_Ptr->Index_Tab[Index_Id].Nb_Equ = 0;
Root_Ptr->Index_Tab[Index_Id].Type = NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_FIFO;
return( ND_List_Recursive_Make( node_ptr, Root_Ptr, Index_Id));
}
/*------------------------------------------------------------------------------*/
/* Conversion d'une structure en arbre binaire */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine du la structure <20> convertir */
/* (I) Type : type du futur arbre */
/*------------------------------------------------------------------------------*/
/*------------------------------- Recursive Kernel -----------------------------*/
NDT_Node *ND_Tree_Recursive_Make( long Depth, long Node_Number, NDT_Node *Node_Ptr )
{
long middle_pos, left_len, right_len, i;
NDT_Node *left_node_ptr, *middle_node_ptr, *right_node_ptr;
if( !Node_Ptr) return (NULL);
/* On calcule le milieu de la liste */
middle_pos = Node_Number / 2 + 1;
middle_node_ptr = Node_Ptr;
for( i = 1; i < middle_pos; i++) middle_node_ptr = middle_node_ptr->Right;
/* On coupe la liste en deux */
if( middle_node_ptr->Left)
{
middle_node_ptr->Left->Right = NULL;
left_node_ptr = Node_Ptr;
left_len = middle_pos - 1;
}
else
{
left_node_ptr = NULL;
left_len = 0;
}
if( middle_node_ptr->Right)
{
middle_node_ptr->Right->Left = NULL;
right_node_ptr = middle_node_ptr->Right;
right_len = Node_Number - middle_pos;
}
else
{
right_node_ptr = NULL;
right_len = 0;
}
/* Construction des sous-arbres */
middle_node_ptr->Left = ND_Tree_Recursive_Make( Depth + 1, left_len, left_node_ptr);
middle_node_ptr->Right = ND_Tree_Recursive_Make( Depth + 1, right_len, right_node_ptr);
if( middle_node_ptr->Left) middle_node_ptr->Left->Parent = middle_node_ptr;
if( middle_node_ptr->Right) middle_node_ptr->Right->Parent = middle_node_ptr;
/* Mise <20> jour des informations statistiques de la structure */
middle_node_ptr->Root->Index_Tab[middle_node_ptr->Index].Node_Number++;
if( !middle_node_ptr->Left && !middle_node_ptr->Right)
{
/*
Si le noeud courant est une feuille, on met <20>ventuellement <20> jour
les longueurs minimale et maximale des branches de l'arbre
*/
if( Depth > middle_node_ptr->Root->Index_Tab[middle_node_ptr->Index].Max_Depth)
{
middle_node_ptr->Root->Index_Tab[middle_node_ptr->Index].Max_Depth = Depth;
}
if( Depth < middle_node_ptr->Root->Index_Tab[middle_node_ptr->Index].Min_Depth)
{
middle_node_ptr->Root->Index_Tab[middle_node_ptr->Index].Min_Depth = Depth;
}
}
return( middle_node_ptr);
}
/*--------------------------------- main body --------------------------------*/
NDT_Status ND_Tree_Make( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id )
{
NDT_Status rc;
NDT_Node *node_ptr;
long node_number;
if( ND_INDEX_SUBTYPE_SORTED_IS( Root_Ptr, Index_Id))
{
rc = ND_List_Sort( Root_Ptr, Index_Id);
if( ND_ERROR(rc)) return rc;
}
node_ptr = Root_Ptr->Index_Tab[Index_Id].Head;
node_number = Root_Ptr->Index_Tab[Index_Id].Node_Number;
Root_Ptr->Index_Tab[Index_Id].Head = NULL;
Root_Ptr->Index_Tab[Index_Id].Tail = NULL;
Root_Ptr->Index_Tab[Index_Id].Max_Dif = DEF_MAX_DIF;
Root_Ptr->Index_Tab[Index_Id].Node_Number = 0;
Root_Ptr->Index_Tab[Index_Id].Max_Depth = 0;
Root_Ptr->Index_Tab[Index_Id].Min_Depth = NDD_HUGE_LONG;
Root_Ptr->Index_Tab[Index_Id].Nb_Equ = 0;
Root_Ptr->Index_Tab[Index_Id].Type = NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_TREE | NDD_INDEX_SUBTYPE_BALANCED;
Root_Ptr->Index_Tab[Index_Id].Head = Root_Ptr->Index_Tab[Index_Id].Tail = ND_Tree_Recursive_Make( 1, node_number, node_ptr);
return NDS_OK;
}
/*----------------------------------------------------------------------------*/
/* Equilibrage d'un arbre binaire */
/*----------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de l'arbre */
/*----------------------------------------------------------------------------*/
NDT_Status ND_Tree_Equalize( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
{
NDT_Status rc;
NDT_Index_Type type;
// char manager[30]; // Win32
void *manager; // Win32
long max_dif, nb_equ;
type = Root_Ptr->Index_Tab[Index_Id].Type;
// strcpy( Manager, Root_Ptr->Manager); // Win32
manager = Root_Ptr->Manager_Ptr; // Win32
max_dif = Root_Ptr->Index_Tab[Index_Id].Max_Dif;
nb_equ = Root_Ptr->Index_Tab[Index_Id].Nb_Equ;
rc = ND_List_Make( Root_Ptr, Index_Id);
if( ND_ERROR(rc)) return(rc);
Root_Ptr->Index_Tab[Index_Id].Type = NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_SORTED;
rc = ND_Tree_Make( Root_Ptr, Index_Id);
if( ND_ERROR(rc)) return(rc);
Root_Ptr->Index_Tab[Index_Id].Type = type;
// strcpy( Root_Ptr->Manager, Manager); // Win32
Root_Ptr->Manager_Ptr = manager; // Win32
Root_Ptr->Index_Tab[Index_Id].Max_Dif = max_dif;
Root_Ptr->Index_Tab[Index_Id].Nb_Equ = nb_equ + 1;
return(NDS_OK);
}
/*----------------------------------------------------------------------------*/
/* Retourne la profondeur de la plus grande branche <20> partir d'un noeud */
/*----------------------------------------------------------------------------*/
/* (I) Node : pointeur sur le noeud */
/*----------------------------------------------------------------------------*/
long ND_Tree_MaxDepth_Get( NDT_Node *Node_Ptr)
{
long Max_Left, Max_Right;
if( !Node_Ptr) return ( 0);
Max_Left = ND_Tree_MaxDepth_Get( Node_Ptr->Left);
Max_Right = ND_Tree_MaxDepth_Get( Node_Ptr->Right);
return( NDD_MAX( Max_Left, Max_Right) + 1 );
}
/*----------------------------------------------------------------------------*/
/* Retourne la profondeur de la plus petite branche <20> partir d'un noeud */
/*----------------------------------------------------------------------------*/
/* (I) Node : pointeur sur le noeud */
/*----------------------------------------------------------------------------*/
long ND_Tree_MinDepth_Get( NDT_Node *Node_Ptr)
{
long Min_Left, Min_Right;
if( !Node_Ptr) return( 0);
Min_Left = ND_Tree_MinDepth_Get( Node_Ptr->Left);
Min_Right = ND_Tree_MinDepth_Get( Node_Ptr->Right);
return( NDD_MIN( Min_Left, Min_Right) + 1 );
}
/*----------------------------------------------------------------------------*/
/* Ajoute un noeud <20> un arbre */
/*----------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de l'arbre */
/* (I) Node : pointeur sur le noeud <20> ajouter */
/*----------------------------------------------------------------------------*/
/*------------------------------ Recursive Kernel ----------------------------*/
void ND_Tree_Node_Recursive_Add( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Parent_Node, NDT_Node **Node_Ptr_Ptr, long Depth, NDT_Node *New_Node_Ptr )
{
if( *Node_Ptr_Ptr)
{
/* Appel r<>cursif */
if( ND_Manager_Exec_I( Root_Ptr, Index_Id, (*Node_Ptr_Ptr), NDD_CMD_VALUE_COMP, New_Node_Ptr->Value, (*Node_Ptr_Ptr)->Value, NULL) == NDS_LOWER)
ND_Tree_Node_Recursive_Add( Root_Ptr, Index_Id, (*Node_Ptr_Ptr), &((*Node_Ptr_Ptr)->Left), Depth + 1, New_Node_Ptr);
else
ND_Tree_Node_Recursive_Add( Root_Ptr, Index_Id, (*Node_Ptr_Ptr), &((*Node_Ptr_Ptr)->Right), Depth + 1, New_Node_Ptr);
}
else
{
long Max_Depth, Min_Depth;
/* Rattachement du nouveau noeud <20> l'arbre */
New_Node_Ptr->Root = Root_Ptr;
New_Node_Ptr->Index = Index_Id;
New_Node_Ptr->Parent = Parent_Node;
*Node_Ptr_Ptr = New_Node_Ptr;
/* Mise <20> jour des informations statistiques de la structure */
Root_Ptr->Index_Tab[Index_Id].Node_Number++;
Max_Depth = ND_Tree_MaxDepth_Get( New_Node_Ptr);
Min_Depth = ND_Tree_MinDepth_Get( New_Node_Ptr);
if( Max_Depth + Depth - 1 > Root_Ptr->Index_Tab[Index_Id].Max_Depth) Root_Ptr->Index_Tab[Index_Id].Max_Depth = Max_Depth + Depth - 1;
if (Min_Depth + Depth - 1 < Root_Ptr->Index_Tab[0].Min_Depth) Root_Ptr->Index_Tab[0].Min_Depth = Min_Depth + Depth - 1 ;
}
}
/*-------------------------------- main body ---------------------------------*/
NDT_Status ND_Tree_Node_Add( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr)
{
ND_Tree_Node_Recursive_Add( Root_Ptr, Index_Id, NULL, &(Root_Ptr->Index_Tab[Index_Id].Head), 1, Node_Ptr);
if( ND_INDEX_SUBTYPE_BALANCED_IS( Root_Ptr, Index_Id) && Root_Ptr->Index_Tab[Index_Id].Max_Depth - Root_Ptr->Index_Tab[Index_Id].Min_Depth > Root_Ptr->Index_Tab[Index_Id].Max_Dif)
return ND_Tree_Equalize( Root_Ptr, Index_Id);
return NDS_OK;
}
/*------------------------------------------------------------------------------*/
/* Ajoute tous les noeud d'une liste <20> un arbre */
/*------------------------------------------------------------------------------*/
/* (I) Tree_Root : pointeur sur la racine de l'arbre */
/* (I) List_Root : pointeur sur la racine de la liste */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Tree_List_Add( NDT_Root *Tree_Root_Ptr, NDT_Index_Id Tree_Index_Id, NDT_Root *List_Root_Ptr, NDT_Index_Id List_Index_Id)
{
NDT_Status rc;
NDT_Node *node_ptr;
node_ptr = List_Root_Ptr->Index_Tab[List_Index_Id].Head;
while( node_ptr)
{
rc = ND_Tree_Node_Add( Tree_Root_Ptr, Tree_Index_Id, node_ptr);
if( ND_ERROR(rc)) return(rc);
node_ptr = node_ptr->Right;
}
return(NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Affiche toutes les informations d'une structure de donn<6E>es */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure */
/*------------------------------------------------------------------------------*/
/*------------------------------- Recursive Kernel -----------------------------*/
void ND_Tree_Recursive_Print( NDT_Node *Node_Ptr, long Depth, FILE *Out)
{
const int BRANCH_LEN = 4;
if( !Node_Ptr) return;
if( Node_Ptr->Right)
{
ND_Tree_Recursive_Print( Node_Ptr->Right, Depth + 1, Out);
fprintf( Out, "%*s/\n", (int)(Depth * BRANCH_LEN - 1), "");
}
fprintf( Out, "%*s (%p) ", (int)((Depth - 1) * BRANCH_LEN), "", Node_Ptr);
/* Affichage des toutes les informations (noeud et valeur) :
if (Node->Root) fprintf (Out, "Root=%p ", Node->Root);
if (Node->Parent) fprintf (Out, "Parent=%p ", Node->Parent);
if (Node->Left) fprintf (Out, "Left=%p ", Node->Left);
if (Node->Right) fprintf (Out, "Right=%p ", Node->Right);
fprintf (Out, "Value=[");
ND_Manager_Exec (Node->Root->Manager, NDD_CMD_PRINT_VALUE, Node->Value, Out);
fprintf (Out, "]\n");
*/
/* Affichage de la valeur seule : */
ND_Manager_Exec_I( Node_Ptr->Root, Node_Ptr->Index, Node_Ptr, NDD_CMD_VALUE_PRINT, Node_Ptr->Value, Out, NULL);
fprintf( Out, "\n");
if( Node_Ptr->Left)
{
fprintf( Out, "%*s\\\n", (int)(Depth * BRANCH_LEN - 1), "");
ND_Tree_Recursive_Print( Node_Ptr->Left, Depth + 1, Out);
}
}
/*------------------------------------------------------------------------------*/
/* Function de comparaison de noeuds (pour le quick sort) */
/*------------------------------------------------------------------------------*/
int ND_Node_Compare( void **Node1_Ptr_Ptr, void **Node2_Ptr_Ptr)
{
NDT_Status rc;
// rc = ND_Manager_Exec_I( Tmp_Root->Manager, NDD_CMD_COMP_VALUE_COMP, ((NDT_Node *)(*Node1))->Value, ((NDT_Node *)(*Node2))->Value);
rc = ND_Manager_Exec_I( ((NDT_Node *)(*Node1_Ptr_Ptr))->Root, ((NDT_Node *)(*Node1_Ptr_Ptr))->Index, *Node1_Ptr_Ptr, NDD_CMD_VALUE_COMP, ((NDT_Node *)(*Node1_Ptr_Ptr))->Value, ((NDT_Node *)(*Node2_Ptr_Ptr))->Value, NULL);
switch( (int)rc)
{
case NDS_EQUAL: return 0;
case NDS_LOWER: return -1;
case NDS_GREATER: return 1;
default:
sprintf( ND_Error_Msg, "Error ND_Node_Compare : incorrect return code from the manager: %d", rc);
ND_Error_Print ();
return 0;
}
}
/*----------------------------------------------------------------------------*/
/* Ordonne une liste cha<68>n<EFBFBD>e : */
/*----------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la liste <20> trier */
/*----------------------------------------------------------------------------*/
NDT_Status ND_List_Sort( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id)
{
int i;
NDT_Node *node_ptr;
void **tab;
if( Root_Ptr->Index_Tab[Index_Id].Node_Number < 2) return NDS_OK;
/* Allocation d'un tableau de pointeur de noeuds */
tab = (void **)malloc( Root_Ptr->Index_Tab[Index_Id].Node_Number * sizeof( NDT_Node *));
/* On remplit le tableau avec les noeuds de la structure <20> trier */
i = 0;
node_ptr = Root_Ptr->Index_Tab[Index_Id].Head;
while( node_ptr)
{
tab[i] = node_ptr;
node_ptr = node_ptr->Right;
i++;
}
/* Tri du tableau de pointeurs de noeuds */
// Tmp_Root = Root;
// qsort( (void *)tab, (size_t)(Root_Ptr->Index_Tab[Index_Id].Node_Number), sizeof(NDT_Node *), (int (__cdecl *)(const void *, const void *))&ND_Node_Compare);
qsort( (void *)tab, (size_t)(Root_Ptr->Index_Tab[Index_Id].Node_Number), sizeof(NDT_Node *), (int (*)(const void *, const void *))&ND_Node_Compare);
/* On met <20> jour les liens entre les noeuds */
for (i = 0; i < Root_Ptr->Index_Tab[0].Node_Number; i++)
{
node_ptr = (NDT_Node *)tab[i];
node_ptr->Left = (i ? (NDT_Node *)(tab[i - 1]) : NULL);
node_ptr->Right = (i != Root_Ptr->Index_Tab[Index_Id].Node_Number - 1 ? (NDT_Node *)(tab[i + 1]) : NULL);
}
Root_Ptr->Index_Tab[Index_Id].Head = (NDT_Node *)(tab[0]);
Root_Ptr->Index_Tab[Index_Id].Tail = (NDT_Node *)(tab[Root_Ptr->Index_Tab[Index_Id].Node_Number - 1]);
/* D<>sallocation du tableau */
free(tab);
return(NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* R<>cup<75>re le premier noeud dans un sous-arbre */
/*------------------------------------------------------------------------------*/
/* (I) Node : pointeur sur le noeud racine du sous-arbre */
/*------------------------------------------------------------------------------*/
NDT_Node *ND_Tree_Node_First_Recursive_Get( NDT_Node *Node_Ptr)
{
if( !Node_Ptr) return NULL;
if( !Node_Ptr->Left) return(Node_Ptr);
return( ND_Tree_Node_First_Recursive_Get( Node_Ptr->Left));
}
/*------------------------------------------------------------------------------*/
/* R<>cup<75>re le dernier noeud dans un sous-arbre */
/*------------------------------------------------------------------------------*/
/* (I) Node : pointeur sur le noeud racine du sous-arbre */
/*------------------------------------------------------------------------------*/
NDT_Node *ND_Tree_Node_Last_Recursive_Get( NDT_Node *Node_Ptr)
{
if( !Node_Ptr) return NULL;
if( !Node_Ptr->Right) return(Node_Ptr);
return ND_Tree_Node_Last_Recursive_Get( Node_Ptr->Right);
}
/*------------------------------------------------------------------------------*/
/* Red<65>finition de la fonction malloc () avec retour de type NDT_Status */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Default_Allocator( size_t Size, void **Ptr_Ptr, void *Data_Ptr)
{
*Ptr_Ptr = malloc(Size);
if( !*Ptr_Ptr) return(NDS_ERRMEM);
return(NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Red<65>finition de la fonction free () avec retour de type NDT_Status */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Default_Desallocator( void *Ptr, void *Data_Ptr)
{
if( !Ptr) return(NDS_ERRAPI);
free( Ptr);
return(NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Function de v<>rification d'une liste : */
/*------------------------------------------------------------------------------*/
void ND_List_Check( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out)
{
/* On v<>rifie les liens entre les noeuds */
ND_List_Link_Check( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out);
/* On v<>rifie les valeurs des noeuds */
ND_Value_Check( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out);
}
/*------------------------------------------------------------------------------*/
/* Function de v<>rification et correction des liens entre noeuds d'une liste */
/*------------------------------------------------------------------------------*/
void ND_List_Link_Check( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out)
{
NDT_Node *node_ptr;
int left2right_node_number = 0;
int right2left_node_number = 0;
/*
On commence <20> v<>rifier si l'on trouve le m<>me nombre de noeuds
en parcourant la liste de droite <20> gauche, puis de gauche <20> droite
*/
node_ptr = Root_Ptr->Index_Tab[Index_Id].Head;
while( node_ptr)
{
left2right_node_number++;
node_ptr = node_ptr->Right;
}
node_ptr = Root_Ptr->Index_Tab[Index_Id].Tail;
while( node_ptr)
{
right2left_node_number++;
node_ptr = node_ptr->Left;
}
/* Cas o<> tout est OK */
if( left2right_node_number == Root_Ptr->Index_Tab[Index_Id].Node_Number && left2right_node_number == right2left_node_number) return;
/* Cas o<> le nombre de noeuds n'a simplement pas <20>t<EFBFBD> mis <20> jour au niveau de la racine */
if( left2right_node_number == right2left_node_number)
{
Root_Ptr->Index_Tab[Index_Id].Node_Number = left2right_node_number;
fprintf( Out, "\t- number of node has been corrected on structure %p:%d\n", Root_Ptr, Index_Id);
(*Nb_Detected_Ptr)++;
(*Nb_Corrected_Ptr)++;
return;
}
/* Cas o<> le parcours de gauche <20> droite est plus complet : il manque un lien 'Left' */
if( left2right_node_number > right2left_node_number)
{
node_ptr = Root_Ptr->Index_Tab[Index_Id].Head;
while( node_ptr)
{
if( node_ptr->Right && ( node_ptr->Right->Left != node_ptr))
{
fprintf( Out, "\t- link 'Left' has been corrected on node %p of structure %p:%d\n", node_ptr->Right, Root_Ptr, Index_Id);
node_ptr->Right->Left = node_ptr;
(*Nb_Detected_Ptr)++;
(*Nb_Corrected_Ptr)++;
}
if( !node_ptr->Right && ( node_ptr != Root_Ptr->Index_Tab[Index_Id].Tail))
{
fprintf( Out, "\t- link 'Tail' has been corrected on structure %p:%d\n", Root_Ptr, Index_Id);
Root_Ptr->Index_Tab[Index_Id].Tail = node_ptr;
(*Nb_Detected_Ptr)++;
(*Nb_Corrected_Ptr)++;
}
node_ptr = node_ptr->Right;
}
if( Root_Ptr->Index_Tab[Index_Id].Node_Number != left2right_node_number)
{
fprintf( Out, "\t- number of node has been corrected on structure %p:%d\n", Root_Ptr, Index_Id);
Root_Ptr->Index_Tab[Index_Id].Node_Number = left2right_node_number;
(*Nb_Detected_Ptr)++;
(*Nb_Corrected_Ptr)++;
}
return;
}
/* Cas o<> le parcours de droite <20> gauche est plus complet : il manque un lien 'Right' */
if( right2left_node_number > left2right_node_number)
{
node_ptr = Root_Ptr->Index_Tab[Index_Id].Tail;
while( node_ptr)
{
if( node_ptr->Left && ( node_ptr->Left->Right != node_ptr))
{
fprintf( Out, "\t- link 'Right' has been corrected on node %p of list %p:%d\n", node_ptr->Left, Root_Ptr, Index_Id);
node_ptr->Left->Right = node_ptr;
(*Nb_Detected_Ptr)++;
(*Nb_Corrected_Ptr)++;
}
if( !node_ptr->Left && ( node_ptr != Root_Ptr->Index_Tab[Index_Id].Head))
{
fprintf( Out, "\t- link 'Head' has been corrected on the structure root %p:%d\n", Root_Ptr, Index_Id);
Root_Ptr->Index_Tab[Index_Id].Head = node_ptr;
(*Nb_Detected_Ptr)++;
(*Nb_Corrected_Ptr)++;
}
node_ptr = node_ptr->Left;
}
if( Root_Ptr->Index_Tab[Index_Id].Node_Number != right2left_node_number)
{
fprintf( Out, "\t- number of node has been corrected on structure %p:%d\n", Root_Ptr, Index_Id);
Root_Ptr->Index_Tab[Index_Id].Node_Number = right2left_node_number;
(*Nb_Detected_Ptr)++;
(*Nb_Corrected_Ptr)++;
}
}
}
/*------------------------------------------------------------------------------*/
/* Function de v<>rification des valeurs des noeuds d'une liste */
/*------------------------------------------------------------------------------*/
void ND_Value_Check( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected, int *Nb_Corrected, FILE *Out)
{
NDT_Node *node_ptr, *next_node_ptr;
/* Chaque noeud sans valeur est purement et simplement supprim<69> de la liste */
ND_Index_Node_First_Get_I( &node_ptr, Root_Ptr, Index_Id);
while( node_ptr)
{
ND_Index_Node_Next_Get_I( &next_node_ptr, node_ptr);
if( !node_ptr->Value)
{
fprintf( Out, "\t- node %p has been removed from structure %p:%d because no value is attached to it\n", node_ptr, Root_Ptr, Index_Id);
ND_Index_Node_Remove( node_ptr);
node_ptr = next_node_ptr;
(*Nb_Detected)++;
(*Nb_Corrected)++;
}
else if( ND_Address_Check( node_ptr->Value) != NDS_OK)
{
fprintf (Out, "\t- node %p has been removed from structure %p:%d because its value cannot be accessed\n", node_ptr, Root_Ptr, Index_Id);
ND_Index_Node_Remove( node_ptr);
node_ptr = next_node_ptr;
(*Nb_Detected)++;
(*Nb_Corrected)++;
}
else ND_Index_Node_Next_Get( &node_ptr, node_ptr);
}
}
/*------------------------------------------------------------------------------*/
/* Function de v<>rification d'un arbre : */
/*------------------------------------------------------------------------------*/
void ND_Tree_Check( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out)
{
/* On v<>rifie les liens entre les noeuds */
ND_Tree_Link_Check( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out);
/* On v<>rifie les valeurs attach<63>es aux noeuds */
ND_Value_Check( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out);
/* On met <20> jour les informations statistiques de la racine */
Root_Ptr->Index_Tab[Index_Id].Max_Depth = ND_Tree_MaxDepth_Get( Root_Ptr->Index_Tab[Index_Id].Head);
Root_Ptr->Index_Tab[Index_Id].Min_Depth = ND_Tree_MaxDepth_Get( Root_Ptr->Index_Tab[Index_Id].Head);
}
/*------------------------------------------------------------------------------*/
/* Function de v<>rification et correction des liens entre noeuds d'un arbre */
/*------------------------------------------------------------------------------*/
void ND_Tree_Link_Check( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out)
{
/* On v<>rifie les liens 'Parent' et les liens 'Root' de chaque noeud */
if( Root_Ptr->Index_Tab[Index_Id].Head)
{
if( Root_Ptr->Index_Tab[Index_Id].Head->Root != Root_Ptr)
{
Root_Ptr->Index_Tab[Index_Id].Head->Root = Root_Ptr;
fprintf( Out, "\t- link 'Root' has been corrected on node %p of structure %p:%d\n", Root_Ptr->Index_Tab[Index_Id].Head, Root_Ptr, Index_Id);
(*Nb_Detected_Ptr)++;
(*Nb_Corrected_Ptr)++;
}
ND_Tree_Link_Recursive_Check( Root_Ptr->Index_Tab[Index_Id].Head, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out);
}
/*
On v<>rifie si le lien 'Save' contient un noeud (cela signifie
que la proc<6F>dure ND_Node_Remove n'a pas <20>t<EFBFBD> jusqu'<27> son terme).
*/
if( Root_Ptr->Index_Tab[Index_Id].Save)
{
NDT_Node *node_ptr;
/* On attache le noeud contenu dans 'Save' <20> l'arbre s'il n'existe pas d<>j<EFBFBD> */
if( ND_Index_Node_Find( &node_ptr, Root_Ptr, Index_Id, Root_Ptr->Index_Tab[Index_Id].Save->Value, NULL) != NDS_OK)
{
ND_Index_Node_Add( Root_Ptr, Index_Id, Root_Ptr->Index_Tab[Index_Id].Save);
fprintf( Out, "\t- saved node %p has been restored to structure %p:%d\n", Root_Ptr->Index_Tab[Index_Id].Save, Root_Ptr, Index_Id);
(*Nb_Detected_Ptr)++;
(*Nb_Corrected_Ptr)++;
}
Root_Ptr->Index_Tab[Index_Id].Save = NULL;
}
}
/*------------------------------ Recursive Kernel ------------------------------*/
void ND_Tree_Link_Recursive_Check( NDT_Node *Node_Ptr, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out)
{
if( Node_Ptr->Left)
{
if( Node_Ptr->Left->Root != Node_Ptr->Root)
{
Node_Ptr->Left->Root = Node_Ptr->Root;
fprintf( Out, "\t- link 'Root' has been corrected on node %p of structure %p:%d\n", Node_Ptr->Left, Node_Ptr->Root, Node_Ptr->Index);
(*Nb_Detected_Ptr)++;
(*Nb_Corrected_Ptr)++;
}
if( Node_Ptr->Left->Parent != Node_Ptr)
{
Node_Ptr->Left->Parent = Node_Ptr;
fprintf( Out, "\t- link 'Parent' has been corrected on node %p of structure %p:%d\n", Node_Ptr->Left, Node_Ptr->Root, Node_Ptr->Index);
(*Nb_Detected_Ptr)++;
(*Nb_Corrected_Ptr)++;
}
/* Appel r<>cursif */
ND_Tree_Link_Recursive_Check( Node_Ptr->Left, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out);
}
if( Node_Ptr->Right)
{
if( Node_Ptr->Right->Root != Node_Ptr->Root)
{
Node_Ptr->Right->Root = Node_Ptr->Root;
fprintf( Out, "\t- link 'Root' has been corrected on node %p of structure %p:%d\n", Node_Ptr->Right, Node_Ptr->Root, Node_Ptr->Index);
(*Nb_Detected_Ptr)++;
(*Nb_Corrected_Ptr)++;
}
if( Node_Ptr->Right->Parent != Node_Ptr)
{
Node_Ptr->Right->Parent = Node_Ptr;
fprintf( Out, "\t- link 'Parent' has been corrected on node %p of structure %p:%d\n", Node_Ptr->Right, Node_Ptr->Root, Node_Ptr->Index);
(*Nb_Detected_Ptr)++;
(*Nb_Corrected_Ptr)++;
}
/* Appel r<>cursif */
ND_Tree_Link_Recursive_Check( Node_Ptr->Right, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out);
}
}
/*------------------------------------------------------------------------------*/
/* V<>rifie qu'une adresse est valide */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Address_Check( void *Address)
{
int test;
Sig_Trapped = 0;
/* On trappe les signaux SIGBUS et SIGSEGV */
// signal (SIGBUS, ND_Signal_Trap); Win32
// signal (SIGSEGV, ND_Signal_Trap); Win32
/* On tente d'acc<63>der <20> l'adresse fournie */
test = *( (int *)Address);
// sigrelse (SIGBUS); Win32
// sigrelse (SIGSEGV); Win32
if( Sig_Trapped != 0) return(NDS_KO);
return(NDS_OK);
}
/*------------------------------------------------------------------------------*/
/* Trap d'un signal */
/*------------------------------------------------------------------------------*/
void ND_Signal_Trap( int Sig_Num)
{
Sig_Trapped = Sig_Num;
}
/*------------------------------------------------------------------------------*/
/* Routine d'affichage d'un message d'erreur */
/*------------------------------------------------------------------------------*/
void ND_Error_Print( void)
{
if( ND_stderr) fprintf( ND_stderr, "%s\n", ND_Error_Msg);
}