From 1218622bc64f9c2bf6e55a2812a6d7ade57c5709 Mon Sep 17 00:00:00 2001 From: "Arnaud G. GIBERT" Date: Sun, 20 Mar 2022 23:46:24 +0100 Subject: [PATCH] Initial commit: - Kit and Instrument data structure - Kit and Instrument XML loading - No layer support! - No GFX and no Sound! --- .gitignore | 6 + drummer.c | 1626 +++++++++++++++ drummer.h | 288 +++ go.sh | 6 + libnode.c | 5876 ++++++++++++++++++++++++++++++++++++++++++++++++++++ libnode.h | 347 ++++ node.h | 1260 +++++++++++ 7 files changed, 9409 insertions(+) create mode 100644 .gitignore create mode 100644 drummer.c create mode 100644 drummer.h create mode 100755 go.sh create mode 100644 libnode.c create mode 100644 libnode.h create mode 100644 node.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e6e71d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*~ +*.o +*.so +*.ttl +drummer +/tmp diff --git a/drummer.c b/drummer.c new file mode 100644 index 0000000..17dbf1e --- /dev/null +++ b/drummer.c @@ -0,0 +1,1626 @@ +/*---------------------------------------------------------------------------------*/ +/* Includes */ +/*---------------------------------------------------------------------------------*/ + +#define _IMRD_C_ + + + +#include + + + + + +/*---------------------------------------------------------------------------------*/ +/* */ +/*---------------------------------------------------------------------------------*/ + +NDT_Status DR_Instrument_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list *Args_Ptr) +{ + NDT_Command_Name Command_Name; + + + switch( Command) + { + case NDD_CMD_MANAGER_VERSION: + { + ND_VA_ARG_GET( Version_Name_Ptr, *Args_Ptr, NDT_Version_Name *); + + + Command_Name = "NDD_CMD_MANAGER_VERSION"; + + *Version_Name_Ptr = "$Revision: 1.0 $ $Name: Instrument_Manager $ $Date: 2021/12/12 21:27:12 $ $Author: agibert $"; + + return( NDS_OK); + } + + case NDD_CMD_INDEX_GET: + { + /* + ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *); + ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *); + ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command); + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + */ + + ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *); + ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *); + ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command); + ND_VA_ARG_GET( Instrument_Ptr, *Args_Ptr, DRT_Instrument *); + + + 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; + } + ... + */ + + case NDD_CMD_INDEX0_PRINT: + { + *Reply_Index_Id_Ptr = 0; + *Reply_Command_Ptr = Cmd; + break; + } + + case NDD_CMD_INDEX1_PRINT: + { + *Reply_Index_Id_Ptr = 1; + *Reply_Command_Ptr = Cmd; + break; + } + + default: + { + *Reply_Index_Id_Ptr = Index_Id; + *Reply_Command_Ptr = Cmd; + break; + } + } + + return( NDS_OK); + } + + case NDD_CMD_VALUE_ALLOC: + { + /* + ND_VA_ARG_GET( Value_Ptr_Ptr, *Args_Ptr, void **); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + ND_VA_ARG_GET( Instrument_Ptr_Ptr, *Args_Ptr, DRT_Instrument **); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + ND_VA_ARG_GET( Name, user_args, char *); + ND_VA_ARG_GET( FileName, user_args, char *); + ND_VA_ARG_GET( Gain, user_args, double); + ND_VA_ARG_GET( Sample_Ptr, user_args, char *); + ND_VA_ARG_GET( Sample_Size, user_args, long); + + ND_VA_LIST_CLOSE( user_args); + + + Command_Name = "NDD_CMD_VALUE_ALLOC"; + + if( ( *Instrument_Ptr_Ptr = (DRT_Instrument *)malloc( sizeof( DRT_Instrument))) != NULL) + { + ( *Instrument_Ptr_Ptr)->Id = Root_Ptr->Index_Tab[NDD_INDEX_PRIMARY].Node_Number; + + strncpy( ( *Instrument_Ptr_Ptr)->Name, Name, NAME_LEN); + strncpy( ( *Instrument_Ptr_Ptr)->FileName, FileName, FILENAME_LEN); + + (*Instrument_Ptr_Ptr)->Name[ NAME_LEN] = '\0'; + (*Instrument_Ptr_Ptr)->FileName[FILENAME_LEN] = '\0'; + + ( *Instrument_Ptr_Ptr)->Gain = Gain; + ( *Instrument_Ptr_Ptr)->Sample_Ptr = Sample_Ptr; + ( *Instrument_Ptr_Ptr)->Sample_Size = Sample_Size; + + return( NDS_OK); + } + else + { + return( NDS_KO); + } + } + + case NDD_CMD_VALUE_FREE: + { + /* + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + ND_VA_ARG_GET( Instrument_Ptr, *Args_Ptr, DRT_Instrument *); + + + Command_Name = "NDD_CMD_VALUE_FREE"; + + + free( Instrument_Ptr); + + return( NDS_OK); + } + + case NDD_CMD_VALUE_COMP: + { + /* + ND_VA_ARG_GET( Value1_Ptr, *Args_Ptr, void *); + ND_VA_ARG_GET( Value2_Ptr, *Args_Ptr, void *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + ND_VA_ARG_GET( Instrument1_Ptr, *Args_Ptr, DRT_Instrument *); + ND_VA_ARG_GET( Instrument2_Ptr, *Args_Ptr, DRT_Instrument *); + + long rc; + + + Command_Name = "NDD_CMD_VALUE_COMP"; + + switch( Index_Id) + { + case 0: + { + rc = Instrument1_Ptr->Id - Instrument2_Ptr->Id; + break; + } + + case 1: + { + rc = strcmp( Instrument1_Ptr->Name, Instrument2_Ptr->Name); + break; + } + + default: + { + printf( "Unknown COMP idx (%d) !\n", Index_Id); + return( NDS_KO); + } + } + + if( rc < 0) + { + return( NDS_LOWER); + } + else + { + if( rc > 0) + { + return( NDS_GREATER); + } + else + { + return( NDS_EQUAL); + } + } + } + + case NDD_CMD_VALUE_ADD: + { + /* + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + + Command_Name = "NDD_CMD_VALUE_ADD"; + + return( NDS_OK); + } + + case NDD_CMD_VALUE_REMOVE: + { + /* + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + + Command_Name = "NDD_CMD_VALUE_REMOVE"; + + return( NDS_OK); + } + + case NDD_CMD_VALUE_PRINT: + { + /* + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( lib_args, *Args_Ptr); + + ND_VA_ARG_GET( Out, lib_args, FILE *); + ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode); + ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth); + ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset); + + ND_VA_LIST_OPEN( user_args, lib_args); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + ND_VA_LIST_CLOSE( lib_args); + + void *Value_Ptr = Node_Ptr->Value; + */ + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( lib_args, *Args_Ptr); + + ND_VA_ARG_GET( Out, lib_args, FILE *); + ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode); + ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth); + ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset); + + ND_VA_LIST_OPEN( user_args, lib_args); + + ND_VA_ARG_GET( Count_Ptr, user_args, long *); + + ND_VA_LIST_CLOSE( user_args); + ND_VA_LIST_CLOSE( lib_args); + + DRT_Instrument *Instrument_Ptr = Node_Ptr->Value; + + + Command_Name = "NDD_CMD_VALUE_PRINT"; + + if( DR_Instrument_Dump( Instrument_Ptr, ++(*Count_Ptr)) != DRS_OK) + { + return( NDS_KO); + } + else + { + return( NDS_OK); + } + } + + case NDD_CMD_INFO_PRINT: + { + /* + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( lib_args, *Args_Ptr); + + ND_VA_ARG_GET( Out, lib_args, FILE *); + ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode); + ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth); + ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset); + + ND_VA_LIST_OPEN( user_args, lib_args); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + ND_VA_LIST_CLOSE( lib_args); + */ + + + Command_Name = "NDD_CMD_INFO_PRINT"; + + return( NDS_OK); + + } + + case NDD_CMD_INDEX0_PRINT: + case NDD_CMD_INDEX1_PRINT: + { + /* + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( Out, user_args, FILE *); + ND_VA_ARG_GET( Count_Ptr, user_args, long *); + + ND_VA_LIST_CLOSE( user_args); + + DRT_Instrument *Instrument_Ptr = Node_Ptr->Value; + + + Command_Name = "NDD_CMD_INDEX_PRINT"; + + if( DR_Instrument_Dump( Instrument_Ptr, ++(*Count_Ptr)) != DRS_OK) + { + return( NDS_KO); + } + else + { + return( NDS_OK); + } + } +/* + case NDD_CMD_PHONEBOOK_SAVE: + { + /* + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ +/* + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( Out, user_args, FILE *); + ND_VA_ARG_GET( Count_Ptr, user_args, long *); + + ND_VA_LIST_CLOSE( user_args); + + DRT_Instrument *Instrument_Ptr = Node_Ptr->Value; + + + Command_Name = "NDD_CMD_PHONEBOOK_SAVE"; + + fprintf( Out, "%s:%s:%s:%s\n", Instrument_Ptr->Number, Instrument_Ptr->Name, Instrument_Ptr->Address, Instrument_Ptr->Email); + (*Count_Ptr)++; + + return( NDS_OK); + } +*/ + default: + { + printf( "Instrument_Manager() called with an undefined command %d\n", Command); + return( NDS_ERRAPI); + + } + } + + printf( "Instrument_Manager() called with command %d (%s)\n", Command, Command_Name); + return( NDS_OK); +} + + + + + +/*---------------------------------------------------------------------------------*/ +/* */ +/*---------------------------------------------------------------------------------*/ + +NDT_Status DR_Kit_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list *Args_Ptr) +{ + NDT_Command_Name Command_Name; + + + switch( Command) + { + case NDD_CMD_MANAGER_VERSION: + { + ND_VA_ARG_GET( Version_Name_Ptr, *Args_Ptr, NDT_Version_Name *); + + + Command_Name = "NDD_CMD_MANAGER_VERSION"; + + *Version_Name_Ptr = "$Revision: 1.0 $ $Name: Kit_Manager $ $Date: 2021/12/12 21:27:12 $ $Author: agibert $"; + + return( NDS_OK); + } + + case NDD_CMD_INDEX_GET: + { + /* + ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *); + ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *); + ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command); + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + */ + + ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *); + ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *); + ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command); + ND_VA_ARG_GET( Kit_Ptr, *Args_Ptr, DRT_Kit *); + + + 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; + } + ... + */ + + case NDD_CMD_INDEX0_PRINT: + { + *Reply_Index_Id_Ptr = 0; + *Reply_Command_Ptr = Cmd; + break; + } + + case NDD_CMD_VALUE_PRINT: + case NDD_CMD_INDEX1_PRINT: + { + *Reply_Index_Id_Ptr = 1; + *Reply_Command_Ptr = Cmd; + break; + } + + default: + { + *Reply_Index_Id_Ptr = Index_Id; + *Reply_Command_Ptr = Cmd; + break; + } + } + + return( NDS_OK); + } + + case NDD_CMD_VALUE_ALLOC: + { + /* + ND_VA_ARG_GET( Value_Ptr_Ptr, *Args_Ptr, void **); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + ND_VA_ARG_GET( Kit_Ptr_Ptr, *Args_Ptr, DRT_Kit **); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( Name, user_args, char *); + ND_VA_ARG_GET( Desc, user_args, char *); + ND_VA_ARG_GET( FileName, user_args, char *); + + ND_VA_LIST_CLOSE( user_args); + + NDT_Status nd_status; + + + Command_Name = "NDD_CMD_VALUE_ALLOC"; + + if( ( *Kit_Ptr_Ptr = (DRT_Kit *)malloc( sizeof( DRT_Kit))) != NULL) + { + ( *Kit_Ptr_Ptr)->Id = Root_Ptr->Index_Tab[NDD_INDEX_PRIMARY].Node_Number; + + strncpy( ( *Kit_Ptr_Ptr)->Name, Name, NAME_LEN); + strncpy( ( *Kit_Ptr_Ptr)->Desc, Desc, DESC_LEN); + strncpy( ( *Kit_Ptr_Ptr)->FileName, FileName, FILENAME_LEN); + + (*Kit_Ptr_Ptr)->Name[ NAME_LEN] = '\0'; + (*Kit_Ptr_Ptr)->Desc[ DESC_LEN] = '\0'; + (*Kit_Ptr_Ptr)->FileName[FILENAME_LEN] = '\0'; + + if( ( nd_status = ND_DataStruct_Open( &((*Kit_Ptr_Ptr)->Instrument_DS_Ptr), DRD_INSTRUMENT_DS_INDEX_NB, DRG_Instrument_DS_Index_Tab_Initial, "Instrument_Manager", DR_Instrument_Manager, NULL, NULL, NULL, NULL, NDD_TRUE, NULL)) != NDS_OK) + { + printf( "DR_Instrument_Manager: ND_DataStruct_Open() failed (%d) !\n", nd_status); + return( NDS_KO); + } + + return( NDS_OK); + } + else + { + return( NDS_KO); + } + } + + case NDD_CMD_VALUE_FREE: + { + /* + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + ND_VA_ARG_GET( Kit_Ptr, *Args_Ptr, DRT_Kit *); + + NDT_Status nd_status; + + + Command_Name = "NDD_CMD_VALUE_FREE"; + + if( ( nd_status = ND_DataStruct_Close( Kit_Ptr->Instrument_DS_Ptr)) != NDS_OK) + { + printf( "Can't close Kit_DS (%d)!\n", nd_status); + return( DRS_KO); + } + + free( Kit_Ptr); + + return( NDS_OK); + } + + case NDD_CMD_VALUE_COMP: + { + /* + ND_VA_ARG_GET( Value1_Ptr, *Args_Ptr, void *); + ND_VA_ARG_GET( Value2_Ptr, *Args_Ptr, void *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + ND_VA_ARG_GET( Kit1_Ptr, *Args_Ptr, DRT_Kit *); + ND_VA_ARG_GET( Kit2_Ptr, *Args_Ptr, DRT_Kit *); + + long rc; + + + Command_Name = "NDD_CMD_VALUE_COMP"; + + switch( Index_Id) + { + case 0: + { + rc = Kit1_Ptr->Id - Kit2_Ptr->Id; + break; + } + + case 1: + { + rc = strcmp( Kit1_Ptr->Name, Kit2_Ptr->Name); + break; + } + + default: + { + printf( "Unknown COMP idx (%d) !\n", Index_Id); + return( NDS_KO); + } + } + + if( rc < 0) + { + return( NDS_LOWER); + } + else + { + if( rc > 0) + { + return( NDS_GREATER); + } + else + { + return( NDS_EQUAL); + } + } + } + + case NDD_CMD_VALUE_ADD: + { + /* + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + + Command_Name = "NDD_CMD_VALUE_ADD"; + + return( NDS_OK); + } + + case NDD_CMD_VALUE_REMOVE: + { + /* + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + + Command_Name = "NDD_CMD_VALUE_REMOVE"; + + return( NDS_OK); + } + + case NDD_CMD_VALUE_PRINT: + { + /* + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( lib_args, *Args_Ptr); + + ND_VA_ARG_GET( Out, lib_args, FILE *); + ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode); + ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth); + ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset); + + ND_VA_LIST_OPEN( user_args, lib_args); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + ND_VA_LIST_CLOSE( lib_args); + + void *Value_Ptr = Node_Ptr->Value; + */ + + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( lib_args, *Args_Ptr); + + ND_VA_ARG_GET( Out, lib_args, FILE *); + ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode); + ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth); + ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset); + + ND_VA_LIST_OPEN( user_args, lib_args); + + ND_VA_ARG_GET( Count_Ptr, user_args, long *); + + ND_VA_LIST_CLOSE( user_args); + ND_VA_LIST_CLOSE( lib_args); + + DRT_Kit *Kit_Ptr = Node_Ptr->Value; + + + Command_Name = "NDD_CMD_VALUE_PRINT"; + + if( DR_Kit_Dump( Kit_Ptr, ++(*Count_Ptr)) != DRS_OK) + { + return( NDS_KO); + } + else + { + return( NDS_OK); + } + } + + case NDD_CMD_INFO_PRINT: + { + /* + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( lib_args, *Args_Ptr); + + ND_VA_ARG_GET( Out, lib_args, FILE *); + ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode); + ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth); + ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset); + + ND_VA_LIST_OPEN( user_args, lib_args); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + ND_VA_LIST_CLOSE( lib_args); + */ + + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( lib_args, *Args_Ptr); + + ND_VA_ARG_GET( Out, lib_args, FILE *); + ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode); + ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth); + ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset); + + ND_VA_LIST_CLOSE( lib_args); + + NDT_Status nd_status; + DRT_Kit *Kit_Ptr = Node_Ptr->Value; + + + Command_Name = "NDD_CMD_INFO_PRINT"; + + if( ( nd_status = ND_DataStruct_Info_Print( Out, Kit_Ptr->Instrument_DS_Ptr, NDD_RECURSIVE_MODE_PARENT_CHILD, 0, 0)) != NDS_OK) + { + printf( "ND_DataStruct_Info_Print() failed (%d) !\n", nd_status); + return( DRS_KO); + } + + return( NDS_OK); + + } + + case NDD_CMD_INDEX0_PRINT: + case NDD_CMD_INDEX1_PRINT: + { + /* + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( Out, user_args, FILE *); + ND_VA_ARG_GET( Count_Ptr, user_args, long *); + + ND_VA_LIST_CLOSE( user_args); + + DRT_Kit *Kit_Ptr = Node_Ptr->Value; + + + Command_Name = "NDD_CMD_INDEX_PRINT"; + + if( DR_Kit_Dump( Kit_Ptr, ++(*Count_Ptr)) != DRS_OK) + { + return( NDS_KO); + } + else + { + return( NDS_OK); + } + } +/* + case NDD_CMD_PHONEBOOK_SAVE: + { + /* + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ /* + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( Out, user_args, FILE *); + ND_VA_ARG_GET( Count_Ptr, user_args, long *); + + ND_VA_LIST_CLOSE( user_args); + + DRT_Kit *Kit_Ptr = Node_Ptr->Value; + + + Command_Name = "NDD_CMD_PHONEBOOK_SAVE"; + + fprintf( Out, "%s:%s:%s:%s\n", Kit_Ptr->Number, Kit_Ptr->Name, Kit_Ptr->Address, Kit_Ptr->Email); + (*Count_Ptr)++; + + return( NDS_OK); + } +*/ + default: + { + printf( "Kit_Manager() called with an undefined command %d\n", Command); + return( NDS_ERRAPI); + } + } + + printf( "Kit_Manager() called with command %d (%s)\n", Command, Command_Name); + return( NDS_OK); +} + + + + + +/*---------------------------------------------------------------------------------*/ +/* DR_Instrument_Add */ +/*---------------------------------------------------------------------------------*/ + +DRT_Status DR_Instrument_Add( DRT_Instrument **Instrument_Ptr_Ptr, NDT_Root *DS_Ptr, char *Name, char *FileName, double Gain, char *Sample_Ptr, long Sample_Size) +{ + NDT_Status nd_status; + + + if( ( nd_status = ND_Value_Alloc( DS_Ptr, (void **)Instrument_Ptr_Ptr, Name, FileName, Gain, Sample_Ptr, Sample_Size)) != NDS_OK) + { + printf( "Can't allocate new instrument: ND_Value_Alloc() failed (%d) !\n", nd_status); + return( DRS_KO); + } + else + { + if( ( nd_status = ND_DataStruct_Value_Add( DS_Ptr, (void *)*Instrument_Ptr_Ptr)) != NDS_OK) + { + printf( "Can't add new kit: ND_Value_Add() failed (%d) !\n", nd_status); + return( DRS_KO); + } + } + + return( DRS_OK); +} + + + + + +/*---------------------------------------------------------------------------------*/ +/* DR_Instrument_Dump */ +/*---------------------------------------------------------------------------------*/ + +DRT_Status DR_Instrument_Dump( DRT_Instrument *Instrument_Ptr, long count) +{ + NDT_Status nd_status; + + + fprintf( stderr, " %03d) Instrument: ", count); + fprintf( stderr, " Id: (% 3d) Name: [%s] File Name: [%s] Gain: (%f) Sample: [%lx] Sample Size: (%d)\n", + Instrument_Ptr->Id, Instrument_Ptr->Name, Instrument_Ptr->FileName, Instrument_Ptr->Gain, Instrument_Ptr->Sample_Ptr, Instrument_Ptr->Sample_Size); +// fprintf( stderr, "\n"); + + return( DRS_OK); +} + + + + + +/*---------------------------------------------------------------------------------*/ +/* DR_Kit_Add */ +/*---------------------------------------------------------------------------------*/ + +DRT_Status DR_Kit_Add( DRT_Kit **Kit_Ptr_Ptr, NDT_Root *DS_Ptr, char *Name, char *Desc, char *FileName) +{ + NDT_Status nd_status; + + + if( ( nd_status = ND_Value_Alloc( DS_Ptr, (void **)Kit_Ptr_Ptr, Name, Desc, FileName)) != NDS_OK) + { + printf( "Can't allocate new kit: ND_Value_Alloc() failed (%d) !\n", nd_status); + return( DRS_KO); + } + else + { + if( ( nd_status = ND_DataStruct_Value_Add( DS_Ptr, (void **)*Kit_Ptr_Ptr)) != NDS_OK) + { + printf( "Can't add new kit: ND_Value_Add() failed (%d) !\n", nd_status); + return( DRS_KO); + } + } + + return( DRS_OK); +} + + + + + +/*---------------------------------------------------------------------------------*/ +/* DR_Kit_Dump */ +/*---------------------------------------------------------------------------------*/ + +DRT_Status DR_Kit_Dump( DRT_Kit *Kit_Ptr, long count) +{ + NDT_Status nd_status; + long count2; + + + + fprintf( stderr, " %03d) DrumKit:", count); + fprintf( stderr, " Id: (% 3d) Name: [%s] Descrition: [%.32s] File Name: [%s]\n", Kit_Ptr->Id, Kit_Ptr->Name, Kit_Ptr->Desc, Kit_Ptr->FileName); + fprintf( stderr, " Instruments List:\n"); + + if( Kit_Ptr->Instrument_DS_Ptr->Index_Tab[NDD_INDEX_PRIMARY].Node_Number == 0) + { + fprintf( stderr, " Empty list!\n"); + } + else + { + count2 = 0; + + if( ( nd_status = ND_DataStruct_Value_Print( stderr, Kit_Ptr->Instrument_DS_Ptr, NDD_RECURSIVE_MODE_PARENT_CHILD, 0, 0, &count2)) != NDS_OK) + { + printf( "Cant't dump intruments: ND_DataStruct_Traverse() failed (%d) !\n", nd_status); + return( DRS_KO); + } + } + + fprintf( stderr, "\n"); + + return( DRS_OK); +} + + + + + +/*---------------------------------------------------------------------------------*/ +/* DR_Kits_Load */ +/*---------------------------------------------------------------------------------*/ + +void element_names_print( xmlNode *xml_node, int depth) +{ + xmlNode *xml_cur_node; + + + for( xml_cur_node = xml_node; xml_cur_node; xml_cur_node = xml_cur_node->next) + { + if( xml_cur_node->type == XML_ELEMENT_NODE) + { + printf( "% *cnode type: Element, name: %s\n", depth*2, ' ', xml_cur_node->name); + } + + element_names_print( xml_cur_node->children, depth + 1); + } +} + + + + + +/*---------------------------------------------------------------------------------*/ +/* DR_XML_Value_Get */ +/*---------------------------------------------------------------------------------*/ + +DRT_Status DR_XML_Value_Get( char *Value_Ptr, long Max_Len, xmlDocPtr Xml_Doc, xmlXPathContextPtr Xml_XpathCtx, char *Xpath_Request) +{ + DRT_Status status; + xmlXPathObjectPtr xml_xpathobj; + xmlNodeSetPtr nodeset; + char *tmpval_ptr; + long tmpval_len; + + + if( ( xml_xpathobj = xmlXPathEvalExpression( Xpath_Request, Xml_XpathCtx)) == NULL) + { + fprintf( stderr, "xmlXPathEvalExpression failed!\n"); + status = DRS_KO; + } + else + { + nodeset = xml_xpathobj->nodesetval; + + if( xmlXPathNodeSetIsEmpty( nodeset)) + { + fprintf( stderr, "[%s] not found!\n", Xpath_Request); + status = DRS_KO; + } + else + { + if( ( tmpval_ptr = xmlNodeListGetString( Xml_Doc, nodeset->nodeTab[0]->xmlChildrenNode, 1)) == NULL) + { + fprintf( stderr, "[%s] value not found!\n", Xpath_Request); + status = DRS_KO; + } + else + { + fprintf( stderr, "[%s] = [%s] found!\n", nodeset->nodeTab[0]->name, tmpval_ptr); + + if( ( tmpval_len = strlen( tmpval_ptr)) > Max_Len) + { + fprintf( stderr, "Value too long (%d)>(%d)!\n", tmpval_len, Max_Len); + status = DRS_OK; + } + else + { + strcpy( Value_Ptr, tmpval_ptr); + status = DRS_OK; + } + } + + xmlFree( tmpval_ptr); + } + } + + return( status); +} + + + + + +/*---------------------------------------------------------------------------------*/ +/* DR_XML_Node_Exist */ +/*---------------------------------------------------------------------------------*/ + +DRT_Status DR_XML_Node_Exist( xmlDocPtr Xml_Doc, xmlXPathContextPtr Xml_XpathCtx, char *Xpath_Request) +{ + DRT_Status status; + xmlXPathObjectPtr xml_xpathobj; + xmlNodeSetPtr nodeset; + char *tmpval_ptr; + long tmpval_len; + + + if( ( xml_xpathobj = xmlXPathEvalExpression( Xpath_Request, Xml_XpathCtx)) == NULL) + { + fprintf( stderr, "xmlXPathEvalExpression failed!\n"); + status = DRS_KO; + } + else + { + nodeset = xml_xpathobj->nodesetval; + + if( xmlXPathNodeSetIsEmpty( nodeset)) + { + fprintf( stderr, "[%s] not found!\n", Xpath_Request); + status = DRS_KO; + } + else + { + fprintf( stderr, "[%s] found!\n", Xpath_Request); + status = DRS_OK; + } + } + + return( status); +} + + + + + +/*---------------------------------------------------------------------------------*/ +/* DR_Kit_Load */ +/*---------------------------------------------------------------------------------*/ + +DRT_Status DR_Kit_Load( DRT_Base *Base_Ptr, char *FileName) +{ + DRT_Status status; + NDT_Status nd_status; + DRT_Kit kit_template; + DRT_Kit *kit_ptr; + DRT_Instrument instrument_template; + DRT_Instrument *instrument_ptr; + char tmp_str[256]; + char xpath_instrument[256]; + char xpath_value[256]; + xmlDocPtr xml_doc; + xmlXPathContextPtr xml_xpathCtx; + xmlXPathObjectPtr xml_xpathObj; + int i; + + + fprintf( stderr, "Loading: [%s]...\n", FileName); + + if( strlen( FileName) > FILENAME_LEN) + { + fprintf( stderr, "Kit file name too long [%s]!", FileName); + status = DRS_KO; + } + else + { + strcpy( kit_template.FileName, FileName); + + if( ( xml_doc = xmlParseFile( kit_template.FileName)) == NULL) + { + fprintf( stderr, "xml_doc failed!\n"); + status = DRS_KO; + } + else + { + if( ( xml_xpathCtx = xmlXPathNewContext( xml_doc)) == NULL) + { + fprintf( stderr, "xmlXPathNewContext failed!\n"); + status = DRS_KO; + } + else + { + if( xmlXPathRegisterNs( xml_xpathCtx, "drumkit", "http://www.hydrogen-music.org/drumkit") != 0) + { + fprintf( stderr,"Error: unable to register default NS!\n"); + status = DRS_KO; + } + + if( ( status = DR_XML_Node_Exist( xml_doc, xml_xpathCtx, XML_XPATH_DRUMKIT_BASE_STR) != DRS_OK)) + { + fprintf( stderr, "Bad drumkit file!\n"); + } + else + { + if( ( status = DR_XML_Value_Get( kit_template.Name, NAME_LEN, xml_doc, xml_xpathCtx, XML_XPATH_DRUMKIT_KIT_NAME_FULL)) != DRS_OK) + { + fprintf( stderr, "Name not found!\n"); + } + else if( DR_XML_Value_Get( kit_template.Desc, DESC_LEN, xml_doc, xml_xpathCtx, XML_XPATH_DRUMKIT_KIT_INFO_FULL) != DRS_OK) + { + fprintf( stderr, "Info not found!\n"); + strcpy( kit_template.Desc, ""); + } + + if( ( status = DR_Kit_Add( &kit_ptr, Base_Ptr->Kit_DS_Ptr, kit_template.Name, kit_template.Desc, kit_template.FileName)) != DRS_OK) + { + fprintf( stderr, "Can't create a new kit!\n"); + } + else + { + fprintf( stderr, "New kit!\n"); + + status = DRS_OK; + i = 1; + while( ( status == DRS_OK) + && ( sprintf( xpath_instrument, XML_XPATH_DRUMKIT_INSTRUMENT_FULL, i) > 0) + && ( DR_XML_Node_Exist( xml_doc, xml_xpathCtx, xpath_instrument) == DRS_OK)) + { + strcpy( xpath_value, xpath_instrument); +// strcat( xpath_value, "/drumkit:id"); + strcat( xpath_value, XML_XPATH_DRUMKIT_ID_STR); + + if( ( status = DR_XML_Value_Get( tmp_str, 256, xml_doc, xml_xpathCtx, xpath_value)) != DRS_OK) + { + fprintf( stderr, "Instrument id not found!\n"); + } + else + { + instrument_template.Id = atoi( tmp_str); + + strcpy( xpath_value, xpath_instrument); +// strcat( xpath_value, "/drumkit:name"); + strcat( xpath_value, XML_XPATH_DRUMKIT_NAME_STR); + + if( ( status = DR_XML_Value_Get( instrument_template.Name, NAME_LEN, xml_doc, xml_xpathCtx, xpath_value)) != DRS_OK) + { + fprintf( stderr, "Instrument name not found!\n"); + strcpy( instrument_template.Name, ""); + status = DRS_OK; + } + + strcpy( xpath_value, xpath_instrument); + strcat( xpath_value, XML_XPATH_DRUMKIT_LAYER_FILENAME_STR); + + if( ( status = DR_XML_Value_Get( instrument_template.FileName, FILENAME_LEN, xml_doc, xml_xpathCtx, xpath_value)) != DRS_OK) + { + fprintf( stderr, "Instrument file name not found!\n"); + strcpy( instrument_template.FileName, ""); + status = DRS_OK; + } + + if( ( status = DR_Instrument_Add( &instrument_ptr, kit_ptr->Instrument_DS_Ptr, instrument_template.Name, instrument_template.FileName, 1.01, NULL, 0)) != DRS_OK) + { + fprintf( stderr, "Can't create a new instrument!\n"); + } + else + { + fprintf( stderr, "New Instrument!\n"); + i++; + } + } + } + } + } + + xmlXPathFreeContext( xml_xpathCtx); + } + + xmlFreeDoc( xml_doc); + } + } + + xmlCleanupParser(); + + return( status); +} + + + + + +/*---------------------------------------------------------------------------------*/ +/* DR_Kits_Load */ +/*---------------------------------------------------------------------------------*/ + +DRT_Status DR_Kits_Load( DRT_Base *Base_Ptr) +{ + DRT_Status status; + NDT_Status nd_status; + char glob_pattern[] = "~/.hydrogen/data/drumkits/*/drumkit.xml"; +// char glob_pattern[] = "~/.hydrogen/data/drumkits/AVL-BlackPearl-4A-1.1/drumkit.xml"; +// char glob_pattern[] = "~/.hydrogen/data/drumkits/Mars Lindrum: 02-Kit 2/drumkit.xml"; + glob_t glob_struct; + int i; + + + LIBXML_TEST_VERSION; + + if( glob( glob_pattern, (GLOB_NOSORT + GLOB_TILDE), NULL, &glob_struct) != 0) + { + fprintf( stderr, "glob() error!\n"); + status = DRS_KO; + } + else + { + for( i = 0; i < glob_struct.gl_pathc; i++) + { +// printf( "[%s]\n", glob_struct.gl_pathv[i]); + + if( ( status = DR_Kit_Load( Base_Ptr, glob_struct.gl_pathv[i])) != DRS_OK) + { + fprintf( stderr, "Can't load kit [%s]!\n", glob_struct.gl_pathv[i]); + } + } + + if( ( nd_status = ND_DataStruct_Convert( Base_Ptr->Kit_DS_Ptr, DRG_Kit_DS_Index_Tab_Final)) != NDS_OK) + { + fprintf( stderr, "ND_DataStruct_Convert() failed (%d) !\n", status); + status = DRS_KO; + } + else + { + status = DRS_OK; + } + } + + globfree( &glob_struct); + + return( status); +} + + + +/* + if( ( xml_xpathObj = xmlXPathEvalExpression( "/drumkit:drumkit_info/drumkit:name", xml_xpathCtx)) == NULL) + { + fprintf( stderr, "xmlXPathEvalExpression failed!\n"); + status = DRS_KO; + } + else + { + xmlNodeSetPtr nodeset = xml_xpathObj->nodesetval; + + if( !xmlXPathNodeSetIsEmpty( xml_xpathObj->nodesetval)) + { + fprintf( stderr, "Name [%s] found!\n", nodeset->nodeTab[0]->name); + + int i; + char *keyword; + + for( i=0; i < nodeset->nodeNr; i++) + { + keyword = xmlNodeListGetString( xml_doc, nodeset->nodeTab[i]->xmlChildrenNode, 1); + printf( "keyword: %s\n", keyword); + xmlFree( keyword); + } + } + + DRT_Status DR_XML_Value_Get( char **Value_Ptr_Ptr, xmlDocPtr Xml_Doc, xmlXPathContextPtr xml_xpathCtx, char *Xpath_Request) + { + xmlXPathObjectPtr xml_xpathobj; + xmlNodeSetPtr nodeset; + + + if( ( xml_xpathobj = xmlXPathEvalExpression( "/drumkit:drumkit_info/drumkit:name", xml_xpathCtx)) == NULL) + { + fprintf( stderr, "xmlXPathEvalExpression failed!\n"); + status = DRS_KO; + } + else + { + nodeset = xml_xpathobj->nodesetval; + + if( !xmlXPathNodeSetIsEmpty( nodeset)) + { + (*Value_Ptr_Ptr) = xmlNodeListGetString( Xml_Doc, nodeset->nodeTab[0]->xmlChildrenNode, 1); + + fprintf( stderr, "[%s] = [%s] found!\n", nodeset->nodeTab[0]->name, *Value_Ptr_Ptr); + } + } + + xmlXPathFreeObject(xml_xpathObj); + status = DRS_OK; + } + +/* + xmlNodeSetPtr nodes = xml_xpathObj->nodesetval; + xmlNodePtr cur; + int size; + int i; + + size = (nodes) ? nodes->nodeNr : 0; + + fprintf( stderr, "Result (%d nodes):\n", size); + + for( i = 0; i < size; ++i) + { + assert( nodes->nodeTab[i]); + + if(nodes->nodeTab[i]->type == XML_NAMESPACE_DECL) + { + xmlNsPtr ns; + + ns = (xmlNsPtr)nodes->nodeTab[i]; + cur = (xmlNodePtr)ns->next; + + if(cur->ns) + { + fprintf( stderr, "= namespace \"%s\"=\"%s\" for node %s:%s\n", ns->prefix, ns->href, cur->ns->href, cur->name); + } + else + { + fprintf( stderr, "= namespace \"%s\"=\"%s\" for node %s\n", ns->prefix, ns->href, cur->name); + } + } + else + { + if( nodes->nodeTab[i]->type == XML_ELEMENT_NODE) + { + cur = nodes->nodeTab[i]; + + if(cur->ns) + { + fprintf( stderr, "= element node \"%s:%s\"\n", cur->ns->href, cur->name); + } + else + { + fprintf( stderr, "= element node \"%s\"\n", cur->name); + } + } + else + { + cur = nodes->nodeTab[i]; + fprintf( stderr, "= node \"%s\": type %d\n", cur->name, cur->type); + } + } + } +*/ +/* + + if( ( status = DR_Kit_Add( &kit_ptr, Base_Ptr->Kit_DS_Ptr, "Kit number one", "This is the best drumkit!", "/tmp/toto.xml")) != DRS_OK) + { + return( status); + } + + if( ( status = DR_Instrument_Add( &instrument_ptr, kit_ptr->Instrument_DS_Ptr, "Instrument 1.1", "/tmp/instrument-1.1.wav", 1.01, NULL, 0)) != DRS_OK) + { + return( status); + } + + if( ( status = DR_Instrument_Add( &instrument_ptr, kit_ptr->Instrument_DS_Ptr, "Instrument 1.2", "/tmp/instrument-1.2.wav", 2.01, NULL, 0)) != DRS_OK) + { + return( status); + } + + if( ( status = DR_Instrument_Add( &instrument_ptr, kit_ptr->Instrument_DS_Ptr, "Instrument 1.3", "/tmp/instrument-1.3.wav", 0.02, NULL, 0)) != DRS_OK) + { + return( status); + } + + + if( ( status = DR_Kit_Add( &kit_ptr, Base_Ptr->Kit_DS_Ptr, "Kit number two", "This is a good drumkit.", "/tmp/titi.xml")) != DRS_OK) + { + return( status); + } + + if( ( status = DR_Instrument_Add( &instrument_ptr, kit_ptr->Instrument_DS_Ptr, "Instrument 2.1", "/tmp/instrument-2.1.wav", 1.01, NULL, 0)) != DRS_OK) + { + return( status); + } + + if( ( status = DR_Instrument_Add( &instrument_ptr, kit_ptr->Instrument_DS_Ptr, "Instrument 2.2", "/tmp/instrument-2.2.wav", 2.01, NULL, 0)) != DRS_OK) + { + return( status); + } + + if( ( status = DR_Instrument_Add( &instrument_ptr, kit_ptr->Instrument_DS_Ptr, "Instrument 2.3", "/tmp/instrument-2.3.wav", 0.02, NULL, 0)) != DRS_OK) + { + return( status); + } + + + if( ( status = DR_Kit_Add( &kit_ptr, Base_Ptr->Kit_DS_Ptr, "Kit number three", "This is not the the best drum kit...", "/tmp/tata.xml")) != DRS_OK) + { + return( status); + } +*/ + + + + + + +/*---------------------------------------------------------------------------------*/ +/* DR_Kits_Dump */ +/*---------------------------------------------------------------------------------*/ + +DRT_Status DR_Kits_Dump( DRT_Base *Base_Ptr) +{ + NDT_Status nd_status; + short index; + long count = 0; + + + fprintf( stderr, "DrumKit List:\n"); + + if( ( nd_status = ND_DataStruct_Info_Print( stderr, Base_Ptr->Kit_DS_Ptr, NDD_RECURSIVE_MODE_PARENT_CHILD, 0, 0)) != NDS_OK) + { + printf( "ND_DataStruct_Info_Print() failed (%d) !\n", nd_status); + return( DRS_KO); + } + +/* + for( index = 0; index < Base_Ptr->Kit_DS_Ptr->Index_Nb; index++) + { + count = 0; + fprintf( stderr, "Dump Index: (%d)\n", index); + + if( Base_Ptr-> Kit_DS_Ptr->Index_Tab[index].Node_Number == 0) + { + fprintf( stderr, " Empty list!\n"); + } + else + { + if( ( nd_status = ND_DataStruct_Traverse( Base_Ptr->Kit_DS_Ptr, (NDD_CMD_INDEX0_PRINT + index), stderr, &count)) != NDS_OK) + { + printf( "Can't dump kits: ND_DataStruct_Traverse() failed (%d) !\n", nd_status); + return( DRS_KO); + } + } + + fprintf( stderr, "\n"); + } +*/ + if( ( nd_status = ND_DataStruct_Value_Print( stderr, Base_Ptr->Kit_DS_Ptr, NDD_RECURSIVE_MODE_PARENT_CHILD, 0, 0, &count)) != NDS_OK) + { + printf( "Can't dump kits: ND_DataStruct_Value_Print() failed (%d) !\n", nd_status); + return( DRS_KO); + } + + return( DRS_OK); +} + + + + + +/*---------------------------------------------------------------------------------*/ +/* DR_Init */ +/*---------------------------------------------------------------------------------*/ + +DRT_Status DR_Init( DRT_Base *Base_Ptr) +{ + NDT_Status nd_status; + + + if( ( nd_status = ND_Library_Open( NDD_TRUE)) != NDS_OK) + { + fprintf( stderr, "Can't open node library (%d) !", nd_status); + return( DRS_KO); + } + + if( ( nd_status = ND_DataStruct_Open( &(Base_Ptr->Kit_DS_Ptr), DRD_KIT_DS_INDEX_NB, DRG_Kit_DS_Index_Tab_Initial, "Kit_Manager", DR_Kit_Manager, NULL, NULL, NULL, NULL, NDD_TRUE, NULL)) != NDS_OK) + { + printf( "Kit_DS: ND_DataStruct_Open() failed (%d) !\n", nd_status); + return( DRS_KO); + } + + return( DRS_OK); +} + + + + + +/*---------------------------------------------------------------------------------*/ +/* DR_DeInit */ +/*---------------------------------------------------------------------------------*/ + +DRT_Status DR_DeInit( DRT_Base *Base_Ptr) +{ + NDT_Status nd_status; + + + if( ( nd_status = ND_DataStruct_Close( Base_Ptr->Kit_DS_Ptr)) != NDS_OK) + { + printf( "Can't close Kit_DS (%d)!\n", nd_status); + return( DRS_KO); + } + + if( ( nd_status = ND_Library_Close()) != NDS_OK) + { + fprintf( stderr, "Can't close node library (%d)!", nd_status); + return( DRS_KO); + } + + return( DRS_OK); +} + + + + + + +/*---------------------------------------------------------------------------------*/ +/* main */ +/*---------------------------------------------------------------------------------*/ + +int main( int argc, char **argv) +{ + DRT_Base base; + DRT_Status status; + + + if( ( status = DR_Init( &base)) != DRS_OK) + { + exit( -1); + } + + if( ( status = DR_Kits_Load( &base)) != DRS_OK) + { + exit( -1); + } + + printf( "hello world!\n"); + + if( ( status = DR_Kits_Dump( &base)) != DRS_OK) + { + exit( -1); + } + + if( ( status = DR_DeInit( &base)) != DRS_OK) + { + exit( -1); + } + + exit( 0); +} diff --git a/drummer.h b/drummer.h new file mode 100644 index 0000000..577c8d2 --- /dev/null +++ b/drummer.h @@ -0,0 +1,288 @@ +/*---------------------------------------------------------------------------------*/ +/* Includes */ +/*---------------------------------------------------------------------------------*/ + +#ifndef _DRUMMER_H_ +#define _DRUMMER_H_ + + + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + + + + + +/*----------------------------------------------------------------------------*/ +/* Global definitions */ +/*----------------------------------------------------------------------------*/ + +typedef short DRT_Boolean; + +#define DRD_FALSE ( DRT_Boolean) 0 +#define DRD_TRUE ( DRT_Boolean) 1 + +#define DRD_NO 'n' +#define DRD_YES 'y' + +#define DRD_MAX(A,B) (((A) < (B)) ? (B) : (A)) +#define DRD_MIN(A,B) (((A) > (B)) ? (B) : (A)) + +#define NDD_CMD_INDEX0_PRINT ( NDT_Command) 65 +#define NDD_CMD_INDEX1_PRINT ( NDT_Command) 66 + +#define NAME_LEN (short) 256 +#define NAME_SIZE (NAME_LEN + 1) +#define FILENAME_LEN (short) 1024 +#define FILENAME_SIZE (FILENAME_LEN) +#define DESC_LEN (short) 2048 +#define DESC_SIZE (DESC_LEN + 1) + + + + + +/*----------------------------------------------------------------------------*/ +/* Status definition */ +/*----------------------------------------------------------------------------*/ + +typedef short DRT_Status; + +#define DRS_OK ( DRT_Status) 0 + +#define DRS_KO ( DRT_Status) 1 +#define DRS_NO_IDENT ( DRT_Status) -2 +#define DRS_BAD_FORMAT ( DRT_Status) -3 +#define DRS_ROLLBACK ( DRT_Status) -4 + +#define DRS_NO_DATA ( DRT_Status) 3 +#define DRS_SIGNAL ( DRT_Status) 4 + + + + + +/*----------------------------------------------------------------------------*/ +/* Kit_DS Indexes */ +/*----------------------------------------------------------------------------*/ + +#define DRD_INSTRUMENT_DS_INDEX_NB (short)2 + +static NDT_Index_Type DRG_Instrument_DS_Index_Tab_Initial[DRD_INSTRUMENT_DS_INDEX_NB] = +{ + (NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_SORTED), + (NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_SORTED) +}; + +static NDT_Index_Type DRG_Instrument_DS_Index_Tab_Final[DRD_INSTRUMENT_DS_INDEX_NB] = +{ + (NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_TREE | NDD_INDEX_SUBTYPE_BALANCED), + (NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_TREE | NDD_INDEX_SUBTYPE_BALANCED) +}; + + + +/*----------------------------------------------------------------------------*/ +/* Kit_DS Indexes */ +/*----------------------------------------------------------------------------*/ + +#define DRD_KIT_DS_INDEX_NB (short)2 + +static NDT_Index_Type DRG_Kit_DS_Index_Tab_Initial[DRD_KIT_DS_INDEX_NB] = +{ + (NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_SORTED), + (NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_SORTED) +}; + +static NDT_Index_Type DRG_Kit_DS_Index_Tab_Final[DRD_KIT_DS_INDEX_NB] = +{ + (NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_TREE | NDD_INDEX_SUBTYPE_BALANCED), + (NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_TREE | NDD_INDEX_SUBTYPE_BALANCED) +}; + + + + + +/*---------------------------------------------------------------------------------*/ +/* XML XPATH Tags */ +/*---------------------------------------------------------------------------------*/ + +#define STR(A) #A +#define TAG(A) STR(A) + +#define XML_XPATH_ELEMENT(A) *[local-name()=(A)] + +#define XML_XPATH_DRUMKIT_BASE_TAG XML_XPATH_ELEMENT('drumkit_info') +#define XML_XPATH_DRUMKIT_NAME_TAG XML_XPATH_ELEMENT('name') +#define XML_XPATH_DRUMKIT_INFO_TAG XML_XPATH_ELEMENT('info') +#define XML_XPATH_DRUMKIT_INSTRUMENTLIST_TAG XML_XPATH_ELEMENT('instrumentList') +#define XML_XPATH_DRUMKIT_INSTRUMENT_TAG XML_XPATH_ELEMENT('instrument') +#define XML_XPATH_DRUMKIT_ID_TAG XML_XPATH_ELEMENT('id') +#define XML_XPATH_DRUMKIT_INSTRUMENTCOMPONENT_TAG XML_XPATH_ELEMENT('instrumentComponent') +#define XML_XPATH_DRUMKIT_LAYER_TAG XML_XPATH_ELEMENT('layer') +#define XML_XPATH_DRUMKIT_FILENAME_TAG XML_XPATH_ELEMENT('filename') + +#define XML_XPATH_DRUMKIT_BASE_STR TAG(/XML_XPATH_DRUMKIT_BASE_TAG) +#define XML_XPATH_DRUMKIT_ID_STR TAG(/XML_XPATH_DRUMKIT_ID_TAG) +#define XML_XPATH_DRUMKIT_NAME_STR TAG(/XML_XPATH_DRUMKIT_NAME_TAG) +#define XML_XPATH_DRUMKIT_LAYER_FILENAME_STR TAG(/XML_XPATH_DRUMKIT_INSTRUMENTCOMPONENT_TAG/XML_XPATH_DRUMKIT_LAYER_TAG[1]/XML_XPATH_DRUMKIT_FILENAME_TAG) + +#define XML_XPATH_DRUMKIT_KIT_NAME_FULL TAG(/XML_XPATH_DRUMKIT_BASE_TAG/XML_XPATH_DRUMKIT_NAME_TAG) +#define XML_XPATH_DRUMKIT_KIT_INFO_FULL TAG(/XML_XPATH_DRUMKIT_BASE_TAG/XML_XPATH_DRUMKIT_INFO_TAG) +#define XML_XPATH_DRUMKIT_INSTRUMENT_FULL TAG(/XML_XPATH_DRUMKIT_BASE_TAG/XML_XPATH_DRUMKIT_INSTRUMENTLIST_TAG/XML_XPATH_DRUMKIT_INSTRUMENT_TAG[%i]) + + + + + +/*---------------------------------------------------------------------------------*/ +/* TypeDefs */ +/*---------------------------------------------------------------------------------*/ + +typedef struct DRT_Instrument +{ + short Id; + char Name[ NAME_SIZE]; + char FileName[ FILENAME_SIZE]; + double Gain; + char *Sample_Ptr; + long Sample_Size; +} DRT_Instrument; + + + +typedef struct DRT_Kit +{ + short Id; + char Name[ NAME_SIZE]; + char Desc[ DESC_SIZE]; + char FileName[ FILENAME_SIZE]; + NDT_Root *Instrument_DS_Ptr; +} DRT_Kit; + + +/* +typedef struct DRT_Library +{ + NDT_Root *Kit_DS; +} DRT_Library; +*/ + + +typedef struct DRT_Base +{ + NDT_Root *Kit_DS_Ptr; +} DRT_Base; + + + + + +/*----------------------------------------------------------------------------*/ +/* Prototypes */ +/*----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------------*/ +/* DS Managers */ +/*---------------------------------------------------------------------------------*/ + +NDT_Status DR_Instrument_Manager( NDT_Root *, NDT_Index_Id, NDT_Node *, NDT_Command, va_list *); +NDT_Status DR_Kit_Manager( NDT_Root *, NDT_Index_Id, NDT_Node *, NDT_Command, va_list *); + + + +/*----------------------------------------------------------------------------*/ +/* DR_Instrument_Add */ +/*----------------------------------------------------------------------------*/ + +DRT_Status DR_Instrument_Add( DRT_Instrument **, NDT_Root *, char *, char *, double, char *, long); + + + +/*---------------------------------------------------------------------------------*/ +/* DR_Instrument_Dump */ +/*---------------------------------------------------------------------------------*/ + +DRT_Status DR_Instrument_Dump( DRT_Instrument *, long); + + + +/*----------------------------------------------------------------------------*/ +/* DR_Kit_Add */ +/*----------------------------------------------------------------------------*/ + +DRT_Status DR_Kit_Add( DRT_Kit **, NDT_Root *, char *, char *, char *); + + + +/*---------------------------------------------------------------------------------*/ +/* DR_Kit_Dump */ +/*---------------------------------------------------------------------------------*/ + +DRT_Status DR_Kit_Dump( DRT_Kit *, long); + + + +/*----------------------------------------------------------------------------*/ +/* DR_Kits_Load */ +/*----------------------------------------------------------------------------*/ + +DRT_Status DRT_Kits_Load( DRT_Base *); + + + +/*----------------------------------------------------------------------------*/ +/* DR_Kits_Dump */ +/*----------------------------------------------------------------------------*/ + +DRT_Status DRT_Kits_Dump( DRT_Base *); + + + +/*----------------------------------------------------------------------------*/ +/* DR_Init */ +/*----------------------------------------------------------------------------*/ + +DRT_Status DRT_Init( DRT_Base *); + + + +/*----------------------------------------------------------------------------*/ +/* DeInit */ +/*----------------------------------------------------------------------------*/ + +DRT_Status DRT_DeInit( DRT_Base *); + + + +/*----------------------------------------------------------------------------*/ +/* main */ +/*----------------------------------------------------------------------------*/ +/* ArgC: argument number */ +/* ArgV: Argument tab */ +/*----------------------------------------------------------------------------*/ + +int main( int, char **); + + + + + +/*----------------------------------------------------------------------------*/ + +#endif diff --git a/go.sh b/go.sh new file mode 100755 index 0000000..76523ca --- /dev/null +++ b/go.sh @@ -0,0 +1,6 @@ +gcc -g -c -I . -o libnode.o libnode.c + +#gcc -g -I . -L . -shared -o drummer.so -fPIC drummer.c + +gcc -g -I. -I/usr/include/libxml2 -o drummer -fPIC libnode.o -ldl -lxml2 -lz -llzma -lm drummer.c +#gcc -g -I. -I/usr/include/libxml2 -o xpath -fPIC -ldl -lxml2 -lz -llzma -lm xpath.c diff --git a/libnode.c b/libnode.c new file mode 100644 index 0000000..9bc22af --- /dev/null +++ b/libnode.c @@ -0,0 +1,5876 @@ +/*---------------------------------------------------------------------------------*/ +/* $RCSfile: libnode.c,v $ */ +/*---------------------------------------------------------------------------------*/ +/* $Revision: 2.17 $ */ +/* $Name: libnode-2_2_0-1 $ */ +/* $Date: 2010/06/06 21:26:31 $ */ +/* $Author: agibert $ */ +/*---------------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------------*/ +/* This file is part of LibNode */ +/* */ +/* LibNode is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU Lesser General Public Licence as published by */ +/* the Free Software Foundation; either version 2.1 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* LibNode is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with LibNode; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/*---------------------------------------------------------------------------------*/ + + + + + +#define _LIBNODE_C_ + +#include + +#ifdef _LIBVER_SUPPORT +VER_INFO_EXPORT( libnode, "$Revision: 2.17 $", "$Name: libnode-2_2_0-1 $", __FILE__, "$Author: agibert $") +#endif + + + + + + + +/*------------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------------*/ +/* Node Manager Template */ +/*------------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Default_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list *Args_Ptr) +{ + NDT_Command_Name Command_Name; + + + switch( Command) + { + case NDD_CMD_MANAGER_VERSION: + { + ND_VA_ARG_GET( Version_Name_Ptr, *Args_Ptr, NDT_Version_Name *); + + + Command_Name = "NDD_CMD_MANAGER_VERSION"; + + *Version_Name_Ptr = "$Revision: 2.17 $ $Name: libnode-2_2_0-1 $ $Date: 2010/06/06 21:26:31 $ $Author: agibert $"; + + return( NDS_OK); + } + + case NDD_CMD_INDEX_GET: + { + /* + ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *); + ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *); + ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command); + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + */ + ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *); + ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *); + ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command); + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + + + Command_Name = "NDD_CMD_INDEX_GET"; + + switch(Cmd) + { + /* + case NDT_CMD_SOME_USER_CMD: + { + *Reply_Index_Id_Ptr = 0; + *Reply_Command_Ptr = NDD_CMD_SOME_OTHER_CMD; + break; + } + + ... + */ + + default: + { + *Reply_Index_Id_Ptr = Index_Id; + *Reply_Command_Ptr = Cmd; + break; + } + } + + return( NDS_OK); + } + + case NDD_CMD_VALUE_ALLOC: + { + /* + ND_VA_ARG_GET( Value_Ptr_Ptr, *Args_Ptr, void **); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( 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: + { + /* + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + + Command_Name = "NDD_CMD_VALUE_FREE"; + + /* + free( Value_Ptr); + + return( NDS_OK); + */ + } + + case NDD_CMD_VALUE_COMP: + { + /* + ND_VA_ARG_GET( Value1_Ptr, *Args_Ptr, void *); + ND_VA_ARG_GET( Value2_Ptr, *Args_Ptr, void *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( 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: + { + /* + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + + Command_Name = "NDD_CMD_VALUE_ADD"; + + /* + return( NDS_OK); + */ + } + + case NDD_CMD_VALUE_REMOVE: + { + /* + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + + Command_Name = "NDD_CMD_VALUE_REMOVE"; + /* + return( NDS_OK); + */ + } + + case NDD_CMD_VALUE_PRINT: + { + /* + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( lib_args, *Args_Ptr); + + ND_VA_ARG_GET( Out, lib_args, FILE *); + ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode); + ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth); + ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset); + + ND_VA_LIST_OPEN( user_args, lib_args); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + ND_VA_LIST_CLOSE( lib_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: + { + /* + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( lib_args, *Args_Ptr); + + ND_VA_ARG_GET( Out, lib_args, FILE *); + ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode); + ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth); + ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset); + + ND_VA_LIST_OPEN( user_args, lib_args); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + ND_VA_LIST_CLOSE( lib_args); + */ + + + Command_Name = "NDD_CMD_INFO_PRINT"; + + /* + return( NDS_OK); + */ + } + + case NDD_CMD_USER_TRAVERSE: + { + /* + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + + + void *Value_Ptr = Node_Ptr->Value; + */ + + + Command_Name = "NDD_CMD_USER_TRAVERSE"; + + /* + return( NDS_OK); + */ + } + + default: + { + printf( "ND_Default_Manager() called with an undefined command %d\n", Command); + return(NDS_ERRAPI); + } + } + + printf( "ND_Default_Manager() called with command %d (%s)\n", Command, Command_Name); + return(NDS_OK); +} + + + + + + + +/*------------------------------------------------------------------------------*/ +/* OpenStruct Manager */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_OpenStruct_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list *Args_Ptr) +{ + NDT_Command_Name Command_Name; + + + switch( Command) + { + case NDD_CMD_MANAGER_VERSION: + { + ND_VA_ARG_GET( Version_Name_Ptr, *Args_Ptr, NDT_Version_Name *); + + + Command_Name = "NDD_CMD_MANAGER_VERSION"; + + *Version_Name_Ptr = "$Revision: 2.17 $ $Name: libnode-2_2_0-1 $ $Date: 2010/06/06 21:26:31 $ $Author: agibert $"; + + return( NDS_OK); + } + + case NDD_CMD_INDEX_GET: + { + /* + ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *); + ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *); + ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command); + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + */ + ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *); + ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *); + ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command); + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + + + Command_Name = "NDD_CMD_INDEX_GET"; + + switch(Cmd) + { + default: + { + *Reply_Index_Id_Ptr = Index_Id; + *Reply_Command_Ptr = Cmd; + break; + } + } + + return( NDS_OK); + } + + case NDD_CMD_VALUE_ALLOC: + { + /* + ND_VA_ARG_GET( Value_Ptr_Ptr, *Args_Ptr, void **); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + + Command_Name = "NDD_CMD_VALUE_ALLOC"; + + return( NDS_OK); + } + + case NDD_CMD_VALUE_FREE: + { + /* + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + + Command_Name = "NDD_CMD_VALUE_FREE"; + + return( NDS_OK); + } + + case NDD_CMD_VALUE_COMP: + { + /* + ND_VA_ARG_GET( Value1_Ptr, *Args_Ptr, void *); + ND_VA_ARG_GET( Value2_Ptr, *Args_Ptr, void *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + ND_VA_ARG_GET( Value1_Ptr, *Args_Ptr, void *); + ND_VA_ARG_GET( Value2_Ptr, *Args_Ptr, void *); + + + Command_Name = "NDD_CMD_VALUE_COMP"; + + switch( Index_Id) + { + case 0: + { + if( Value1_Ptr < Value2_Ptr) + { + return(NDS_LOWER); + } + else + { + if( Value1_Ptr > Value2_Ptr) + { + return(NDS_GREATER); + } + else + { + return(NDS_EQUAL); + } + } + } + + default: + { + printf( "Unknown COMP idx (%d) !\n", Index_Id); + return( NDS_KO); + } + } + + return( NDS_OK); + } + + case NDD_CMD_VALUE_ADD: + { + /* + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + + Command_Name = "NDD_CMD_VALUE_ADD"; + + return( NDS_OK); + } + + case NDD_CMD_VALUE_REMOVE: + { + /* + ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); + + ND_VA_LIST_OPEN( user_args, *Args_Ptr); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + */ + + + Command_Name = "NDD_CMD_VALUE_REMOVE"; + + return( NDS_OK); + } + + case NDD_CMD_VALUE_PRINT: + { + /* + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( lib_args, *Args_Ptr); + + ND_VA_ARG_GET( Out, lib_args, FILE *); + ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode); + ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth); + ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset); + + ND_VA_LIST_OPEN( user_args, lib_args); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + ND_VA_LIST_CLOSE( lib_args); + + void *Value_Ptr = Node_Ptr->Value; + */ + + + Command_Name = "NDD_CMD_VALUE_PRINT"; + + return( NDS_OK); + } + + case NDD_CMD_INFO_PRINT: + { + /* + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( lib_args, *Args_Ptr); + + ND_VA_ARG_GET( Out, lib_args, FILE *); + ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode); + ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth); + ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset); + + ND_VA_LIST_OPEN( user_args, lib_args); + + ND_VA_ARG_GET( user_data, user_args, user_type); + ND_VA_ARG_GET( ..., user_args, ...); + + ND_VA_LIST_CLOSE( user_args); + ND_VA_LIST_CLOSE( lib_args); + */ + ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); + + ND_VA_LIST_OPEN( lib_args, *Args_Ptr); + + ND_VA_ARG_GET( Out, lib_args, FILE *); + ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode); + ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth); + ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset); + + ND_VA_LIST_CLOSE( lib_args); + + void *Value_Ptr = Node_Ptr->Value; + + + Command_Name = "NDD_CMD_INFO_PRINT"; + + return( ND_DataStruct_Info_Print_I( Out, (NDT_Root *)Value_Ptr, Recursive_Mode, --Recursive_Depth, ++Recursive_Offset)); + } + + default: + { + printf( "OpenStruct_Manager() called with an undefined command %d\n", Command); + return( NDS_ERRAPI); + } + } + + printf( "OpenStruct_Manager() called with command %d (%s)\n", Command, Command_Name); + return( NDS_OK); +} + + + + + + + +/*------------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------------*/ +/* FONCTIONS PUBLIQUES */ +/*------------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------------*/ + + + + + +/*------------------------------------------------------------------------------*/ +/* Initialisation du contexte de la librairie */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Library_Open_I( int Debug_Mode) +{ + NDG_Base.Debug_Mode = Debug_Mode; + NDG_Base.Open_Status = NDD_TRUE; + + if( Debug_Mode == NDD_TRUE) + { + ND_Library_StdErr_Set_I( stderr); + } + +#if !defined(_WIN32) + if( ( NDG_Base.DL_Ptr = dlopen( NULL, ( RTLD_NOW | RTLD_GLOBAL))) == NULL) + { + sprintf( NDG_Base.Err_String, "Error ND_Library_Open_I: can't dlopen [%s]", dlerror()); + ND_Error_Print(); + + return( NDS_KO); + } +#endif + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Initialisation du contexte de la librairie */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Library_Open_C( int Debug_Mode) +{ + NDT_Status status; + + + if( NDG_Base.Open_Status != NDD_FALSE) + { + sprintf( NDG_Base.Err_String, "Error ND_Library_Open_C: library is not closed"); + ND_Error_Print(); + + return( NDS_KO); + } + else + { + if( Debug_Mode == NDD_TRUE) + { + if( ( status = ND_DataStruct_Open_I( &(NDG_Base.OpenStruct_Ptr), 1, NDG_Base.OpenStruct_Index_Type, "ND_OpenStruct_Manager", ND_OpenStruct_Manager, NULL, NULL, NULL, NULL, 0, NULL)) != NDS_OK) + { + sprintf( NDG_Base.Err_String, "Error ND_Library_Open_C: can't open OpenStruct"); + ND_Error_Print(); + + return( NDS_KO); + } + } + } + + return( ND_Library_Open_I( Debug_Mode)); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Fermeture du contexte de la librairie */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Library_Close_I( void) +{ + NDT_Symbol *Symbol, *Next_Symbol; + + + /* Désallocation de la table des symboles locale */ + + Symbol = NDG_Base.Symbol_First_Ptr; + + while( Symbol) + { + Next_Symbol = Symbol->Next; + free( Symbol->Name); + free( Symbol); + Symbol = Next_Symbol; + } + + NDG_Base.Symbol_First_Ptr = (NDT_Symbol *)NULL; + +#if !defined(_WIN32) + if( dlclose( NDG_Base.DL_Ptr) != 0) + { + sprintf( NDG_Base.Err_String, "Error ND_Library_Close_I: can't dlclose [%s]", dlerror()); + ND_Error_Print(); + + return( NDS_KO); + } +#endif + + NDG_Base.Open_Status = NDD_FALSE; + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Fermeture du contexte de la librairie */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Library_Close_C( void) +{ + NDT_Status status; + + + if( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Library_Close_C: library is not opened"); + ND_Error_Print(); + + return( NDS_KO); + } + + if( ( NDG_Base.Debug_Mode == NDD_TRUE) && ( NDG_Base.Err_Stream != NULL)) + { + if( NDG_Base.OpenStruct_Ptr->Index_Tab[NDD_INDEX_PRIMARY].Node_Number > 0) + { + sprintf( NDG_Base.Err_String, "Error ND_Library_Close_C: Unclosed DataStruct:"); + ND_Error_Print(); + + if( ( status = ND_DataStruct_Info_Print_I( NDG_Base.Err_Stream, NDG_Base.OpenStruct_Ptr, NDD_RECURSIVE_MODE_PARENT_CHILD, 0, 0)) != NDS_OK) + { + sprintf( NDG_Base.Err_String, "Error ND_Library_Close_C: can't print OpenStruct info"); + ND_Error_Print(); + + return( NDS_KO); + } + } + + if( ( status = ND_DataStruct_Close_I( NDG_Base.OpenStruct_Ptr)) != NDS_OK) + { + sprintf( NDG_Base.Err_String, "Error ND_Library_Close_C: can't close OpenStruct"); + ND_Error_Print(); + + return( NDS_KO); + } + } + + 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) +{ + NDG_Base.Err_Stream = 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) +{ + if( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Library_StdErr_Set_C: library is not opened"); + ND_Error_Print(); + + return( NDS_KO); + } + + 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_Index_Open_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Index_Type Type) +{ + NDT_Status status; + NDT_Node *node_ptr; + + + if( ( status = ND_Index_Clear( Root_Ptr, Index_Id)) != NDS_OK) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Open_I: Index cleaning error"); + ND_Error_Print(); + + return( NDS_KO); + } + + Root_Ptr->Index_Tab[Index_Id].Type = Type & NDD_INDEX_STATUS_RMSK | NDD_INDEX_STATUS_OPENED ; + + Root_Ptr->Index_Open_Count++; + + if( Index_Id != NDD_INDEX_PRIMARY) + { + if( ( status = ND_Index_Node_First_Get_I( &node_ptr, Root_Ptr, NDD_INDEX_PRIMARY)) != NDS_OK) + { + sprintf( NDG_Base.Err_String, "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( NDG_Base.Err_String, "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( NDG_Base.Err_String, "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( NDG_Base.Err_String, "Error ND_Index_Open_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Open_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !ND_INDEX_STATUS_CLOSED_IS( Root_Ptr, Index_Id)) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Open_C: index is not closed"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( ( Root_Ptr->Index_Open_Count == 0) && ( Index_Id != NDD_INDEX_PRIMARY)) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Open_I: fist opened index should be the primary"); + 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; + 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 defined(_WIN32) + if( ( Manager_Name != NULL) && ( Manager_Ptr == NULL)) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Open_I: no symbol lookup support, Manager_Ptr shouldn't be NULL"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } +#endif + + if( ( Manager_Name != NULL) || ( Manager_Ptr != NULL)) + { + Real_Manager_Name = Manager_Name; + Real_Manager_Ptr = Manager_Ptr; + } + else + { + Real_Manager_Name = "ND_Default_Manager"; + Real_Manager_Ptr = ND_Default_Manager; + } + +#if defined(_WIN32) + if( ( Allocator_Name != NULL) && ( Allocator_Ptr == NULL)) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Open_I: no symbol lookup support, Allocator_Ptr shouldn't be NULL"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } +#endif + + if( ( Allocator_Name != NULL) || ( Allocator_Ptr != NULL)) + { + Real_Allocator_Name = Allocator_Name; + Real_Allocator_Ptr = Allocator_Ptr; + } + else + { + Real_Allocator_Name = "ND_Default_Allocator"; + Real_Allocator_Ptr = ND_Default_Allocator; + } + +#if defined(_WIN32) + if( ( Desallocator_Name != NULL) && ( Desallocator_Ptr == NULL)) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Open_I: no symbol lookup support, Desallocator_Ptr shouldn't be NULL"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } +#endif + + if( ( Desallocator_Name != NULL) || ( Desallocator_Ptr != NULL)) + { + Real_Desallocator_Name = Desallocator_Name; + Real_Desallocator_Ptr = Desallocator_Ptr; + } + else + { + Real_Desallocator_Name = "ND_Default_Desallocator"; + Real_Desallocator_Ptr = ND_Default_Desallocator; + } + + status = ND_Node_Root_Alloc( Root_Ptr_Ptr, Index_Nb, Type_Ptr, Real_Manager_Name, Real_Manager_Ptr, Real_Allocator_Name, Real_Allocator_Ptr, Real_Desallocator_Name, Real_Desallocator_Ptr, Own_Value, Data); + + if( ND_ERROR( status)) return( status); + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Cré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) +{ + NDT_Status status; + + + if( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Open_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( ( status = 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)) != NDS_OK) + { + return( status); + } + + if( ( NDG_Base.Debug_Mode == NDD_TRUE) && ( Manager_Ptr != NULL) && ( NDG_Base.Open_Status == NDD_TRUE)) + { + if( ( status = ND_DataStruct_Value_Add_I( NDG_Base.OpenStruct_Ptr, (void **)*Root_Ptr_Ptr)) != NDS_OK) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Open_C: can't add value in OpenStruct"); + ND_Error_Print(); + + return( NDS_KO); + } + } + + 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_Index_Close_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id) +{ + NDT_Status status; + + + if( ( Root_Ptr->Index_Open_Count != 1) && ( Index_Id == NDD_INDEX_PRIMARY)) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Close_I: the primary should be the last closed"); + ND_Error_Print(); + return(NDS_ERRAPI); + } + + status = ND_Index_Flush_I( Root_Ptr, Index_Id); + if( ND_ERROR( status)) return( status); + + Root_Ptr->Index_Tab[ Index_Id].Type = Root_Ptr->Index_Tab[ Index_Id].Type & NDD_INDEX_STATUS_RMSK | NDD_INDEX_STATUS_CLOSED; + + Root_Ptr->Index_Open_Count--; + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Destruction d'une structure de données */ +/*------------------------------------------------------------------------------*/ +/* (O) Root: pointeur sur la racine de la structure de données à détruire */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Index_Close_C( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id) +{ + if( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Close_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Close_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !ND_INDEX_STATUS_OPENED_IS( Root_Ptr, Index_Id)) + { + sprintf( NDG_Base.Err_String, "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) +{ + NDT_Status status; + + + if( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Close_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if (!Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Close_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( ( status = ND_DataStruct_Close_I( Root_Ptr)) != NDS_OK) + { + return( status); + } + + if( NDG_Base.Debug_Mode == NDD_TRUE) + { + if( ( status = ND_DataStruct_Value_Remove_I( NDG_Base.OpenStruct_Ptr, (void *)Root_Ptr)) != NDS_OK) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Close_I: can't remove value from OpenStruct"); + ND_Error_Print(); + + return( NDS_KO); + } + } + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* (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) + { + status = ND_Manager_Exec_I( Root_Ptr, Index_Id, Node_Ptr, NDD_CMD_VALUE_FREE, Node_Ptr->Value); + if( ND_ERROR( status)) return( status); + } + else + { + status = ND_Manager_Exec_I( Root_Ptr, Index_Id, Node_Ptr, NDD_CMD_VALUE_REMOVE, Node_Ptr->Value); + if( ND_ERROR( status)) return( status); + } + + status = ND_Index_Node_Remove_I( Node_Ptr); + if( ND_ERROR( status)) return( status); + + status = ND_Node_Free( Root_Ptr, Node_Ptr); + if (ND_ERROR( status)) return( status); + + Node_Ptr = Next_Node_Ptr; + } + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Destruction d'une structure de donné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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Flush_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Flush_C: structure root is null"); + ND_Error_Print(); + + return(NDS_ERRAPI); + } + + return( ND_Index_Flush_I( Root_Ptr, Index_Id)); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Destruction d'une structure de données */ +/*------------------------------------------------------------------------------*/ +/* (O) Root: pointeur sur la racine de la structure de données à détruire */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_DataStruct_Flush_I( NDT_Root *Root_Ptr) +{ + NDT_Status status; + NDT_Index_Id index_id; + + + for( index_id = ( Root_Ptr->Index_Nb - 1); index_id >= 0 ; index_id--) + { + status = ND_Index_Flush_I( Root_Ptr, index_id); + if( ND_ERROR( status)) return( status); + } + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Destruction d'une structure de donné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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Flush_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if (!Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Flush_C: 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 */ +/* - 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_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Detected_Nb_Ptr, int *Corrected_Nb_Ptr, FILE *Out) +{ + *Detected_Nb_Ptr = 0; + *Corrected_Nb_Ptr = 0; + + + if( ND_INDEX_STATUS_OPENED_IS( Root_Ptr, Index_Id)) + { + if( ND_INDEX_TYPE_LIST_IS( Root_Ptr, Index_Id)) + { + ND_List_Check( Root_Ptr, Index_Id, Detected_Nb_Ptr, Corrected_Nb_Ptr, Out); + } + else if( ND_INDEX_TYPE_TREE_IS( Root_Ptr, Index_Id)) + { + ND_Tree_Check( Root_Ptr, Index_Id, Detected_Nb_Ptr, Corrected_Nb_Ptr, Out); + } + else + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Check_I: unknown structure type (%d) in structure (%p:%d)\n", Root_Ptr->Index_Tab[Index_Id].Type, Root_Ptr, Index_Id); + ND_Error_Print(); + + (*Detected_Nb_Ptr)++; + return( NDS_OK); + } + + /* Affichage du résultat de la procédure de vérification */ + + if( *Detected_Nb_Ptr == 0) + { + fprintf( Out, "No error detected in the node structure (%p:%d)\n", Root_Ptr, Index_Id); + } + else + { + fprintf( Out, "%d/%d error(s) corrected in the node structure (%p:%d)\n", *Corrected_Nb_Ptr, *Detected_Nb_Ptr, Root_Ptr, Index_Id); + } + } + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Function de réparation d'une structure : */ +/* - vérifie que tous les noeuds sont correctement lié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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Check_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Check_C: structure root is null"); + ND_Error_Print(); + + (*Nb_Detected_Ptr)++; + + return(NDS_ERRAPI); + } + + if( !Out) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Check_C: 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 *Error_Detected_Nb_Ptr, int *Error_Corrected_Nb_Ptr, FILE *Out) +{ + NDT_Status status; + NDT_Index_Id index_id; + int index_error_detected_nb, index_error_corrected_nb; + + + for( index_id = 0; index_id < Root_Ptr->Index_Nb; index_id++) + { + status = ND_Index_Check_I( Root_Ptr, index_id, &index_error_detected_nb, &index_error_corrected_nb, Out); + if( ND_ERROR(status)) return(status); + + *Error_Detected_Nb_Ptr = *Error_Detected_Nb_Ptr + index_error_detected_nb; + *Error_Corrected_Nb_Ptr = *Error_Corrected_Nb_Ptr + index_error_corrected_nb; + } + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Function de réparation d'une structure : */ +/* - vérifie que tous les noeuds sont correctement lié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_Ptr, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out) +{ + if( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Check_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Check_C: structure root is null"); + ND_Error_Print(); + (*Nb_Detected_Ptr)++; + + return( NDS_ERRAPI); + } + + if( !Out) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Check_C: 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; + + + if( ND_INDEX_STATUS_OPENED_IS( Root_Ptr, Index_Id)) + { + switch( Root_Ptr->Index_Tab[Index_Id].Type & NDD_INDEX_TYPE_MSK) + { + case NDD_INDEX_TYPE_LIST: + { + + switch( Target_Type & ( NDD_INDEX_TYPE_MSK | NDD_INDEX_SUBTYPE_MSK)) + { + case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_SORTED): + { + rc = ND_List_Sort( Root_Ptr, Index_Id); + if( ND_ERROR( rc)) return( rc); + + Root_Ptr->Index_Tab[Index_Id].Type = Target_Type; + + return( rc); + } + + case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_FIFO): + case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_LIFO): + { + Root_Ptr->Index_Tab[Index_Id].Type = Target_Type; + + return( NDS_OK); + } + + + case( NDD_INDEX_TYPE_TREE | NDD_INDEX_SUBTYPE_BALANCED): + case( NDD_INDEX_TYPE_TREE | NDD_INDEX_SUBTYPE_UNBALANCED): + { + rc = ND_List_Sort( Root_Ptr, Index_Id); + if( rc != NDS_OK) return( rc); + + rc = ND_Tree_Make( Root_Ptr, Index_Id); + if( ND_ERROR( rc)) return( rc); + + Root_Ptr->Index_Tab[Index_Id].Type = Target_Type; + + return( rc); + } + + default: + { + return( NDS_KO); + } + } + + break; + } + + case NDD_INDEX_TYPE_TREE: + { + switch( Target_Type & ( NDD_INDEX_TYPE_MSK | NDD_INDEX_SUBTYPE_MSK)) + { + case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_SORTED): + case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_FIFO): + case( NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_LIFO): + { + + rc = ND_List_Make( Root_Ptr, Index_Id); + if( ND_ERROR( rc)) return( rc); + + Root_Ptr->Index_Tab[Index_Id].Type = Target_Type; + + return( rc); + } + + default: + { + return( NDS_KO); + } + } + + break; + } + + default: + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Convert_I: 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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Convert_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Convert_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + return( ND_Index_Convert_I( Root_Ptr, Index_Id, Target_Type)); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Conversion d'une structure de donné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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Convert_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Convert_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Target_Type_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Convert_C: 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( NDG_Base.Err_String, "Error ND_DataStruct_Reorg_C: 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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Reorg_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Reorg_C: structure root is null"); + ND_Error_Print (); + + return( NDS_ERRAPI); + } + + return( ND_Index_Reorg_I( Root_Ptr, Index_Id)); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Réorganisation d'une structure de donné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_Ptr) +{ + NDT_Status status; + NDT_Index_Id index_id; + + + for( index_id = 0; index_id < Root_Ptr->Index_Nb; index_id++) + { + status = ND_Index_Reorg_I( Root_Ptr, index_id); + if( ND_ERROR( status)) return status; + } + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Réorganisation d'une structure de donné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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Reorg_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Reorg_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + return( ND_DataStruct_Reorg_I( Root_Ptr)); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Parcours de tous les noeuds d'une structure de donné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_Ptr) +{ + 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_Ptr); + 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_Ptr); + 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_Ptr) +{ + if( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Traverse_VC: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "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_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_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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Traverse_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "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_Ptr) +{ + NDT_Status status; + NDT_Index_Id new_index; + NDT_Command new_cmd; + + + status = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_PRIMARY, NULL, NDD_CMD_INDEX_GET, &new_index, &new_cmd, Command, NULL); + if( ND_ERROR(status)) return( status); + + return( ND_Index_Traverse_VI( Root_Ptr, new_index, new_cmd, Args_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_DataStruct_Traverse_VC( NDT_Root *Root_Ptr, NDT_Command Command, va_list *Args_Ptr) +{ + if( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Traverse_VC: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Traverse_VC: structure root is null"); + ND_Error_Print(); + return( NDS_ERRAPI); + } + + return( ND_DataStruct_Traverse_VI( Root_Ptr, Command, Args_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_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_PRIMARY, NULL, NDD_CMD_INDEX_GET, &new_index, &new_cmd, Command, NULL); + if( ND_ERROR( status)) return( status); + + status = ND_Index_Traverse_VI( Root_Ptr, 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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Taverse_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "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'; + + fprintf( Out, "%s Index Id: (%d)\tType: (%#06x) [%s:%s:%s]\tNode Nb: (%d)\tHead: (%s%p)\tTail: (%s%p)\n%s Min Depth: (%d)\tMax Depth: (%d)\tMax Dif: (%d)\tNb Equ: (%d)\tSave: (%s%p)\n\n", + offset, Index_Id, Root_Ptr->Index_Tab[Index_Id].Type, ND_INDEX_STATUS_ASCII_GET( Root_Ptr, Index_Id), ND_INDEX_TYPE_ASCII_GET( Root_Ptr, Index_Id), ND_INDEX_SUBTYPE_ASCII_GET( Root_Ptr, Index_Id), + Root_Ptr->Index_Tab[Index_Id].Node_Number, + NDD_PRINTF_PTR_PREFIX, Root_Ptr->Index_Tab[Index_Id].Head, NDD_PRINTF_PTR_PREFIX, Root_Ptr->Index_Tab[Index_Id].Tail, + offset, Root_Ptr->Index_Tab[Index_Id].Min_Depth, Root_Ptr->Index_Tab[Index_Id].Max_Depth, Root_Ptr->Index_Tab[Index_Id].Max_Dif, Root_Ptr->Index_Tab[Index_Id].Nb_Equ, + NDD_PRINTF_PTR_PREFIX, Root_Ptr->Index_Tab[Index_Id].Save); + } + + if( ND_RECURSIVE_CHILD_IS(Recursive_Mode)) + { + status = ND_Index_Traverse_I( Root_Ptr, Index_Id, NDD_CMD_INFO_PRINT, Out, NDD_RECURSIVE_MODE_PARENT_CHILD, Recursive_Depth, Recursive_Offset); + } + else + { + status = NDS_OK; + } + + return( status); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Affichage d'informations sur une structure de donné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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Info_Print_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Info_Print_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Out) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Info_Print_C: 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); + + fprintf( Out, "%sRoot: (%s%p)\tIndex Nb: (%d)\tIndex Open Count: (%d)\tManager: (%s%p) [%s]\n%sAllocator: (%s%p) [%s]\tDesallocator: (%s%p) [%s]\tUser: (%s%p)\n%sManager Version: [%s]\n\n", + offset, NDD_PRINTF_PTR_PREFIX, Root_Ptr, Root_Ptr->Index_Nb, Root_Ptr->Index_Open_Count, NDD_PRINTF_PTR_PREFIX, Root_Ptr->Manager_Ptr, Root_Ptr->Manager_Name, + offset, NDD_PRINTF_PTR_PREFIX, Root_Ptr->Allocator_Ptr, Root_Ptr->Allocator_Name, NDD_PRINTF_PTR_PREFIX, Root_Ptr->Desallocator_Ptr, Root_Ptr->Desallocator_Name, NDD_PRINTF_PTR_PREFIX, Root_Ptr->User_Ptr, + 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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Info_Print_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf (NDG_Base.Err_String, "Error ND_DataStruct_Info_Print_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Out) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Info_Print_C: 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( NDG_Base.Err_String, "Error ND_Index_Value_Add_I: 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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Value_Add_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Value_Add_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Value_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Value_Add_C: 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_I( 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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Value_Add_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Value_Add_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Value_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_DatatStruct_Value_Add_C: 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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Value_Remove_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Value_Remove_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Value_Ptr) + { + sprintf (NDG_Base.Err_String, "Error ND_Index_Value_Remove_C: 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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Value_Remove_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Value_Remove_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Value_Ptr) + { + sprintf (NDG_Base.Err_String, "Error ND_DataStruct_Value_Remove_C: 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_Ptr) +{ + NDT_Status status; + + + status = ND_Index_Traverse_I( Root_Ptr, Index_Id, NDD_CMD_VALUE_PRINT, Out, Recursive_Mode, Recursive_Depth, Recursive_Offset, Args_Ptr); + + 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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Value_Print_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Value_Print_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Out) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Value_Print_C: 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_Ptr) +{ + NDT_Status status; + + status = ND_DataStruct_Traverse_I( Root_Ptr, NDD_CMD_VALUE_PRINT, Out, Recursive_Mode, Recursive_Depth, Recursive_Offset, User_Args_Ptr); + + 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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Value_Print_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Value_Print_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Out) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Value_Print_C: 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_Index_Node_Add_I( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr ) +{ + if( ND_INDEX_TYPE_LIST_IS( Root_Ptr, Index_Id)) return ND_List_Node_Add( Root_Ptr, Index_Id, Node_Ptr); + else if( ND_INDEX_TYPE_TREE_IS( Root_Ptr, Index_Id)) return ND_Tree_Node_Add( Root_Ptr, Index_Id, Node_Ptr); + else + { + sprintf (NDG_Base.Err_String, "Error ND_Index_Node_Add_I: unknown structure type (%d)", Root_Ptr->Index_Tab[Index_Id].Type); + ND_Error_Print (); + return( NDS_ERRAPI); + } + + 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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Node_Add_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf (NDG_Base.Err_String, "Error ND_Index_Node_Add_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Node_Ptr) + { + sprintf (NDG_Base.Err_String, "Error ND_Index_Node_Add_C: 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_Index_Node_Remove_I( NDT_Node *Node_Ptr) +{ + NDT_Root *root_ptr; + NDT_Index_Id index_id; + + + root_ptr = Node_Ptr->Root; + index_id = Node_Ptr->Index; + + if( ND_INDEX_TYPE_LIST_IS( root_ptr, index_id)) return ND_List_Node_Remove( Node_Ptr); + else if( ND_INDEX_TYPE_TREE_IS( root_ptr, index_id)) + { + NDT_Node **tmp_ptr_ptr; + + /* On récupère l'adresse du lien entre le noeud à supprimer et son père */ + + if( Node_Ptr->Parent) + { + /* Cas général */ + + if( Node_Ptr == Node_Ptr->Parent->Left) tmp_ptr_ptr = &(Node_Ptr->Parent->Left); + else tmp_ptr_ptr = &(Node_Ptr->Parent->Right); + } + else + { + /* Cas du noeud racine */ + + tmp_ptr_ptr = NULL; + } + + if( Node_Ptr->Right) + { + NDT_Node *Right_Node_Ptr = Node_Ptr->Right; + NDT_Node *Left_Node_Ptr = Node_Ptr->Left; + NDT_Node *First_Node_Ptr; + + /* + On sauve le fils gauche du noeud à supprimer dans un pointeur de + sauvegarde pour pouvoir le récupérer au cas où la procédure serait + interrompue (recovery). + */ + + root_ptr->Index_Tab[index_id].Save = Left_Node_Ptr; + + /* On remplace le noeud supprimé par son sous-arbre droit */ + + if( !tmp_ptr_ptr) root_ptr->Index_Tab[index_id].Head = root_ptr->Index_Tab[index_id].Tail = Node_Ptr->Right; + else *tmp_ptr_ptr = Node_Ptr->Right; + + Right_Node_Ptr->Parent = Node_Ptr->Parent; + + /* On attache le sous-arbre gauche au premier noeud du sous-arbre droit */ + + if( root_ptr->Index_Tab[index_id].Save) + { + First_Node_Ptr = ND_Tree_Node_First_Recursive_Get(Right_Node_Ptr); + + First_Node_Ptr->Left = root_ptr->Index_Tab[index_id].Save; + + root_ptr->Index_Tab[index_id].Save->Parent = First_Node_Ptr; + + root_ptr->Index_Tab[index_id].Save = NULL; + } + } + else + { + /* On remplace le noeud supprimé par son sous-arbre gauche */ + + if( !tmp_ptr_ptr) root_ptr->Index_Tab[index_id].Head = root_ptr->Index_Tab[index_id].Tail = Node_Ptr->Left; + else *tmp_ptr_ptr = Node_Ptr->Left; + + if( Node_Ptr->Left) Node_Ptr->Left->Parent = Node_Ptr->Parent; + } + + root_ptr->Index_Tab[index_id].Node_Number--; + + /* Pas de mise à jour des informations de profondeur : trop coûteux */ + + Node_Ptr->Root = NULL; + Node_Ptr->Index = NDD_INDEX_UNKNOWN; + Node_Ptr->Left = NULL; + Node_Ptr->Right = NULL; + Node_Ptr->Parent = NULL; + } + else + { + sprintf (NDG_Base.Err_String, "Error ND_Index_Node_Remove_I: unknown structure type (%d)", root_ptr->Index_Tab[index_id].Type); + ND_Error_Print (); + return(NDS_ERRAPI); + } + + return(NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Suppression d'un noeud dans une structure de données */ +/*------------------------------------------------------------------------------*/ +/* (I) Node: pointeur sur le noeud à supprimer */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Index_Node_Remove_C( NDT_Node *Node_Ptr) +{ + if( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Node_Remove_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Node_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Node_Remove_C: the node to remove is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + return( ND_Index_Node_Remove_I( Node_Ptr)); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* 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_I( NDT_Node **First_Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id) +{ + *First_Node_Ptr_Ptr = NULL; + + if( ND_INDEX_TYPE_LIST_IS(Root_Ptr, Index_Id)) *First_Node_Ptr_Ptr = (Root_Ptr->Index_Tab)[Index_Id].Head; + + else if( ND_INDEX_TYPE_TREE_IS(Root_Ptr, Index_Id)) *First_Node_Ptr_Ptr = ND_Tree_Node_First_Recursive_Get( Root_Ptr->Index_Tab[Index_Id].Head); + + // if(!*First_Node_Ptr_Ptr) return(NDS_KO); + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Récupé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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Node_First_Get_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Node_First_Get_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + return( ND_Index_Node_First_Get_I( First_Node_Ptr_Ptr, Root_Ptr, Index_Id)); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Récupération du dernier noeud d'une structure */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine dont on cherche le dernier noeud */ +/* (O) Last_Node : adresse du pointeur sur le premier noeud */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Index_Node_Last_Get_I ( NDT_Node **Last_Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id) +{ + *Last_Node_Ptr_Ptr = NULL; + + if( ND_INDEX_TYPE_LIST_IS(Root_Ptr, Index_Id)) *Last_Node_Ptr_Ptr = Root_Ptr->Index_Tab[Index_Id].Tail; + + else if( ND_INDEX_TYPE_TREE_IS(Root_Ptr, Index_Id)) *Last_Node_Ptr_Ptr = ND_Tree_Node_Last_Recursive_Get( Root_Ptr->Index_Tab[Index_Id].Head); + + // if(!*Last_Node_Ptr_Ptr) return(NDS_KO); + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Récupé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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Node_Last_Get_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Node_Last_Get_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + return( ND_Index_Node_Last_Get_I( Last_Node_Ptr_Ptr, Root_Ptr, Index_Id)); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Récupération du noeud suivant */ +/*------------------------------------------------------------------------------*/ +/* (I) Node : pointeur sur le noeud dont on cherche le suivant */ +/* (O) Next_Node : adresse du pointeur sur le noeud suivant */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Index_Node_Next_Get_I ( NDT_Node **Next_Node_Ptr_Ptr, NDT_Node *Node_Ptr) +{ + if( ND_INDEX_TYPE_LIST_IS( Node_Ptr->Root, Node_Ptr->Index)) + { + *Next_Node_Ptr_Ptr = Node_Ptr->Right; + } + else if( ND_INDEX_TYPE_TREE_IS( Node_Ptr->Root, Node_Ptr->Index)) + { + if( !Node_Ptr->Right) + { + *Next_Node_Ptr_Ptr = ND_Tree_Parent_Next_Recursive_Get(Node_Ptr); + } + else + { + *Next_Node_Ptr_Ptr = ND_Tree_Node_First_Recursive_Get(Node_Ptr->Right); + } + } + + // if(!*Next_Node_Ptr_Ptr) return(NDS_KO); + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Récupé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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Node_Next_Get_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Node_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Node_Next_Get_C: 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_Index_Node_Previous_Get_I( NDT_Node **Prev_Node_Ptr_Ptr, NDT_Node *Node_Ptr) +{ + if( ND_INDEX_TYPE_LIST_IS( Node_Ptr->Root, Node_Ptr->Index)) *Prev_Node_Ptr_Ptr = Node_Ptr->Left; + + if( ND_INDEX_TYPE_TREE_IS( Node_Ptr->Root, Node_Ptr->Index)) + { + if( !Node_Ptr->Left) + { + *Prev_Node_Ptr_Ptr = ND_Tree_Parent_Previous_Recursive_Get( Node_Ptr); + } + else + { + *Prev_Node_Ptr_Ptr = ND_Tree_Node_Last_Recursive_Get( Node_Ptr->Left); + } + } + + // if( !*Prev_Node_Ptr_Ptr) return( NDS_KO); + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Récupé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_Index_Node_Previous_Get_C( NDT_Node **Prev_Node_Ptr_Ptr, NDT_Node *Node_Ptr) +{ + if( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Node_Previous_Get_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Node_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Node_Previous_Get_C: node is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + return( ND_Index_Node_Previous_Get_I( Prev_Node_Ptr_Ptr, Node_Ptr)); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Recherche un noeud à 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_VI( NDT_Node **Node_Ptr_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr, va_list *Args_Ptr) +{ + if( ND_INDEX_TYPE_LIST_IS( Root_Ptr, Index_Id)) + { + *Node_Ptr_Ptr = ND_List_Node_Find( Root_Ptr, Index_Id, Value_Ptr, Args_Ptr); + } + 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_Ptr); + } + else + { + sprintf (NDG_Base.Err_String, "Error ND_Index_Node_Find_VI: unknown structure type (%d)", Root_Ptr->Index_Tab[Index_Id].Type); + ND_Error_Print (); + + return( NDS_KO); + } + + 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_Ptr) +{ + NDT_Status status; + + + if( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Node_Find_VC: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Node_Find_VC: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Value_Ptr) + { + sprintf( NDG_Base.Err_String, "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_Ptr); + + + 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 (NDG_Base.Err_String, "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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Node_Find_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Node_Find_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Value_Ptr) + { + sprintf( NDG_Base.Err_String, "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_Ptr) +{ + 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_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, Args_Ptr); + 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_Ptr) +{ + NDT_Status status; + + + if( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Value_Find_VC: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Value_Find_VC: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Ref_Value_Ptr) + { + sprintf( NDG_Base.Err_String, "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_Ptr); + + 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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Value_Find_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_DataStruct_Value_Find_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Ref_Value_Ptr) + { + sprintf( NDG_Base.Err_String, "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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Node_Root_Get_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Node_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Node_Root_Get_C: 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 */ +/*------------------------------------------------------------------------------*/ +/* (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_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( user_args, Value_Ptr_Ptr); + + /* Appel du manager */ + + rc = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_UNKNOWN, NULL, NDD_CMD_VALUE_ALLOC, Value_Ptr_Ptr, &user_args); + + va_end( user_args); + + return( rc); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Allocation d'une valeur d'une structure de donné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_C( NDT_Root *Root_Ptr, void **Value_Ptr_Ptr, ...) +{ + NDT_Status rc; + va_list user_args; + + + if( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Value_Alloc_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Value_Alloc_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + /* Récupération des arguments pour l'allocation de la valeur */ + + va_start( user_args, Value_Ptr_Ptr); + + /* Appel du manager */ + + rc = ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_UNKNOWN, NULL, NDD_CMD_VALUE_ALLOC, Value_Ptr_Ptr, &user_args); + + va_end( user_args); + + return( rc); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Désallocation d'une valeur d'une structure de donné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_Ptr, void *Value_Ptr) +{ + return( ND_Manager_Exec_I( Root_Ptr, NDD_INDEX_UNKNOWN, NULL, NDD_CMD_VALUE_FREE, Value_Ptr)); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Désallocation d'une valeur d'une structure de donné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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Value_Free_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Value_Free_C: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Value_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Value_Free_C: the value to free is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + /* Appel du manager */ + + return( ND_Value_Free_I( Root_Ptr, Value_Ptr)); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Exé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_VI( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list *Args_Ptr) +{ + NDT_Status status; + NDT_Manager *manager_ptr; + + + if( Root_Ptr->Manager_Ptr != NULL) + { + manager_ptr = Root_Ptr->Manager_Ptr; + } + else + { + if( ND_Symbol_Find( (void **)&manager_ptr, Root_Ptr->Manager_Name) != NDS_OK) + { + sprintf( NDG_Base.Err_String, "ND_Manager_Exec_VI: cant't find manger function"); + ND_Error_Print(); + + return( NDS_KO); + } + } + + status = manager_ptr( Root_Ptr, Index_Id, Node_Ptr, Command, Args_Ptr); + + 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_Ptr) +{ + NDT_Status status; + + + if( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Manager_Exec_VC: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "Error ND_Manager_Exec_VC: structure root is null"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr->Manager_Ptr || !*(Root_Ptr->Manager_Ptr)) + { + sprintf( NDG_Base.Err_String, "Error ND_Manager_Exec_VC: undefined function name"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + status = ND_Manager_Exec_VI( Root_Ptr, Index_Id, Node_Ptr, Command, Args_Ptr); + + 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); + + if( Root_Ptr->Manager_Ptr != NULL) + { + manager_ptr = Root_Ptr->Manager_Ptr; + } + else + { + if( ND_Symbol_Find( (void **)&manager_ptr, Root_Ptr->Manager_Name) != NDS_OK) + { + sprintf( NDG_Base.Err_String, "ND_Manager_Exec_I: cant't find manger function"); + ND_Error_Print(); + + return( NDS_KO); + } + } + + 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( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Manager_Exec_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( !Root_Ptr) + { + sprintf( NDG_Base.Err_String, "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( NDG_Base.Err_String, "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 */ +/*------------------------------------------------------------------------------*/ +/* (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( void **Ptr_Ptr, size_t Size, NDT_Allocator_Name Allocator_Name, NDT_Allocator *Allocator_Ptr, void *Data_Ptr) +{ + NDT_Allocator *allocator_ptr; + + + if( Allocator_Ptr != NULL) + { + allocator_ptr = Allocator_Ptr; + } + else + { + if( ND_Symbol_Find( (void **)&allocator_ptr, Allocator_Name) != NDS_OK) + { + sprintf( NDG_Base.Err_String, "Error ND_Manager_Exec_I: cant't find allocator function"); + ND_Error_Print(); + + return( NDS_KO); + } + } + + return allocator_ptr( Ptr_Ptr, Size, 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( void **Ptr_Ptr, size_t Size, NDT_Allocator_Name Allocator_Name, NDT_Allocator *Allocator_Ptr, void *Data_Ptr) +{ + if( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Allocator_Exec_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( ( Allocator_Name == NULL) && ( Allocator_Ptr == NULL)) + { + sprintf( NDG_Base.Err_String, "Error ND_Allocator_Exec_C: undefined function name"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + return( ND_Allocator_Exec_I( Ptr_Ptr, Size, Allocator_Name, Allocator_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_I( void *Ptr, NDT_Desallocator_Name Desallocator_Name, NDT_Desallocator *Desallocator_Ptr, void *Data_Ptr) +{ + NDT_Desallocator *desallocator_ptr; + + + if( Desallocator_Ptr != NULL) + { + desallocator_ptr = Desallocator_Ptr; + } + else + { + if( ND_Symbol_Find( (void **)&desallocator_ptr, Desallocator_Name) != NDS_OK) + { + sprintf( NDG_Base.Err_String, "Error ND_Manager_Exec_I: cant't find desallocator function"); + ND_Error_Print(); + + return( NDS_KO); + } + } + + 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( void *Ptr, NDT_Desallocator_Name Desallocator_Name, NDT_Desallocator *Desallocator_Ptr, void *Data_Ptr) +{ + if( NDG_Base.Open_Status != NDD_TRUE) + { + sprintf( NDG_Base.Err_String, "Error ND_Desallocator_Exec_C: library is not open"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + if( ( Desallocator_Name == NULL) && ( Desallocator_Ptr == NULL)) + { + sprintf( NDG_Base.Err_String, "Error ND_Desallocator_Exec_C: undefined function name"); + ND_Error_Print(); + + return( NDS_ERRAPI); + } + + return( ND_Desallocator_Exec_I( Ptr, Desallocator_Name, Desallocator_Ptr, Data_Ptr)); +} + + + + + + + +/*------------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------------*/ +/* PRIVATE FUNCTIONS */ +/*------------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------*/ +/* Symbol Lookup */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Symbol_Find( void **Ptr_Ptr, const char *Symbol_Name) +{ +#if !defined(_WIN32) + NDT_Symbol *Symbol_Ptr; + + + /* Recherche du symbole dans la table des symboles locale */ + + Symbol_Ptr = NDG_Base.Symbol_First_Ptr; + + while( Symbol_Ptr) + { + if( !strcmp( Symbol_Ptr->Name, Symbol_Name)) + { + *Ptr_Ptr = Symbol_Ptr->Ptr; + return( NDS_OK); + } + else + { + Symbol_Ptr = Symbol_Ptr->Next; + } + } + + + /* Si le symbole n'a pas été trouvée dans la table des symboles locale, on l'y ajoute */ + + if( ( *Ptr_Ptr = dlsym( NDG_Base.DL_Ptr, (const char *)Symbol_Name)) == NULL) + { + sprintf( NDG_Base.Err_String, "Error ND_Symbol_Find: unable to find \"%s\"' in symbol table (%s)", Symbol_Name, dlerror()); + ND_Error_Print(); + + return( NDS_KO); + } + + Symbol_Ptr = (NDT_Symbol *)malloc( sizeof( NDT_Symbol)); + if( Symbol_Ptr == NULL) + { + sprintf( NDG_Base.Err_String, "Error ND_Symbol_Find: no more memory"); + ND_Error_Print(); + + return( NDS_KO); + } + else + { + Symbol_Ptr->Name = strdup (Symbol_Name); + Symbol_Ptr->Ptr = *Ptr_Ptr; + Symbol_Ptr->Next = NDG_Base.Symbol_First_Ptr; + + NDG_Base.Symbol_First_Ptr = Symbol_Ptr; + } +#endif + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Allocation d'un noeud */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure */ +/* (O) Node : adresse du pointeur sur le nouveau noeud */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Node_Alloc( NDT_Root *Root_Ptr, NDT_Node **Node_Ptr_Ptr ) +{ + NDT_Status rc; + + + rc = ND_Allocator_Exec_I( (void **)Node_Ptr_Ptr, sizeof(NDT_Node), Root_Ptr->Allocator_Name, Root_Ptr->Allocator_Ptr, Root_Ptr->User_Ptr); + if( ND_ERROR( rc)) return( rc); + + (*Node_Ptr_Ptr)->Root = NULL; + (*Node_Ptr_Ptr)->Index = NDD_INDEX_UNKNOWN; + (*Node_Ptr_Ptr)->Parent = NULL; + (*Node_Ptr_Ptr)->Left = NULL; + (*Node_Ptr_Ptr)->Right = NULL; + (*Node_Ptr_Ptr)->Value = NULL; + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Désallocation d'un noeud */ +/*------------------------------------------------------------------------------*/ +/* (I) Root: pointeur sur la racine de la structure */ +/* (I) Node : pointeur sur le noeud à détruire */ +/*------------------------------------------------------------------------------*/ +NDT_Status ND_Node_Free( NDT_Root *Root_Ptr, NDT_Node *Node_Ptr) +{ + return( ND_Desallocator_Exec_I( Node_Ptr, Root_Ptr->Desallocator_Name, Root_Ptr->Desallocator_Ptr, Root_Ptr->User_Ptr)); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* 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_Clear( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id) +{ + Root_Ptr->Index_Tab[Index_Id].Type = NDD_INDEX_STATUS_UNKNOWN; + + Root_Ptr->Index_Tab[Index_Id].Head = NULL; + Root_Ptr->Index_Tab[Index_Id].Tail = NULL; + Root_Ptr->Index_Tab[Index_Id].Save = NULL; + + Root_Ptr->Index_Tab[Index_Id].Max_Dif = DEF_MAX_DIF; + + Root_Ptr->Index_Tab[Index_Id].Node_Number = 0; + Root_Ptr->Index_Tab[Index_Id].Max_Depth = 0; + Root_Ptr->Index_Tab[Index_Id].Min_Depth = NDD_HUGE_LONG; + Root_Ptr->Index_Tab[Index_Id].Nb_Equ = 0; + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Allocation d'une racine de structure de données */ +/*------------------------------------------------------------------------------*/ +/* (O) New_Root: adresse du pointeur sur la nouvelle racine */ +/* (I) Type: type de la structure de données */ +/* (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 */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Node_Root_Alloc( NDT_Root **Root_Ptr_Ptr, NDT_Index_Nb Index_Nb, NDT_Index_Type *Type_Ptr, char *Manager_Name, NDT_Manager *Manager_Ptr, char *Allocator_Name, NDT_Allocator *Allocator_Ptr, char *Desallocator_Name, NDT_Desallocator *Desallocator_Ptr, short Own_Value, void *Data_Ptr) +{ + NDT_Status status; + NDT_Index_Id index_id; + + + status = ND_Allocator_Exec_I( (void **)Root_Ptr_Ptr, ( sizeof( NDT_Root) + sizeof(NDT_Index) * (Index_Nb - 1)), Allocator_Name, Allocator_Ptr, Data_Ptr); + if( ND_ERROR(status)) return( status); + + if( strlen(Manager_Name) > NDD_MANAGER_NAME_LEN_MAX) return( NDS_ERRAPI); + strcpy( (*Root_Ptr_Ptr)->Manager_Name, Manager_Name); + (*Root_Ptr_Ptr)->Manager_Ptr = Manager_Ptr; + + if( strlen(Allocator_Name) > NDD_ALLOCATOR_NAME_LEN_MAX) return( NDS_ERRAPI); + strcpy( (*Root_Ptr_Ptr)->Allocator_Name, Allocator_Name); + (*Root_Ptr_Ptr)->Allocator_Ptr = Allocator_Ptr; + + if( strlen(Desallocator_Name) > NDD_DESALLOCATOR_NAME_LEN_MAX) return( NDS_ERRAPI); + strcpy( (*Root_Ptr_Ptr)->Desallocator_Name, Desallocator_Name); + (*Root_Ptr_Ptr)->Desallocator_Ptr = Desallocator_Ptr; + + (*Root_Ptr_Ptr)->Own_Value = Own_Value; + (*Root_Ptr_Ptr)->User_Ptr = Data_Ptr; + + (*Root_Ptr_Ptr)->Index_Nb = Index_Nb; + (*Root_Ptr_Ptr)->Index_Open_Count = 0; + + for( index_id = 0; index_id < Index_Nb; index_id++) + { + if( ( Type_Ptr[index_id] & NDD_INDEX_STATUS_MSK) == NDD_INDEX_STATUS_OPENED) + { + status = ND_Index_Open_I( *Root_Ptr_Ptr, index_id, Type_Ptr[index_id]); + if( ND_ERROR( status)) return( status); + } + else + { + if( ( status = ND_Index_Clear( *Root_Ptr_Ptr, index_id)) != NDS_OK) + { + sprintf( NDG_Base.Err_String, "Error ND_Index_Open_I: Index cleaning error"); + ND_Error_Print(); + return( NDS_KO); + } + + ( *Root_Ptr_Ptr)->Index_Tab[index_id].Type = NDD_INDEX_STATUS_CLOSED; + } + } + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Désallocation de la racine d'une structure de donné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, Root_Ptr->Desallocator_Name, Root_Ptr->Desallocator_Ptr, Root_Ptr->User_Ptr)); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* 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_Ptr, NDT_Index_Id Index_Id, NDT_Node *New_Node_Ptr) +{ + /* Ajout dans une liste triée */ + + if( ND_INDEX_SUBTYPE_SORTED_IS( Root_Ptr, Index_Id)) + { + NDT_Node *node_ptr; + NDT_Status rc; + + + New_Node_Ptr->Root = Root_Ptr; + New_Node_Ptr->Index = Index_Id; + New_Node_Ptr->Parent = New_Node_Ptr->Left = New_Node_Ptr->Right = NULL; + + /* + Une liste triée peut être orientée de 2 manières : + + - FIFO : un noeud sera inséré APRES un noeud de même valeur (par défaut) + - FILO : un noeud sera inséré AVANT un noeud de même valeur + */ + + 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_ptr = Root_Ptr->Index_Tab[Index_Id].Head; + + while( node_ptr) + { + rc = ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_COMP, New_Node_Ptr->Value, node_ptr->Value, NULL); + + if(rc == NDS_GREATER) + node_ptr = node_ptr->Right; + else + { + /* On insère avant le noeud courant si le nouveau noeud est de valeur inférieure ou égale */ + + New_Node_Ptr->Left = node_ptr->Left; + New_Node_Ptr->Right = node_ptr; + + if(!node_ptr->Left) Root_Ptr->Index_Tab[Index_Id].Head = New_Node_Ptr; + else node_ptr->Left->Right = New_Node_Ptr; + + node_ptr->Left = New_Node_Ptr; + node_ptr = NULL; + } + } + + /* Insertion en queue de liste si le noeud n'a pas été inséré */ + + if(!New_Node_Ptr->Left && !New_Node_Ptr->Right) + { + if( !Root_Ptr->Index_Tab[Index_Id].Tail) Root_Ptr->Index_Tab[Index_Id].Head = Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr; + else + { + Root_Ptr->Index_Tab[Index_Id].Tail->Right = New_Node_Ptr; + New_Node_Ptr->Left = Root_Ptr->Index_Tab[Index_Id].Tail; + Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr; + } + } + } + else + { + /* Pour une liste triée orientée FIFO, on parcourt la liste dans le sens inverse */ + + node_ptr = Root_Ptr->Index_Tab[Index_Id].Tail; + while( node_ptr) + { + rc = ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_COMP, New_Node_Ptr->Value, node_ptr->Value, NULL); + + /* On insère après le noeud courant si le nouveau noeud est de valeur strictement supérieure ou égale */ + + if( rc == NDS_LOWER) node_ptr = node_ptr->Left; + else + { + New_Node_Ptr->Left = node_ptr; + New_Node_Ptr->Right = node_ptr->Right; + + if( !node_ptr->Right) Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr; + else node_ptr->Right->Left = New_Node_Ptr; + + node_ptr->Right = New_Node_Ptr; + node_ptr = NULL; + } + } + + /* Insertion en tête de liste si le noeud n'a pas été inséré */ + + if( !New_Node_Ptr->Left && !New_Node_Ptr->Right) + { + if( !Root_Ptr->Index_Tab[Index_Id].Head) Root_Ptr->Index_Tab[Index_Id].Head = Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr; + else + { + Root_Ptr->Index_Tab[Index_Id].Head->Left = New_Node_Ptr; + New_Node_Ptr->Right = Root_Ptr->Index_Tab[Index_Id].Head; + Root_Ptr->Index_Tab[Index_Id].Head = New_Node_Ptr; + } + } + } + + Root_Ptr->Index_Tab[Index_Id].Node_Number++; + + return( NDS_OK); + } + else + { + /* FIFO = ajout en queue de liste */ + + if( ND_INDEX_SUBTYPE_FIFO_IS( Root_Ptr, Index_Id)) + { + New_Node_Ptr->Root = Root_Ptr; + New_Node_Ptr->Index = Index_Id; + New_Node_Ptr->Parent = NULL; + New_Node_Ptr->Left = Root_Ptr->Index_Tab[Index_Id].Tail; + New_Node_Ptr->Right = NULL; + + if( !Root_Ptr->Index_Tab[Index_Id].Head) Root_Ptr->Index_Tab[Index_Id].Head = New_Node_Ptr; + else Root_Ptr->Index_Tab[Index_Id].Tail->Right = New_Node_Ptr; + + Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr; + Root_Ptr->Index_Tab[Index_Id].Node_Number++; + + return( NDS_OK); + } + + /* FILO = ajout en tête de liste */ + + if( ND_INDEX_SUBTYPE_LIFO_IS( Root_Ptr, Index_Id)) + { + + New_Node_Ptr->Root = Root_Ptr; + New_Node_Ptr->Index = Index_Id; + New_Node_Ptr->Parent = NULL; + New_Node_Ptr->Left = NULL; + New_Node_Ptr->Right = Root_Ptr->Index_Tab[Index_Id].Head; + + if( !Root_Ptr->Index_Tab[Index_Id].Tail) Root_Ptr->Index_Tab[Index_Id].Tail = New_Node_Ptr; + else Root_Ptr->Index_Tab[Index_Id].Head->Left = New_Node_Ptr; + + Root_Ptr->Index_Tab[Index_Id].Head = New_Node_Ptr; + Root_Ptr->Index_Tab[Index_Id].Node_Number++; + + return( NDS_OK); + } + } + + printf( "ND_List_Node_Add: unknown list type (%d)\n", Root_Ptr->Index_Tab[Index_Id].Type); + return( NDS_ERRAPI); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Ajout d'une nouvelle valeur à 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_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr) +{ + NDT_Status rc; + NDT_Node *node_ptr; + + + rc = ND_Node_Alloc( Root_Ptr, &node_ptr); + if( ND_ERROR(rc)) return(rc); + + node_ptr->Value = Value_Ptr; + +// return ND_List_Node_Add( Root, Node); + + rc = ND_List_Node_Add( Root_Ptr, Index_Id, node_ptr); + if( ND_ERROR(rc)) + { + return( rc); + } + else + { + return( ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_ADD, Value_Ptr, NULL)); + } +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Ajout d'un noeud à 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_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr) +{ + NDT_Status rc; + NDT_Node *node_ptr; + + + rc = ND_Node_Alloc( Root_Ptr, &node_ptr); + if( ND_ERROR(rc)) return(rc); + + node_ptr->Value = Value_Ptr; + +// return ND_Tree_Node_Add( Root, Node); + + rc = ND_Tree_Node_Add( Root_Ptr, Index_Id, node_ptr); + if( ND_ERROR(rc)) + { + return( rc); + } + else + { + return ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_ADD, Value_Ptr, NULL); + } +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Recherche une valeur dans une liste et retourne le noeud correspondant */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la liste */ +/* (I) Value : pointeur sur la valeur à rechercher */ +/* (I) Data : pointeur de données */ +/*------------------------------------------------------------------------------*/ + +NDT_Node *ND_List_Node_Find( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr, va_list *User_Args_Ptr) +{ + NDT_Node *node_ptr; + NDT_Status rc; + + + node_ptr = Root_Ptr->Index_Tab[Index_Id].Head; + + if( ND_INDEX_SUBTYPE_SORTED_IS( Root_Ptr, Index_Id)) + { + /* Pour les listes triées, la recherche peut être optimisée */ + + while( node_ptr) + { + rc = ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_COMP, Value_Ptr, node_ptr->Value, User_Args_Ptr); + + switch( rc) + { + case NDS_EQUAL: + { + 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); + } + + case NDS_GREATER: + { + node_ptr = node_ptr->Right; + break; + } + } + } + } + else + { + /* Pour les listes non triées, il faut parcourir toute la liste */ + + while( node_ptr && ( ND_Manager_Exec_I( Root_Ptr, Index_Id, node_ptr, NDD_CMD_VALUE_COMP, Value_Ptr, node_ptr->Value, User_Args_Ptr) != NDS_EQUAL)) + { + node_ptr = node_ptr->Right; + } + } + + return( node_ptr); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Recherche un noeud dans un arbre et retourne le pointeur sur le noeud */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de l'abre */ +/* (I) Value : pointeur sur la valeur à rechercher */ +/* (I) Data : pointeur de données */ +/*------------------------------------------------------------------------------*/ + +/*------------------------------ Recursive Kernel ------------------------------*/ + +NDT_Node *ND_Tree_Node_Recursive_Find( NDT_Node *Node_Ptr, void *Value_Ptr, va_list *User_Args_Ptr) +{ + NDT_Status answer; + + + if( !Node_Ptr) return(NULL); + + answer = ND_Manager_Exec_I( Node_Ptr->Root, Node_Ptr->Index, Node_Ptr, NDD_CMD_VALUE_COMP, Value_Ptr, Node_Ptr->Value, User_Args_Ptr); + + /* Noeud trouvé */ + + if( answer == NDS_EQUAL) return(Node_Ptr); + + /* Continuation de la recherche par appel récursif */ + + if( answer == NDS_LOWER) return( ND_Tree_Node_Recursive_Find( Node_Ptr->Left, Value_Ptr, User_Args_Ptr)); + + if( answer == NDS_GREATER) return( ND_Tree_Node_Recursive_Find( Node_Ptr->Right, Value_Ptr, User_Args_Ptr)); + + return( NULL); +} + + + +/*-------------------------------- main body ---------------------------------*/ + +NDT_Node *ND_Tree_Node_Find( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, void *Value_Ptr, va_list *User_Args_Ptr) +{ + return( ND_Tree_Node_Recursive_Find( Root_Ptr->Index_Tab[Index_Id].Head, Value_Ptr, User_Args_Ptr)); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* 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_Ptr) +{ + if( !Node_Ptr->Parent) return( NULL); + + if( Node_Ptr == Node_Ptr->Parent->Right) return( ND_Tree_Parent_Next_Recursive_Get( Node_Ptr->Parent)); + + return( Node_Ptr->Parent); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Recherche du premier noeud parent situé avant */ +/*------------------------------------------------------------------------------*/ +/* (I) Node : pointeur sur le noeud */ +/*------------------------------------------------------------------------------*/ + +NDT_Node *ND_Tree_Parent_Previous_Recursive_Get( NDT_Node *Node_Ptr) +{ + if( !Node_Ptr->Parent) return( NULL); + + if( Node_Ptr == Node_Ptr->Parent->Left) return( ND_Tree_Parent_Previous_Recursive_Get( Node_Ptr->Parent)); + + return( Node_Ptr->Parent); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Supprime le noeud d'une liste */ +/*------------------------------------------------------------------------------*/ +/* (I) Node : pointeur sur le noeud à supprimer */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_List_Node_Remove( NDT_Node *Node_Ptr) +{ + if( !Node_Ptr->Left) Node_Ptr->Root->Index_Tab[Node_Ptr->Index].Head = Node_Ptr->Right; + else Node_Ptr->Left->Right = Node_Ptr->Right; + + if( !Node_Ptr->Right) Node_Ptr->Root->Index_Tab[Node_Ptr->Index].Tail = Node_Ptr->Left; + else Node_Ptr->Right->Left = Node_Ptr->Left; + + Node_Ptr->Root->Index_Tab[Node_Ptr->Index].Node_Number--; + + Node_Ptr->Root = NULL; + Node_Ptr->Index = NDD_INDEX_UNKNOWN; + Node_Ptr->Left = NULL; + Node_Ptr->Right = NULL; + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Conversion d'un arbre en liste chaînée */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine du la structure à convertir */ +/*------------------------------------------------------------------------------*/ + +/*------------------------------- Recursive Kernel -----------------------------*/ + +NDT_Status ND_List_Recursive_Make( NDT_Node *Node_Ptr, NDT_Root *Root_Ptr, NDT_Index_Id Index_Id) +{ + NDT_Node *right_node_ptr; + + + if( !Node_Ptr) return NDS_OK; + + if( ND_List_Recursive_Make( Node_Ptr->Left, Root_Ptr, Index_Id) != NDS_OK) return NDS_KO; + + right_node_ptr = Node_Ptr->Right; + + if( ND_List_Node_Add( Root_Ptr, Index_Id, Node_Ptr) != NDS_OK) return NDS_KO; + + return( ND_List_Recursive_Make( right_node_ptr, Root_Ptr, Index_Id)); +} + + + +/*--------------------------------- main body --------------------------------*/ + +NDT_Status ND_List_Make( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id) +{ + NDT_Node *node_ptr; + + + node_ptr = Root_Ptr->Index_Tab[Index_Id].Head; + + Root_Ptr->Index_Tab[Index_Id].Head = NULL; + Root_Ptr->Index_Tab[Index_Id].Tail = NULL; + Root_Ptr->Index_Tab[Index_Id].Max_Dif = DEF_MAX_DIF; + Root_Ptr->Index_Tab[Index_Id].Node_Number = 0; + Root_Ptr->Index_Tab[Index_Id].Max_Depth = 0; + Root_Ptr->Index_Tab[Index_Id].Min_Depth = NDD_HUGE_LONG; + Root_Ptr->Index_Tab[Index_Id].Nb_Equ = 0; + Root_Ptr->Index_Tab[Index_Id].Type = NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_FIFO; + + return( ND_List_Recursive_Make( node_ptr, Root_Ptr, Index_Id)); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Conversion d'une structure en arbre binaire */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine du la structure à convertir */ +/* (I) Type : type du futur arbre */ +/*------------------------------------------------------------------------------*/ + +/*------------------------------- Recursive Kernel -----------------------------*/ + +NDT_Node *ND_Tree_Recursive_Make( long Depth, long Node_Number, NDT_Node *Node_Ptr ) +{ + long middle_pos, left_len, right_len, i; + NDT_Node *left_node_ptr, *middle_node_ptr, *right_node_ptr; + + + if( !Node_Ptr) return( NULL); + + /* On calcule le milieu de la liste */ + + middle_pos = Node_Number / 2 + 1; + middle_node_ptr = Node_Ptr; + + for( i = 1; i < middle_pos; i++) middle_node_ptr = middle_node_ptr->Right; + + /* On coupe la liste en deux */ + + if( middle_node_ptr->Left) + { + middle_node_ptr->Left->Right = NULL; + left_node_ptr = Node_Ptr; + left_len = middle_pos - 1; + } + else + { + left_node_ptr = NULL; + left_len = 0; + } + + if( middle_node_ptr->Right) + { + middle_node_ptr->Right->Left = NULL; + right_node_ptr = middle_node_ptr->Right; + right_len = Node_Number - middle_pos; + } + else + { + right_node_ptr = NULL; + right_len = 0; + } + + /* Construction des sous-arbres */ + + middle_node_ptr->Left = ND_Tree_Recursive_Make( Depth + 1, left_len, left_node_ptr); + + middle_node_ptr->Right = ND_Tree_Recursive_Make( Depth + 1, right_len, right_node_ptr); + + if( middle_node_ptr->Left) middle_node_ptr->Left->Parent = middle_node_ptr; + + if( middle_node_ptr->Right) middle_node_ptr->Right->Parent = middle_node_ptr; + + /* Mise à jour des informations statistiques de la structure */ + + middle_node_ptr->Root->Index_Tab[middle_node_ptr->Index].Node_Number++; + + if( !middle_node_ptr->Left && !middle_node_ptr->Right) + { + /* + Si le noeud courant est une feuille, on met éventuellement à jour + les longueurs minimale et maximale des branches de l'arbre + */ + + if( Depth > middle_node_ptr->Root->Index_Tab[middle_node_ptr->Index].Max_Depth) + { + middle_node_ptr->Root->Index_Tab[middle_node_ptr->Index].Max_Depth = Depth; + } + + if( Depth < middle_node_ptr->Root->Index_Tab[middle_node_ptr->Index].Min_Depth) + { + middle_node_ptr->Root->Index_Tab[middle_node_ptr->Index].Min_Depth = Depth; + } + } + + return( middle_node_ptr); +} + + + +/*--------------------------------- main body --------------------------------*/ + +NDT_Status ND_Tree_Make( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id ) +{ + NDT_Status rc; + NDT_Node *node_ptr; + long node_number; + + + if( ND_INDEX_SUBTYPE_SORTED_IS( Root_Ptr, Index_Id)) + { + rc = ND_List_Sort( Root_Ptr, Index_Id); + if( ND_ERROR(rc)) return( rc); + } + + node_ptr = Root_Ptr->Index_Tab[Index_Id].Head; + node_number = Root_Ptr->Index_Tab[Index_Id].Node_Number; + + Root_Ptr->Index_Tab[Index_Id].Head = NULL; + Root_Ptr->Index_Tab[Index_Id].Tail = NULL; + Root_Ptr->Index_Tab[Index_Id].Max_Dif = DEF_MAX_DIF; + Root_Ptr->Index_Tab[Index_Id].Node_Number = 0; + Root_Ptr->Index_Tab[Index_Id].Max_Depth = 0; + Root_Ptr->Index_Tab[Index_Id].Min_Depth = NDD_HUGE_LONG; + Root_Ptr->Index_Tab[Index_Id].Nb_Equ = 0; + Root_Ptr->Index_Tab[Index_Id].Type = NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_TREE | NDD_INDEX_SUBTYPE_BALANCED; + + Root_Ptr->Index_Tab[Index_Id].Head = Root_Ptr->Index_Tab[Index_Id].Tail = ND_Tree_Recursive_Make( 1, node_number, node_ptr); + + return( NDS_OK); +} + + + + + +/*----------------------------------------------------------------------------*/ +/* Equilibrage d'un arbre binaire */ +/*----------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de l'arbre */ +/*----------------------------------------------------------------------------*/ + +NDT_Status ND_Tree_Equalize( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id) +{ + NDT_Status rc; + NDT_Index_Type type; + long max_dif, nb_equ; + + + type = Root_Ptr->Index_Tab[Index_Id].Type; + max_dif = Root_Ptr->Index_Tab[Index_Id].Max_Dif; + nb_equ = Root_Ptr->Index_Tab[Index_Id].Nb_Equ; + + rc = ND_List_Make( Root_Ptr, Index_Id); + if( ND_ERROR(rc)) return(rc); + + Root_Ptr->Index_Tab[Index_Id].Type = NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_SORTED; + + rc = ND_Tree_Make( Root_Ptr, Index_Id); + if( ND_ERROR(rc)) return(rc); + + Root_Ptr->Index_Tab[Index_Id].Type = type; + 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_Ptr) +{ + long Max_Left, Max_Right; + + + if( !Node_Ptr) return( 0); + + Max_Left = ND_Tree_MaxDepth_Get( Node_Ptr->Left); + + Max_Right = ND_Tree_MaxDepth_Get( Node_Ptr->Right); + + return( NDD_MAX( Max_Left, Max_Right) + 1 ); +} + +/*----------------------------------------------------------------------------*/ +/* Retourne la profondeur de la plus petite branche à partir d'un noeud */ +/*----------------------------------------------------------------------------*/ +/* (I) Node : pointeur sur le noeud */ +/*----------------------------------------------------------------------------*/ + +long ND_Tree_MinDepth_Get( NDT_Node *Node_Ptr) +{ + long Min_Left, Min_Right; + + + if( !Node_Ptr) return( 0); + + Min_Left = ND_Tree_MinDepth_Get( Node_Ptr->Left); + + Min_Right = ND_Tree_MinDepth_Get( Node_Ptr->Right); + + return( NDD_MIN( Min_Left, Min_Right) + 1 ); +} + + + + + +/*----------------------------------------------------------------------------*/ +/* Ajoute un noeud à un arbre */ +/*----------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de l'arbre */ +/* (I) Node : pointeur sur le noeud à ajouter */ +/*----------------------------------------------------------------------------*/ + +/*------------------------------ Recursive Kernel ----------------------------*/ + +void ND_Tree_Node_Recursive_Add( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Parent_Node, NDT_Node **Node_Ptr_Ptr, long Depth, NDT_Node *New_Node_Ptr ) +{ + if( *Node_Ptr_Ptr) + { + /* Appel récursif */ + + if( ND_Manager_Exec_I( Root_Ptr, Index_Id, (*Node_Ptr_Ptr), NDD_CMD_VALUE_COMP, New_Node_Ptr->Value, (*Node_Ptr_Ptr)->Value, NULL) == NDS_LOWER) + ND_Tree_Node_Recursive_Add( Root_Ptr, Index_Id, (*Node_Ptr_Ptr), &((*Node_Ptr_Ptr)->Left), Depth + 1, New_Node_Ptr); + else + ND_Tree_Node_Recursive_Add( Root_Ptr, Index_Id, (*Node_Ptr_Ptr), &((*Node_Ptr_Ptr)->Right), Depth + 1, New_Node_Ptr); + } + else + { + long Max_Depth, Min_Depth; + + /* Rattachement du nouveau noeud à l'arbre */ + + New_Node_Ptr->Root = Root_Ptr; + New_Node_Ptr->Index = Index_Id; + New_Node_Ptr->Parent = Parent_Node; + + *Node_Ptr_Ptr = New_Node_Ptr; + + /* Mise à jour des informations statistiques de la structure */ + + Root_Ptr->Index_Tab[Index_Id].Node_Number++; + + Max_Depth = ND_Tree_MaxDepth_Get( New_Node_Ptr); + + Min_Depth = ND_Tree_MinDepth_Get( New_Node_Ptr); + + if( Max_Depth + Depth - 1 > Root_Ptr->Index_Tab[Index_Id].Max_Depth) Root_Ptr->Index_Tab[Index_Id].Max_Depth = Max_Depth + Depth - 1; + + if( Min_Depth + Depth - 1 < Root_Ptr->Index_Tab[Index_Id].Min_Depth) Root_Ptr->Index_Tab[Index_Id].Min_Depth = Min_Depth + Depth - 1 ; + } +} + + + +/*-------------------------------- main body ---------------------------------*/ + +NDT_Status ND_Tree_Node_Add( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr) +{ + ND_Tree_Node_Recursive_Add( Root_Ptr, Index_Id, NULL, &(Root_Ptr->Index_Tab[Index_Id].Head), 1, Node_Ptr); + + if( ND_INDEX_SUBTYPE_BALANCED_IS( Root_Ptr, Index_Id) && Root_Ptr->Index_Tab[Index_Id].Max_Depth - Root_Ptr->Index_Tab[Index_Id].Min_Depth > Root_Ptr->Index_Tab[Index_Id].Max_Dif) + return( ND_Tree_Equalize( Root_Ptr, Index_Id)); + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Ajoute tous les noeud d'une liste à un arbre */ +/*------------------------------------------------------------------------------*/ +/* (I) Tree_Root : pointeur sur la racine de l'arbre */ +/* (I) List_Root : pointeur sur la racine de la liste */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Tree_List_Add( NDT_Root *Tree_Root_Ptr, NDT_Index_Id Tree_Index_Id, NDT_Root *List_Root_Ptr, NDT_Index_Id List_Index_Id) +{ + NDT_Status rc; + NDT_Node *node_ptr; + + + node_ptr = List_Root_Ptr->Index_Tab[List_Index_Id].Head; + + while( node_ptr) + { + rc = ND_Tree_Node_Add( Tree_Root_Ptr, Tree_Index_Id, node_ptr); + if( ND_ERROR( rc)) return( rc); + node_ptr = node_ptr->Right; + } + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Affiche toutes les informations d'une structure de données */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la structure */ +/*------------------------------------------------------------------------------*/ + +/*------------------------------- Recursive Kernel -----------------------------*/ + +void ND_Tree_Recursive_Print( NDT_Node *Node_Ptr, long Depth, FILE *Out) +{ + const int BRANCH_LEN = 4; + + + if( !Node_Ptr) return; + + if( Node_Ptr->Right) + { + ND_Tree_Recursive_Print( Node_Ptr->Right, Depth + 1, Out); + fprintf( Out, "%*s/\n", (int)(Depth * BRANCH_LEN - 1), ""); + } + + fprintf( Out, "%*s (%p) ", (int)((Depth - 1) * BRANCH_LEN), "", Node_Ptr); + +/* Affichage des toutes les informations (noeud et valeur) : + +if( Node->Root) fprintf( Out, "Root=%p ", Node->Root); +if( Node->Parent) fprintf( Out, "Parent=%p ", Node->Parent); +if( Node->Left) fprintf( Out, "Left=%p ", Node->Left); +if( Node->Right) fprintf( Out, "Right=%p ", Node->Right); + +fprintf( Out, "Value=["); +ND_Manager_Exec( Node->Root->Manager, NDD_CMD_PRINT_VALUE, Node->Value, Out); +fprintf( Out, "]\n"); +*/ + +/* Affichage de la valeur seule : */ + + ND_Manager_Exec_I( Node_Ptr->Root, Node_Ptr->Index, Node_Ptr, NDD_CMD_VALUE_PRINT, Node_Ptr->Value, Out, NULL); + fprintf( Out, "\n"); + + if( Node_Ptr->Left) + { + fprintf( Out, "%*s\\\n", (int)( Depth * BRANCH_LEN - 1), ""); + ND_Tree_Recursive_Print( Node_Ptr->Left, Depth + 1, Out); + } +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Function de comparaison de noeuds (pour le quick sort) */ +/*------------------------------------------------------------------------------*/ + +int ND_Node_Compare( void **Node1_Ptr_Ptr, void **Node2_Ptr_Ptr) +{ + NDT_Status rc; + + + rc = ND_Manager_Exec_I( ( ( 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( NDG_Base.Err_String, "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_Ptr, NDT_Index_Id Index_Id) +{ + int i; + NDT_Node *node_ptr; + void **tab; + + + if( Root_Ptr->Index_Tab[Index_Id].Node_Number < 2) return NDS_OK; + + /* Allocation d'un tableau de pointeur de noeuds */ + + tab = (void **)malloc( Root_Ptr->Index_Tab[Index_Id].Node_Number * sizeof( NDT_Node *)); + + /* On remplit le tableau avec les noeuds de la structure à trier */ + + i = 0; + node_ptr = Root_Ptr->Index_Tab[Index_Id].Head; + + while( node_ptr) + { + tab[i] = node_ptr; + node_ptr = node_ptr->Right; + i++; + } + + /* Tri du tableau de pointeurs de noeuds */ + + 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_Ptr->Index_Tab[Index_Id].Node_Number; i++) + { + node_ptr = (NDT_Node *)tab[i]; + + node_ptr->Left = (i ? (NDT_Node *)( tab[i - 1]) : NULL); + node_ptr->Right = (i != Root_Ptr->Index_Tab[Index_Id].Node_Number - 1 ? (NDT_Node *)( tab[i + 1]) : NULL); + } + + Root_Ptr->Index_Tab[Index_Id].Head = (NDT_Node *)( tab[0]); + Root_Ptr->Index_Tab[Index_Id].Tail = (NDT_Node *)( tab[Root_Ptr->Index_Tab[Index_Id].Node_Number - 1]); + + /* Désallocation du tableau */ + + free(tab); + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Récupère le premier noeud dans un sous-arbre */ +/*------------------------------------------------------------------------------*/ +/* (I) Node : pointeur sur le noeud racine du sous-arbre */ +/*------------------------------------------------------------------------------*/ + +NDT_Node *ND_Tree_Node_First_Recursive_Get( NDT_Node *Node_Ptr) +{ + if( !Node_Ptr) return NULL; + + if( !Node_Ptr->Left) return( Node_Ptr); + + return( ND_Tree_Node_First_Recursive_Get( Node_Ptr->Left)); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Récupère le dernier noeud dans un sous-arbre */ +/*------------------------------------------------------------------------------*/ +/* (I) Node : pointeur sur le noeud racine du sous-arbre */ +/*------------------------------------------------------------------------------*/ + +NDT_Node *ND_Tree_Node_Last_Recursive_Get( NDT_Node *Node_Ptr) +{ + if( !Node_Ptr) return NULL; + + if( !Node_Ptr->Right) return( Node_Ptr); + + return ND_Tree_Node_Last_Recursive_Get( Node_Ptr->Right); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Redéfinition de la fonction malloc() avec retour de type NDT_Status */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Default_Allocator( void **Ptr_Ptr, size_t Size, void *Data_Ptr) +{ + *Ptr_Ptr = malloc( Size); + + + if( !*Ptr_Ptr) return( NDS_ERRMEM); + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Redéfinition de la fonction free() avec retour de type NDT_Status */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Default_Desallocator( void *Ptr, void *Data_Ptr) +{ + if( !Ptr) return( NDS_ERRAPI); + + free( Ptr); + + return( NDS_OK); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Function de vérification d'une liste : */ +/*------------------------------------------------------------------------------*/ + +void ND_List_Check( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out) +{ + /* On vérifie les liens entre les noeuds */ + + ND_List_Link_Check( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out); + + /* On vérifie les valeurs des noeuds */ + + ND_Value_Check( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Function de vérification et correction des liens entre noeuds d'une liste */ +/*------------------------------------------------------------------------------*/ + +void ND_List_Link_Check( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out) +{ + NDT_Node *node_ptr; + int left2right_node_number = 0; + int right2left_node_number = 0; + + + /* + On commence à vérifier si l'on trouve le même nombre de noeuds + en parcourant la liste de droite à gauche, puis de gauche à droite + */ + + node_ptr = Root_Ptr->Index_Tab[Index_Id].Head; + + while( node_ptr) + { + left2right_node_number++; + node_ptr = node_ptr->Right; + } + + node_ptr = Root_Ptr->Index_Tab[Index_Id].Tail; + + while( node_ptr) + { + right2left_node_number++; + node_ptr = node_ptr->Left; + } + + /* Cas où tout est OK */ + + if( left2right_node_number == Root_Ptr->Index_Tab[Index_Id].Node_Number && left2right_node_number == right2left_node_number) return; + + /* Cas où le nombre de noeuds n'a simplement pas été mis à jour au niveau de la racine */ + + if( left2right_node_number == right2left_node_number) + { + Root_Ptr->Index_Tab[Index_Id].Node_Number = left2right_node_number; + fprintf( Out, "\t- number of node has been corrected on structure %p:%d\n", Root_Ptr, Index_Id); + (*Nb_Detected_Ptr)++; + (*Nb_Corrected_Ptr)++; + return; + } + + /* Cas où le parcours de gauche à droite est plus complet : il manque un lien 'Left' */ + + if( left2right_node_number > right2left_node_number) + { + node_ptr = Root_Ptr->Index_Tab[Index_Id].Head; + + while( node_ptr) + { + if( node_ptr->Right && ( node_ptr->Right->Left != node_ptr)) + { + fprintf( Out, "\t- link 'Left' has been corrected on node %p of structure %p:%d\n", node_ptr->Right, Root_Ptr, Index_Id); + node_ptr->Right->Left = node_ptr; + (*Nb_Detected_Ptr)++; + (*Nb_Corrected_Ptr)++; + } + + if( !node_ptr->Right && ( node_ptr != Root_Ptr->Index_Tab[Index_Id].Tail)) + { + fprintf( Out, "\t- link 'Tail' has been corrected on structure %p:%d\n", Root_Ptr, Index_Id); + Root_Ptr->Index_Tab[Index_Id].Tail = node_ptr; + (*Nb_Detected_Ptr)++; + (*Nb_Corrected_Ptr)++; + } + + node_ptr = node_ptr->Right; + } + + if( Root_Ptr->Index_Tab[Index_Id].Node_Number != left2right_node_number) + { + fprintf( Out, "\t- number of node has been corrected on structure %p:%d\n", Root_Ptr, Index_Id); + Root_Ptr->Index_Tab[Index_Id].Node_Number = left2right_node_number; + (*Nb_Detected_Ptr)++; + (*Nb_Corrected_Ptr)++; + } + + return; + } + + /* Cas où le parcours de droite à gauche est plus complet : il manque un lien 'Right' */ + + if( right2left_node_number > left2right_node_number) + { + node_ptr = Root_Ptr->Index_Tab[Index_Id].Tail; + + while( node_ptr) + { + if( node_ptr->Left && ( node_ptr->Left->Right != node_ptr)) + { + fprintf( Out, "\t- link 'Right' has been corrected on node %p of list %p:%d\n", node_ptr->Left, Root_Ptr, Index_Id); + node_ptr->Left->Right = node_ptr; + (*Nb_Detected_Ptr)++; + (*Nb_Corrected_Ptr)++; + } + + if( !node_ptr->Left && ( node_ptr != Root_Ptr->Index_Tab[Index_Id].Head)) + { + fprintf( Out, "\t- link 'Head' has been corrected on the structure root %p:%d\n", Root_Ptr, Index_Id); + Root_Ptr->Index_Tab[Index_Id].Head = node_ptr; + (*Nb_Detected_Ptr)++; + (*Nb_Corrected_Ptr)++; + } + + node_ptr = node_ptr->Left; + } + + if( Root_Ptr->Index_Tab[Index_Id].Node_Number != right2left_node_number) + { + fprintf( Out, "\t- number of node has been corrected on structure %p:%d\n", Root_Ptr, Index_Id); + Root_Ptr->Index_Tab[Index_Id].Node_Number = right2left_node_number; + (*Nb_Detected_Ptr)++; + (*Nb_Corrected_Ptr)++; + } + } +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Function de vérification des valeurs des noeuds d'une liste */ +/*------------------------------------------------------------------------------*/ + +void ND_Value_Check( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected, int *Nb_Corrected, FILE *Out) +{ + NDT_Node *node_ptr, *next_node_ptr; + + + /* Chaque noeud sans valeur est purement et simplement supprimé de la liste */ + + ND_Index_Node_First_Get_I( &node_ptr, Root_Ptr, Index_Id); + + while( node_ptr) + { + ND_Index_Node_Next_Get_I( &next_node_ptr, node_ptr); + + if( !node_ptr->Value) + { + fprintf( Out, "\t- node %p has been removed from structure %p:%d because no value is attached to it\n", node_ptr, Root_Ptr, Index_Id); + + ND_Index_Node_Remove_I( node_ptr); + + node_ptr = next_node_ptr; + + (*Nb_Detected)++; + (*Nb_Corrected)++; + } + else if( ND_Address_Check( node_ptr->Value) != NDS_OK) + { + fprintf (Out, "\t- node %p has been removed from structure %p:%d because its value cannot be accessed\n", node_ptr, Root_Ptr, Index_Id); + + ND_Index_Node_Remove_I( node_ptr); + + node_ptr = next_node_ptr; + + (*Nb_Detected)++; + (*Nb_Corrected)++; + } + else ND_Index_Node_Next_Get( &node_ptr, node_ptr); + } +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Function de vérification d'un arbre : */ +/*------------------------------------------------------------------------------*/ + +void ND_Tree_Check( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out) +{ + /* On vérifie les liens entre les noeuds */ + + ND_Tree_Link_Check( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out); + + /* On vérifie les valeurs attachées aux noeuds */ + + ND_Value_Check( Root_Ptr, Index_Id, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out); + + /* On met à jour les informations statistiques de la racine */ + + Root_Ptr->Index_Tab[Index_Id].Max_Depth = ND_Tree_MaxDepth_Get( Root_Ptr->Index_Tab[Index_Id].Head); + Root_Ptr->Index_Tab[Index_Id].Min_Depth = ND_Tree_MaxDepth_Get( Root_Ptr->Index_Tab[Index_Id].Head); +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Function de vérification et correction des liens entre noeuds d'un arbre */ +/*------------------------------------------------------------------------------*/ + +void ND_Tree_Link_Check( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out) +{ + /* On vérifie les liens 'Parent' et les liens 'Root' de chaque noeud */ + + if( Root_Ptr->Index_Tab[Index_Id].Head) + { + if( Root_Ptr->Index_Tab[Index_Id].Head->Root != Root_Ptr) + { + Root_Ptr->Index_Tab[Index_Id].Head->Root = Root_Ptr; + fprintf( Out, "\t- link 'Root' has been corrected on node %p of structure %p:%d\n", Root_Ptr->Index_Tab[Index_Id].Head, Root_Ptr, Index_Id); + (*Nb_Detected_Ptr)++; + (*Nb_Corrected_Ptr)++; + } + + ND_Tree_Link_Recursive_Check( Root_Ptr->Index_Tab[Index_Id].Head, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out); + } + + /* + On vérifie si le lien 'Save' contient un noeud (cela signifie + que la procédure ND_Node_Remove n'a pas été jusqu'à son terme). + */ + + if( Root_Ptr->Index_Tab[Index_Id].Save) + { + NDT_Node *node_ptr; + + + /* On attache le noeud contenu dans 'Save' à l'arbre s'il n'existe pas déjà */ + + if( ND_Index_Node_Find_I( &node_ptr, Root_Ptr, Index_Id, Root_Ptr->Index_Tab[Index_Id].Save->Value, NULL) != NDS_OK) + { + ND_Index_Node_Add_I( Root_Ptr, Index_Id, Root_Ptr->Index_Tab[Index_Id].Save); + fprintf( Out, "\t- saved node %p has been restored to structure %p:%d\n", Root_Ptr->Index_Tab[Index_Id].Save, Root_Ptr, Index_Id); + (*Nb_Detected_Ptr)++; + (*Nb_Corrected_Ptr)++; + } + + Root_Ptr->Index_Tab[Index_Id].Save = NULL; + } +} + + + +/*------------------------------ Recursive Kernel ------------------------------*/ + +void ND_Tree_Link_Recursive_Check( NDT_Node *Node_Ptr, int *Nb_Detected_Ptr, int *Nb_Corrected_Ptr, FILE *Out) +{ + if( Node_Ptr->Left) + { + if( Node_Ptr->Left->Root != Node_Ptr->Root) + { + Node_Ptr->Left->Root = Node_Ptr->Root; + fprintf( Out, "\t- link 'Root' has been corrected on node %p of structure %p:%d\n", Node_Ptr->Left, Node_Ptr->Root, Node_Ptr->Index); + (*Nb_Detected_Ptr)++; + (*Nb_Corrected_Ptr)++; + } + + if( Node_Ptr->Left->Parent != Node_Ptr) + { + Node_Ptr->Left->Parent = Node_Ptr; + fprintf( Out, "\t- link 'Parent' has been corrected on node %p of structure %p:%d\n", Node_Ptr->Left, Node_Ptr->Root, Node_Ptr->Index); + (*Nb_Detected_Ptr)++; + (*Nb_Corrected_Ptr)++; + } + + /* Appel récursif */ + + ND_Tree_Link_Recursive_Check( Node_Ptr->Left, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out); + } + + if( Node_Ptr->Right) + { + if( Node_Ptr->Right->Root != Node_Ptr->Root) + { + Node_Ptr->Right->Root = Node_Ptr->Root; + fprintf( Out, "\t- link 'Root' has been corrected on node %p of structure %p:%d\n", Node_Ptr->Right, Node_Ptr->Root, Node_Ptr->Index); + (*Nb_Detected_Ptr)++; + (*Nb_Corrected_Ptr)++; + } + + if( Node_Ptr->Right->Parent != Node_Ptr) + { + Node_Ptr->Right->Parent = Node_Ptr; + fprintf( Out, "\t- link 'Parent' has been corrected on node %p of structure %p:%d\n", Node_Ptr->Right, Node_Ptr->Root, Node_Ptr->Index); + (*Nb_Detected_Ptr)++; + (*Nb_Corrected_Ptr)++; + } + + /* Appel récursif */ + + ND_Tree_Link_Recursive_Check( Node_Ptr->Right, Nb_Detected_Ptr, Nb_Corrected_Ptr, Out); + } +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Target address access try */ +/*------------------------------------------------------------------------------*/ + +NDT_Status ND_Address_Check( void *Address) +{ +#if !defined(_WIN32) + NDT_Status status; + int rc; + int test; + struct sigaction act = {0}, oact_bus, oact_segv; + + act.sa_handler = ND_Signal_Trap; + + NDG_Base.Sig_Trapped = 0; + + + + /* Trap SIGBUS and SIGSEGV */ + + if( ( rc = sigaction( SIGBUS, &act, &oact_bus)) != 0) + { + sprintf( NDG_Base.Err_String, "Error ND_Address_Check: sigaction (Add SIGBUS Hdl) rc: %d errno: %d", rc, errno); + ND_Error_Print(); + + return( NDS_KO); + } + + if( ( rc = sigaction( SIGSEGV, &act, &oact_segv)) != 0) + { + sprintf( NDG_Base.Err_String, "Error ND_Address_Check: sigaction (Add SIGSEGV Hdl) rc: %d errno: %d", rc, errno); + ND_Error_Print(); + + return( NDS_KO); + } + + + + /* Target address access try */ + + if( sigsetjmp( NDG_Base.SigLongJmp_Env, 1) == 0 ) + { + test = *( (int *)Address); + + status = NDS_OK; + } + else + { + status = NDS_KO; + } + + + + /* Untrap SIGBUS and SIGSEGV */ + + if( ( rc = sigaction( SIGBUS, &oact_bus, &act)) != 0) + { + sprintf( NDG_Base.Err_String, "Error ND_Address_Check: sigaction (Remove SIGBUS Hdl) rc: %d errno: %d", rc, errno); + ND_Error_Print(); + + return( NDS_KO); + } + + if( ( rc = sigaction( SIGSEGV, &oact_segv, &act)) != 0) + { + sprintf( NDG_Base.Err_String, "Error ND_Address_Check: sigaction (Remove SIGSEGV Hdl) rc: %d errno: %d", rc, errno); + ND_Error_Print(); + + return( NDS_KO); + } + + return( status); +#else + NDT_Status status; + int test; + void (__cdecl *old_sigsegv_sighandler)(int); + + + NDG_Base.Sig_Trapped = 0; + + + + /* Trap SIGSEGV */ + + if( ( old_sigsegv_sighandler = signal( SIGSEGV, ND_Signal_Trap)) == SIG_ERR) + { + sprintf( NDG_Base.Err_String, "Error ND_Address_Check: signal (Add SIGSEGV Hdl) errno: %d", errno); + ND_Error_Print(); + + return( NDS_KO); + } + + + + /* Target address access try */ + + if( setjmp( NDG_Base.SigLongJmp_Env) == 0 ) + { + test = *( (int *)Address); + + status = NDS_OK; + } + else + { + status = NDS_KO; + } + + + + /* Untrap SIGSEGV */ + + if( ( old_sigsegv_sighandler = signal( SIGSEGV, old_sigsegv_sighandler)) == SIG_ERR) + { + sprintf( NDG_Base.Err_String, "Error ND_Address_Check: signal (Remove SIGSEGV Hdl) errno: %d", errno); + ND_Error_Print(); + + return( NDS_KO); + } + + return( status); +#endif +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Trap d'un signal */ +/*------------------------------------------------------------------------------*/ + +void ND_Signal_Trap( int Sig_Num) +{ + NDG_Base.Sig_Trapped = Sig_Num; + +#if !defined(_WIN32) + siglongjmp( NDG_Base.SigLongJmp_Env, 1); +#else + longjmp( NDG_Base.SigLongJmp_Env, 1); +#endif +} + + + + + +/*------------------------------------------------------------------------------*/ +/* Routine d'affichage d'un message d'erreur */ +/*------------------------------------------------------------------------------*/ + +void ND_Error_Print( void) +{ + if( NDG_Base.Err_Stream) fprintf( ( NDG_Base.Err_Stream == (FILE *)-1 ) ? stderr : NDG_Base.Err_Stream, "%s\n", NDG_Base.Err_String); +} diff --git a/libnode.h b/libnode.h new file mode 100644 index 0000000..bd0f4fe --- /dev/null +++ b/libnode.h @@ -0,0 +1,347 @@ +/*---------------------------------------------------------------------------------*/ +/* $RCSfile: libnode.h,v $ */ +/*---------------------------------------------------------------------------------*/ +/* $Revision: 2.10 $ */ +/* $Name: libnode-2_2_0-1 $ */ +/* $Date: 2010/06/06 21:26:31 $ */ +/* $Author: agibert $ */ +/*---------------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------------*/ +/* This file is part of LibNode */ +/* */ +/* LibNode is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU Lesser General Public Licence as published by */ +/* the Free Software Foundation; either version 2.1 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* LibNode is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with LibNode; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/*---------------------------------------------------------------------------------*/ + + + + + +#include +#include +#include +#include +#include +#include +#include + + + +/* Utilisation des API de la LIBNODE sans vérification des arguments */ + +#define ND_MODE 1 + +#include + + + + + + + +#ifdef __linux +# define NDD_PRINTF_PTR_PREFIX "" +#else +# define NDD_PRINTF_PTR_PREFIX "0x" +#endif + + + + + +#define NDD_HUGE_LONG ( long) 0xFFFFFFL + + + +/* Table des symboles locale */ + +struct NDT_Symbol; + +typedef struct NDT_Symbol +{ + void *Ptr; + char *Name; + struct NDT_Symbol *Next; +} NDT_Symbol; + + + +/* LibNode Global Base Structure */ + +typedef struct NDT_Base +{ + int Open_Status; + int Debug_Mode; + char Err_String[512]; + FILE *Err_Stream; + int Sig_Trapped; +#if !defined(_WIN32) + sigjmp_buf SigLongJmp_Env; +#else + jmp_buf SigLongJmp_Env; +#endif + NDT_Symbol *Symbol_First_Ptr; + void *DL_Ptr; + NDT_Index_Type OpenStruct_Index_Type[1]; + NDT_Root *OpenStruct_Ptr; +} NDT_Base; + +NDT_Base NDG_Base = +{ + NDD_FALSE, + NDD_TRUE, + "", + (FILE *) -1, + 0, + {0}, + (NDT_Symbol *) NULL, + NULL, + { NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_FIFO}, + (NDT_Root *) NULL +}; + + + + + +/*------------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------------*/ +/* Fonctions et procédures privées de la librairie (moyen niveau) */ +/*------------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------*/ +/* Manager par défaut */ +/*------------------------------------------------------------------------------*/ +/* (I) va_list Arguments : Liste d'arguments contextuels */ +/*------------------------------------------------------------------------------*/ +NDT_Status ND_Default_Manager( NDT_Root *, NDT_Index_Id, NDT_Node *, NDT_Command, va_list *); + +/*------------------------------------------------------------------------------*/ +/* OpenStruct Manager */ +/*------------------------------------------------------------------------------*/ +/* (I) va_list Arguments : Liste d'arguments contextuels */ +/*------------------------------------------------------------------------------*/ +NDT_Status ND_OpenStruct_Manager( NDT_Root *, NDT_Index_Id, NDT_Node *, NDT_Command, va_list *); + +/*------------------------------------------------------------------------------*/ +/* Redéfinition de la fonction malloc() avec retour de type NDT_Status */ +/*------------------------------------------------------------------------------*/ +NDT_Status ND_Default_Allocator( void **, size_t, void *); + +/*------------------------------------------------------------------------------*/ +/* Redéfinition de la fonction free() avec retour de type NDT_Status */ +/*------------------------------------------------------------------------------*/ +NDT_Status ND_Default_Desallocator( void *, void *); + +/*------------------------------------------------------------------------------*/ +/* Création d'un noeud */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : adresse de la racine pour laquelle on crée un noeud */ +/* (O) New_Node : adresse du pointeur sur le nouveau noeud */ +/*------------------------------------------------------------------------------*/ +NDT_Status ND_Node_Alloc( NDT_Root * Root, NDT_Node ** New_Node); + +/*------------------------------------------------------------------------------*/ +/* Destruction d'un noeud */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : adresse de la racine dans laquelle on détruit un noeud */ +/* (I) Node : pointeur sur le noeud à détruire */ +/*------------------------------------------------------------------------------*/ +NDT_Status ND_Node_Free( NDT_Root *, NDT_Node *); + +/*------------------------------------------------------------------------------*/ +/* 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_Clear( NDT_Root *, NDT_Index_Id); + +/*------------------------------------------------------------------------------*/ +/* Création de la racine d'une structure de données quelconque */ +/*------------------------------------------------------------------------------*/ +/* (O) New_Root : adresse du pointeur sur la nouvelle racine */ +/* (I) Type : type de la structure de données */ +/* (I) Allocater : pointeur vers la fonction d'allocation */ +/* (I) Desallocater : pointeur vers la fonction de désallocation */ +/* (I) Data : pointeur de données utiles à l'allocateur */ +/*------------------------------------------------------------------------------*/ +NDT_Status ND_Node_Root_Alloc( NDT_Root **, NDT_Index_Nb, NDT_Index_Type[], char *, NDT_Manager *, char *, NDT_Allocator *, char *, NDT_Desallocator *, short, void *); + +/*------------------------------------------------------------------------------*/ +/* Destruction d'une racine */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine à détruire */ +/*------------------------------------------------------------------------------*/ +NDT_Status ND_Node_Root_Free( NDT_Root *); + +/*------------------------------------------------------------------------------*/ +/* 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 *, NDT_Index_Id, NDT_Node *); + +/*------------------------------------------------------------------------------*/ +/* 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 *, NDT_Index_Id, void *); + +/*------------------------------------------------------------------------------*/ +/* 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 *, NDT_Index_Id, void *); + +/*------------------------------------------------------------------------------*/ +/* Supprime le noeud d'une liste */ +/*------------------------------------------------------------------------------*/ +/* (I) Node : pointeur sur le noeud à supprimer */ +/*------------------------------------------------------------------------------*/ +NDT_Status ND_List_Node_Remove( NDT_Node *); + +/*------------------------------------------------------------------------------*/ +/* Conversion d'une structure en liste chaînée */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine du la structure à convertir */ +/*------------------------------------------------------------------------------*/ +NDT_Status ND_List_Make( NDT_Root *, NDT_Index_Id); + +/*------------------------------------------------------------------------------*/ +/* Recherche une valeur dans une liste et retourne le noeud correspondant */ +/*------------------------------------------------------------------------------*/ +NDT_Node *ND_List_Node_Find( NDT_Root *, NDT_Index_Id, void *, va_list *); + +/*------------------------------------------------------------------------------*/ +/* Recherche un noeud dans un arbre et retourne le pointeur sur le noeud */ +/*------------------------------------------------------------------------------*/ +NDT_Node *ND_Tree_Node_Find( NDT_Root *, NDT_Index_Id, void *, va_list *); + +/*------------------------------------------------------------------------------*/ +/* Conversion d'une structure en arbre binaire */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine du la structure à convertir */ +/* (I) Type : type du futur arbre */ +/*------------------------------------------------------------------------------*/ +NDT_Status ND_Tree_Make( NDT_Root *, NDT_Index_Id); + +/*------------------------------------------------------------------------------*/ +/* Equilibrage d'un arbre */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de l'arbre */ +/*------------------------------------------------------------------------------*/ +NDT_Status ND_Tree_Equalize( NDT_Root *, NDT_Index_Id); + +/*------------------------------------------------------------------------------*/ +/* 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 *); + +/*------------------------------------------------------------------------------*/ +/* Retourne la profondeur de la plus petite branche à partir d'un noeud */ +/*------------------------------------------------------------------------------*/ +/* (I) Node : pointeur sur le noeud */ +/*------------------------------------------------------------------------------*/ +long ND_Tree_MinDepth_Get( NDT_Node *); + +/*------------------------------------------------------------------------------*/ +/* Ajout d'un noeud à un arbre binaire */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de l'arbre */ +/* (I) Node : pointeur sur le noeud à ajouter */ +/*------------------------------------------------------------------------------*/ +NDT_Status ND_Tree_Node_Add( NDT_Root *, NDT_Index_Id, NDT_Node *); + +/*------------------------------------------------------------------------------*/ +/* 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 *, NDT_Index_Id, NDT_Root *, NDT_Index_Id); + +/*------------------------------------------------------------------------------*/ +/* Fonction de comparaison de noeuds (pour le quick sort) */ +/*------------------------------------------------------------------------------*/ +int ND_Node_Compare( void **, void **); + +/*------------------------------------------------------------------------------*/ +/* Ordonne une liste chaînée selon l'algorithme du tri à bulle */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de la liste à trier */ +/*------------------------------------------------------------------------------*/ +NDT_Status ND_List_Sort( NDT_Root *, NDT_Index_Id); + + + + + + +/*------------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------------*/ +/* PRIVATE FUNCTIONS */ +/*------------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------------*/ + +void ND_List_Check( NDT_Root *, NDT_Index_Id, int *, int *, FILE *); + +void ND_List_Link_Check( NDT_Root *, NDT_Index_Id, int *, int *, FILE *); + +void ND_Value_Check( NDT_Root *, NDT_Index_Id, int *, int *, FILE *); + +void ND_Tree_Check( NDT_Root *, NDT_Index_Id, int *, int *, FILE *); + +void ND_Tree_Link_Check( NDT_Root *, NDT_Index_Id, int *, int *, FILE *); + +NDT_Status ND_List_Recursive_Make( NDT_Node *, NDT_Root *, NDT_Index_Id); + +NDT_Node *ND_Tree_Recursive_Make( long, long, NDT_Node *); + +void ND_Tree_Node_Recursive_Add( NDT_Root *, NDT_Index_Id, NDT_Node *, NDT_Node **, long , NDT_Node *); + +NDT_Node *ND_Tree_Node_First_Recursive_Get( NDT_Node *); + +NDT_Node *ND_Tree_Node_Last_Recursive_Get( NDT_Node *); + +NDT_Node *ND_Tree_Node_Recursive_Find( NDT_Node *, void *, va_list *); + +NDT_Node *ND_Tree_Parent_Next_Recursive_Get( NDT_Node *); + +NDT_Node *ND_Tree_Parent_Previous_Recursive_Get( NDT_Node *); + +void ND_Tree_Recursive_Print( NDT_Node *, long, FILE *); + +void ND_Tree_Link_Recursive_Check( NDT_Node *, int *, int *, FILE *); + +NDT_Status ND_Symbol_Find( void **, const char *); + +void ND_Error_Print( void); + +void ND_Signal_Trap( int); + +NDT_Status ND_Address_Check( void *); diff --git a/node.h b/node.h new file mode 100644 index 0000000..7964390 --- /dev/null +++ b/node.h @@ -0,0 +1,1260 @@ +/*---------------------------------------------------------------------------------*/ +/* $RCSfile: node.h,v $ */ +/*---------------------------------------------------------------------------------*/ +/* $Revision: 2.13 $ */ +/* $Name: libnode-2_2_0-1 $ */ +/* $Date: 2010/06/06 21:26:31 $ */ +/* $Author: agibert $ */ +/*---------------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------------*/ +/* This file is part of LibNode */ +/* */ +/* LibNode is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU Lesser General Public Licence as published by */ +/* the Free Software Foundation; either version 2.1 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* LibNode is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with LibNode; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/*---------------------------------------------------------------------------------*/ + + + + + + +#ifndef _LIBNODE_H_ +# define _LIBNODE_H_ + +# ifdef __cplusplus +extern "C" { +# endif + +# include +# include +# include +# include + +# ifdef _LIBVER_SUPPORT +# include +# endif + + + + + + + +#define NDD_TRUE 1 + +#define NDD_FALSE 0 + +#define NDD_MIN(A,B) ((A > B) ? B : A) + +#define NDD_MAX(A,B) ((A < B) ? B : A) + + + +/* + Différence de profondeur entre la branche la plus courte et + la plus longue d'un arbre. + Le dépassement de ce seuil provoque le rééquilibrage de l'arbre +*/ + +#define DEF_MAX_DIF 100 + +/* Types de structure */ + +typedef short NDT_Root_Type; + +typedef int NDT_Index_Type; + +#define NDD_INDEX_MSK 0xffff +#define NDD_INDEX_RMSK 0x0000 + +#define NDD_INDEX_STATUS_UNKNOWN 0x0000 +#define NDD_INDEX_STATUS_OPENED 0x0001 +#define NDD_INDEX_STATUS_CLOSED 0x0002 +#define NDD_INDEX_STATUS_MSK (NDD_INDEX_STATUS_UNKNOWN | NDD_INDEX_STATUS_OPENED | NDD_INDEX_STATUS_CLOSED) +#define NDD_INDEX_STATUS_RMSK (NDD_INDEX_MSK ^ NDD_INDEX_STATUS_MSK) + +#define ND_INDEX_STATUS_VALUE_UNKNOWN_IS( v) ( ( (v) & NDD_INDEX_STATUS_MSK) == NDD_INDEX_STATUS_UNKNOWN) +#define ND_INDEX_STATUS_VALUE_OPENED_IS( v) ( ( (v) & NDD_INDEX_STATUS_MSK) == NDD_INDEX_STATUS_OPENED) +#define ND_INDEX_STATUS_VALUE_CLOSED_IS( v) ( ( (v) & NDD_INDEX_STATUS_MSK) == NDD_INDEX_STATUS_CLOSED) +#define ND_INDEX_STATUS_UNKNOWN_IS( r, i) ND_INDEX_STATUS_VALUE_UNKNOWN_IS( (r)->Index_Tab[(i)].Type) +#define ND_INDEX_STATUS_OPENED_IS( r, i) ND_INDEX_STATUS_VALUE_OPENED_IS( (r)->Index_Tab[(i)].Type) +#define ND_INDEX_STATUS_CLOSED_IS( r, i) ND_INDEX_STATUS_VALUE_CLOSED_IS( (r)->Index_Tab[(i)].Type) + +#define ND_INDEX_STATUS_VALUE_ASCII_GET( v) ( ND_INDEX_STATUS_VALUE_UNKNOWN_IS( (v)) ? "UNKNOWN" : ( ND_INDEX_STATUS_VALUE_OPENED_IS( (v)) ? "OPENED" : ( ND_INDEX_STATUS_VALUE_CLOSED_IS( (v)) ? "CLOSED" : "???"))) +#define ND_INDEX_STATUS_ASCII_GET( r, i) ND_INDEX_STATUS_VALUE_ASCII_GET( (r)->Index_Tab[(i)].Type) + + + +#define NDD_INDEX_TYPE_UNKNOWN 0x0000 +#define NDD_INDEX_TYPE_LIST 0x0010 +#define NDD_INDEX_TYPE_TREE 0x0020 +#define NDD_INDEX_TYPE_MSK (NDD_INDEX_TYPE_UNKNOWN | NDD_INDEX_TYPE_LIST | NDD_INDEX_TYPE_TREE) +#define NDD_INDEX_TYPE_RMSK (NDD_INDEX_MSK ^ NDD_INDEX_TYPE_MSK) + +#define ND_INDEX_TYPE_VALUE_UNKNOWN_IS( v) ( ( (v) & NDD_INDEX_TYPE_MSK) == NDD_INDEX_TYPE_UNKNOWN) +#define ND_INDEX_TYPE_VALUE_LIST_IS( v) ( ( (v) & NDD_INDEX_TYPE_MSK) == NDD_INDEX_TYPE_LIST) +#define ND_INDEX_TYPE_VALUE_TREE_IS( v) ( ( (v) & NDD_INDEX_TYPE_MSK) == NDD_INDEX_TYPE_TREE) + +#define ND_INDEX_TYPE_UNKNOWN_IS( r, i) ND_INDEX_TYPE_VALUE_UNKNOWN_IS( (r)->Index_Tab[(i)].Type) +#define ND_INDEX_TYPE_LIST_IS( r, i) ND_INDEX_TYPE_VALUE_LIST_IS( (r)->Index_Tab[(i)].Type) +#define ND_INDEX_TYPE_TREE_IS( r, i) ND_INDEX_TYPE_VALUE_TREE_IS( (r)->Index_Tab[(i)].Type) + +#define ND_INDEX_TYPE_VALUE_ASCII_GET( v) ( ND_INDEX_TYPE_VALUE_UNKNOWN_IS( (v)) ? "UNKNOWN" : ( ND_INDEX_TYPE_VALUE_LIST_IS( (v)) ? "LIST" : ( ND_INDEX_TYPE_VALUE_TREE_IS( (v)) ? "TREE" : "???"))) + +#define ND_INDEX_TYPE_ASCII_GET( r, i) ND_INDEX_TYPE_VALUE_ASCII_GET( (r)->Index_Tab[(i)].Type) + + + +#define NDD_INDEX_SUBTYPE_UNKNOWN 0x0000 +#define NDD_INDEX_SUBTYPE_FIFO 0x0100 /* principe de la file d'attente (First In First Out) */ +#define NDD_INDEX_SUBTYPE_LILO NDD_INDEX_SUBTYPE_FIFO +#define NDD_INDEX_SUBTYPE_LIFO 0x0200 /* principe de la pile (First In Last Out) */ +#define NDD_INDEX_SUBTYPE_FILO NDD_INDEX_SUBTYPE_LIFO +#define NDD_INDEX_SUBTYPE_SORTED 0x0300 /* liste triée */ +#define NDD_INDEX_SUBTYPE_UNBALANCED 0x0400 +#define NDD_INDEX_SUBTYPE_BALANCED 0x0500 /* arbre auto-équilibré */ +#define NDD_INDEX_SUBTYPE_MSK ( NDD_INDEX_SUBTYPE_UNKNOWN | NDD_INDEX_SUBTYPE_FIFO | NDD_INDEX_SUBTYPE_FILO | NDD_INDEX_SUBTYPE_SORTED | NDD_INDEX_SUBTYPE_UNBALANCED | NDD_INDEX_SUBTYPE_BALANCED) +#define NDD_INDEX_SUBTYPE_RMSK (NDD_INDEX_MSK ^ NDD_INDEX_SUBTYPE_MSK) + +#define ND_INDEX_SUBTYPE_VALUE_UNKNOWN_IS( v) ( ( (v) & NDD_INDEX_SUBTYPE_MSK) == NDD_INDEX_SUBTYPE_UNKNOWN) +#define ND_INDEX_SUBTYPE_VALUE_FIFO_IS( v) ( ( (v) & NDD_INDEX_SUBTYPE_MSK) == NDD_INDEX_SUBTYPE_FIFO) +#define ND_INDEX_SUBTYPE_VALUE_LILO_IS( v) ND_INDEX_SUBTYPE_VALUE_FIFO_IS( v) +#define ND_INDEX_SUBTYPE_VALUE_LIFO_IS( v) ( ( (v) & NDD_INDEX_SUBTYPE_MSK) == NDD_INDEX_SUBTYPE_LIFO) +#define ND_INDEX_SUBTYPE_VALUE_FILO_IS( v) ND_INDEX_SUBTYPE_LIFO_IS( r, i) +#define ND_INDEX_SUBTYPE_VALUE_SORTED_IS( v) ( ( (v) & NDD_INDEX_SUBTYPE_MSK) == NDD_INDEX_SUBTYPE_SORTED) +#define ND_INDEX_SUBTYPE_VALUE_UNBALANCED_IS( v) ( ( (v) & NDD_INDEX_SUBTYPE_MSK) == NDD_INDEX_SUBTYPE_UNBALANCED) +#define ND_INDEX_SUBTYPE_VALUE_BALANCED_IS( v) ( ( (v) & NDD_INDEX_SUBTYPE_MSK) == NDD_INDEX_SUBTYPE_BALANCED) + +#define ND_INDEX_SUBTYPE_UNKNOWN_IS( r, i) ND_INDEX_SUBTYPE_VALUE_UNKNOWN_IS( (r)->Index_Tab[(i)].Type) +#define ND_INDEX_SUBTYPE_FIFO_IS( r, i) ND_INDEX_SUBTYPE_VALUE_FIFO_IS( (r)->Index_Tab[(i)].Type) +#define ND_INDEX_SUBTYPE_LILO_IS( r, i) ND_INDEX_SUBTYPE_VALUE_LILO_IS( (r)->Index_Tab[(i)].Type) +#define ND_INDEX_SUBTYPE_LIFO_IS( r, i) ND_INDEX_SUBTYPE_VALUE_LIFO_IS( (r)->Index_Tab[(i)].Type) +#define ND_INDEX_SUBTYPE_FILO_IS( r, i) ND_INDEX_SUBTYPE_VALUE_FILO_IS( (r)->Index_Tab[(i)].Type) +#define ND_INDEX_SUBTYPE_SORTED_IS( r, i) ND_INDEX_SUBTYPE_VALUE_SORTED_IS( (r)->Index_Tab[(i)].Type) +#define ND_INDEX_SUBTYPE_UNBALANCED_IS( r, i) ND_INDEX_SUBTYPE_VALUE_UNBALANCED_IS( (r)->Index_Tab[(i)].Type) +#define ND_INDEX_SUBTYPE_BALANCED_IS( r, i) ND_INDEX_SUBTYPE_VALUE_BALANCED_IS( (r)->Index_Tab[(i)].Type) + +#define ND_INDEX_SUBTYPE_VALUE_ASCII_GET( v) ( ND_INDEX_SUBTYPE_VALUE_UNKNOWN_IS( v) ? "UNKNOWN" : ( ND_INDEX_SUBTYPE_VALUE_FIFO_IS( v) ? "FIFO" : ( ND_INDEX_SUBTYPE_VALUE_LIFO_IS( v) ? "LIFO" : ( ND_INDEX_SUBTYPE_VALUE_SORTED_IS( v) ? "SORTED" : ( ND_INDEX_SUBTYPE_VALUE_UNBALANCED_IS( v) ? "UNBALANCED" : ( ND_INDEX_SUBTYPE_VALUE_BALANCED_IS( v) ? "BALANCED" : "???")))))) +#define ND_INDEX_SUBTYPE_ASCII_GET( r, i) ND_INDEX_SUBTYPE_VALUE_ASCII_GET( (r)->Index_Tab[(i)].Type) + + + +/* Manager Template */ + +// NDT_Status ND_Example_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list *Args_Ptr) +// { +// NDT_Command_Name Command_Name; +// +// +// switch( Command) +// { +// case NDD_CMD_MANAGER_VERSION: +// { +// ND_VA_ARG_GET( Version_Name_Ptr, *Args_Ptr, NDT_Version_Name *); +// +// +// Command_Name = "NDD_CMD_MANAGER_VERSION"; +// +// *Version_Name_Ptr = "$Revision: 2.13 $ $Name: libnode-2_2_0-1 $ $Date: 2010/06/06 21:26:31 $ $Author: agibert $"; +// +// return( NDS_OK); +// } +// +// case NDD_CMD_INDEX_GET: +// { +// /* +// ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *); +// ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *); +// ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command); +// ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); +// */ +// ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *); +// ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *); +// ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command); +// ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); +// +// +// Command_Name = "NDD_CMD_INDEX_GET"; +// +// switch(Cmd) +// { +// /* +// case NDT_CMD_SOME_USER_CMD: +// { +// *Reply_Index_Id_Ptr = 0; +// *Reply_Command_Ptr = NDD_CMD_SOME_OTHER_CMD; +// break; +// } +// +// ... +// */ +// +// default: +// { +// *Reply_Index_Id_Ptr = Index_Id; +// *Reply_Command_Ptr = Cmd; +// break; +// } +// } +// +// return( NDS_OK); +// } +// +// case NDD_CMD_VALUE_ALLOC: +// { +// /* +// ND_VA_ARG_GET( Value_Ptr_Ptr, *Args_Ptr, void **); +// +// ND_VA_LIST_OPEN( user_args, *Args_Ptr); +// +// ND_VA_ARG_GET( user_data, user_args, user_type); +// ND_VA_ARG_GET( ..., user_args, ...); +// +// ND_VA_LIST_CLOSE( 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: +// { +// /* +// ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); +// +// ND_VA_LIST_OPEN( user_args, *Args_Ptr); +// +// ND_VA_ARG_GET( user_data, user_args, user_type); +// ND_VA_ARG_GET( ..., user_args, ...); +// +// ND_VA_LIST_CLOSE( user_args); +// */ +// +// +// Command_Name = "NDD_CMD_VALUE_FREE"; +// +// /* +// free( Value_Ptr); +// +// return( NDS_OK); +// */ +// } +// +// case NDD_CMD_VALUE_COMP: +// { +// /* +// ND_VA_ARG_GET( Value1_Ptr, *Args_Ptr, void *); +// ND_VA_ARG_GET( Value2_Ptr, *Args_Ptr, void *); +// +// ND_VA_LIST_OPEN( user_args, *Args_Ptr); +// +// ND_VA_ARG_GET( user_data, user_args, user_type); +// ND_VA_ARG_GET( ..., user_args, ...); +// +// ND_VA_LIST_CLOSE( 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: +// { +// /* +// ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); +// +// ND_VA_LIST_OPEN( user_args, *Args_Ptr); +// +// ND_VA_ARG_GET( user_data, user_args, user_type); +// ND_VA_ARG_GET( ..., user_args, ...); +// +// ND_VA_LIST_CLOSE( user_args); +// */ +// +// +// Command_Name = "NDD_CMD_VALUE_ADD"; +// +// /* +// return( NDS_OK); +// */ +// } +// +// case NDD_CMD_VALUE_REMOVE: +// { +// /* +// ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *); +// +// ND_VA_LIST_OPEN( user_args, *Args_Ptr); +// +// ND_VA_ARG_GET( user_data, user_args, user_type); +// ND_VA_ARG_GET( ..., user_args, ...); +// +// ND_VA_LIST_CLOSE( user_args); +// */ +// +// +// Command_Name = "NDD_CMD_VALUE_REMOVE"; +// /* +// return( NDS_OK); +// */ +// } +// +// case NDD_CMD_VALUE_PRINT: +// { +// /* +// ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); +// +// ND_VA_LIST_OPEN( lib_args, *Args_Ptr); +// +// ND_VA_ARG_GET( Out, lib_args, FILE *); +// ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode); +// ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth); +// ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset); +// +// ND_VA_LIST_OPEN( user_args, lib_args); +// +// ND_VA_ARG_GET( user_data, user_args, user_type); +// ND_VA_ARG_GET( ..., user_args, ...); +// +// ND_VA_LIST_CLOSE( user_args); +// ND_VA_LIST_CLOSE( lib_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: +// { +// /* +// ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); +// +// ND_VA_LIST_OPEN( lib_args, *Args_Ptr); +// +// ND_VA_ARG_GET( Out, lib_args, FILE *); +// ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode); +// ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth); +// ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset); +// +// ND_VA_LIST_OPEN( user_args, lib_args); +// +// ND_VA_ARG_GET( user_data, user_args, user_type); +// ND_VA_ARG_GET( ..., user_args, ...); +// +// ND_VA_LIST_CLOSE( user_args); +// ND_VA_LIST_CLOSE( lib_args); +// */ +// +// +// Command_Name = "NDD_CMD_INFO_PRINT"; +// +// /* +// return( NDS_OK); +// */ +// } +// +// case NDD_CMD_USER_TRAVERSE: +// { +// /* +// ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *); +// +// ND_VA_LIST_OPEN( user_args, *Args_Ptr); +// +// ND_VA_ARG_GET( user_data, user_args, user_type); +// ND_VA_ARG_GET( ..., user_args, ...); +// +// ND_VA_LIST_CLOSE( user_args); +// +// +// void *Value_Ptr = Node_Ptr->Value; +// */ +// +// +// Command_Name = "NDD_CMD_USER_TRAVERSE"; +// +// /* +// return( NDS_OK); +// */ +// } +// +// default: +// { +// printf( "ND_Default_Manager() called with an undefined command %d\n", Command); +// return(NDS_ERRAPI); +// } +// } +// +// printf( "ND_Default_Manager() called with command %d (%s)\n", Command, Command_Name); +// return(NDS_OK); +// } + + + +/* Var Args Manager Macros */ + +#define ND_VA_LIST_OPEN( VA_List_Target, VA_List_Source) va_list VA_List_Target; va_copy( VA_List_Target, *va_arg( VA_List_Source, va_list *)) +#define ND_VA_LIST_CLOSE( VA_List) va_end( VA_List) +#define ND_VA_ARG_GET( Arg, VA_List, Type) Type Arg = va_arg( VA_List, Type) + + + +/* Commandes du manager */ + +typedef int NDT_Command; + +#define NDD_CMD_UNKNOWN (NDT_Command)0 +#define NDD_CMD_MANAGER_VERSION (NDT_Command)1 +#define NDD_CMD_INDEX_GET (NDT_Command)2 +#define NDD_CMD_VALUE_ALLOC (NDT_Command)3 +#define NDD_CMD_VALUE_FREE (NDT_Command)4 +#define NDD_CMD_VALUE_COMP (NDT_Command)5 +#define NDD_CMD_VALUE_ADD (NDT_Command)6 +#define NDD_CMD_VALUE_REMOVE (NDT_Command)7 +#define NDD_CMD_VALUE_PRINT (NDT_Command)8 +#define NDD_CMD_VALUE_FIND (NDT_Command)9 +#define NDD_CMD_INFO_PRINT (NDT_Command)10 + +#define NDD_CMD_USER_TRAVERSE (NDT_Command)17 + + +typedef char *NDT_Command_Name; +typedef char *NDT_Version_Name; + + + +/* Types de réponse du manager ou code retour des diverses fonctions */ + +typedef int NDT_Status; + +#define ND_ERROR(s) ((s) <= 0) /* All negative or 0 status are errors */ + +#define NDS_OK 1 +#define NDS_KO 0 + +#define NDS_YES 1 +#define NDS_NO 0 + +#define NDS_EQUAL 1 +#define NDS_GREATER 2 +#define NDS_LOWER 3 + +#define NDS_ERRMEM -1 /* Problème d'allocation mémoire */ +#define NDS_ERRAPI -2 /* Utilisation incorrecte des API */ + + + +typedef short NDT_Index_Id; +typedef short NDT_Index_Nb; + +#define NDD_INDEX_UNKNOWN (NDT_Index_Id)-1 +#define NDD_INDEX_PRIMARY (NDT_Index_Id)0 + + + +struct NDT_Root; +struct NDT_Node; + + + +/* Pointeur de fonction sur le manager */ + +#define NDD_MANAGER_NAME_LEN_MAX 64 +#define NDD_MANAGER_NAME_SIZE_MAX (NDD_MANAGER_NAME_LEN_MAX + 1) + +typedef char *NDT_Manager_Name; + +typedef NDT_Status NDT_Manager( struct NDT_Root *, NDT_Index_Id, struct NDT_Node *, NDT_Command, va_list *); + + +/* Pointeur de fonction sur l'allocateur */ + +#define NDD_ALLOCATOR_NAME_LEN_MAX 64 +#define NDD_ALLOCATOR_NAME_SIZE_MAX (NDD_ALLOCATOR_NAME_LEN_MAX + 1) + +typedef char *NDT_Allocator_Name; + +typedef NDT_Status NDT_Allocator( void **, size_t, void *); + + +/* Pointeur de fonction sur le désallocateur */ + +#define NDD_DESALLOCATOR_NAME_LEN_MAX 64 +#define NDD_DESALLOCATOR_NAME_SIZE_MAX (NDD_DESALLOCATOR_NAME_LEN_MAX + 1) + +typedef char *NDT_Desallocator_Name; + +typedef NDT_Status NDT_Desallocator( void *, void *); + + + + +typedef struct NDT_Index +{ + NDT_Index_Type Type; /* Type de la structure (liste, arbre ... ) */ + + long Node_Number; /* Nombre de noeuds dans la structure */ + long Min_Depth; /* Profondeur minimale de l'arbre */ + long Max_Depth; /* Profondeur maximale de l'arbre */ + long Max_Dif; /* Différence maximale autorisée entre la branche la plus courte et la plus longue */ + long Nb_Equ; /* Nombre de réquilibrages réalisés sur l'arbre */ + struct NDT_Node *Head; /* Noeud de tête */ + struct NDT_Node *Tail; /* Noeud de queue */ + struct NDT_Node *Save; /* Pointeur de sauvegarde (utile pour la fonction de restauration) */ + +} NDT_Index; + + + +typedef struct NDT_Root +{ +/* NDT_Root_Type Type;*/ /* Root Structure Type */ +/* NDT_DataStruct_Type DS_Type;*/ /* Type de la structure (liste, arbre ... ) */ + + NDT_Manager *Manager_Ptr; /* Pointeur sur la fonction manager */ + char Manager_Name[NDD_MANAGER_NAME_SIZE_MAX]; /* Nom de la fonction manager */ + NDT_Allocator *Allocator_Ptr; /* Pointeur sur la fonction d'allocation */ + char Allocator_Name[NDD_ALLOCATOR_NAME_SIZE_MAX]; /* Nom de la fonction d'allocation */ + NDT_Desallocator *Desallocator_Ptr; /* Pointeur sur la fonction de désallocation */ + char Desallocator_Name[NDD_DESALLOCATOR_NAME_SIZE_MAX]; /* Nom de la fonction de désallocation */ + + short Own_Value; /* Indique si la structure est propriétaire de ses valeurs */ + void *User_Ptr; /* Pointeur utilisable librement par l'utilisateur */ + + NDT_Index_Nb Index_Nb; + NDT_Index_Nb Index_Open_Count; + NDT_Index Index_Tab[1]; + +} NDT_Root; + + + +typedef struct NDT_DataStruct +{ + + NDT_Root *Root_Ptr; + + NDT_Manager *Manager_Ptr; /* Manager function pointer */ + NDT_Allocator *Allocator_Ptr; /* Allocator function pointer */ + NDT_Desallocator *Desallocator_Ptr; /* Desallocator function pointer */ + +} NDT_DataStruct; + + + +/* Structure de noeud */ + +typedef struct NDT_Node +{ + NDT_Root *Root; + NDT_Index_Id Index; + struct NDT_Node *Parent; + struct NDT_Node *Left; + struct NDT_Node *Right; + void *Value; +} NDT_Node; + + + +typedef int NDT_Recursive_Mode; +typedef int NDT_Recursive_Depth; +typedef int NDT_Recursive_Offset; + +#define NDD_RECURSIVE_MODE_UNKNOWN (NDT_Recursive_Mode)0x00 +#define NDD_RECURSIVE_MODE_PARENT (NDT_Recursive_Mode)0x01 +#define NDD_RECURSIVE_MODE_CHILD (NDT_Recursive_Mode)0x02 +#define NDD_RECURSIVE_MODE_PARENT_CHILD (NDT_Recursive_Mode)0x03 + +#define ND_RECURSIVE_PARENT_IS(m) (m & NDD_RECURSIVE_MODE_PARENT) +#define ND_RECURSIVE_CHILD_IS(m) (m & NDD_RECURSIVE_MODE_CHILD) + +#define ND_RECURSIVE_PRINT_OFFSET 8 + + + +/* Définition des alias de l'API */ + +#ifndef ND_MODE +#define ND_MODE 0 +#endif + +#if ND_MODE == 1 /* API sans vérification des arguments */ + +#define ND_Library_Open ND_Library_Open_I +#define ND_Library_Close ND_Library_Close_I +#define ND_Library_StdErr_Set ND_Library_StdErr_Set_I + +#define ND_DataStruct_Open ND_DataStruct_Open_I +#define ND_DataStruct_Close ND_DataStruct_Close_I +#define ND_DataStruct_Flush ND_DataStruct_Flush_I +#define ND_DataStruct_Check ND_DataStruct_Check_I +#define ND_DataStruct_Convert ND_DataStruct_Convert_I +#define ND_DataStruct_Reorg ND_DataStruct_Reorg_I +#define ND_DataStruct_Traverse_V ND_DataStruct_Traverse_VI +#define ND_DataStruct_Traverse ND_DataStruct_Traverse_I +#define ND_DataStruct_Info_Print ND_DataStruct_Info_Print_I +#define ND_DataStruct_Value_Add ND_DataStruct_Value_Add_I +#define ND_DataStruct_Value_Remove ND_DataStruct_Value_Remove_I +#define ND_DataStruct_Value_Print ND_DataStruct_Value_Print_I +#define ND_DataStruct_Value_Find ND_DataStruct_Value_Find_I + +#define ND_Index_Open ND_Index_Open_I +#define ND_Index_Close ND_Index_Close_I +#define ND_Index_Flush ND_Index_Flush_I +#define ND_Index_Check ND_Index_Check_I +#define ND_Index_Convert ND_Index_Convert_I +#define ND_Index_Reorg ND_Index_Reorg_I +#define ND_Index_Traverse_V ND_Index_Traverse_VI +#define ND_Index_Traverse ND_Index_Traverse_I +#define ND_Index_Info_Print ND_Index_Info_Print_I +#define ND_Index_Value_Add ND_Index_Value_Add_I +#define ND_Index_Value_Remove ND_Index_Value_Remove_I +#define ND_Index_Value_Print ND_Index_Value_Print_I +#define ND_Index_Node_Add ND_Index_Node_Add_I +#define ND_Index_Node_Remove ND_Index_Node_Remove_I +#define ND_Index_Node_First_Get ND_Index_Node_First_Get_I +#define ND_Index_Node_Last_Get ND_Index_Node_Last_Get_I +#define ND_Index_Node_Next_Get ND_Index_Node_Next_Get_I +#define ND_Index_Node_Previous_Get ND_Index_Node_Previous_Get_I +#define ND_Index_Node_Find ND_Index_Node_Find_I + +#define ND_Node_Root_Get ND_Node_Root_Get_I + +#define ND_Value_Alloc ND_Value_Alloc_I +#define ND_Value_Free ND_Value_Free_I + +#define ND_Manager_Exec_V ND_Manager_Exec_VI +#define ND_Manager_Exec ND_Manager_Exec_I +#define ND_Allocator_Exec ND_Allocator_Exec_I +#define ND_Desallocator_Exec ND_Desallocator_Exec_I + +#else /* API avec vérification des arguments */ + +#define ND_Library_Open ND_Library_Open_C +#define ND_Library_Close ND_Library_Close_C +#define ND_Library_StdErr_Set ND_Library_StdErr_Set_C + +#define ND_DataStruct_Open ND_DataStruct_Open_C +#define ND_DataStruct_Close ND_DataStruct_Close_C +#define ND_DataStruct_Flush ND_DataStruct_Flush_C +#define ND_DataStruct_Check ND_DataStruct_Check_C +#define ND_DataStruct_Convert ND_DataStruct_Convert_C +#define ND_DataStruct_Reorg ND_DataStruct_Reorg_C +#define ND_DataStruct_Traverse_V ND_DataStruct_Traverse_VC +#define ND_DataStruct_Traverse ND_DataStruct_Traverse_C +#define ND_DataStruct_Info_Print ND_DataStruct_Info_Print_C +#define ND_DataStruct_Value_Add ND_DataStruct_Value_Add_C +#define ND_DataStruct_Value_Remove ND_DataStruct_Value_Remove_C +#define ND_DataStruct_Value_Print ND_DataStruct_Value_Print_C +#define ND_DataStruct_Value_Find ND_DataStruct_Value_Find_C + +#define ND_Index_Open ND_Index_Open_C +#define ND_Index_Close ND_Index_Close_C +#define ND_Index_Flush ND_Index_Flush_C +#define ND_Index_Check ND_Index_Check_C +#define ND_Index_Convert ND_Index_Convert_C +#define ND_Index_Reorg ND_Index_Reorg_C +#define ND_Index_Traverse_V ND_Index_Traverse_VC +#define ND_Index_Traverse ND_Index_Traverse_C +#define ND_Index_Info_Print ND_Index_Info_Print_C +#define ND_Index_Value_Add ND_Index_Value_Add_C +#define ND_Index_Value_Remove ND_Index_Value_Remove_C +#define ND_Index_Value_Print ND_Index_Value_Print_C +#define ND_Index_Node_Add ND_Index_Node_Add_C +#define ND_Index_Node_Remove ND_Index_Node_Remove_C +#define ND_Index_Node_First_Get ND_Index_Node_First_Get_C +#define ND_Index_Node_Last_Get ND_Index_Node_Last_Get_C +#define ND_Index_Node_Next_Get ND_Index_Node_Next_Get_C +#define ND_Index_Node_Previous_Get ND_Index_Node_Previous_Get_C +#define ND_Index_Node_Find ND_Index_Node_Find_C + +#define ND_Node_Root_Get ND_Node_Root_Get_C + +#define ND_Value_Alloc ND_Value_Alloc_C +#define ND_Value_Free ND_Value_Free_C + +#define ND_Manager_Exec_V ND_Manager_Exec_VC +#define ND_Manager_Exec ND_Manager_Exec_C +#define ND_Allocator_Exec ND_Allocator_Exec_C +#define ND_Desallocator_Exec ND_Desallocator_Exec_C + +#endif + + + +/*------------------------------------------------------------------------------*/ + +# if defined(_WIN32) && !defined(LIBNODE_STATIC) +# ifndef _LIBNODE_C_ +# define NDD_DLL_API __declspec(dllimport) +# else +# define NDD_DLL_API __declspec(dllexport) +# endif +# else +# define NDD_DLL_API +# endif + + + +/*------------------------------------------------------------------------------*/ +/* Initialisation du contexte de la librairie */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Library_Open_I ( int Debug_Mode ); +NDD_DLL_API NDT_Status ND_Library_Open_C ( int Debug_Mode ); + + + +/*------------------------------------------------------------------------------*/ +/* Fermeture du contexte de la librairie */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Library_Close_I( void); +NDD_DLL_API NDT_Status ND_Library_Close_C( void); + + + +/*------------------------------------------------------------------------------*/ +/* Définition de la sortie standard des messages d'erreur de la librairie */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Library_StdErr_Set_I( FILE *); +NDD_DLL_API NDT_Status ND_Library_StdErr_Set_C( FILE *); + + + +/*------------------------------------------------------------------------------*/ +/* 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 */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_DataStruct_Open_I( NDT_Root **, NDT_Index_Nb, NDT_Index_Type *, NDT_Manager_Name, NDT_Manager *, NDT_Allocator_Name, NDT_Allocator *, NDT_Desallocator_Name, NDT_Desallocator *, short, void *); +NDD_DLL_API NDT_Status ND_DataStruct_Open_C( NDT_Root **, NDT_Index_Nb, NDT_Index_Type *, NDT_Manager_Name, NDT_Manager *, NDT_Allocator_Name, NDT_Allocator *, NDT_Desallocator_Name, NDT_Desallocator *, short, void *); + + + +/*------------------------------------------------------------------------------*/ +/* Destruction d'une structure de données */ +/*------------------------------------------------------------------------------*/ +/* (O) Root: pointeur sur la racine de la structure de données */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_DataStruct_Close_I( NDT_Root *); +NDD_DLL_API NDT_Status ND_DataStruct_Close_C( NDT_Root *); + + + +/*------------------------------------------------------------------------------*/ +/* Destruction d'une structure de données */ +/*------------------------------------------------------------------------------*/ +/* (O) Root: pointeur sur la racine de la structure de données */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_DataStruct_Flush_I( NDT_Root *); +NDD_DLL_API NDT_Status ND_DataStruct_Flush_C( NDT_Root *); + + + +/*------------------------------------------------------------------------------*/ +/* 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 */ +/* (O) Nb_Corrected : pointeur sur le nombre d'erreurs */ +/* (I) Out : flux de sortie du rapport */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_DataStruct_Check_I( NDT_Root *, int *, int *, FILE *); +NDD_DLL_API NDT_Status ND_DataStruct_Check_C( NDT_Root *, int *, int *, FILE *); + + + +/*------------------------------------------------------------------------------*/ +/* 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 */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_DataStruct_Reorg_I( NDT_Root *); +NDD_DLL_API NDT_Status ND_DataStruct_Reorg_C( NDT_Root *); + + + +/*------------------------------------------------------------------------------*/ +/* 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 */ +/* (I) Target_Type: type de structure cible */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_DataStruct_Convert_I( NDT_Root *, NDT_Index_Type *); +NDD_DLL_API NDT_Status ND_DataStruct_Convert_C( NDT_Root *, NDT_Index_Type *); + + + +/*------------------------------------------------------------------------------*/ +/* 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 */ +/* (I) Command: Commande à exécuter sur chaque noeud traversé */ +/* (I) Data: pointeur de données utilisateur */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_DataStruct_Traverse_VI( NDT_Root *, NDT_Command, va_list *); +NDD_DLL_API NDT_Status ND_DataStruct_Traverse_VC( NDT_Root *, NDT_Command, va_list *); +NDD_DLL_API NDT_Status ND_DataStruct_Traverse_I( NDT_Root *, NDT_Command, ...); +NDD_DLL_API NDT_Status ND_DataStruct_Traverse_C( NDT_Root *, NDT_Command, ...); + + + +/*------------------------------------------------------------------------------*/ +/* 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 */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_DataStruct_Info_Print_I( FILE *, NDT_Root *, NDT_Recursive_Mode, NDT_Recursive_Depth, NDT_Recursive_Offset); +NDD_DLL_API NDT_Status ND_DataStruct_Info_Print_C( FILE *, NDT_Root *, NDT_Recursive_Mode, NDT_Recursive_Depth, NDT_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 */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_DataStruct_Value_Add_I( NDT_Root *, void *); +NDD_DLL_API NDT_Status ND_DataStruct_Value_Add_C( NDT_Root *, void *); + + + +/*------------------------------------------------------------------------------*/ +/* 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 */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_DataStruct_Value_Remove_I( NDT_Root *, void *); +NDD_DLL_API NDT_Status ND_DataStruct_Value_Remove_C( NDT_Root *, void *); + + + +/*------------------------------------------------------------------------------*/ +/* Affichage de la valeur de tous les noeuds d'une structure de données */ +/*------------------------------------------------------------------------------*/ +/* (I) Root: pointeur sur la racine de la structure de données */ +/* (I) Out : flux de sortie */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_DataStruct_Value_Print_VI( FILE *, NDT_Root *, NDT_Recursive_Mode, NDT_Recursive_Depth, NDT_Recursive_Offset, va_list *); +NDD_DLL_API NDT_Status ND_DataStruct_Value_Print_I( FILE *, NDT_Root *, NDT_Recursive_Mode, NDT_Recursive_Depth, NDT_Recursive_Offset, ...); +NDD_DLL_API NDT_Status ND_DataStruct_Value_Print_C( FILE *, NDT_Root *, NDT_Recursive_Mode, NDT_Recursive_Depth, NDT_Recursive_Offset, ...); + + + +/*------------------------------------------------------------------------------*/ +/* Recherche un noeud à partir d'une valeur */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de l'abre */ +/* (O) Node : pointeur sur le noeud à récuperer */ +/* (I) Value : pointeur sur la valeur à rechercher */ +/* (I) Data : pointeur de données */ +/*------------------------------------------------------------------------------*/ + +NDD_DLL_API NDT_Status ND_DataStruct_Value_Find_VI( void **, NDT_Root *, void *, va_list *); +NDD_DLL_API NDT_Status ND_DataStruct_Value_Find_VC( void **, NDT_Root *, void *, va_list *); +NDD_DLL_API NDT_Status ND_DataStruct_Value_Find_I( void **, NDT_Root *, void *, ...); +NDD_DLL_API NDT_Status ND_DataStruct_Value_Find_C( void **, NDT_Root *, void *, ...); + + + +/*------------------------------------------------------------------------------*/ +/* Create a new index (not yet implemented !) */ +/*------------------------------------------------------------------------------*/ +/* (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 */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Open_I( NDT_Root *, NDT_Index_Id, NDT_Index_Type); +NDD_DLL_API NDT_Status ND_Index_Open_C( NDT_Root *, NDT_Index_Id, NDT_Index_Type); + + + +/*------------------------------------------------------------------------------*/ +/* Remove an Index (not yet implemented !) */ +/*------------------------------------------------------------------------------*/ +/* (O) Root: pointeur sur la racine de la structure de données */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Close_I( NDT_Root *, NDT_Index_Id); +NDD_DLL_API NDT_Status ND_Index_Close_C( NDT_Root *, NDT_Index_Id); + + + +/*------------------------------------------------------------------------------*/ +/* Remove an Index (not yet implemented !) */ +/*------------------------------------------------------------------------------*/ +/* (O) Root: pointeur sur la racine de la structure de données */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Flush_I( NDT_Root *, NDT_Index_Id); +NDD_DLL_API NDT_Status ND_Index_Flush_C( NDT_Root *, NDT_Index_Id); + + + +/*------------------------------------------------------------------------------*/ +/* 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 */ +/* (O) Nb_Corrected : pointeur sur le nombre d'erreurs */ +/* (I) Out : flux de sortie du rapport */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Check_I( NDT_Root *, NDT_Index_Id, int *, int *, FILE *); +NDD_DLL_API NDT_Status ND_Index_Check_C( NDT_Root *, NDT_Index_Id, int *, int *, FILE *); + + + +/*------------------------------------------------------------------------------*/ +/* 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 */ +/* (I) Target_Type: type de structure cible */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Convert_I ( NDT_Root *, NDT_Index_Id, NDT_Index_Type); +NDD_DLL_API NDT_Status ND_Index_Convert_C ( NDT_Root *, NDT_Index_Id, NDT_Index_Type); + + + +/*------------------------------------------------------------------------------*/ +/* 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 */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Reorg_I( NDT_Root *, NDT_Index_Id); +NDD_DLL_API NDT_Status ND_Index_Reorg_C( NDT_Root *, NDT_Index_Id); + + + +/*------------------------------------------------------------------------------*/ +/* 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 */ +/* (I) Command: Commande à exécuter sur chaque noeud traversé */ +/* (I) Data: pointeur de données utilisateur */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Traverse_VI( NDT_Root *, NDT_Index_Id, NDT_Command, va_list *); +NDD_DLL_API NDT_Status ND_Index_Traverse_VC( NDT_Root *, NDT_Index_Id, NDT_Command, va_list *); +NDD_DLL_API NDT_Status ND_Index_Traverse_I( NDT_Root *, NDT_Index_Id, NDT_Command, ...); +NDD_DLL_API NDT_Status ND_Index_Traverse_C( NDT_Root *, NDT_Index_Id, NDT_Command, ...); + + + +/*------------------------------------------------------------------------------*/ +/* 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 */ +/* (I) Command: Commande à exécuter sur chaque noeud traversé */ +/* (I) Data: pointeur de données utilisateur */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Info_Print_I( FILE *, NDT_Root *, NDT_Index_Id, NDT_Recursive_Mode, NDT_Recursive_Depth, NDT_Recursive_Offset); +NDD_DLL_API NDT_Status ND_Index_Info_Print_C( FILE *, NDT_Root *, NDT_Index_Id, NDT_Recursive_Mode, NDT_Recursive_Depth, NDT_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 */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Value_Add_I( NDT_Root *, NDT_Index_Id, void *); +NDD_DLL_API NDT_Status ND_Index_Value_Add_C( NDT_Root *, NDT_Index_Id, void *); + + + +/*------------------------------------------------------------------------------*/ +/* 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 */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Value_Remove_I( NDT_Root *, NDT_Index_Id, void *); +NDD_DLL_API NDT_Status ND_Index_Value_Remove_C( NDT_Root *, NDT_Index_Id, void *); + + + +/*------------------------------------------------------------------------------*/ +/* Affichage de la valeur de tous les noeuds d'une structure de données */ +/*------------------------------------------------------------------------------*/ +/* (I) Root: pointeur sur la racine de la structure de données */ +/* (I) Out : flux de sortie */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Value_Print_VI( FILE *, NDT_Root *, NDT_Index_Id, NDT_Recursive_Mode, NDT_Recursive_Depth, NDT_Recursive_Offset, va_list *); +NDD_DLL_API NDT_Status ND_Index_Value_Print_I( FILE *, NDT_Root *, NDT_Index_Id, NDT_Recursive_Mode, NDT_Recursive_Depth, NDT_Recursive_Offset, ...); +NDD_DLL_API NDT_Status ND_Index_Value_Print_C( FILE *, NDT_Root *, NDT_Index_Id, NDT_Recursive_Mode, NDT_Recursive_Depth, NDT_Recursive_Offset, ...); + + + +/*------------------------------------------------------------------------------*/ +/* 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 */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Node_Add_I( NDT_Root *, NDT_Index_Id, NDT_Node *); +NDD_DLL_API NDT_Status ND_Index_Node_Add_C( NDT_Root *, NDT_Index_Id, NDT_Node *); + + + +/*------------------------------------------------------------------------------*/ +/* Suppression d'un noeud dans une structure de données */ +/*------------------------------------------------------------------------------*/ +/* (I) Node: pointeur sur le noeud à supprimer de la structure de données */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Node_Remove_I( NDT_Node *); +NDD_DLL_API NDT_Status ND_Index_Node_Remove_C( NDT_Node *); + + + +/*------------------------------------------------------------------------------*/ +/* Récupération du premier noeud d'une structure */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine dont on cherche le premier noeud */ +/* (O) Node : pointeur sur le noeud à récupérer */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Node_First_Get_I( NDT_Node **, NDT_Root *, NDT_Index_Id); +NDD_DLL_API NDT_Status ND_Index_Node_First_Get_C( NDT_Node **, NDT_Root *, NDT_Index_Id); + + + +/*------------------------------------------------------------------------------*/ +/* Récupération du dernier noeud d'une structure */ +/*------------------------------------------------------------------------------*/ +/* (I) Root: pointeur sur la racine dont on cherche le dernier noeud */ +/* (O) Node : pointeur sur le noeud à récupérer */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Node_Last_Get_I( NDT_Node **, NDT_Root *, NDT_Index_Id); +NDD_DLL_API NDT_Status ND_Index_Node_Last_Get_C( NDT_Node **, NDT_Root *, NDT_Index_Id); + + + +/*------------------------------------------------------------------------------*/ +/* Récupération du noeud suivant */ +/*------------------------------------------------------------------------------*/ +/* (I) Node: pointeur sur le noeud dont on cherche le suivant */ +/* (O) Next_Node : pointeur sur le noeud suivant */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Node_Next_Get_I( NDT_Node **, NDT_Node *); +NDD_DLL_API NDT_Status ND_Index_Node_Next_Get_C( NDT_Node **, NDT_Node *); + + + +/*------------------------------------------------------------------------------*/ +/* Récupération du noeud précédant */ +/*------------------------------------------------------------------------------*/ +/* (I) Node: pointeur sur le noeud dont on cherche le précédant */ +/* (O) Prev_Node : pointeur sur le noeud précédant */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Node_Previous_Get_I( NDT_Node **, NDT_Node *); +NDD_DLL_API NDT_Status ND_Index_Node_Previous_Get_C( NDT_Node **, NDT_Node *); + + + +/*------------------------------------------------------------------------------*/ +/* Recherche un noeud à partir d'une valeur */ +/*------------------------------------------------------------------------------*/ +/* (I) Root : pointeur sur la racine de l'abre */ +/* (O) Node : pointeur sur le noeud à récuperer */ +/* (I) Value : pointeur sur la valeur à rechercher */ +/* (I) Data : pointeur de données */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Index_Node_Find_VI( NDT_Node **, NDT_Root *, NDT_Index_Id, void *, va_list *); +NDD_DLL_API NDT_Status ND_Index_Node_Find_VC( NDT_Node **, NDT_Root *, NDT_Index_Id, void *, va_list *); +NDD_DLL_API NDT_Status ND_Index_Node_Find_I( NDT_Node **, NDT_Root *, NDT_Index_Id, void *, ...); +NDD_DLL_API NDT_Status ND_Index_Node_Find_C( NDT_Node **, NDT_Root *, NDT_Index_Id, void *, ...); + + + +/*------------------------------------------------------------------------------*/ +/* 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 */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Node_Root_Get_I( NDT_Root **, NDT_Node *); +NDD_DLL_API NDT_Status ND_Node_Root_Get_C( NDT_Root **, NDT_Node *); + + + +/*------------------------------------------------------------------------------*/ +/* 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 */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Value_Alloc_I( NDT_Root *, void **, ...); +NDD_DLL_API NDT_Status ND_Value_Alloc_C( NDT_Root *, void **, ...); + + + +/*------------------------------------------------------------------------------*/ +/* 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 */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Value_Free_I( NDT_Root *, void *); +NDD_DLL_API NDT_Status ND_Value_Free_C( NDT_Root *, void *); + + + +/*------------------------------------------------------------------------------*/ +/* Exécution d'une fonction Manager dont le nom est passé en paramètre */ +/*------------------------------------------------------------------------------*/ +/* (I) Function : nom de la fonction manager à exécuter */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Manager_Exec_VI( NDT_Root *, NDT_Index_Id, NDT_Node *, NDT_Command, va_list *); +NDD_DLL_API NDT_Status ND_Manager_Exec_VC( NDT_Root *, NDT_Index_Id, NDT_Node *, NDT_Command, va_list *); +NDD_DLL_API NDT_Status ND_Manager_Exec_I( NDT_Root *, NDT_Index_Id, NDT_Node *, NDT_Command, ...); +NDD_DLL_API NDT_Status ND_Manager_Exec_C( NDT_Root *, NDT_Index_Id, NDT_Node *, NDT_Command, ...); + + + +/*------------------------------------------------------------------------------*/ +/* 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 : pointeur de données utiles à l'allocateur */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Allocator_Exec_I( void **, size_t, NDT_Allocator_Name, NDT_Allocator *, void *); +NDD_DLL_API NDT_Status ND_Allocator_Exec_C( void **, size_t, NDT_Allocator_Name, NDT_Allocator *, void *); + + + +/*------------------------------------------------------------------------------*/ +/* Exécution d'une fonction de désallocation le dont nom est passé en paramètre */ +/*------------------------------------------------------------------------------*/ +/* (I) Function : nom de la fonction à exécuter */ +/* (I) Function : nom de la fonction à exécuter */ +/* (I) Ptr : adresse de la zone à désallouer */ +/* (I) Data : pointeur de données utiles au désallocateur */ +/*------------------------------------------------------------------------------*/ +NDD_DLL_API NDT_Status ND_Desallocator_Exec_I( void *, NDT_Desallocator_Name, NDT_Desallocator *, void *); +NDD_DLL_API NDT_Status ND_Desallocator_Exec_C( void *, NDT_Desallocator_Name, NDT_Desallocator *, void *); + + + +# ifdef __cplusplus +} +# endif + +#endif