From 89295b4091973a4097d2f6808dfdf4c6675c8e0a Mon Sep 17 00:00:00 2001 From: agibert Date: Mon, 26 Nov 2001 10:17:43 +0000 Subject: [PATCH] Merge win32 branche (1.1.2.37) with main trunc ! --- lib/libnode.c | 4980 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 3554 insertions(+), 1426 deletions(-) diff --git a/lib/libnode.c b/lib/libnode.c index 2adfd7f..93434ec 100644 --- a/lib/libnode.c +++ b/lib/libnode.c @@ -1,89 +1,335 @@ +/*---------------------------------------------------------------------------------*/ +/* $RCSfile: libnode.c,v $ */ +/*---------------------------------------------------------------------------------*/ +/* $Revision: 1.2 $ */ +/* $Name: $ */ +/* $Date: 2001/11/26 10:17:43 $ */ +/* $Author: agibert $ */ +/*---------------------------------------------------------------------------------*/ + + + #include -VER_INFO_EXPORT (libnode,"$Revision: 1.1 $", "$Name: $",__FILE__,"$Author: smas $") +#ifdef _LIBVER +VER_INFO_EXPORT (libnode,"$Revision: 1.2 $", "$Name: $",__FILE__,"$Author: agibert $") +#endif + + + + + + + /*------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------*/ -/* MODELE DE FONCTION MANAGER */ +/* Node Manager Template */ /*------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------*/ -NDT_Status Default_Manager ( va_list Args ) +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 Command; - const char * Command_Name; + NDT_Command_Name Command_Name; - Command = (NDT_Command) va_arg (Args, NDT_Command); - if (Command == NDD_CMD_MAKE_VALUE) + switch( Command) { - /* - NDT_Root * Root = va_arg (Args, NDT_Root *); - void ** Value = va_arg (Args, void **); - va_list Value_Args = va_arg (Args, va_list); - ... = va_arg (Value_Args, ...); - */ + case NDD_CMD_MANAGER_VERSION: + { + NDT_Version_Name *Version_Name_Ptr = (NDT_Version_Name *)va_arg( Args, NDT_Version_Name *); - Command_Name = "NDD_CMD_MAKE_VALUE"; - } - else if (Command == NDD_CMD_SUM_VALUES) - { - /* - void * Value = va_arg (Args, void *); - int * Total = va_arg (Args, int *); - */ - Command_Name = "NDD_CMD_SUM_VALUES"; - } - else if (Command == NDD_CMD_COMP_VALUE) - { - /* - void * Value1 = va_arg (Args, void *); - void * Value2 = va_arg (Args, void *); - */ + Command_Name = "NDD_CMD_MANAGER_VERSION"; - Command_Name = "NDD_CMD_COMP_VALUE"; - } - else if (Command == NDD_CMD_PRINT_VALUE) - { - /* - void * Value = va_arg (Args, void *); - FILE * Out = va_arg (Args, FILE *); - */ + *Version_Name_Ptr = "$Revision: 1.2 $ $Name: $ $Date: 2001/11/26 10:17:43 $ $Author: agibert $"; - Command_Name = "NDD_CMD_PRINT_VALUE"; - } - else if (Command == NDD_CMD_DELETE_VALUE) - { - /* - void * Value = va_arg (Args, void *); - */ + return( NDS_OK); + } - Command_Name = "NDD_CMD_DELETE_VALUE"; - } - else if (Command == NDD_CMD_PRINT_INFO) - { - /* - NDT_Root * Root = va_arg (Args, NDT_Root *); - FILE * Out = va_arg (Args, FILE *); - */ + 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_PRINT_INFO"; - } - else - { - sprintf (ND_Error_Msg, "Calling default manager with an undefined command %d\n", Command); - ND_Error_Print (); - return NDS_ERRAPI; + 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); + } } - sprintf (ND_Error_Msg, "Calling default manager with command %d (%s)\n", Command, Command_Name); - ND_Error_Print (); - - return NDS_OK; + printf( "Default_Manager() called with command %d (%s)\n", Command, Command_Name); + return(NDS_OK); } + + + + + + /*------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------*/ /* FONCTIONS PUBLIQUES */ @@ -94,23 +340,47 @@ NDT_Status Default_Manager ( va_list Args ) /* FONCTIONS OPTIMISEES (ND_MODE = 1) */ /*------------------------------------------------------------------------------*/ + + + + /*------------------------------------------------------------------------------*/ /* Initialisation du contexte de la librairie */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Library_Open_I ( int Debug_Mode ) -{ - if (Debug_Mode == TRUE) ND_Library_Stderr_Set_I (stderr); - return NDS_OK; +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 ) + +NDT_Status ND_Library_Close_I( void) { struct Symbol * Symbol, * Next_Symbol; + /* Désallocation de la table des symboles locale */ Symbol = Symbol_Table; @@ -128,17 +398,54 @@ NDT_Status ND_Library_Close_I ( void ) 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 ) + +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éation d'une nouvelle structure de données */ /*------------------------------------------------------------------------------*/ @@ -149,228 +456,411 @@ NDT_Status ND_Library_Stderr_Set_I ( FILE * Out ) /* (I) Data : pointeur de données utiles à l'allocateur */ /* (I) Own_Value : indique si la structure est propriétaire de ses valeurs */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Open_I ( NDT_Root ** Root, NDT_DataStruct_Type Type, const char * Allocator, const char * Desallocator, void * Data, int Own_Value ) + +NDT_Status ND_Index_Open_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Index_Type Type) { - NDT_Status rc; - const char * Real_Allocator, * Real_Desallocator; + NDT_Status status; + NDT_Node *node_ptr; + + + if( ( Root_Ptr->Index_Open_Nb == 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); + } + + Root_Ptr->Index_Tab[Index_Id].Type = Type & NDD_INDEX_STATUS_RMSK | NDD_INDEX_STATUS_OPENED ; + + 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; + + Root_Ptr->Index_Open_Nb++; + + 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éation d'une nouvelle structure de données */ +/*------------------------------------------------------------------------------*/ +/* (O) Root: adresse d'un pointeur sur la racine de la nouvelle structure */ +/* (I) Type: type de la structure.de donné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ées utiles à l'allocateur */ +/* (I) Own_Value : indique si la structure est proprié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éation d'une nouvelle structure de données */ +/*------------------------------------------------------------------------------*/ +/* (O) Root: adresse d'un pointeur sur la racine de la nouvelle structure */ +/* (I) Type: type de la structure.de donné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ées utiles à l'allocateur */ +/* (I) Own_Value : indique si la structure est proprié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 (Allocator) Real_Allocator = Allocator; - else Real_Allocator = "ND_Malloc"; + 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 (Desallocator) Real_Desallocator = Desallocator; - else Real_Desallocator = "ND_Free"; + 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; + } - rc = ND_Root_Alloc (Root, Type, Real_Allocator, Real_Desallocator, Data); + 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; + } - if (ND_ERROR(rc)) return rc; + 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); - (*Root)->Own_Value = Own_Value; + if( ND_ERROR( status)) return( status); - return NDS_OK; + return( NDS_OK); } + + + + +/*------------------------------------------------------------------------------*/ +/* Création d'une nouvelle structure de données */ +/*------------------------------------------------------------------------------*/ +/* (O) Root: adresse d'un pointeur sur la racine de la nouvelle structure */ +/* (I) Type: type de la structure.de donné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ées utiles à l'allocateur */ +/* (I) Own_Value : indique si la structure est proprié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ées */ /*------------------------------------------------------------------------------*/ /* (O) Root: pointeur sur la racine de la structure de données à détruire */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Close_I ( NDT_Root * Root ) + +NDT_Status ND_Index_Close_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id) { - NDT_Status rc; + NDT_Status status; - /* On supprime toutes les valeurs de la structure */ - rc = ND_DataStruct_Traverse_I (Root, NDD_CMD_DELETE_VALUE, NULL); - - if (ND_ERROR (rc)) return rc; - - return ND_Root_Free (Root); -} - -/*------------------------------------------------------------------------------*/ -/* Réorganisation d'une structure de données */ -/* - ordonnancement d'une liste non ordonnée */ -/* - réquilibrage d'un arbre non auto-équilibré */ -/*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine de la structure de données à supprimer */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Reorg_I ( NDT_Root * Root ) -{ - if (ND_IS_LIST(Root)) + if( ( Root_Ptr->Index_Open_Nb != 1) && ( Index_Id == NDD_INDEX_PRIMARY)) { - if (!ND_IS_ORDERED(Root)) return ND_List_Sort (Root); - else return NDS_OK; + sprintf( ND_Error_Msg, "Error ND_Index_Close_I: the primary should be the last closed"); + ND_Error_Print(); + return(NDS_ERRAPI); } - if (ND_IS_TREE(Root)) return ND_Tree_Equalize (Root); + status = ND_Index_Flush_I( Root_Ptr, Index_Id); + if( ND_ERROR( status)) return( status); - sprintf (ND_Error_Msg, "Error ND_DataStruct_Reorg : unknown structure type (%d)", Root->Type); - ND_Error_Print (); - return NDS_ERRAPI; + 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_Nb--; + + return(NDS_OK); } + + + + /*------------------------------------------------------------------------------*/ -/* Parcours de tous les noeuds d'une structure de données et exécution d'une */ -/* commande sur chacun d'eux */ +/* Destruction d'une structure de données */ /*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine de la structure de données à parcourir */ -/* (I) Command : Commande à exécuter sur chaque noeud traversé */ -/* (I) Data : pointeur de données utilisateur */ +/* (O) Root: pointeur sur la racine de la structure de données à détruire */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Traverse_I ( NDT_Root * Root, NDT_Command Command, void * Data ) + +NDT_Status ND_Index_Close_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id) { - NDT_Status rc; - NDT_Node * Node, * Next_Node; - - if (Command == NDD_CMD_SUM_VALUES) *((int *)(Data)) = 0; - - ND_Node_First_Get_I (Root, &Node); - - while (Node) + if( !Root_Ptr) { - Next_Node = NULL; - ND_Node_Next_Get_I (Node, &Next_Node); + sprintf( ND_Error_Msg, "Error ND_Index_Close_C: structure root is null"); + ND_Error_Print(); + return( NDS_ERRAPI); + } - switch (Command) + 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ées */ +/*------------------------------------------------------------------------------*/ +/* (O) Root: pointeur sur la racine de la structure de données à 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ées */ +/*------------------------------------------------------------------------------*/ +/* (O) Root: pointeur sur la racine de la structure de données à 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ées à 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) { - case NDD_CMD_DELETE_VALUE: - - /* On détruit la valeur si la structure est propriétaire de ses valeurs (TRUE par défaut) */ - - if (Root->Own_Value == TRUE) - { - rc = ND_Value_Free_I (Root, Node->Value); - if (ND_ERROR(rc)) return rc; - } - - rc = ND_Node_Remove_I (Node); - if (ND_ERROR(rc)) return rc; - - rc = ND_Node_Free (Root, Node); - if (ND_ERROR(rc)) return rc; - - break; - - case NDD_CMD_SUM_VALUES: - - rc = ND_Manager_Exec_I (Root->Manager, NDD_CMD_SUM_VALUES, Node->Value, (int *)Data); - if (ND_ERROR(rc)) return rc; - - break; - - case NDD_CMD_PRINT_VALUE: - - rc = ND_Manager_Exec_I (Root->Manager, NDD_CMD_PRINT_VALUE, Node->Value, (FILE *)Data); - if (ND_ERROR(rc)) return rc; - - fprintf ((FILE *)Data, "\n"); - break; - - default: - - rc = ND_Manager_Exec_I (Root->Manager, Command, Root, Node->Value, Data); - if (ND_ERROR(rc)) return rc; - - break; + 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); } - Node = Next_Node; + 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; + return( NDS_OK); } -/*------------------------------------------------------------------------------*/ -/* Conversion d'une structure de données d'un type en un autre */ -/*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine de la structure de données à convertir */ -/* (I) Target_Type : type de structure cible */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Convert_I ( NDT_Root * Root, NDT_DataStruct_Type Target_Type) -{ - NDT_Status rc; - switch (Root->Type & NDD_DS_MSK) + + + +/*------------------------------------------------------------------------------*/ +/* Destruction d'une structure de données */ +/*------------------------------------------------------------------------------*/ +/* (O) Root: pointeur sur la racine de la structure de données à détruire */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Index_Flush_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id) +{ + if( !Root_Ptr) { - case NDD_DS_LIST: - - switch (Target_Type) - { - case (NDD_DS_LIST | NDD_MN_ORDERED): - - rc = ND_List_Sort (Root); - if (ND_ERROR(rc)) return rc; - if (rc == NDS_OK) Root->Type = Target_Type; - - return rc; - - case (NDD_DS_TREE | NDD_MN_AUTO_EQU): - - rc = ND_List_Sort (Root); - if (rc != NDS_OK) return rc; - rc = ND_Tree_Make (Root); - if (ND_ERROR(rc)) return rc; - if (rc == NDS_OK) Root->Type = Target_Type; - - return rc; - - default: - return NDS_OK; - } - - break; - - case NDD_DS_TREE: - - switch (Target_Type) - { - case (NDD_DS_LIST | NDD_MN_ORDERED): - case (NDD_DS_LIST | NDD_MN_FIFO): - case (NDD_DS_LIST | NDD_MN_FILO): - - rc = ND_List_Make (Root); - if (ND_ERROR(rc)) return rc; - if (rc == NDS_OK) Root->Type = Target_Type; - - default: - return NDS_OK; - } - - break; - - default: - sprintf (ND_Error_Msg, "Error ND_DataStruct_Reorg : unknown structure type (%d)", Root->Type); - ND_Error_Print (); - return NDS_ERRAPI; + sprintf( ND_Error_Msg, "Error ND_Index_Close : structure root is null"); + ND_Error_Print(); + return(NDS_ERRAPI); } - return NDS_OK; + return( ND_Index_Flush_I( Root_Ptr, Index_Id)); } -/*------------------------------------------------------------------------------*/ -/* Affichage d'informations sur une structure de données */ -/*------------------------------------------------------------------------------*/ -/* (I) Root: pointeur sur la racine de la structure de données */ -/* (I) Out : flux de sortie */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Info_Print_I ( NDT_Root * Root, FILE * Out ) -{ - return ND_Manager_Exec_I (Root->Manager, NDD_CMD_PRINT_INFO, Root, Out); -} + + + /*------------------------------------------------------------------------------*/ -/* Affichage d'une structure de données */ +/* Destruction d'une structure de données */ /*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine de la structure de données à afficher */ -/* (I) Out : flux de sortie */ +/* (O) Root: pointeur sur la racine de la structure de données à détruire */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Print_I ( NDT_Root * Root, FILE * Out ) + +NDT_Status ND_DataStruct_Flush_I( NDT_Root *Root_Ptr) { - return ND_DataStruct_Traverse_I (Root, NDD_CMD_PRINT_VALUE, Out); + NDT_Status status; + NDT_Index_Id index_id; + + + for( index_id = Root_Ptr->Index_Nb; 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ées */ +/*------------------------------------------------------------------------------*/ +/* (O) Root: pointeur sur la racine de la structure de données à 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és les uns aux autres */ @@ -381,226 +871,1427 @@ NDT_Status ND_DataStruct_Print_I ( NDT_Root * Root, FILE * Out ) /* (O) Nb_Corrected : pointeur sur le nombre d'erreurs corrigées */ /* (I) Out : flux de sortie du rapport */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Check_I ( NDT_Root * Root, int * Nb_Detected, int * Nb_Corrected, FILE * Out ) + +NDT_Status ND_Index_Check_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out) { - if (ND_IS_LIST(Root)) - ND_List_Check (Root, Nb_Detected, Nb_Corrected, Out); - else if (ND_IS_TREE(Root)) - ND_Tree_Check (Root, Nb_Detected, Nb_Corrected, Out); - else - { - sprintf (ND_Error_Msg, "Error ND_DataStruct_Check : unknown structure type (%d)", Root->Type); - ND_Error_Print (); - (*Nb_Detected)++; - return NDS_ERRAPI; - } + 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, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out); + } + else if( ND_INDEX_TYPE_TREE_IS( Root_Ptr, Index_Id)) + { + ND_Tree_Check( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_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(); + (*Nb_Detected_Ptr)++; + return(NDS_ERRAPI); + } + } + else + { + Nb_Detected_Ptr = 0; + Nb_Corrected_Ptr = 0; + return( NDS_OK); + } /* Affichage du résultat de la procédure de vérification */ - if (*Nb_Detected == 0) - fprintf (Out, "No error detected in the node structure\n"); + if(*Nb_Detected_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\n", *Nb_Corrected, *Nb_Detected); + { + fprintf (Out, "%d/%d error(s) corrected in the node structure (%p:%d)\n", *Nb_Corrected_Ptr, *Nb_Detected_Ptr, Root_Ptr, Index_Id); + } - if (*Nb_Corrected < *Nb_Detected) return NDS_KO; + if( *Nb_Corrected_Ptr < *Nb_Detected_Ptr) return( NDS_KO); + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Function de réparation d'une structure : */ +/* - vérifie que tous les noeuds sont correctement lié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ées */ +/* (O) Nb_Corrected : pointeur sur le nombre d'erreurs corrigé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é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ées */ +/* (O) Nb_Corrected : pointeur sur le nombre d'erreurs corrigées */ +/* (I) Out : flux de sortie du rapport */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_DataStruct_Check_I( NDT_Root *Root_Ptr, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out) +{ + NDT_Status status; + NDT_Index_Id index_id; + + + for( index_id = 0; index_id < Root_Ptr->Index_Nb; index_id++) + { + status = ND_Index_Check_I( Root_Ptr, index_id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out); + if( ND_ERROR(status)) return(status); + } return NDS_OK; } + + + + /*------------------------------------------------------------------------------*/ -/* Affiche la structure de données et ses informations statistiques */ +/* Function de réparation d'une structure : */ +/* - vérifie que tous les noeuds sont correctement liés les uns aux autres */ +/* - corrige les informations statistiques de la racine */ /*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine de la structure */ -/* (I) Out : flux de sortie */ +/* (I) Root : pointeur sur la racine de la structure */ +/* (O) Nb_Detected : pointeur sur le nombre d'erreurs détectées */ +/* (O) Nb_Corrected : pointeur sur le nombre d'erreurs corrigées */ +/* (I) Out : flux de sortie du rapport */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Dump_I ( NDT_Root * Root, FILE * Out ) + +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ées d'un type en un autre */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à 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; - NDT_Node * Node; - /* Affichage de la racine */ - fprintf (Out, "Adresse structure = %p\n", Root); + 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: + { - /* Affichage du contenu de la structure */ + 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); + if( rc == NDS_OK) Root_Ptr->Index_Tab[Index_Id].Type = Target_Type; - if (ND_IS_LIST(Root)) + return( rc); + } + + case( NDD_INDEX_TYPE_TREE | NDD_INDEX_SUBTYPE_BALANCED): + { + 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); + if( rc == NDS_OK) 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); + if( rc == NDS_OK) Root_Ptr->Index_Tab[Index_Id].Type = Target_Type; + } + + 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ées d'un type en un autre */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à 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) { - Node = Root->Head; - - while (Node) - { - fprintf (Out, " (%p) [", Node); - rc = ND_Manager_Exec_I (Root->Manager, NDD_CMD_PRINT_VALUE, Node->Value, Out); - if (ND_ERROR(rc)) return rc; - fprintf (Out, "]\n"); - Node = Node->Right; - } - - return NDS_OK; + sprintf( ND_Error_Msg, "Error ND_Index_Convert : structure root is null"); + ND_Error_Print(); + return(NDS_ERRAPI); } - else if (ND_IS_TREE(Root)) - ND_Tree_Recursive_Print (Root->Head, 1, Out); - else + + return ND_Index_Convert_I( Root_Ptr, Index_Id, Target_Type); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Conversion d'une structure de données d'un type en un autre */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à 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ées d'un type en un autre */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à 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_Dump : unknown structure type (%d)", Root->Type); + 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ées */ +/* - ordonnancement d'une liste non ordonnée */ +/* - réquilibrage d'un arbre non auto-équilibré */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à 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ées */ +/* - ordonnancement d'une liste non ordonnée */ +/* - réquilibrage d'un arbre non auto-équilibré */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à 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 NDS_OK; + return ND_Index_Reorg_I( Root_Ptr, Index_Id); } + + + + /*------------------------------------------------------------------------------*/ -/* Récupération de la racine d'une structure */ +/* Réorganisation d'une structure de données */ +/* - ordonnancement d'une liste non ordonnée */ +/* - réquilibrage d'un arbre non auto-équilibré */ /*------------------------------------------------------------------------------*/ -/* (O) Root : adresse du pointeur sur la racine à récupérer */ -/* (I) Node : pointeur sur le noeud dont on cherche la racine */ +/* (I) Root : pointeur sur la racine de la structure de données à supprimer */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Node_Root_Get_I ( NDT_Root ** Root, NDT_Node * Node ) + +NDT_Status ND_DataStruct_Reorg_I( NDT_Root *Root_Ptr) { - *Root = Node->Root; + NDT_Status status; + NDT_Index_Id index_id; - return NDS_OK; -} -/*------------------------------------------------------------------------------*/ -/* Récupé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_Node_First_Get_I ( NDT_Root * Root, NDT_Node ** First_Node ) -{ - *First_Node = NULL; - - if (ND_IS_LIST(Root)) *First_Node = Root->Head; - - if (ND_IS_TREE(Root)) *First_Node = ND_Tree_Node_First_Recursive_Get (Root->Head); - - if (!*First_Node) return NDS_KO; - - return NDS_OK; -} - -/*------------------------------------------------------------------------------*/ -/* Récupé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_Node_Last_Get_I ( NDT_Root * Root, NDT_Node ** Last_Node ) -{ - *Last_Node = NULL; - - if (ND_IS_LIST(Root)) *Last_Node = Root->Queue; - - if (ND_IS_TREE(Root)) *Last_Node = ND_Tree_Node_Last_Recursive_Get (Root->Head); - - if (!*Last_Node) return NDS_KO; - - return NDS_OK; -} - -/*------------------------------------------------------------------------------*/ -/* Récupé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_Node_Next_Get_I ( NDT_Node * Node, NDT_Node ** Next_Node ) -{ - if (ND_IS_LIST(Node->Root)) *Next_Node = Node->Right; - - if (ND_IS_TREE(Node->Root)) + for( index_id = 0; index_id < Root_Ptr->Index_Nb; index_id++) { - if (!Node->Right) *Next_Node = ND_Tree_Parent_Next_Recursive_Get (Node); - else *Next_Node = ND_Tree_Node_First_Recursive_Get (Node->Right); + status = ND_Index_Reorg_I( Root_Ptr, index_id); + if( ND_ERROR( status)) return status; } - if (!*Next_Node) return NDS_KO; - - return NDS_OK; + return( NDS_OK); } -/*------------------------------------------------------------------------------*/ -/* Récupération du noeud précédant */ -/*------------------------------------------------------------------------------*/ -/* (I) Node : pointeur sur le noeud dont on cherche le précédant */ -/* (O) Prev_Node : adresse du pointeur sur le noeud suivant */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_Node_Previous_Get_I ( NDT_Node * Node, NDT_Node ** Prev_Node ) -{ - if (ND_IS_LIST(Node->Root)) *Prev_Node = Node->Left; - if (ND_IS_TREE(Node->Root)) + + + +/*------------------------------------------------------------------------------*/ +/* Réorganisation d'une structure de données */ +/* - ordonnancement d'une liste non ordonnée */ +/* - réquilibrage d'un arbre non auto-équilibré */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à supprimer */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_DataStruct_Reorg_C( NDT_Root *Root_Ptr) +{ + if( !Root_Ptr) { - if (!Node->Left) *Prev_Node = ND_Tree_Parent_Previous_Recursive_Get (Node); - else *Prev_Node = ND_Tree_Node_Last_Recursive_Get (Node->Left); + sprintf( ND_Error_Msg, "Error ND_DataStruct_Reorg : structure root is null"); + ND_Error_Print (); + return NDS_ERRAPI; } - if (!*Prev_Node) return NDS_KO; + return ND_DataStruct_Reorg_I( Root_Ptr); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Parcours de tous les noeuds d'une structure de données et exécution d'une */ +/* commande sur chacun d'eux */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à parcourir */ +/* (I) Command : Commande à exécuter sur chaque noeud traversé */ +/* (I) Data : pointeur de donné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ées et exécution d'une */ +/* commande sur chacun d'eux */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à parcourir */ +/* (I) Command : Commande à exécuter sur chaque noeud traversé */ +/* (I) Data : pointeur de donné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ées et exécution d'une */ +/* commande sur chacun d'eux */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à parcourir */ +/* (I) Command : Commande à exécuter sur chaque noeud traversé */ +/* (I) Data : pointeur de donné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ées et exécution d'une */ +/* commande sur chacun d'eux */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à parcourir */ +/* (I) Command : Commande à exécuter sur chaque noeud traversé */ +/* (I) Data : pointeur de donné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ées et exécution d'une */ +/* commande sur chacun d'eux */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à parcourir */ +/* (I) Command : Commande à exécuter sur chaque noeud traversé */ +/* (I) Data : pointeur de donné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ées et exécution d'une */ +/* commande sur chacun d'eux */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à parcourir */ +/* (I) Command : Commande à exécuter sur chaque noeud traversé */ +/* (I) Data : pointeur de donné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ées et exécution d'une */ +/* commande sur chacun d'eux */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à parcourir */ +/* (I) Command : Commande à exécuter sur chaque noeud traversé */ +/* (I) Data : pointeur de donné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ées et exécution d'une */ +/* commande sur chacun d'eux */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à parcourir */ +/* (I) Command : Commande à exécuter sur chaque noeud traversé */ +/* (I) Data : pointeur de donné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ées */ +/*------------------------------------------------------------------------------*/ +/* (I) Root: pointeur sur la racine de la structure de donné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: (%d) [%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ées */ +/*------------------------------------------------------------------------------*/ +/* (I) Root: pointeur sur la racine de la structure de donné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ées */ +/*------------------------------------------------------------------------------*/ +/* (I) Root: pointeur sur la racine de la structure de donné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 Opened: (%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_Nb, 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ées */ +/*------------------------------------------------------------------------------*/ +/* (I) Root: pointeur sur la racine de la structure de donné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 à une structure de données */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données */ +/* (I) Value : pointeur sur la valeur à ajouter à la structure de donné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 à une structure de données */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données */ +/* (I) Value : pointeur sur la valeur à ajouter à la structure de donné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 à une structure de données */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données */ +/* (I) Value : pointeur sur la valeur à ajouter à la structure de donné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 à une structure de données */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données */ +/* (I) Value : pointeur sur la valeur à ajouter à la structure de donné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 à une valeur donnée */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données */ +/* (I) Reference_Value : pointeur sur la valeur de référence */ +/* (I) Removed_Value : adresse d'un pointeur sur la valeur supprimé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 à la valeur de réfé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 à une valeur donnée */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données */ +/* (I) Reference_Value : pointeur sur la valeur de référence */ +/* (I) Removed_Value : adresse d'un pointeur sur la valeur supprimé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 à une valeur donnée */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données */ +/* (I) Reference_Value : pointeur sur la valeur de référence */ +/* (I) Removed_Value : adresse d'un pointeur sur la valeur supprimé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 à une valeur donnée */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données */ +/* (I) Reference_Value : pointeur sur la valeur de référence */ +/* (I) Removed_Value : adresse d'un pointeur sur la valeur supprimé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ées */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à 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ées */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à 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ées */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à 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ées */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à 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ées */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à 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ées */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données à 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 à une structure de données */ /*------------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la structure de données */ /* (I) Node : pointeur sur le noeud à ajouter */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Node_Add_I ( NDT_Root * Root, NDT_Node * Node ) + +NDT_Status ND_Index_Node_Add_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr ) { - if (ND_IS_LIST(Root)) return ND_List_Node_Add (Root, Node); - else if (ND_IS_TREE(Root)) return ND_Tree_Node_Add (Root, Node); + 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_Node_Add : unknown structure type (%d)", Root->Type); + 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_ERRAPI); } - return NDS_KO; + return(NDS_KO); } + + + + +/*------------------------------------------------------------------------------*/ +/* Ajout d'un noeud à une structure de données */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure de données */ +/* (I) Node : pointeur sur le noeud à 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ées */ /*------------------------------------------------------------------------------*/ /* (I) Node: pointeur sur le noeud à supprimer */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Node_Remove_I ( NDT_Node * Node ) + +NDT_Status ND_Index_Node_Remove_I( NDT_Node *Node_Ptr) { - NDT_Root * Root; + NDT_Root *root_ptr; + NDT_Index_Id index_id; - Root = Node->Root; - if (ND_IS_LIST(Root)) return ND_List_Node_Remove (Node); - else if (ND_IS_TREE(Root)) + 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; + NDT_Node **tmp_ptr_ptr; /* On récupère l'adresse du lien entre le noeud à supprimer et son père */ - if (Node->Parent) + if( Node_Ptr->Parent) { /* Cas général */ - if (Node == Node->Parent->Left) Tmp = &(Node->Parent->Left); - else Tmp = &(Node->Parent->Right); + 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 = NULL; + tmp_ptr_ptr = NULL; } - if (Node->Right) + if( Node_Ptr->Right) { - NDT_Node * Right_Node = Node->Right; - NDT_Node * Left_Node = Node->Left; - NDT_Node * First_Node; + 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 à supprimer dans un pointeur de @@ -608,470 +2299,83 @@ NDT_Status ND_Node_Remove_I ( NDT_Node * Node ) interrompue (recovery). */ - Root->Save = Left_Node; + root_ptr->Index_Tab[index_id].Save = Left_Node_Ptr; /* On remplace le noeud supprimé par son sous-arbre droit */ - if (!Tmp) Root->Head = Root->Queue = Node->Right; - else *Tmp = Node->Right; + 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->Parent = Node->Parent; + Right_Node_Ptr->Parent = Node_Ptr->Parent; /* On attache le sous-arbre gauche au premier noeud du sous-arbre droit */ - if (Root->Save) + if( root_ptr->Index_Tab[index_id].Save) { - First_Node = ND_Tree_Node_First_Recursive_Get (Right_Node); + First_Node_Ptr = ND_Tree_Node_First_Recursive_Get(Right_Node_Ptr); - First_Node->Left = Root->Save; + First_Node_Ptr->Left = root_ptr->Index_Tab[index_id].Save; - Root->Save->Parent = First_Node; + root_ptr->Index_Tab[index_id].Save->Parent = First_Node_Ptr; - Root->Save = NULL; + root_ptr->Index_Tab[index_id].Save = NULL; } } else { /* On remplace le noeud supprimé par son sous-arbre gauche */ - if (!Tmp) Root->Head = Root->Queue = Node->Left; - else *Tmp = Node->Left; + 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->Left) Node->Left->Parent = Node->Parent; + if( Node_Ptr->Left) Node_Ptr->Left->Parent = Node_Ptr->Parent; } - Root->Node_Number--; + root_ptr->Index_Tab[index_id].Node_Number--; /* Pas de mise à jour des informations de profondeur : trop coûteux */ - Node->Left = NULL; - Node->Right = NULL; - Node->Parent = NULL; - Node->Root = NULL; + 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_Node_Remove : unknown structure type (%d)", Root->Type); + 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_ERRAPI); } - return NDS_OK; + return(NDS_OK); } + + + + /*------------------------------------------------------------------------------*/ -/* Recherche un noeud à partir d'une valeur */ +/* Suppression d'un noeud dans une structure de données */ /*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine de l'abre */ -/* (O) Node : adresse du pointeur sur le noeud à récuperer */ -/* (I) Value : pointeur sur la valeur à rechercher */ -/* (I) Data : pointeur de données */ +/* (I) Node: pointeur sur le noeud à supprimer */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Node_Find_I ( NDT_Root * Root, NDT_Node ** Node, void * Value, void * Data ) + +NDT_Status ND_Index_Node_Remove_C( NDT_Node *Node_Ptr) { - if (ND_IS_LIST(Root)) *Node = ND_List_Node_Find (Root, Value, Data); - else if (ND_IS_TREE(Root)) *Node = ND_Tree_Node_Find (Root, Value, Data); - else + if( !Node_Ptr) { - sprintf (ND_Error_Msg, "Error ND_Node_Find : unknown structure type (%d)", Root->Type); - ND_Error_Print (); + sprintf( ND_Error_Msg, "Error ND_Index_Node_Remove : the node to remove is null"); + ND_Error_Print(); + return(NDS_ERRAPI); } - if (!*Node) return NDS_KO; - - return NDS_OK; -} - -/*------------------------------------------------------------------------------*/ -/* Allocation d'une valeur d'une structure de données */ -/*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine de la structure de données */ -/* (O) Value : adresse d'un pointeur sur la valeur à allouer */ -/* (I) ... : arguments relatifs à l'allocation de la valeur */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_Value_Alloc_I ( NDT_Root * Root, void ** Value, ... ) -{ - NDT_Status rc; - va_list Args; - - /* Récupération des arguments pour l'allocation de la valeur */ - - va_start (Args, Value); - - /* Appel du manager */ - - rc = ND_Manager_Exec_I (Root->Manager, NDD_CMD_MAKE_VALUE, Root, Value, Args); - - va_end (Args); - - return rc; -} - -/*------------------------------------------------------------------------------*/ -/* Ajout d'une valeur à une structure de données */ -/*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine de la structure de données */ -/* (I) Value : pointeur sur la valeur à ajouter à la structure de données */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_Value_Add_I ( NDT_Root * Root, void * Value ) -{ - if (ND_IS_LIST(Root)) return ND_List_Value_Add (Root, Value); - else if (ND_IS_TREE(Root)) return ND_Tree_Value_Add (Root, Value); - else - { - sprintf (ND_Error_Msg, "Error ND_Value_Add : unknown structure type (%d)", Root->Type); - ND_Error_Print (); - return NDS_ERRAPI; - } - - return NDS_KO; -} - -/*------------------------------------------------------------------------------*/ -/* Suppression du premier noeud correspondant à une valeur donnée */ -/*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine de la structure de données */ -/* (I) Reference_Value : pointeur sur la valeur de référence */ -/* (I) Removed_Value : adresse d'un pointeur sur la valeur supprimée */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_Value_Remove_I ( NDT_Root * Root, void * Reference_Value, void ** Removed_Value ) -{ - NDT_Status rc; - struct NDT_Node * Node; - - *Removed_Value = NULL; - - /* Recherche du premier noeud correspondant à la valeur de référence */ - - rc = ND_Node_Find_I (Root, &Node, Reference_Value, NULL); - if (ND_ERROR(rc)) return rc; - - if (!Node) return NDS_KO; - - *Removed_Value = Node->Value; - - /* Retrait du noeud de la structure */ - - rc = ND_Node_Remove_I (Node); - if (ND_ERROR(rc)) return rc; - - /* Désallocation du noeud */ - - rc = ND_Node_Free (Root, Node); - - return rc; -} - -/*------------------------------------------------------------------------------*/ -/* Désallocation d'une valeur d'une structure de données */ -/*------------------------------------------------------------------------------*/ -/* (I) Root: pointeur sur la racine de la structure de données */ -/* (I) Value: pointeur sur la valeur à désallouer */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_Value_Free_I ( NDT_Root * Root, void * Value ) -{ - return ND_Manager_Exec_I (Root->Manager, NDD_CMD_DELETE_VALUE, Root, Value); + return ND_Index_Node_Remove_I( Node_Ptr); } -/*------------------------------------------------------------------------------*/ -/* Exécution d'une fonction Manager dont le nom est passé en paramètre */ -/*------------------------------------------------------------------------------*/ -/* (I) Function : nom de la fonction manager à exécuter */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_Manager_Exec_I ( const char * Function, ... ) -{ - NDT_Manager * Manager; - NDT_Status rc; - va_list Args; - va_start (Args, Function); - Manager = (NDT_Manager *) ND_Symbol_Find (Function); - - rc = Manager (Args); - - va_end (Args); - - return rc; -} - -/*------------------------------------------------------------------------------*/ -/* Exécution d'une fonction d'allocation dont le nom est passé en paramètre */ -/*------------------------------------------------------------------------------*/ -/* (I) Function : nom de la fonction à exécuter */ -/* (O) Ptr : adresse d'un pointeur sur la zone à allouer */ -/* (I) Size : taille de la zone à allouer */ -/* (I) Data : données utilisateur utiles à l'allocateur */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_Allocator_Exec_I ( const char * Function, void ** Ptr, size_t Size, void * Data ) -{ - NDT_Allocator * Allocator; - - *Ptr = NULL; - - Allocator = (NDT_Allocator *) ND_Symbol_Find (Function); - - return Allocator (Size, Ptr, Data); -} - -/*------------------------------------------------------------------------------*/ -/* Exécution d'une fonction de désallocation dont nom est passé en paramètre */ -/*------------------------------------------------------------------------------*/ -/* (I) Function : nom de la fonction à exécuter */ -/* (I) Ptr : adresse de la zone à désallouer */ -/* (I) Data : données utilisateur utiles à l'allocateur */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_Desallocator_Exec_I ( const char * Function, void * Ptr, void * Data ) -{ - NDT_Desallocator * Desallocator; - - Desallocator = (NDT_Desallocator *) ND_Symbol_Find (Function); - - return Desallocator (Ptr, Data); -} - -/*------------------------------------------------------------------------------*/ -/* FONCTIONS SECURISEES (ND_MODE = 0) */ -/*------------------------------------------------------------------------------*/ - -/*------------------------------------------------------------------------------*/ -/* 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_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_C ( FILE * Out ) -{ - return ND_Library_Stderr_Set_I (Out); -} - -/*------------------------------------------------------------------------------*/ -/* Création d'une nouvelle structure de données */ -/*------------------------------------------------------------------------------*/ -/* (O) Root: adresse d'un pointeur sur la racine de la nouvelle structure */ -/* (I) Type: type de la structure.de donné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ées utiles à l'allocateur */ -/* (I) Own_Value : indique si la structure est propriétaire de ses valeurs */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Open_C ( NDT_Root ** Root, NDT_DataStruct_Type Type, const char * Allocator, const char * Desallocator, void * Data, int Own_Value ) -{ - return ND_DataStruct_Open_I (Root, Type, Allocator, Desallocator, Data, Own_Value); -} - -/*------------------------------------------------------------------------------*/ -/* Destruction d'une structure de données */ -/*------------------------------------------------------------------------------*/ -/* (O) Root: pointeur sur la racine de la structure de données à détruire */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Close_C ( NDT_Root * Root ) -{ - if (!Root) - { - sprintf (ND_Error_Msg, "Error ND_DataStruct_Close : structure root is null"); - ND_Error_Print (); - return NDS_ERRAPI; - } - - return ND_DataStruct_Close_I (Root); -} - -/*------------------------------------------------------------------------------*/ -/* Réorganisation d'une structure de données */ -/* - ordonnancement d'une liste non ordonnée */ -/* - réquilibrage d'un arbre non auto-équilibré */ -/*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine de la structure de données à supprimer */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Reorg_C ( NDT_Root * Root ) -{ - if (!Root) - { - sprintf (ND_Error_Msg, "Error ND_DataStruct_Reorg : structure root is null"); - ND_Error_Print (); - return NDS_ERRAPI; - } - - return ND_DataStruct_Reorg_I (Root); -} - -/*------------------------------------------------------------------------------*/ -/* Parcours de tous les noeuds d'une structure de données et exécution d'une */ -/* commande sur chacun d'eux */ -/*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine de la structure de données à parcourir */ -/* (I) Command : Commande à exécuter sur chaque noeud traversé */ -/* (I) Data : pointeur de données utilisateur */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Traverse_C ( NDT_Root * Root, NDT_Command Command, void * Data ) -{ - if (!Root) - { - sprintf (ND_Error_Msg, "Error ND_DataStruct_Traverse : structure root is null"); - ND_Error_Print (); - return NDS_KO; - } - - return ND_DataStruct_Traverse_I (Root, Command, Data); -} - -/*------------------------------------------------------------------------------*/ -/* Conversion d'une structure de données d'un type en un autre */ -/*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine de la structure de données à convertir */ -/* (I) Target_Type : type de structure cible */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Convert_C ( NDT_Root * Root, NDT_DataStruct_Type Target_Type) -{ - if (!Root) - { - sprintf (ND_Error_Msg, "Error ND_DataStruct_Convert : structure root is null"); - ND_Error_Print (); - return NDS_ERRAPI; - } - - return ND_DataStruct_Convert_I (Root, Target_Type); -} - -/*------------------------------------------------------------------------------*/ -/* Affichage d'informations sur une structure de données */ -/*------------------------------------------------------------------------------*/ -/* (I) Root: pointeur sur la racine de la structure de données */ -/* (I) Out : flux de sortie */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Info_Print_C ( NDT_Root * Root, FILE * Out ) -{ - if (!Root) - { - sprintf (ND_Error_Msg, "Error ND_DataStruct_Print : structure root is null"); - ND_Error_Print (); - return NDS_ERRAPI; - } - - if (!Out) - { - sprintf (ND_Error_Msg, "Error ND_DataStruct_Print : the stream descriptor is null"); - ND_Error_Print (); - return NDS_ERRAPI; - } - - return ND_DataStruct_Info_Print_I (Root, Out); -} - -/*------------------------------------------------------------------------------*/ -/* Affichage d'une structure de données */ -/*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine de la structure de données à afficher */ -/* (I) Out : flux de sortie */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Print_C ( NDT_Root * Root, FILE * Out ) -{ - if (!Root) - { - sprintf (ND_Error_Msg, "Error ND_DataStruct_Print : structure root is null"); - ND_Error_Print (); - return NDS_ERRAPI; - } - - if (!Out) - { - sprintf (ND_Error_Msg, "Error ND_DataStruct_Print : the stream descriptor is null"); - ND_Error_Print (); - return NDS_ERRAPI; - } - - return ND_DataStruct_Print_I (Root, Out); -} - -/*------------------------------------------------------------------------------*/ -/* Function de réparation d'une structure : */ -/* - vérifie que tous les noeuds sont correctement lié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ées */ -/* (O) Nb_Corrected : pointeur sur le nombre d'erreurs corrigées */ -/* (I) Out : flux de sortie du rapport */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Check_C ( NDT_Root * Root, int * Nb_Detected, int * Nb_Corrected, FILE * Out ) -{ - if (!Root) - { - sprintf (ND_Error_Msg, "Error ND_DataStruct_Check : structure root is null"); - ND_Error_Print (); - (*Nb_Detected)++; - 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, Nb_Detected, Nb_Corrected, Out); -} - -/*------------------------------------------------------------------------------*/ -/* Affiche la structure de données et ses informations statistiques */ -/*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine de la structure */ -/* (I) Out : flux de sortie */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_DataStruct_Dump_C ( NDT_Root * Root, FILE * Out ) -{ - if (!Root) - { - sprintf (ND_Error_Msg, "Error ND_DataStruct_Dump : structure root is null"); - ND_Error_Print (); - return NDS_ERRAPI; - } - - if (!Out) - { - sprintf (ND_Error_Msg, "Error ND_DataStruct_Dump : the stream descriptor is null"); - ND_Error_Print (); - return NDS_ERRAPI; - } - - return ND_DataStruct_Dump_I (Root, Out); -} - -/*------------------------------------------------------------------------------*/ -/* Récupération de la racine d'une structure */ -/*------------------------------------------------------------------------------*/ -/* (O) Root : adresse du pointeur sur la racine à récupérer */ -/* (I) Node : pointeur sur le noeud dont on cherche la racine */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_Node_Root_Get_C ( NDT_Root ** Root, NDT_Node * Node ) -{ - if (!Node) - { - 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, Node); -} /*------------------------------------------------------------------------------*/ /* Récupération du premier noeud d'une structure */ @@ -1079,113 +2383,205 @@ NDT_Status ND_Node_Root_Get_C ( NDT_Root ** Root, NDT_Node * Node ) /* (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_Node_First_Get_C ( NDT_Root * Root, NDT_Node ** First_Node ) + +NDT_Status ND_Index_Node_First_Get_I( NDT_Node **First_Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id) { - if (!Root) + *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é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_Node_First_Get : structure root is null"); - ND_Error_Print (); - return NDS_ERRAPI; + sprintf( ND_Error_Msg, "Error ND_Index_Node_First_Get : structure root is null"); + ND_Error_Print(); + return(NDS_ERRAPI); } - return ND_Node_First_Get_I (Root, First_Node); + return ND_Index_Node_First_Get_I( First_Node_Ptr_Ptr, Root_Ptr, Index_Id); } + + + + /*------------------------------------------------------------------------------*/ /* Récupé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_Node_Last_Get_C ( NDT_Root * Root, NDT_Node ** Last_Node ) + +NDT_Status ND_Index_Node_Last_Get_I ( NDT_Node **Last_Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id) { - if (!Root) + *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é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_Node_Last_Get : structure root is null"); - ND_Error_Print (); - return NDS_ERRAPI; + sprintf( ND_Error_Msg, "Error ND_Index_Node_Last_Get : structure root is null"); + ND_Error_Print(); + return(NDS_ERRAPI); } - return ND_Node_Last_Get_I (Root, Last_Node); + return ND_Index_Node_Last_Get_I( Last_Node_Ptr_Ptr, Root_Ptr, Index_Id); } + + + + /*------------------------------------------------------------------------------*/ /* Récupé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_Node_Next_Get_C ( NDT_Node * Node, NDT_Node ** Next_Node ) + +NDT_Status ND_Index_Node_Next_Get_I ( NDT_Node **Next_Node_Ptr_Ptr, NDT_Node *Node_Ptr) { - if (!Node) + 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)) { - sprintf (ND_Error_Msg, "Error ND_Node_Next_Get : node is null"); - ND_Error_Print (); - return NDS_ERRAPI; + 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); + } } - return ND_Node_Next_Get_I (Node, Next_Node); + // if(!*Next_Node_Ptr_Ptr) return(NDS_KO); + + return(NDS_OK); } + + + + +/*------------------------------------------------------------------------------*/ +/* Récupé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ération du noeud précédant */ /*------------------------------------------------------------------------------*/ /* (I) Node : pointeur sur le noeud dont on cherche le précédant */ /* (O) Prev_Node : adresse du pointeur sur le noeud suivant */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Node_Previous_Get_C ( NDT_Node * Node, NDT_Node ** Prev_Node ) + +NDT_Status ND_Index_Node_Previous_Get_I( NDT_Node **Prev_Node_Ptr_Ptr, NDT_Node *Node_Ptr) { - if (!Node) + 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)) { - sprintf (ND_Error_Msg, "Error ND_Node_Previous_Get : node is null"); - ND_Error_Print (); - return NDS_ERRAPI; + 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); + } } - return ND_Node_Previous_Get_I (Node, Prev_Node); + // if( !*Prev_Node_Ptr_Ptr) return( NDS_KO); + + return( NDS_OK); } + + + + /*------------------------------------------------------------------------------*/ -/* Ajout d'un noeud à une structure de données */ +/* Récupération du noeud précédant */ /*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine de la structure de données */ -/* (I) Node : pointeur sur le noeud à ajouter */ +/* (I) Node : pointeur sur le noeud dont on cherche le précédant */ +/* (O) Prev_Node : adresse du pointeur sur le noeud suivant */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Node_Add_C ( NDT_Root * Root, NDT_Node * Node ) + +NDT_Status ND_Index_Node_Previous_Get_C( NDT_Node **Prev_Node_Ptr_Ptr, NDT_Node *Node_Ptr) { - if (!Root) + if( !Node_Ptr) { - sprintf (ND_Error_Msg, "Error ND_Node_Add : structure root is null"); - ND_Error_Print (); - return NDS_ERRAPI; + sprintf( ND_Error_Msg, "Error ND_Index_Node_Previous_Get : node is null"); + ND_Error_Print(); + return(NDS_ERRAPI); } - if (!Node) - { - sprintf (ND_Error_Msg, "Error ND_Node_Add : the node to add is null"); - ND_Error_Print (); - return NDS_ERRAPI; - } - - return ND_Node_Add_I (Root, Node); + return ND_Index_Node_Previous_Get_I( Prev_Node_Ptr_Ptr, Node_Ptr); } -/*------------------------------------------------------------------------------*/ -/* Suppression d'un noeud dans une structure de données */ -/*------------------------------------------------------------------------------*/ -/* (I) Node: pointeur sur le noeud à supprimer */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_Node_Remove_C ( NDT_Node * Node ) -{ - if (!Node) - { - sprintf (ND_Error_Msg, "Error ND_Node_Remove : the node to remove is null"); - ND_Error_Print (); - return NDS_ERRAPI; - } - return ND_Node_Remove_I (Node); -} + + /*------------------------------------------------------------------------------*/ /* Recherche un noeud à partir d'une valeur */ @@ -1195,25 +2591,353 @@ NDT_Status ND_Node_Remove_C ( NDT_Node * Node ) /* (I) Value : pointeur sur la valeur à rechercher */ /* (I) Data : pointeur de données */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Node_Find_C ( NDT_Root * Root, NDT_Node ** Node, void * Value, void * Data ) + +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 (!Root) + if( ND_INDEX_TYPE_LIST_IS( Root_Ptr, Index_Id)) { - sprintf (ND_Error_Msg, "Error ND_Node_Find : structure root is null"); + *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_ERRAPI; } - if (!Value) - { - sprintf (ND_Error_Msg, "Error ND_Node_Find : the value to find is null"); - ND_Error_Print (); - return NDS_ERRAPI; - } - - return ND_Node_Find_I (Root, Node, Value, Data); + return( NDS_OK); } + + + + +/*------------------------------------------------------------------------------*/ +/* Recherche un noeud à partir d'une valeur */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de l'abre */ +/* (O) Node : adresse du pointeur sur le noeud à récuperer */ +/* (I) Value : pointeur sur la valeur à rechercher */ +/* (I) Data : pointeur de donné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 à partir d'une valeur */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de l'abre */ +/* (O) Node : adresse du pointeur sur le noeud à récuperer */ +/* (I) Value : pointeur sur la valeur à rechercher */ +/* (I) Data : pointeur de donné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 à partir d'une valeur */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de l'abre */ +/* (O) Node : adresse du pointeur sur le noeud à récuperer */ +/* (I) Value : pointeur sur la valeur à rechercher */ +/* (I) Data : pointeur de donné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 à partir d'une valeur */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de l'abre */ +/* (O) Node : adresse du pointeur sur le noeud à récuperer */ +/* (I) Value : pointeur sur la valeur à rechercher */ +/* (I) Data : pointeur de donné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 à partir d'une valeur */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de l'abre */ +/* (O) Node : adresse du pointeur sur le noeud à récuperer */ +/* (I) Value : pointeur sur la valeur à rechercher */ +/* (I) Data : pointeur de donné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 à partir d'une valeur */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de l'abre */ +/* (O) Node : adresse du pointeur sur le noeud à récuperer */ +/* (I) Value : pointeur sur la valeur à rechercher */ +/* (I) Data : pointeur de donné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 à partir d'une valeur */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de l'abre */ +/* (O) Node : adresse du pointeur sur le noeud à récuperer */ +/* (I) Value : pointeur sur la valeur à rechercher */ +/* (I) Data : pointeur de donné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ération de la racine d'une structure */ +/*------------------------------------------------------------------------------*/ +/* (O) Root : adresse du pointeur sur la racine à récupé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ération de la racine d'une structure */ +/*------------------------------------------------------------------------------*/ +/* (O) Root : adresse du pointeur sur la racine à récupé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ées */ /*------------------------------------------------------------------------------*/ @@ -1221,81 +2945,67 @@ NDT_Status ND_Node_Find_C ( NDT_Root * Root, NDT_Node ** Node, void * Value, voi /* (O) Value : adresse d'un pointeur sur la valeur à allouer */ /* (I) ... : arguments relatifs à l'allocation de la valeur */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Value_Alloc_C ( NDT_Root * Root, void ** Value, ... ) -{ - NDT_Status rc; - va_list Args; - if (!Root) - { - sprintf (ND_Error_Msg, "Error ND_Value_Alloc : structure root is null"); - ND_Error_Print (); - return NDS_ERRAPI; - } +NDT_Status ND_Value_Alloc_I( NDT_Root *Root_Ptr, void **Value_Ptr_Ptr, ...) +{ + NDT_Status rc; + va_list user_args; + /* Récupération des arguments pour l'allocation de la valeur */ - va_start (Args, Value); + va_start( user_args, Value_Ptr_Ptr); /* Appel du manager */ - rc = ND_Manager_Exec_I (Root->Manager, NDD_CMD_MAKE_VALUE, Root, Value, Args); + rc = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_UNKNOWN, NULL, NDD_CMD_VALUE_ALLOC, Value_Ptr_Ptr, user_args); - va_end (Args); + va_end( user_args); return rc; } + + + + /*------------------------------------------------------------------------------*/ -/* Ajout d'une valeur à une structure de données */ +/* Allocation d'une valeur d'une structure de données */ /*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine de la structure de données */ -/* (I) Value : pointeur sur la valeur à ajouter à la structure de données */ +/* (I) Root : pointeur sur la racine de la structure de données */ +/* (O) Value : adresse d'un pointeur sur la valeur à allouer */ +/* (I) ... : arguments relatifs à l'allocation de la valeur */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Value_Add_C ( NDT_Root * Root, void * Value ) + +NDT_Status ND_Value_Alloc_C( NDT_Root *Root_Ptr, void **Value_Ptr_Ptr, ...) { - if (!Root) + NDT_Status rc; + va_list user_args; + + + if( !Root_Ptr) { - sprintf (ND_Error_Msg, "Error ND_Value_Add : structure root is null"); - ND_Error_Print (); - return NDS_ERRAPI; + sprintf( ND_Error_Msg, "Error ND_Value_Alloc : structure root is null"); + ND_Error_Print(); + return(NDS_ERRAPI); } - if (!Value) - { - sprintf (ND_Error_Msg, "Error ND_Value_Add : the value to add is null"); - ND_Error_Print (); - return NDS_ERRAPI; - } + /* Récupération des arguments pour l'allocation de la valeur */ - return ND_Value_Add_I (Root, Value ); + 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); } -/*------------------------------------------------------------------------------*/ -/* Suppression du premier noeud correspondant à une valeur donnée */ -/*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine de la structure de données */ -/* (I) Reference_Value : pointeur sur la valeur de référence */ -/* (I) Removed_Value : adresse d'un pointeur sur la valeur supprimée */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_Value_Remove_C ( NDT_Root * Root, void * Reference_Value, void ** Removed_Value ) -{ - if (!Root) - { - sprintf (ND_Error_Msg, "Error ND_Value_Remove : structure root is null"); - ND_Error_Print (); - return NDS_ERRAPI; - } - if (!Reference_Value) - { - sprintf (ND_Error_Msg, "Error ND_Value_Remove : the reference value is null"); - ND_Error_Print (); - return NDS_ERRAPI; - } - return ND_Value_Remove_I (Root, Reference_Value, Removed_Value); -} + /*------------------------------------------------------------------------------*/ /* Désallocation d'une valeur d'une structure de données */ @@ -1303,59 +3013,170 @@ NDT_Status ND_Value_Remove_C ( NDT_Root * Root, void * Reference_Value, void ** /* (I) Root: pointeur sur la racine de la structure de données */ /* (I) Value: pointeur sur la valeur à désallouer */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Value_Free_C ( NDT_Root * Root, void * Value ) + +NDT_Status ND_Value_Free_I( NDT_Root *Root_Ptr, void *Value_Ptr) { - if (!Root) + 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ées */ +/*------------------------------------------------------------------------------*/ +/* (I) Root: pointeur sur la racine de la structure de données */ +/* (I) Value: pointeur sur la valeur à 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 : structure root is null"); - ND_Error_Print (); - return NDS_ERRAPI; + sprintf( ND_Error_Msg, "Error ND_Value_Free_C : structure root is null"); + ND_Error_Print(); + return( NDS_ERRAPI); } - if (!Value) + if( !Value_Ptr) { - sprintf (ND_Error_Msg, "Error ND_Value_Free : the value to free is null"); - ND_Error_Print (); - return NDS_ERRAPI; + 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, Value); + return( ND_Value_Free_I( Root_Ptr, Value_Ptr)); } + + + /*------------------------------------------------------------------------------*/ /* Exécution d'une fonction Manager dont le nom est passé en paramètre */ /*------------------------------------------------------------------------------*/ /* (I) Function : nom de la fonction manager à exécuter */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Manager_Exec_C ( const char * Function, ... ) -{ - NDT_Manager * Manager; - NDT_Status rc; - va_list Args; - if (!Function || !*Function) +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écution d'une fonction Manager dont le nom est passé en paramètre */ +/*------------------------------------------------------------------------------*/ +/* (I) Function : nom de la fonction manager à exé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 : undefined function name"); - ND_Error_Print (); - return NDS_ERRAPI; + sprintf( ND_Error_Msg, "Error ND_Manager_Exec_VC : structure root is null"); + ND_Error_Print(); + return( NDS_ERRAPI); } - va_start (Args, Function); + 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); + } - Manager = (NDT_Manager *) ND_Symbol_Find (Function); + status = ND_Manager_Exec_VI( Root_Ptr, Index_Id, Node_Ptr, Command, Args); - if (!Manager) return NDS_ERRAPI; - - rc = Manager (Args); - - va_end (Args); - - return rc; + return(status); } + + + + +/*------------------------------------------------------------------------------*/ +/* Exécution d'une fonction Manager dont le nom est passé en paramètre */ +/*------------------------------------------------------------------------------*/ +/* (I) Function : nom de la fonction manager à exé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écution d'une fonction Manager dont le nom est passé en paramètre */ +/*------------------------------------------------------------------------------*/ +/* (I) Function : nom de la fonction manager à exé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écution d'une fonction d'allocation dont le nom est passé en paramètre */ /*------------------------------------------------------------------------------*/ @@ -1364,26 +3185,56 @@ NDT_Status ND_Manager_Exec_C ( const char * Function, ... ) /* (I) Size : taille de la zone à allouer */ /* (I) Data : données utilisateur utiles à l'allocateur */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Allocator_Exec_C ( const char * Function, void ** Ptr, size_t Size, void * Data ) + +NDT_Status ND_Allocator_Exec_I( NDT_Allocator *Function, void **Ptr_Ptr, size_t Size, void *Data_Ptr) { - NDT_Allocator * Allocator; + NDT_Allocator *allocator_ptr; - *Ptr = NULL; + *Ptr_Ptr = NULL; - if (!Function || !*Function) + allocator_ptr = Function; + + return allocator_ptr( Size, Ptr_Ptr, Data_Ptr); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Exécution d'une fonction d'allocation dont le nom est passé en paramètre */ +/*------------------------------------------------------------------------------*/ +/* (I) Function : nom de la fonction à exécuter */ +/* (O) Ptr : adresse d'un pointeur sur la zone à allouer */ +/* (I) Size : taille de la zone à allouer */ +/* (I) Data : données utilisateur utiles à 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"); + sprintf( ND_Error_Msg, "Error ND_Allocator_Exec : undefined function name"); ND_Error_Print (); - return NDS_ERRAPI; + return(NDS_ERRAPI); } - Allocator = (NDT_Allocator *) ND_Symbol_Find (Function); + Allocator_Ptr = Function; - if (!Allocator) return NDS_ERRAPI; + if( !Allocator_Ptr) return(NDS_ERRAPI); - return Allocator (Size, Ptr, Data); + return( Allocator_Ptr (Size, Ptr_Ptr, Data_Ptr)); } + + + + /*------------------------------------------------------------------------------*/ /* Exécution d'une fonction de désallocation dont nom est passé en paramètre */ /*------------------------------------------------------------------------------*/ @@ -1391,9 +3242,32 @@ NDT_Status ND_Allocator_Exec_C ( const char * Function, void ** Ptr, size_t Size /* (I) Ptr : adresse de la zone à désallouer */ /* (I) Data : données utilisateur utiles à l'allocateur */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Desallocator_Exec_C ( const char * Function, void * Ptr, void * Data ) + +NDT_Status ND_Desallocator_Exec_I( NDT_Desallocator *Function, void *Ptr, void *Data_Ptr) { - NDT_Desallocator * Desallocator; + NDT_Desallocator *desallocator_ptr; + + desallocator_ptr = Function; + + return desallocator_ptr( Ptr, Data_Ptr); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Exécution d'une fonction de désallocation dont nom est passé en paramètre */ +/*------------------------------------------------------------------------------*/ +/* (I) Function : nom de la fonction à exécuter */ +/* (I) Ptr : adresse de la zone à désallouer */ +/* (I) Data : données utilisateur utiles à l'allocateur */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Desallocator_Exec_C( NDT_Desallocator *Function, void *Ptr, void *Data_Ptr) +{ + NDT_Desallocator *desallocator_ptr; + if (!Function || !*Function) { @@ -1402,13 +3276,26 @@ NDT_Status ND_Desallocator_Exec_C ( const char * Function, void * Ptr, void * Da return NDS_ERRAPI; } - Desallocator = (NDT_Desallocator *) ND_Symbol_Find (Function); + desallocator_ptr = Function; - if (!Desallocator) return NDS_ERRAPI; + if( !desallocator_ptr) return( NDS_ERRAPI); - return Desallocator (Ptr, Data); + return desallocator_ptr( Ptr, Data_Ptr); } + + + + + + +/*------------------------------------------------------------------------------*/ +/* FONCTIONS SECURISEES (ND_MODE = 0) */ +/*------------------------------------------------------------------------------*/ + + + + /*------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------*/ /* FONCTIONS PRIVEES */ @@ -1434,10 +3321,10 @@ void * ND_Symbol_Find ( const char * Symbol_Name ) /* Si le symbole n'a pas été trouvée dans la table des symboles locale, on l'y ajoute */ - Ptr = dlsym (RTLD_DEFAULT, (const char *) Symbol_Name); +// 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, dlerror ()); + 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; } @@ -1454,49 +3341,53 @@ void * ND_Symbol_Find ( const char * Symbol_Name ) 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, NDT_Node ** Node ) + +NDT_Status ND_Node_Alloc( NDT_Root *Root_Ptr, NDT_Node **Node_Ptr_Ptr ) { - NDT_Status rc; + NDT_Status rc; - rc = ND_Allocator_Exec_I (Root->Allocator, (void **)Node, sizeof (NDT_Node), Root->User); - if (ND_ERROR(rc)) return 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)->Parent = NULL; - (*Node)->Left = NULL; - (*Node)->Right = NULL; - (*Node)->Root = NULL; - (*Node)->Value = NULL; + (*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; + return(NDS_OK); } + + + + /*------------------------------------------------------------------------------*/ /* Désallocation d'un noeud */ /*------------------------------------------------------------------------------*/ /* (I) Root: pointeur sur la racine de la structure */ /* (I) Node : pointeur sur le noeud à détruire */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Node_Free ( NDT_Root * Root, NDT_Node * Node ) +NDT_Status ND_Node_Free ( NDT_Root *Root_Ptr, NDT_Node *Node_Ptr) { - return ND_Desallocator_Exec_I (Root->Desallocator, Node, Root->User); + return ND_Desallocator_Exec_I( Root_Ptr->Desallocator_Ptr, Node_Ptr, Root_Ptr->User); } -/*------------------------------------------------------------------------------*/ -/* Désallocation de la racine d'une structure de donnée */ -/*------------------------------------------------------------------------------*/ -/* (I) Root : pointeur sur la racine à détruire */ -/*------------------------------------------------------------------------------*/ -NDT_Status ND_Root_Free ( NDT_Root * Root ) -{ - return ND_Desallocator_Exec_I (Root->Desallocator, Root, Root->User); -} + + + /*------------------------------------------------------------------------------*/ /* Allocation d'une racine de structure de données */ @@ -1507,53 +3398,88 @@ NDT_Status ND_Root_Free ( NDT_Root * Root ) /* (I) Desallocator: pointeur vers la fonction de désallocation */ /* (I) Data : pointeur de données utiles à l'allocateur */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Root_Alloc ( NDT_Root ** Root, NDT_DataStruct_Type Type, const char * Allocator, const char * Desallocator, void * Data ) + +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 rc; + NDT_Status status; + NDT_Index_Id index_id; - rc = ND_Allocator_Exec_I (Allocator, (void **)Root, sizeof (NDT_Root), Data); - if (ND_ERROR(rc)) return rc; + 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); - (*Root)->Type = Type; + 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; - (*Root)->Head = NULL; - (*Root)->Queue = NULL; - (*Root)->Save = NULL; + 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; - (*Root)->Max_Dif = DEF_MAX_DIF; + 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)->Node_Number = 0; - (*Root)->Max_Depth = 0; - (*Root)->Min_Depth = HUGE_LONG; - (*Root)->Nb_Equ = 0; - (*Root)->User = Data; - (*Root)->Own_Value = TRUE; /* par défaut, une structure de données est propriétaire de ses valeurs */ + (*Root_Ptr_Ptr)->Own_Value = Own_Value; + (*Root_Ptr_Ptr)->User = Data_Ptr; - strcpy ((*Root)->Manager, "Default_Manager"); - strcpy ((*Root)->Allocator, Allocator); - strcpy ((*Root)->Desallocator, Desallocator); + (*Root_Ptr_Ptr)->Index_Nb = Index_Nb; + (*Root_Ptr_Ptr)->Index_Open_Nb = 0; - return NDS_OK; + for( index_id = 0; index_id <= Index_Nb; index_id++) + { + (*Root_Ptr_Ptr)->Index_Tab[index_id].Type = NDD_INDEX_STATUS_CLOSED; + + 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); + + (*Root_Ptr_Ptr)->Index_Open_Nb++; + } + } + + return(NDS_OK); } + + + + +/*------------------------------------------------------------------------------*/ +/* Désallocation de la racine d'une structure de donnée */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine à 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 à une liste chaînée */ /*------------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la liste */ /* (I) New_Node : pointeur sur le noeud à ajouter */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_List_Node_Add ( NDT_Root * Root, NDT_Node * New_Node ) + +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ée */ - if (ND_IS_ORDERED(Root)) + if( ND_INDEX_SUBTYPE_SORTED_IS( Root_Ptr, Index_Id)) { - NDT_Node * Node; - NDT_Status rc; + NDT_Node *node_ptr; + NDT_Status rc; - New_Node->Root = Root; - New_Node->Parent = New_Node->Left = New_Node->Right = NULL; + + 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ée peut être orientée de 2 manières : @@ -1562,43 +3488,43 @@ NDT_Status ND_List_Node_Add ( NDT_Root * Root, NDT_Node * New_Node ) - FILO : un noeud sera inséré AVANT un noeud de même valeur */ - if (ND_IS_FILO(Root)) + if( ND_INDEX_SUBTYPE_LIFO_IS( Root_Ptr, Index_Id)) { /* Pour une liste triée orientée FILO, on parcourt la liste en sens normal */ - Node = Root->Head; + node_ptr = Root_Ptr->Index_Tab[Index_Id].Head; - while (Node) + while( node_ptr) { - rc = ND_Manager_Exec_I (Root->Manager, NDD_CMD_COMP_VALUE, New_Node->Value, Node->Value); + 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 = Node->Right; + if(rc == NDS_GREATER) + node_ptr = node_ptr->Right; else { /* On insère avant le noeud courant si le nouveau noeud est de valeur inférieure ou égale */ - New_Node->Left = Node->Left; - New_Node->Right = Node; + New_Node_Ptr->Left = node_ptr->Left; + New_Node_Ptr->Right = node_ptr; - if (!Node->Left) Root->Head = New_Node; - else Node->Left->Right = New_Node; + if(!node_ptr->Left) Root_Ptr->Index_Tab[Index_Id].Head = New_Node_Ptr; + else node_ptr->Left->Right = New_Node_Ptr; - Node->Left = New_Node; - Node = NULL; + node_ptr->Left = New_Node_Ptr; + node_ptr = NULL; } } /* Insertion en queue de liste si le noeud n'a pas été inséré */ - if (!New_Node->Left && !New_Node->Right) + if(!New_Node_Ptr->Left && !New_Node_Ptr->Right) { - if (!Root->Queue) Root->Head = Root->Queue = New_Node; + 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->Queue->Right = New_Node; - New_Node->Left = Root->Queue; - Root->Queue = New_Node; + 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; } } } @@ -1606,130 +3532,165 @@ NDT_Status ND_List_Node_Add ( NDT_Root * Root, NDT_Node * New_Node ) { /* Pour une liste triée orientée FIFO, on parcourt la liste dans le sens inverse */ - Node = Root->Queue; - while (Node) + node_ptr = Root_Ptr->Index_Tab[Index_Id].Tail; + while( node_ptr) { - rc = ND_Manager_Exec_I (Root->Manager, NDD_CMD_COMP_VALUE, New_Node->Value, Node->Value); + 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ère après le noeud courant si le nouveau noeud est de valeur strictement supérieure ou égale */ - if (rc == NDS_LOWER) Node = Node->Left; + if( rc == NDS_LOWER) node_ptr = node_ptr->Left; else { - New_Node->Left = Node; - New_Node->Right = Node->Right; + New_Node_Ptr->Left = node_ptr; + New_Node_Ptr->Right = node_ptr->Right; - if (!Node->Right) Root->Queue = New_Node; - else Node->Right->Left = New_Node; + if( !node_ptr->Right) Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr; + else node_ptr->Right->Left = New_Node_Ptr; - Node->Right = New_Node; - Node = NULL; + node_ptr->Right = New_Node_Ptr; + node_ptr = NULL; } } /* Insertion en tête de liste si le noeud n'a pas été inséré */ - if (!New_Node->Left && !New_Node->Right) + if( !New_Node_Ptr->Left && !New_Node_Ptr->Right) { - if (!Root->Head) Root->Head = Root->Queue = New_Node; + 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->Head->Left = New_Node; - New_Node->Right = Root->Head; - Root->Head = New_Node; + 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->Node_Number++; + Root_Ptr->Index_Tab[Index_Id].Node_Number++; - return NDS_OK; + return( NDS_OK); } else { /* FIFO = ajout en queue de liste */ - if (ND_IS_FIFO(Root)) + if( ND_INDEX_SUBTYPE_FIFO_IS( Root_Ptr, Index_Id)) { - New_Node->Root = Root; - New_Node->Parent = NULL; - New_Node->Left = Root->Queue; - New_Node->Right = NULL; + 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->Head) Root->Head = New_Node; - else Root->Queue->Right = New_Node; + 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->Queue = New_Node; - Root->Node_Number++; + Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr; + Root_Ptr->Index_Tab[Index_Id].Node_Number++; - return NDS_OK; + return( NDS_OK); } /* FILO = ajout en tête de liste */ - if (ND_IS_FILO(Root)) + if( ND_INDEX_SUBTYPE_LIFO_IS( Root_Ptr, Index_Id)) { - New_Node->Root = Root; + 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; - New_Node->Parent = NULL; - New_Node->Left = NULL; - New_Node->Right = Root->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; - if (!Root->Queue) Root->Queue = New_Node; - else Root->Head->Left = New_Node; + Root_Ptr->Index_Tab[Index_Id].Head = New_Node_Ptr; + Root_Ptr->Index_Tab[Index_Id].Node_Number++; - Root->Head = New_Node; - Root->Node_Number++; - - return NDS_OK; + return( NDS_OK); } } - printf ("ND_List_Node_Add : unknown list type (%d)\n", Root->Type); - return NDS_ERRAPI; + 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 à une liste */ /*------------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la liste */ /* (I) Value : pointeur sur la valeur à ajouter */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_List_Value_Add ( NDT_Root * Root, void * Value ) + +NDT_Status ND_List_Value_Add( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr) { - NDT_Status rc; - NDT_Node * Node; + NDT_Status rc; + NDT_Node *node_ptr; - rc = ND_Node_Alloc (Root, &Node); - if (ND_ERROR(rc)) return rc; + rc = ND_Node_Alloc( Root_Ptr, &node_ptr); + if( ND_ERROR(rc)) return(rc); - Node->Value = Value; + node_ptr->Value = Value_Ptr; - return ND_List_Node_Add (Root, Node); +// 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 à un arbre binaire */ /*------------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de l'arbre */ /* (I) Value : pointeur sur la valeur à ajouter */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Tree_Value_Add ( NDT_Root * Root, void * Value ) + +NDT_Status ND_Tree_Value_Add( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr) { NDT_Status rc; - NDT_Node * Node; + NDT_Node *node_ptr; - rc = ND_Node_Alloc (Root, &Node); - if (ND_ERROR(rc)) return rc; + rc = ND_Node_Alloc( Root_Ptr, &node_ptr); + if( ND_ERROR(rc)) return(rc); - Node->Value = Value; + node_ptr->Value = Value_Ptr; - return ND_Tree_Node_Add (Root, Node); +// 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 */ /*------------------------------------------------------------------------------*/ @@ -1737,37 +3698,42 @@ NDT_Status ND_Tree_Value_Add ( NDT_Root * Root, void * Value ) /* (I) Value : pointeur sur la valeur à rechercher */ /* (I) Data : pointeur de données */ /*------------------------------------------------------------------------------*/ -NDT_Node * ND_List_Node_Find ( NDT_Root * Root, void * Value, void * Data ) + +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; - NDT_Status rc; + NDT_Node *node_ptr; + NDT_Status rc; - Node = Root->Head; - if (ND_IS_ORDERED(Root)) + node_ptr = Root_Ptr->Index_Tab[Index_Id].Head; + + if( ND_INDEX_SUBTYPE_SORTED_IS( Root_Ptr, Index_Id)) { /* Pour les listes triées, la recherche peut être optimisée */ - while (Node) + while( node_ptr) { - rc = ND_Manager_Exec_I (Root->Manager, NDD_CMD_COMP_VALUE, Value, Node->Value, Data); + 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; + { + return(node_ptr); + } case NDS_LOWER: - + { /* Ce n'est pas a peine de continuer car on a déjà dépassé la valeur recherchée */ - return NULL; + return(NULL); + } case NDS_GREATER: - - Node = Node->Right; + { + node_ptr = node_ptr->Right; break; + } } } } @@ -1775,13 +3741,19 @@ NDT_Node * ND_List_Node_Find ( NDT_Root * Root, void * Value, void * Data ) { /* Pour les listes non triées, il faut parcourir toute la liste */ - while (Node && ND_Manager_Exec_I (Root->Manager, NDD_CMD_COMP_VALUE, Value, Node->Value, Data) != NDS_EQUAL) - Node = Node->Right; + 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; + return node_ptr; } + + + + /*------------------------------------------------------------------------------*/ /* Recherche un noeud dans un arbre et retourne le pointeur sur le noeud */ /*------------------------------------------------------------------------------*/ @@ -1792,84 +3764,107 @@ NDT_Node * ND_List_Node_Find ( NDT_Root * Root, void * Value, void * Data ) /*------------------------------ Recursive Kernel ------------------------------*/ -NDT_Node * ND_Tree_Node_Recursive_Find ( NDT_Node * Node, void * Value, void * Data ) +NDT_Node *ND_Tree_Node_Recursive_Find( NDT_Node *Node_Ptr, void *Value_Ptr, va_list User_Args) { - NDT_Status Answer; + NDT_Status answer; - if (!Node) return NULL; - Answer = ND_Manager_Exec_I (Node->Root->Manager, NDD_CMD_COMP_VALUE, Value, Node->Value, Data); + 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é */ - if (Answer == NDS_EQUAL) return Node; + 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->Left, Value, Data); + 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->Right, Value, Data); + if( answer == NDS_GREATER) return( ND_Tree_Node_Recursive_Find( Node_Ptr->Right, Value_Ptr, User_Args)); - return NULL; + return(NULL); } + + /*-------------------------------- main body ---------------------------------*/ -NDT_Node * ND_Tree_Node_Find ( NDT_Root * Root, void * Value, void * Data ) +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->Head, Value, Data); + return( ND_Tree_Node_Recursive_Find( Root_Ptr->Index_Tab[Index_Id].Head, Value_Ptr, User_Args)); } + + + + /*------------------------------------------------------------------------------*/ /* Recherche du premier noeud parent situé après */ /*------------------------------------------------------------------------------*/ /* (I) Node : pointeur sur le noeud */ /*------------------------------------------------------------------------------*/ -NDT_Node * ND_Tree_Parent_Next_Recursive_Get ( NDT_Node * Node ) + +NDT_Node *ND_Tree_Parent_Next_Recursive_Get( NDT_Node *Node_Ptr) { - if (!Node->Parent) return NULL; + if( !Node_Ptr->Parent) return( NULL); - if (Node == Node->Parent->Right) return ND_Tree_Parent_Next_Recursive_Get (Node->Parent); + if( Node_Ptr == Node_Ptr->Parent->Right) return( ND_Tree_Parent_Next_Recursive_Get( Node_Ptr->Parent)); - return Node->Parent; + return( Node_Ptr->Parent); } + + + + /*------------------------------------------------------------------------------*/ /* Recherche du premier noeud parent situé avant */ /*------------------------------------------------------------------------------*/ /* (I) Node : pointeur sur le noeud */ /*------------------------------------------------------------------------------*/ -NDT_Node * ND_Tree_Parent_Previous_Recursive_Get ( NDT_Node * Node ) + +NDT_Node *ND_Tree_Parent_Previous_Recursive_Get( NDT_Node *Node_Ptr) { - if (!Node->Parent) return NULL; + if( !Node_Ptr->Parent) return( NULL); - if (Node == Node->Parent->Left) return ND_Tree_Parent_Previous_Recursive_Get (Node->Parent); + if( Node_Ptr == Node_Ptr->Parent->Left) return( ND_Tree_Parent_Previous_Recursive_Get( Node_Ptr->Parent)); - return Node->Parent; + return( Node_Ptr->Parent); } + + + + /*------------------------------------------------------------------------------*/ /* Supprime le noeud d'une liste */ /*------------------------------------------------------------------------------*/ /* (I) Node : pointeur sur le noeud à supprimer */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_List_Node_Remove ( NDT_Node * Node ) + +NDT_Status ND_List_Node_Remove( NDT_Node *Node_Ptr) { - if (!Node->Left) Node->Root->Head = Node->Right; - else Node->Left->Right = Node->Right; + 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->Right) Node->Root->Queue = Node->Left; - else Node->Right->Left = Node->Left; + 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->Root->Node_Number--; + Node_Ptr->Root->Index_Tab[Node_Ptr->Index].Node_Number--; - Node->Left = NULL; - Node->Right = NULL; - Node->Root = NULL; + Node_Ptr->Root = NULL; + Node_Ptr->Index = NDD_INDEX_UNKNOWN; + Node_Ptr->Left = NULL; + Node_Ptr->Right = NULL; - return NDS_OK; + return( NDS_OK); } + + + + /*------------------------------------------------------------------------------*/ /* Conversion d'un arbre en liste chaînée */ /*------------------------------------------------------------------------------*/ @@ -1878,40 +3873,47 @@ NDT_Status ND_List_Node_Remove ( NDT_Node * Node ) /*------------------------------- Recursive Kernel -----------------------------*/ -NDT_Status ND_List_Recursive_Make ( NDT_Node * Node, NDT_Root * Root ) +NDT_Status ND_List_Recursive_Make( NDT_Node *Node_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id) { - NDT_Node * Right_Node; + NDT_Node *right_node_ptr; - if (!Node) return NDS_OK; - if (ND_List_Recursive_Make (Node->Left, Root) != NDS_OK) return NDS_KO; + if( !Node_Ptr) return NDS_OK; - Right_Node = Node->Right; + if( ND_List_Recursive_Make( Node_Ptr->Left, Root_Ptr, Index_Id) != NDS_OK) return NDS_KO; - if (ND_List_Node_Add (Root, Node) != NDS_OK) return NDS_KO; + right_node_ptr = Node_Ptr->Right; - return ND_List_Recursive_Make (Right_Node, Root); + 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 ) +NDT_Status ND_List_Make( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id) { - NDT_Node * Node; + NDT_Node *node_ptr; - Node = Root->Head; + node_ptr = Root_Ptr->Index_Tab[Index_Id].Head; - Root->Head = NULL; - Root->Queue = NULL; - Root->Max_Dif = DEF_MAX_DIF; - Root->Node_Number = 0; - Root->Max_Depth = 0; - Root->Min_Depth = HUGE_LONG; - Root->Nb_Equ = 0; - Root->Type = NDD_DS_LIST | NDD_MN_FIFO; + 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, Root); + return( ND_List_Recursive_Make( node_ptr, Root_Ptr, Index_Id)); } + + + + /*------------------------------------------------------------------------------*/ /* Conversion d'une structure en arbre binaire */ /*------------------------------------------------------------------------------*/ @@ -1921,156 +3923,178 @@ NDT_Status ND_List_Make ( NDT_Root * Root ) /*------------------------------- Recursive Kernel -----------------------------*/ -NDT_Node * ND_Tree_Recursive_Make ( long Depth, long Node_Number, NDT_Node * Node ) +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, * Middle_Node, * Right_Node; + long middle_pos, left_len, right_len, i; + NDT_Node *left_node_ptr, *middle_node_ptr, *right_node_ptr; - if (!Node) return (NULL); + if( !Node_Ptr) return (NULL); /* On calcule le milieu de la liste */ - Middle_Pos = Node_Number / 2 + 1; + middle_pos = Node_Number / 2 + 1; + middle_node_ptr = Node_Ptr; - Middle_Node = Node; - - for (i = 1; i < Middle_Pos; i++) Middle_Node = Middle_Node->Right; + for( i = 1; i < middle_pos; i++) middle_node_ptr = middle_node_ptr->Right; /* On coupe la liste en deux */ - if (Middle_Node->Left) + if( middle_node_ptr->Left) { - Middle_Node->Left->Right = NULL; - Left_Node = Node; - Left_Len = Middle_Pos - 1; + middle_node_ptr->Left->Right = NULL; + left_node_ptr = Node_Ptr; + left_len = middle_pos - 1; } else { - Left_Node = NULL; - Left_Len = 0; + left_node_ptr = NULL; + left_len = 0; } - if (Middle_Node->Right) + if( middle_node_ptr->Right) { - Middle_Node->Right->Left = NULL; - Right_Node = Middle_Node->Right; - Right_Len = Node_Number - Middle_Pos; + middle_node_ptr->Right->Left = NULL; + right_node_ptr = middle_node_ptr->Right; + right_len = Node_Number - middle_pos; } else { - Right_Node = NULL; - Right_Len = 0; + right_node_ptr = NULL; + right_len = 0; } /* Construction des sous-arbres */ - Middle_Node->Left = ND_Tree_Recursive_Make (Depth + 1, Left_Len, Left_Node); + middle_node_ptr->Left = ND_Tree_Recursive_Make( Depth + 1, left_len, left_node_ptr); - Middle_Node->Right = ND_Tree_Recursive_Make (Depth + 1, Right_Len, Right_Node); + middle_node_ptr->Right = ND_Tree_Recursive_Make( Depth + 1, right_len, right_node_ptr); - if (Middle_Node->Left) Middle_Node->Left->Parent = Middle_Node; + if( middle_node_ptr->Left) middle_node_ptr->Left->Parent = middle_node_ptr; - if (Middle_Node->Right) Middle_Node->Right->Parent = Middle_Node; + if( middle_node_ptr->Right) middle_node_ptr->Right->Parent = middle_node_ptr; /* Mise à jour des informations statistiques de la structure */ - Middle_Node->Root->Node_Number++; + middle_node_ptr->Root->Index_Tab[middle_node_ptr->Index].Node_Number++; - if (!Middle_Node->Left && !Middle_Node->Right) + if( !middle_node_ptr->Left && !middle_node_ptr->Right) { /* Si le noeud courant est une feuille, on met éventuellement à jour les longueurs minimale et maximale des branches de l'arbre */ - if (Depth > Middle_Node->Root->Max_Depth) Middle_Node->Root->Max_Depth = Depth; + 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->Root->Min_Depth) Middle_Node->Root->Min_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; + return( middle_node_ptr); } + + /*--------------------------------- main body --------------------------------*/ -NDT_Status ND_Tree_Make ( NDT_Root * Root ) +NDT_Status ND_Tree_Make( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id ) { - NDT_Status rc; - NDT_Node * Node; - long Node_Number; + NDT_Status rc; + NDT_Node *node_ptr; + long node_number; - if (ND_IS_ORDERED(Root)) + + if( ND_INDEX_SUBTYPE_SORTED_IS( Root_Ptr, Index_Id)) { - rc = ND_List_Sort (Root); - if (ND_ERROR(rc)) return rc; + rc = ND_List_Sort( Root_Ptr, Index_Id); + if( ND_ERROR(rc)) return rc; } - Node = Root->Head; - Node_Number = Root->Node_Number; + node_ptr = Root_Ptr->Index_Tab[Index_Id].Head; + node_number = Root_Ptr->Index_Tab[Index_Id].Node_Number; - Root->Head = NULL; - Root->Queue = NULL; - Root->Max_Dif = DEF_MAX_DIF; - Root->Node_Number = 0; - Root->Max_Depth = 0; - Root->Min_Depth = HUGE_LONG; - Root->Nb_Equ = 0; - Root->Type = NDD_DS_TREE | NDD_MN_AUTO_EQU; + 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->Head = Root->Queue = ND_Tree_Recursive_Make (1, Node_Number, Node); + 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 ) + +NDT_Status ND_Tree_Equalize( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id) { - NDT_Status rc; - NDT_DataStruct_Type Type; - char Manager[30]; - long Max_Dif, Nb_Equ; + NDT_Status rc; + NDT_Index_Type type; +// char manager[30]; // Win32 + void *manager; // Win32 + long max_dif, nb_equ; - Type = Root->Type; - strcpy (Manager, Root->Manager); - Max_Dif = Root->Max_Dif; - Nb_Equ = Root->Nb_Equ; - rc = ND_List_Make (Root); - if (ND_ERROR(rc)) return rc; + 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; - Root->Type = NDD_DS_LIST | NDD_MN_ORDERED; + rc = ND_List_Make( Root_Ptr, Index_Id); + if( ND_ERROR(rc)) return(rc); - rc = ND_Tree_Make (Root); - 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; - Root->Type = Type; - strcpy (Root->Manager, Manager); - Root->Max_Dif = Max_Dif; - Root->Nb_Equ = Nb_Equ + 1; + rc = ND_Tree_Make( Root_Ptr, Index_Id); + if( ND_ERROR(rc)) return(rc); - return NDS_OK; + 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 à partir d'un noeud */ /*----------------------------------------------------------------------------*/ /* (I) Node : pointeur sur le noeud */ /*----------------------------------------------------------------------------*/ -long ND_Tree_MaxDepth_Get ( NDT_Node * Node ) + +long ND_Tree_MaxDepth_Get( NDT_Node *Node_Ptr) { - long Max_Left, Max_Right; + long Max_Left, Max_Right; - if (!Node) return 0; + if( !Node_Ptr) return ( 0); - Max_Left = ND_Tree_MaxDepth_Get (Node->Left); + Max_Left = ND_Tree_MaxDepth_Get( Node_Ptr->Left); - Max_Right = ND_Tree_MaxDepth_Get (Node->Right); + Max_Right = ND_Tree_MaxDepth_Get( Node_Ptr->Right); - return ( max (Max_Left, Max_Right) + 1 ); + return( NDD_MAX( Max_Left, Max_Right) + 1 ); } /*----------------------------------------------------------------------------*/ @@ -2078,19 +4102,25 @@ long ND_Tree_MaxDepth_Get ( NDT_Node * Node ) /*----------------------------------------------------------------------------*/ /* (I) Node : pointeur sur le noeud */ /*----------------------------------------------------------------------------*/ -long ND_Tree_MinDepth_Get ( NDT_Node * Node) + +long ND_Tree_MinDepth_Get( NDT_Node *Node_Ptr) { - long Min_Left, Min_Right; + long Min_Left, Min_Right; - if (!Node) return 0; - Min_Left = ND_Tree_MinDepth_Get (Node->Left); + if( !Node_Ptr) return( 0); - Min_Right = ND_Tree_MinDepth_Get (Node->Right); + Min_Left = ND_Tree_MinDepth_Get( Node_Ptr->Left); - return ( min (Min_Left, Min_Right) + 1 ); + Min_Right = ND_Tree_MinDepth_Get( Node_Ptr->Right); + + return( NDD_MIN( Min_Left, Min_Right) + 1 ); } + + + + /*----------------------------------------------------------------------------*/ /* Ajoute un noeud à un arbre */ /*----------------------------------------------------------------------------*/ @@ -2100,16 +4130,16 @@ long ND_Tree_MinDepth_Get ( NDT_Node * Node) /*------------------------------ Recursive Kernel ----------------------------*/ -void ND_Tree_Node_Recursive_Add ( NDT_Root * Root, NDT_Node * Parent_Node, NDT_Node ** Node, long Depth, NDT_Node * New_Node ) +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) + if( *Node_Ptr_Ptr) { /* Appel récursif */ - if (ND_Manager_Exec_I (Root->Manager, NDD_CMD_COMP_VALUE, New_Node->Value, (*Node)->Value) == NDS_LOWER) - ND_Tree_Node_Recursive_Add (Root, (*Node), &((*Node)->Left), Depth + 1, New_Node); + 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, (*Node), &((*Node)->Right), Depth + 1, New_Node); + ND_Tree_Node_Recursive_Add( Root_Ptr, Index_Id, (*Node_Ptr_Ptr), &((*Node_Ptr_Ptr)->Right), Depth + 1, New_Node_Ptr); } else { @@ -2117,59 +4147,73 @@ void ND_Tree_Node_Recursive_Add ( NDT_Root * Root, NDT_Node * Parent_Node, NDT_N /* Rattachement du nouveau noeud à l'arbre */ - New_Node->Parent = Parent_Node; - New_Node->Root = Root; + New_Node_Ptr->Root = Root_Ptr; + New_Node_Ptr->Index = Index_Id; + New_Node_Ptr->Parent = Parent_Node; - *Node = New_Node; + *Node_Ptr_Ptr = New_Node_Ptr; /* Mise à jour des informations statistiques de la structure */ - Root->Node_Number++; + Root_Ptr->Index_Tab[Index_Id].Node_Number++; - Max_Depth = ND_Tree_MaxDepth_Get (New_Node); + Max_Depth = ND_Tree_MaxDepth_Get( New_Node_Ptr); - Min_Depth = ND_Tree_MinDepth_Get (New_Node); + Min_Depth = ND_Tree_MinDepth_Get( New_Node_Ptr); - if (Max_Depth + Depth - 1 > Root->Max_Depth) Root->Max_Depth = Max_Depth + Depth - 1; + 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->Min_Depth) Root->Min_Depth = Min_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, NDT_Node * Node ) -{ - ND_Tree_Node_Recursive_Add (Root, NULL, &(Root->Head), 1, Node); - if (ND_IS_AUTO_EQU(Root) && Root->Max_Depth - Root->Min_Depth > Root->Max_Dif) - return ND_Tree_Equalize (Root); + +/*-------------------------------- 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 à 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, NDT_Root * List_Root) + +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; + NDT_Status rc; + NDT_Node *node_ptr; - Node = List_Root->Head; - while (Node) + node_ptr = List_Root_Ptr->Index_Tab[List_Index_Id].Head; + + while( node_ptr) { - rc = ND_Tree_Node_Add (Tree_Root, Node); - if (ND_ERROR(rc)) return rc; - Node = Node->Right; + 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; + return(NDS_OK); } + + + + /*------------------------------------------------------------------------------*/ /* Affiche toutes les informations d'une structure de données */ /*------------------------------------------------------------------------------*/ @@ -2178,19 +4222,20 @@ NDT_Status ND_Tree_List_Add ( NDT_Root * Tree_Root, NDT_Root * List_Root) /*------------------------------- Recursive Kernel -----------------------------*/ -void ND_Tree_Recursive_Print ( NDT_Node * Node, long Depth, FILE * Out ) +void ND_Tree_Recursive_Print( NDT_Node *Node_Ptr, long Depth, FILE *Out) { const int BRANCH_LEN = 4; - if (!Node) return; - if (Node->Right) + if( !Node_Ptr) return; + + if( Node_Ptr->Right) { - ND_Tree_Recursive_Print (Node->Right, Depth + 1, Out); - fprintf (Out, "%*s/\n", (int)(Depth * BRANCH_LEN - 1), ""); + 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); + fprintf( Out, "%*s (%p) ", (int)((Depth - 1) * BRANCH_LEN), "", Node_Ptr); /* Affichage des toutes les informations (noeud et valeur) : @@ -2206,235 +4251,283 @@ void ND_Tree_Recursive_Print ( NDT_Node * Node, long Depth, FILE * Out ) /* Affichage de la valeur seule : */ - ND_Manager_Exec_I (Node->Root->Manager, NDD_CMD_PRINT_VALUE, Node->Value, Out); - fprintf (Out, "\n"); + 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->Left) + if( Node_Ptr->Left) { - fprintf (Out, "%*s\\\n", (int)(Depth * BRANCH_LEN - 1), ""); - ND_Tree_Recursive_Print (Node->Left, Depth + 1, Out); + 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, void ** Node2 ) + +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, ((NDT_Node *)(*Node1))->Value, ((NDT_Node *)(*Node2))->Value); - switch ((int)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); + 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înée : */ /*----------------------------------------------------------------------------*/ /* (I) Root : pointeur sur la racine de la liste à trier */ /*----------------------------------------------------------------------------*/ -NDT_Status ND_List_Sort ( NDT_Root * Root ) -{ - int i; - NDT_Node * Node; - void ** Tab; - if (Root->Node_Number < 2) return NDS_OK; +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->Node_Number * sizeof (NDT_Node *)); + tab = (void **)malloc( Root_Ptr->Index_Tab[Index_Id].Node_Number * sizeof( NDT_Node *)); /* On remplit le tableau avec les noeuds de la structure à trier */ i = 0; - Node = Root->Head; - while (Node) + node_ptr = Root_Ptr->Index_Tab[Index_Id].Head; + + while( node_ptr) { - Tab[i] = Node; - Node = Node->Right; + tab[i] = node_ptr; + node_ptr = node_ptr->Right; i++; } /* Tri du tableau de pointeurs de noeuds */ - Tmp_Root = Root; +// Tmp_Root = Root; - qsort (Tab, (size_t)(Root->Node_Number), sizeof (NDT_Node *), &ND_Node_Compare); + // 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 à jour les liens entre les noeuds */ - for (i = 0; i < Root->Node_Number; i++) + for (i = 0; i < Root_Ptr->Index_Tab[0].Node_Number; i++) { - Node = (NDT_Node *) Tab [i]; + node_ptr = (NDT_Node *)tab[i]; - Node->Left = (i ? (NDT_Node *)(Tab [i - 1]) : NULL); - Node->Right = (i != Root->Node_Number - 1 ? (NDT_Node *)(Tab [i + 1]) : NULL); + 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->Head = (NDT_Node *)(Tab [0]); - Root->Queue = (NDT_Node *)(Tab [Root->Node_Number - 1]); + 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); + free(tab); - return NDS_OK; + return(NDS_OK); } + + + + /*------------------------------------------------------------------------------*/ /* Récupè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 ) + +NDT_Node *ND_Tree_Node_First_Recursive_Get( NDT_Node *Node_Ptr) { - if (!Node) return NULL; + if( !Node_Ptr) return NULL; - if (!Node->Left) return Node; + if( !Node_Ptr->Left) return(Node_Ptr); - return ND_Tree_Node_First_Recursive_Get (Node->Left); + return( ND_Tree_Node_First_Recursive_Get( Node_Ptr->Left)); } + + + + /*------------------------------------------------------------------------------*/ /* Récupè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 ) + +NDT_Node *ND_Tree_Node_Last_Recursive_Get( NDT_Node *Node_Ptr) { - if (!Node) return NULL; + if( !Node_Ptr) return NULL; - if (!Node->Right) return Node; + if( !Node_Ptr->Right) return(Node_Ptr); - return ND_Tree_Node_Last_Recursive_Get (Node->Right); + return ND_Tree_Node_Last_Recursive_Get( Node_Ptr->Right); } + + + + /*------------------------------------------------------------------------------*/ /* Redéfinition de la fonction malloc () avec retour de type NDT_Status */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Malloc ( size_t Size, void ** ptr, void * Data ) + +NDT_Status ND_Default_Allocator( size_t Size, void **Ptr_Ptr, void *Data_Ptr) { - *ptr = malloc (Size); + *Ptr_Ptr = malloc(Size); - if (!*ptr) return NDS_ERRMEM; - return NDS_OK; + if( !*Ptr_Ptr) return(NDS_ERRMEM); + + return(NDS_OK); } + + + + /*------------------------------------------------------------------------------*/ /* Redéfinition de la fonction free () avec retour de type NDT_Status */ /*------------------------------------------------------------------------------*/ -NDT_Status ND_Free (void * ptr) + +NDT_Status ND_Default_Desallocator( void *Ptr, void *Data_Ptr) { - if (!ptr) return NDS_ERRAPI; + if( !Ptr) return(NDS_ERRAPI); - free (ptr); + free( Ptr); - return NDS_OK; + return(NDS_OK); } + + + + /*------------------------------------------------------------------------------*/ /* Function de vérification d'une liste : */ /*------------------------------------------------------------------------------*/ -void ND_List_Check ( NDT_Root * Root, int * Nb_Detected, int * Nb_Corrected, FILE * Out ) + +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, Nb_Detected, Nb_Corrected, Out); + 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, Nb_Detected, Nb_Corrected, Out); + 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, int * Nb_Detected, int * Nb_Corrected, FILE * Out ) + +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; - int LeftToRight_Node_Number = 0; - int RightToLeft_Node_Number = 0; + NDT_Node *node_ptr; + int left2right_node_number = 0; + int right2left_node_number = 0; + /* On commence à vérifier si l'on trouve le même nombre de noeuds en parcourant la liste de droite à gauche, puis de gauche à droite */ - Node = Root->Head; + node_ptr = Root_Ptr->Index_Tab[Index_Id].Head; - while (Node) + while( node_ptr) { - LeftToRight_Node_Number++; - Node = Node->Right; + left2right_node_number++; + node_ptr = node_ptr->Right; } - Node = Root->Queue; + node_ptr = Root_Ptr->Index_Tab[Index_Id].Tail; - while (Node) + while( node_ptr) { - RightToLeft_Node_Number++; - Node = Node->Left; + right2left_node_number++; + node_ptr = node_ptr->Left; } /* Cas où tout est OK */ - if (LeftToRight_Node_Number == Root->Node_Number && LeftToRight_Node_Number == RightToLeft_Node_Number) return; + 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 été mis à jour au niveau de la racine */ - if (LeftToRight_Node_Number == RightToLeft_Node_Number) + if( left2right_node_number == right2left_node_number) { - Root->Node_Number = LeftToRight_Node_Number; - fprintf (Out, "\t- number of node has been corrected on structure %p\n", Root); - (*Nb_Detected)++; - (*Nb_Corrected)++; + 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 à droite est plus complet : il manque un lien 'Left' */ - if (LeftToRight_Node_Number > RightToLeft_Node_Number) + if( left2right_node_number > right2left_node_number) { - Node = Root->Head; + node_ptr = Root_Ptr->Index_Tab[Index_Id].Head; - while (Node) + while( node_ptr) { - if (Node->Right && Node->Right->Left != Node) + if( node_ptr->Right && ( node_ptr->Right->Left != node_ptr)) { - fprintf (Out, "\t- link 'Left' has been corrected on node %p of structure %p\n", Node->Right, Root); - Node->Right->Left = Node; - (*Nb_Detected)++; - (*Nb_Corrected)++; + 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->Right && Node != Root->Queue) + if( !node_ptr->Right && ( node_ptr != Root_Ptr->Index_Tab[Index_Id].Tail)) { - fprintf (Out, "\t- link 'Queue' has been corrected on structure %p\n", Root); - Root->Queue = Node; - (*Nb_Detected)++; - (*Nb_Corrected)++; + 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 = Node->Right; + node_ptr = node_ptr->Right; } - if (Root->Node_Number != LeftToRight_Node_Number) + if( Root_Ptr->Index_Tab[Index_Id].Node_Number != left2right_node_number) { - fprintf (Out, "\t- number of node has been corrected on structure %p\n", Root); - Root->Node_Number = LeftToRight_Node_Number; - (*Nb_Detected)++; - (*Nb_Corrected)++; + 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; @@ -2442,119 +4535,135 @@ void ND_List_Link_Check ( NDT_Root * Root, int * Nb_Detected, int * Nb_Corrected /* Cas où le parcours de droite à gauche est plus complet : il manque un lien 'Right' */ - if (RightToLeft_Node_Number> LeftToRight_Node_Number) + if( right2left_node_number > left2right_node_number) { - Node = Root->Queue; + node_ptr = Root_Ptr->Index_Tab[Index_Id].Tail; - while (Node) + while( node_ptr) { - if (Node->Left && Node->Left->Right != Node) + if( node_ptr->Left && ( node_ptr->Left->Right != node_ptr)) { - fprintf (Out, "\t- link 'Right' has been corrected on node %p of list %p\n", Node->Left, Root); - Node->Left->Right = Node; - (*Nb_Detected)++; - (*Nb_Corrected)++; + 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->Left && Node != Root->Head) + 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\n", Root); - Root->Head = Node; - (*Nb_Detected)++; - (*Nb_Corrected)++; + 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 = Node->Left; + node_ptr = node_ptr->Left; } - if (Root->Node_Number != RightToLeft_Node_Number) + if( Root_Ptr->Index_Tab[Index_Id].Node_Number != right2left_node_number) { - fprintf (Out, "\t- number of node has been corrected on structure %p\n", Root); - Root->Node_Number = RightToLeft_Node_Number; - (*Nb_Detected)++; - (*Nb_Corrected)++; + 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, int * Nb_Detected, int * Nb_Corrected, FILE * Out ) + +void ND_Value_Check( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected, int *Nb_Corrected, FILE *Out) { - NDT_Node * Node, * Next_Node; + NDT_Node *node_ptr, *next_node_ptr; + /* Chaque noeud sans valeur est purement et simplement supprimé de la liste */ - ND_Node_First_Get_I (Root, &Node); + ND_Index_Node_First_Get_I( &node_ptr, Root_Ptr, Index_Id); - while (Node) + while( node_ptr) { - ND_Node_Next_Get_I (Node, &Next_Node); + ND_Index_Node_Next_Get_I( &next_node_ptr, node_ptr); - if (!Node->Value) + if( !node_ptr->Value) { - fprintf (Out, "\t- node %p has been removed from structure %p because no value is attached to it\n", Node, Root); + 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_Node_Remove (Node); + ND_Index_Node_Remove( node_ptr); - Node = Next_Node; + node_ptr = next_node_ptr; (*Nb_Detected)++; (*Nb_Corrected)++; } - else if (ND_Address_Check (Node->Value) != NDS_OK) + else if( ND_Address_Check( node_ptr->Value) != NDS_OK) { - fprintf (Out, "\t- node %p has been removed from structure %p because its value cannot be accessed\n", Node, Root); + 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_Node_Remove (Node); + ND_Index_Node_Remove( node_ptr); - Node = Next_Node; + node_ptr = next_node_ptr; (*Nb_Detected)++; (*Nb_Corrected)++; } - else ND_Node_Next_Get (Node, &Node); + else ND_Index_Node_Next_Get( &node_ptr, node_ptr); } } + + + + /*------------------------------------------------------------------------------*/ /* Function de vérification d'un arbre : */ /*------------------------------------------------------------------------------*/ -void ND_Tree_Check ( NDT_Root * Root, int * Nb_Detected, int * Nb_Corrected, FILE * Out ) + +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, Nb_Detected, Nb_Corrected, Out); + ND_Tree_Link_Check( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out); /* On vérifie les valeurs attachées aux noeuds */ - ND_Value_Check (Root, Nb_Detected, Nb_Corrected, Out); + ND_Value_Check( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out); /* On met à jour les informations statistiques de la racine */ - Root->Max_Depth = ND_Tree_MaxDepth_Get (Root->Head); - Root->Min_Depth = ND_Tree_MaxDepth_Get (Root->Head); + 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, int * Nb_Detected, int * Nb_Corrected, FILE * Out ) + +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->Head) + if( Root_Ptr->Index_Tab[Index_Id].Head) { - if (Root->Head->Root != Root) + if( Root_Ptr->Index_Tab[Index_Id].Head->Root != Root_Ptr) { - Root->Head->Root = Root; - fprintf (Out, "\t- link 'Root' has been corrected on node %p of structure %p\n", Root->Head, Root); - (*Nb_Detected)++; - (*Nb_Corrected)++; + 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->Head, Nb_Detected, Nb_Corrected, Out); + ND_Tree_Link_Recursive_Check( Root_Ptr->Index_Tab[Index_Id].Head, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out); } /* @@ -2562,113 +4671,132 @@ void ND_Tree_Link_Check ( NDT_Root * Root, int * Nb_Detected, int * Nb_Corrected que la procédure ND_Node_Remove n'a pas été jusqu'à son terme). */ - if (Root->Save) + if( Root_Ptr->Index_Tab[Index_Id].Save) { - NDT_Node * Node; + NDT_Node *node_ptr; + /* On attache le noeud contenu dans 'Save' à l'arbre s'il n'existe pas déjà */ - if (ND_Node_Find (Root, &Node, Root->Save->Value, NULL) != NDS_OK) + if( ND_Index_Node_Find( &node_ptr, Root_Ptr, Index_Id, Root_Ptr->Index_Tab[Index_Id].Save->Value, NULL) != NDS_OK) { - ND_Node_Add (Root, Root->Save); - fprintf (Out, "\t- saved node %p has been restored to structure %p\n", Root->Save, Root); - (*Nb_Detected)++; - (*Nb_Corrected)++; + 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->Save = NULL; + Root_Ptr->Index_Tab[Index_Id].Save = NULL; } } + + /*------------------------------ Recursive Kernel ------------------------------*/ -void ND_Tree_Link_Recursive_Check ( NDT_Node * Node, int * Nb_Detected, int * Nb_Corrected, FILE * Out ) +void ND_Tree_Link_Recursive_Check( NDT_Node *Node_Ptr, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out) { - if (Node->Left) + if( Node_Ptr->Left) { - if (Node->Left->Root != Node->Root) + if( Node_Ptr->Left->Root != Node_Ptr->Root) { - Node->Left->Root = Node->Root; - fprintf (Out, "\t- link 'Root' has been corrected on node %p of structure %p\n", Node->Left, Node->Root); - (*Nb_Detected)++; - (*Nb_Corrected)++; + 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->Left->Parent != Node) + if( Node_Ptr->Left->Parent != Node_Ptr) { - Node->Left->Parent = Node; - fprintf (Out, "\t- link 'Parent' has been corrected on node %p of structure %p\n", Node->Left, Node->Root); - (*Nb_Detected)++; - (*Nb_Corrected)++; + 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->Left, Nb_Detected, Nb_Corrected, Out); + ND_Tree_Link_Recursive_Check( Node_Ptr->Left, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out); } - if (Node->Right) + if( Node_Ptr->Right) { - if (Node->Right->Root != Node->Root) + if( Node_Ptr->Right->Root != Node_Ptr->Root) { - Node->Right->Root = Node->Root; - fprintf (Out, "\t- link 'Root' has been corrected on node %p of structure %p\n", Node->Right, Node->Root); - (*Nb_Detected)++; - (*Nb_Corrected)++; + 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->Right->Parent != Node) + if( Node_Ptr->Right->Parent != Node_Ptr) { - Node->Right->Parent = Node; - fprintf (Out, "\t- link 'Parent' has been corrected on node %p of structure %p\n", Node->Right, Node->Root); - (*Nb_Detected)++; - (*Nb_Corrected)++; + 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->Right, Nb_Detected, Nb_Corrected, Out); + 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 ) + +NDT_Status ND_Address_Check( void *Address) { int test; + Sig_Trapped = 0; /* On trappe les signaux SIGBUS et SIGSEGV */ - signal (SIGBUS, ND_Signal_Trap); - signal (SIGSEGV, ND_Signal_Trap); +// signal (SIGBUS, ND_Signal_Trap); Win32 +// signal (SIGSEGV, ND_Signal_Trap); Win32 /* On tente d'accéder à l'adresse fournie */ - test = *((int *)Address); + test = *( (int *)Address); - sigrelse (SIGBUS); - sigrelse (SIGSEGV); +// sigrelse (SIGBUS); Win32 +// sigrelse (SIGSEGV); Win32 - if (Sig_Trapped != 0) return NDS_KO; + if( Sig_Trapped != 0) return(NDS_KO); - return NDS_OK; + return(NDS_OK); } + + + + /*------------------------------------------------------------------------------*/ /* Trap d'un signal */ /*------------------------------------------------------------------------------*/ -void ND_Signal_Trap ( int Sig_Num ) + +void ND_Signal_Trap( int Sig_Num) { Sig_Trapped = Sig_Num; } + + + + /*------------------------------------------------------------------------------*/ /* Routine d'affichage d'un message d'erreur */ /*------------------------------------------------------------------------------*/ -void ND_Error_Print ( void ) + +void ND_Error_Print( void) { - if (ND_stderr) fprintf (ND_stderr, "%s\n", ND_Error_Msg); + if( ND_stderr) fprintf( ND_stderr, "%s\n", ND_Error_Msg); }