First stable version LINUX / SOLARIS compatible.

This commit is contained in:
smas 2000-07-18 14:51:56 +00:00
commit 6fe492faf6
7 changed files with 4794 additions and 0 deletions

BIN
doc/libnode.doc Normal file

Binary file not shown.

947
doc/man3/libnode.3 Normal file
View File

@ -0,0 +1,947 @@
'\" t
.\" @(#)LIBNODE.3 1.0 99/10/12 SMA;
.TH LIBNODE 3 "10 Oct 1999"
.SH NOM
LIBNODE (librairie de structure de donnees a base de noeuds)
.SH SYNOPSIS
.LP
.B cc [flag ...] file ... -lver -ldl -lnode [library ...]
.LP
.B #include <node.h>
.LP
.BI "NDT_Status ND_Library_Open ( int " Debug_Mode " );"
.LP
.BI "NDT_Status ND_Library_Close ( void );"
.LP
.BI "NDT_Status ND_Library_Stderr_Set ( FILE * " Out " );"
.LP
.BI "NDT_Status ND_DataStruct_Open ( NDT_Root ** " Root ", NDT_DataStruct_Type " Type ", const char * " Allocator ", const char * " Desallocator ", void * " User " );"
.LP
.BI "NDT_Status ND_DataStruct_Close ( NDT_Root * " Root " );"
.LP
.BI "NDT_Status ND_DataStruct_Reorg ( NDT_Root * " Root " );"
.LP
.BI "NDT_Status ND_DataStruct_Traverse ( NDT_Root * " Root ", NDT_Command, void * " Command ", void * " Data " );"
.LP
.BI "NDT_Status ND_DataStruct_Convert ( NDT_Root * " Root ", ND_Conversion_Type " Target_Type " );"
.LP
.BI "NDT_Status ND_DataStruct_Info_Print ( NDT_Root * " Root ", FILE * " Out " );"
.LP
.BI "NDT_Status ND_DataStruct_Print ( NDT_Root * " Root ", FILE * " Out " );"
.LP
.BI "NDT_Status ND_DataStruct_Check ( NDT_Root * " Root ", int * " Nb_Detected ", int * " Nb_Corrected " ,FILE * " Out " );"
.LP
.BI "NDT_Status ND_DataStruct_Dump ( NDT_Root * " Root ", FILE * " Out " );"
.LP
.BI "NDT_Status ND_Node_Root_Get ( NDT_Root ** " Root ", NDT_Node * " Node " );"
.LP
.BI "NDT_Status ND_Node_First_Get ( NDT_Root * " Root ", NDT_Node ** " Node " );"
.LP
.BI "NDT_Status ND_Node_Last_Get ( NDT_Root * " Root ", NDT_Node ** " Node " );"
.LP
.BI "NDT_Status ND_Node_Next_Get ( NDT_Node * " Node ", NDT_Node ** " Next_Node " );"
.LP
.BI "NDT_Status ND_Node_Previous_Get ( NDT_Node * " Node ", NDT_Node ** " Prev_Node " );"
.LP
.BI "NDT_Status ND_Node_Add ( NDT_Root * " Root ", NDT_Node * " Node " );"
.LP
.BI "NDT_Status ND_Node_Remove ( NDT_Node * " Node " );"
.LP
.BI "NDT_Status ND_Node_Find ( NDT_Root * " Root ", NDT_Node ** " Node ",void * " Value " , void * " Data " );"
.LP
.BI "NDT_Status ND_Value_Alloc ( NDT_Root * " Root ", void ** " Value ", ... );"
.LP
.BI "NDT_Status ND_Value_Add ( NDT_Root * " Root ", void * " Value " );"
.LP
.BI "NDT_Status ND_Value_Remove ( NDT_Root * " Root ", void * " Reference_Value " , void ** " Removed_Value " );"
.LP
.BI "NDT_Status ND_Value_Free ( NDT_Root * " Root ", void * " Value " );"
.LP
.BI "NDT_Status ND_Manager_Exec (const char * " Function_Name ", ...)"
.LP
.BI "NDT_Status ND_Allocator_Exec (const char * " Function_Name ", void ** " Ptr ", size_t " Size ", void * " Data " );"
.LP
.BI "NDT_Status ND_Desallocator_Exec (const char * " Function_Name ", void * " Ptr ", void * " Data " );"
.LP
.SH DESCRIPTION
.LP
La bibliotheque LIBNODE implemente deux types de structure de donnees a base de noeuds :
.LP
.RS 3
- liste chainee
.LP
- arbre binaire
.RS -3
.LP
Une structure de donnees est composee d'une racine ( voir le type
.B NDT_Root
) et de zero, un ou plusieurs noeuds (voir le type
.B NDT_Node
).
.LP
Fondamentalement, seul le chainage entre les noeuds distingue les differents types de structure implementes dans cette librairie.
.LP
La librairie LIBNODE implemente les fonctions minimales pour ce type de structure.
Elle pourra bien entendu etre enrichie suite aux remarques des utilisateurs.
.LP
.SH TYPES
.LP
La librairie LIBNODE definit les types suivants :
.LP
.BI NDT_Root
.LP
.RS 3
Designe le type d'une racine de structure de donnees
.LP
Il s'agit d'une structure qui contient toutes les informations statistiques de la structure de donnees sous-jacente :
.LP
.RS 3
- nombre de noeuds (
.B ND_Node_Number
)
.LP
- profondeur minimum (
.B Min_Depth
) (pour les arbres)
.LP
- profondeur maximum (
.B Max_Depth
) (pour les arbres)
.LP
- nombre de reequilibrages (
.B Nb_Equ
) (pour les arbres)
.RS -3
.LP
La structure racine pointe sur les noeuds de tete (
.B Head
) et de queue (
.B Queue
) de la structure de donnees.
Pour une liste chainee, le noeud de tete est le premier noeud de la liste et le noeud de queue est le dernier noeud de la liste.
Pour un arbre binaire, le noeud de tete et le noeud de queue correpondent tous deux au meme noeud racine de l'arbre.
.LP
La gestion des arbres binaires prend en compte un reequilibrage automatique.
La structure racine conserve pour cela la taille de la plus grande branche de l'arbre (
.B Max_Depth
) ainsi que celle de la plus courte (
.B Min_Depth
).
Pour un arbre auto-equilibre, le depassement d'un seuil (
.B Max_Dif
) provoque immediatement son reequilibrage.
.LP
La racine d'une structure reference enfin les fonctions suivantes par leur nom :
.LP
.RS 3
-
.B Manager
: fonction qui implemente les commandes specifiques a realiser sur les valeurs, notamment :
.RS 3
.LP
- la creation d'une valeur
.LP
- la suppression d'une valeur
.LP
- l'affichage d'une valeur
.LP
- la comparaison de deux valeurs
.RS -3
.LP
-
.B Allocator
: fonction qui realise l'allocation de memoire pour la structure
.LP
-
.B Desallocator
: fonction qui realise la desallocation de memoire pour la structure
.LP
.RS -3
.I NB
: une racine contient un pointeur librement utilisable par l'utilisateur (
.B User
).
.LP
.RS -3
.B NDT_DataStruct_Type
.LP
.RS 3
Ce type definit sur un entier long le type de chainage de la structure de donnees :
.LP
.RS 3
-
.B NDD_DS_LIST
: liste chainee
.LP
-
.B NDD_DS_TREE
: arbre binaire
.RS -3
.LP
et son mode de gestion :
.RS 3
.LP
-
.B NDD_MN_FIFO
(ou
.B NDD_MN_LILO
) : principe de la file d'attente (First In First Out)
.LP
-
.B NDD_MN_FILO
(ou
.B NDD_MN_LIFO
) : principe de la pile (First In Last Out)
.LP
-
.B NDD_MN_ORDERED
: ordonnancement des valeurs (liste triee).
Losque deux noeuds ont la meme valeur, ils seront ordonnes dans l'ordre chronologique d'insertion.
.LP
Toutefois, l'utilisateur pourra combiner par addition binaire les types
.B NDD_MN_ORDERED
et
.B NDD_MN_FILO
afin que deux noeuds de meme valeur soient ordonnes dans l'ordre inverse.
.LP
-
.B NDD_MN_AUTO_EQU
: auto-equilibre (arbre)
.RS -3
.LP
Les valeurs NDD_DS* et NDD_MN* peuvent etre utilisees de maniere combinee par addition binaire.
.LP
.I Exemple
:
.LP
Mon_Type =
.B NDD_DS_LIST
|
.B NDD_MN_ORDERED
;
.LP
Mon_Type =
.B NDD_DS_TREE
|
.B NDD_MN_AUTO_EQU
;
.LP
Des valeurs "masque" permettent de ne recuperer que l'une des deux parties du type :
.LP
.RS 3
-
.B NDD_DS_MSK
: masque sur le type de chainage
.LP
-
.B NDD_MN_MSK
: masque sur le mode de gestion
.LP
.RS -3
.I Exemple
:
.LP
(Mon_Type &
.B NDD_DS_MSK
) renverra la valeur
.B NDD_DS_LIST
ou
.B NDD_DS_TREE
.
.LP
(Mon_Type &
.B NDD_MN_MSK
) renverra l'une des valeurs
.B NDD_MN_FILO
,
.B NDD_MN_FIFO
,
.B NDD_MN_ORDERED
ou
.B NDD_MN_AUTO_EQU
.
.LP
.RS -3
.BI NDT_Node
.LP
.RS 3
Designe le type d'un noeud
.LP
Il s'agit d'une structure qui permet aux noeuds d'etre relies les uns aux autres :
.LP
.RS 3
- pointeur sur le noeud droite (
.B Right
)
.LP
- pointeur sur le noeud gauche (
.B Left
)
.RS -3
.LP
Pour une structure de type arbre, chaque noeud pointe aussi sur son noeud pere (
.B Parent
).
Chaque noeud possede enfin un pointeur sur sa structure racine (
.B Root
).
.LP
A chaque noeud sera associee une valeur dont l'utilisateur de la librairie devra lui meme definir le type.
.RS -3
.LP
.BI NDT_Value
.LP
.RS 3
Designe le type d'une valeur attachee a un noeud. Ce type sera surcharge par celui defini par l'utilisateur.
.LP
.RS -3
.BI NDT_Manager
.LP
.RS 3
Designe le type d'une fonction manager.
.LP
Une fonction manager est attachee a la racine de la structure via son nom et permet d'executer des commandes (voir
.B NDT_Command
) specifiques sur la structure ou sur ses valeurs.
.LP
L'implementation des ces commandes est a definir par l'utilisateur lui-meme.
.LP
Le premier argument d'une fonction manager correspond toujours au type de la commande a executer.
.LP
Les autres arguments dependent bien evidemment de la commande a executer.
.LP
Une fonction manager doit etre executee via la fonction
.B NDT_Manager_Exec
(voir FONCTIONS).
.LP
.RS -3
.BI NDT_Command
.LP
.RS 3
Designe le type d'une commande pouvant etre executee par le manager :
.RS 3
.LP
-
.B NDD_CMD_COMP_VALUE
: comparaison de valeurs
.LP
-
.B NDD_CMD_MAKE_VALUE
: creation de valeur
.LP
-
.B NDD_CMD_PRINT_VALUE
: affichage de valeur
.LP
-
.B NDD_CMD_DELETE_VALUE
: suppression de valeur
.LP
-
.B NDD_CMD_PRINT_INFO
: affichage des informations de la racine
.RS -3
.LP
.I NB
Toutes ces commandes ne doivent pas necessairement etre implementees par l'utilisateur. A priori, seule la commande permettant de detruire une valeur est obligatoire.
De nouvelles commandes pourront aussi etre definies par l'utilisateur, sous reserve qu'elles soient implementee par la fonction manager.
.RS -3
.LP
.BI NDT_Allocator
.LP
.RS 3
Designe le type d'une fonction d'allocation memoire.
.LP
Une fonction d'allocation est attachee a la racine de la structure par son nom et permet de d'allouer de la memoire pour le stockage de la structure (racine et noeuds).
.LP
Par defaut, une structure de donnees definira la fonction malloc() comme fonction d'allocation.
.LP
.I NB
: une fonction d'allocation devra etre executee via la fonction
.B NDT_Allocator_Exec
(voir FONCTIONS).
.LP
.RS -3
.BI NDT_Desallocator
.LP
.RS 3
Designe le type d'une fonction de desallocation memoire.
.LP
Une fonction de desallocation est attachee a la racine de la structure par son nom et permet de liberer la memoire allouee pour le stockage de la structure.
.LP
Par defaut, une structure de donnees definira la fonction free() comme fonction de desallocation.
.LP
.I NB
: une fonction de desallocation devra etre executee via la fonction
.B NDT_Desallocator_Exec
(voir FONCTIONS).
.LP
.RS -3
.SH FONCTIONS
.BI "ND_Library_Open ( int " Debug_Mode " )"
.RS 3
.LP
Cette fonction permet d'initialiser les eventuelles ressources de la librairie.
Elle doit etre systematiquement appelee au debut de chaque programme utilisant la librairie.
.LP
L'argument
.I Debug_Mode
(TRUE ou FALSE) permet d'utiliser la librairie en mode bavard ou non, ce qui sigifie que tous les messages d'erreur seront affiches par defaut sur la sortie standard.
.LP
.RS -3
.BI "ND_Library_Close ( void )"
.RS 3
.LP
Cette fonction permet de fermer les eventuelles ressources de la librairie.
Elle doit etre systematiquement appelee a la fin de chaque programme utilisant la librairie.
.LP
.RS -3
.BI "NDT_Status ND_Library_Stderr_Set ( FILE * " Out " );"
.LP
.RS 3
Cette fonction permet de definir
.I Out
comme la sortie standard des messages d'erreur de la librarie.
.RS -3
.LP
.BI "NDT_Status ND_DataStruct_Open ( NDT_Root ** " Root ", NDT_DataStruct_Type " Type ", const char * " Allocator ", const char * " Desallocator ", void * " User " , int " Own_Value " );"
.RS 3
.LP
Cette fonction permet de creer une structure de donnees.
.LP
Elle doit recevoir les arguments suivants :
.LP
.RS 3
* (Out)
.I Root
: l'adresse du pointeur sur la racine de la nouvelle structure de donnees
.LP
* (In)
.I Type
: le type de la nouvelle structure de donnees
.LP
* (In)
.I Allocator
: le nom de la fonction d'allocation memoire (fonction de type
.B NDT_Allocator
) associee a la nouvelle structure de donnees.
Si cet argument est positionne a NULL, alors la fonction d'allocation locale malloc() sera utilisee par defaut.
.LP
* (In)
.I Desallocator
: le nom de la fonction de desallocation memoire (fonction de type
.B NDT_Desallocator
) associee a la nouvelle structure de donnees.
Si cet argument est positionne a NULL, alors la fonction de desallocation locale free() sera utilisee par defaut.
.LP
* (In)
.I User
: un pointeur de donnees qui sera systematiquement passe au manager pour l'allocation et la desallocation.
.LP
* (In)
.I Own_Value
: valeur TRUE ou FALSE indiquant si la structure est proprietaire de ses valeurs.
.LP
.I NB
: si une structure est proprietaire de ses valeurs, alors sa destruction provoque aussi la desallocation des valeurs rattachees a ses noeuds
.LP
.RS -3
.RS -3
.BI "NDT_Status ND_DataStruct_Close ( NDT_Root * " Root " );"
.RS 3
.LP
Cette fonction permet de detruire une structure de donnees (desallocation des ressources).
.LP
L'argument
.I Root
est un pointeur sur la racine de la structure de donnees a detruire.
.LP
.I NB
: les valeurs de la structure seront desallouees en meme temps que leur noeud selon que la structure est proprietaire ou non de ses valeurs.
.LP
.RS -3
.BI "NDT_Status ND_DataStruct_Reorg ( NDT_Root * " Root " );"
.RS 3
.LP
Cette fonction permet de reorganiser les donnees d'une structure (tri pour une liste, reequilibrage pour un arbre).
.LP
L'argument
.I Root
est un pointeur sur la racine de la structure de donnees a reorganiser.
.LP
.RS -3
.BI "NDT_Status ND_DataStruct_Traverse ( NDT_Root * " Root ", NDT_Command, void * " Command ", void * " Data " );"
.RS 3
.LP
Cette fonction permet de parcourir tous les noeuds d'une structure de donnees avec execution d'une commande sur chacun d'eux.
.LP
Elle doit recevoir les arguments suivants :
.LP
.RS 3
* (In)
.I Root
: un pointeur sur la racine de la structure de donnees a parcourir.
.LP
* (In)
.I Command
: la commande a executer sur chaque noeud traverse
.LP
* (In)
.I Data
: un pointeur de donnees propre a la commande
.RS -3
.LP
.RS -3
.BI "NDT_Status ND_DataStruct_Convert ( NDT_Root * " Root ", ND_Conversion_Type " Target_Type " );"
.RS 3
.LP
Cette fonction permet de convertir une structure de donnees d'un type en un autre.
.LP
Elle doit recevoir les arguments suivants :
.LP
.RS 3
* (In)
.I Root
: un pointeur sur la racine de la structure de donnees a convertir.
.LP
* (In)
.I Target_Type
: le type cible de la structure
.LP
.RS -3
.RS -3
.BI "NDT_Status ND_DataStruct_Print ( NDT_Root * " Root ", FILE * " Out " );"
.LP
.RS 3
Cette fonction permet d'afficher toutes les valeurs des noeuds d'une structure de donnees.
.LP
Elle doit recevoir les arguments suivants :
.LP
.RS 3
* (In)
.I Root
: un pointeur sur la racine de la structure de donnees a afficher.
.LP
* (In)
.I Out
: un pointeur sur le flux de sortie
.RS -3
.LP
.RS -3
.BI "NDT_Status ND_DataStruct_Info_Print ( NDT_Root * " Root ", FILE * " Out " );"
.LP
.RS 3
Cette fonction permet d'afficher des informations concernant une structure de donnees.
.LP
Elle doit recevoir les arguments suivants :
.LP
.RS 3
* (In)
.I Root
: un pointeur sur la racine de la structure de donnees
.LP
* (In)
.I Out
: un pointeur sur le flux de sortie
.RS -3
.LP
.RS -3
.BI "NDT_Status ND_DataStruct_Check ( NDT_Root * " Root ", int * " Nb_Detected ", int * " Nb_Corrected " ,FILE * " Out " );"
.LP
.RS 3
Cette fonction permet de verifier et de corriger des incoherences contenues dans une structure de donnees.
Elle verifie notamment les liens entre les noeuds, supprime les noeuds sans valeur ou ceux dont les valeurs ne sont pas accessibles et met a jour les informations statistiques de la racine.
Un rapport de toutes les erreurs detectees ou corrigees est affiche.
.LP
Elle doit recevoir les arguments suivants :
.LP
.RS 3
* (In)
.I Root
: un pointeur sur la racine de la structure de donnees a verifier.
.LP
* (Out)
.I Nb_Detected
: un pointeur sur le nombre d'erreurs detectees
.LP
* (Out)
.I Nb_Corrected
: un pointeur sur le nombre d'erreurs corrigees
.LP
* (In)
.I Out
: un pointeur sur le flux de sortie du rapport
.RS -3
.LP
.RS -3
.BI "NDT_Status ND_DataStruct_Dump ( NDT_Root * " Root ", FILE * " Out " );"
.LP
.RS 3
Cette fonction permet d'afficher toutes les informations de la structure (racine et contenu).
.LP
Elle doit recevoir les arguments suivants :
.LP
.RS 3
* (In)
.I Root
: un pointeur sur la racine de la structure de donnees a afficher.
.LP
* (In)
.I Out
: un pointeur sur le flux de sortie
.RS -3
.LP
.I NB
: cette fonction a ete implementee dans une optique de deboggage.
.LP
.RS -3
.BI "NDT_Status ND_Node_Root_Get ( NDT_Root ** " Root ", NDT_Node * " Node " );"
.LP
.RS 3
Cette fonction permet de recuperer la racine d'une structure a partir d'un de ses noeuds.
.LP
Elle doit recevoir les arguments suivants :
.LP
.RS 3
* (Out)
.I Root
: l'adresse d'un pointeur sur la racine a recuperer
.LP
* (In)
.I Node
: un pointeur sur un noeud
.RS -3
.LP
.RS -3
.BI "NDT_Status ND_Node_First_Get ( NDT_Root * " Root ", NDT_Node ** " Node " );"
.LP
.RS 3
Cette fonction permet de recuperer le premier noeud d'une structure.
.LP
Elle doit recevoir les arguments suivants :
.LP
.RS 3
* (In)
.I Root
: un pointeur sur la racine de la structure
.LP
* (Out)
.I Node
: l'adresse d'un pointeur sur le premier noeud a recuperer
.RS -3
.LP
.RS -3
.BI "NDT_Status ND_Node_Last_Get ( NDT_Root * " Root ", NDT_Node ** " Node " );"
.LP
.RS 3
Cette fonction permet de recuperer le dernier noeud d'une structure.
.LP
Elle doit recevoir les arguments suivants :
.LP
.RS 3
* (In)
.I Root
: un pointeur sur la racine de la structure
.LP
* (Out)
.I Node
: un pointeur sur le dernier noeud a recuperer
.RS -3
.LP
.RS -3
.BI "NDT_Status ND_Node_Next_Get ( NDT_Node * " Node ", NDT_Node ** " Next_Node " );"
.LP
.RS 3
Cette fonction permet de recuperer le noeud qui suit immediatement un noeud particulier.
.LP
Elle doit recevoir les arguments suivants :
.LP
.RS 3
* (In)
.I Node
: un pointeur sur le noeud de reference
.LP
* (Out)
.I Next_Node
: l'adresse d'un pointeur sur le noeud qui suit le noeud de reference
.RS -3
.LP
.RS -3
.BI "NDT_Status ND_Node_Previous_Get ( NDT_Node * " Node ", NDT_Node ** " Prev_Node " );"
.LP
.RS 3
Cette fonction permet de recuperer le noeud qui precede immediatement un noeud particulier.
.LP
Elle doit recevoir les arguments suivants :
.LP
.RS 3
* (In)
.I Node
: un pointeur sur le noeud de reference
.LP
* (Out)
.I Prev_Node
: l'adresse d'un pointeur sur le noeud qui precede le noeud de reference
.RS -3
.LP
.RS -3
.BI "NDT_Status ND_Node_Add ( NDT_Root * " Root ", NDT_Node * " Node " );"
.LP
.RS 3
Cette fonction permet d'ajouter un noeud a une structure.
.LP
Elle doit recevoir les arguments suivants :
.LP
.RS 3
* (In)
.I Root
: un pointeur sur la racine de la structure de donnees
.LP
* (In)
.I Node
: un pointeur sur le noeud a ajouter
.RS -3
.LP
.RS -3
.BI "NDT_Status ND_Node_Remove ( NDT_Node * " Node " );"
.RS 3
.LP
Cette fonction permet de supprimer le noeud d'une structure de donnees.
.LP
L'argument
.I Node
est un pointeur sur le noeud a supprimer
.LP
.I NB
: le noeud supprime n'est pas detruit mais simplement detache de la structure
.LP
.RS -3
.BI "NDT_Status ND_Node_Find ( NDT_Root * " Root ", NDT_Node ** " Node ", void * " Value " , void * " Data " );"
.LP
.RS 3
Cette fonction permet de rechercher dans une structure de donnees le premier noeud correspondant a une valeur.
.LP
Elle doit recevoir les arguments suivants :
.LP
.RS 3
* (In)
.I Root
: un pointeur sur la racine de la structure de donnees
.LP
* (Out)
.I Node
: l'adresse d'un pointeur sur le noeud resultat
.LP
* (In)
.I Value
: un pointeur sur la valeur a rechercher
.LP
* (In)
.I Data
: un pointeur de donnees qui sera passe a la fonction manager pour la recherche
.RS -3
.LP
.RS -3
.LP
.BI "NDT_Status ND_Value_Alloc ( NDT_Root * " Root ", void ** " Value ", ... );"
.LP
.RS 3
Cette fonction permet d'allouer une valeur pour une structure de donnees.
.LP
Elle doit recevoir les arguments suivants :
.LP
.RS 3
* (In)
.I Root
: un pointeur sur la racine de la structure de donnees
.LP
* (Out)
.I Value
: l'adresse d'un pointeur sur la valeur a allouer
.LP
* (In)
.I ...
: des arguments supplementaires pour l'allocation de la valeur
.RS -3
.LP
.RS -3
.BI "NDT_Status ND_Value_Add ( NDT_Root * " Root ", void * " Value " );"
.LP
.RS 3
Cette fonction permet d'ajouter une valeur a une structure de donnees.
.LP
Elle doit recevoir les arguments suivants :
.LP
.RS 3
* (In)
.I Root
: un pointeur sur la racine de la structure de donnees
.LP
* (In)
.I Value
: un pointeur sur la valeur a ajouter
.RS -3
.LP
.RS -3
.BI "NDT_Status ND_Value_Remove ( NDT_Root * " Root ", void * " Reference_Value " , void ** " Removed_Value " );"
.RS 3
.LP
Cette fonction permet de supprimer le premier noeud correspondant a une valeur.
.LP
Elle doit recevoir les arguments suivants :
.RS 3
.LP
* (In)
.I Root
: un pointeur sur la racine de la structure de donnees
.LP
* (In)
.I Reference_Value
: un pointeur sur la valeur de reference
.LP
* (Out)
.I Removed_Value
: l'adresse d'un pointeur sur la valeur du noeud supprime
.LP
.RS -3
.I NB
: la suppression d'un noeud implique son retrait de la structure et sa desallocation.
.LP
Si la structure contient plusieurs fois la valeur, seul le premier noeud correspondant a cette valeur est detruit.
.LP
.RS -3
.BI "NDT_Status ND_Value_Free ( NDT_Root * " Root ", void * " Value " );"
.LP
.RS 3
Cette fonction permet de desallouer une valeur faisant partie d'une structure de donnees.
.LP
Elle doit recevoir les arguments suivants :
.LP
.RS 3
* (In)
.I Root
: un pointeur sur la racine de la structure de donnees
.LP
* (In)
.I Value
: un pointeur sur la valeur a desallouer
.RS -3
.LP
.RS -3
.BI "NDT_Status ND_Manager_Exec (const char * " Function_Name ", ...)"
.LP
.RS 3
Cette fonction permet d'executer une fonction manager a partir de son nom.
.LP
L'argument
.I Function_Name
est le nom de la fonction manager (fonction de type
.B NDT_Manager
), suivi de tous les arguments contextuels necessaires a son execution.
.LP
.RS -3
.BI "NDT_Status ND_Allocator_Exec (const char * " Function_Name ", void ** " Ptr ", size_t " Size ", void * " Data " );"
.LP
.RS 3
Cette fonction permet d'executer une fonction d'allocation a partir de son nom.
.LP
Elle doit recevoir les arguments suivants :
.RS 3
.LP
* (In)
.I Function_Name
: le nom de la fonction d'allocation (fonction de type
.B NDT_Allocator
)
.LP
* (Out)
.I Ptr
: l'adresse d'un pointeur sur la zone a allouer
.LP
* (In)
.I Size
: la taille a allouer
.LP
* (In)
.I Data
: un pointeur de donneees utile a la fonction d'allocation
.RS -3
.LP
.RS -3
.BI "NDT_Status ND_Desallocator_Exec (const char * " Function_Name ", void * " Ptr ", void * " Data " );"
.LP
.RS 3
Cette fonction permet d'executer une fonction de desallocation a partir de son nom.
.LP
Elle doit recevoir les arguments suivants :
.RS 3
.LP
* (In)
.I Function_Name
: le nom de la fonction de desallocation (fonction de type
.B NDT_Desallocator
)
.LP
* (In)
.I Ptr
: l'adresse de la zone memoire a desallouer
.LP
* (In)
.I Data
: un pointeur de donneees utile a la fonction de desallocation
.RS -3
.LP
.RS -3
.SH CODES RETOUR
.LP
Toutes les fonctions constituant l'API de la librairie LIBND retournent un code de type
.B NDT_Status
:
.LP
.RS 3
-
.B NDS_OK
: la fonction s'est correctement executee et a produit un resultat
.LP
-
.B NDS_KO
: la fonction s'est correctement executee mais n'a pas produit de resultat
.LP
-
.B NDS_ERRAPI
: la fonction a ete appelee avec des arguments de valeur incorrecte
.LP
-
.B NDS_ERRMEM
: la fonction ne s'est pas correctement executee pour un probleme d'allocation memoire
.RS -3
.LP
La macro
.B ND_ERROR(rc)
permet de tester si un code retour correspond a une erreur.
.LP
En cas d'erreur, la variable ND_Error_Msg contient un message du type :
.LP
.RS 3
Error <Nom fonction> : <message d'erreur>
.RS -3
.LP
Lorsque le manager est appele avec la commande
.B NDD_CMD_COMP_VALUE
(comparaison de valeurs), l'une des trois valeurs suivantes est retournee :
.RS 3
.LP
-
.B NDS_EQUAL
.LP
-
.B NDS_LOWER
.LP
-
.B NDS_GREATER
.LP
.RS -3
.LP
.SH VOIR AUSSI
.B libdatastr
(3)

461
include/node.h Normal file
View File

@ -0,0 +1,461 @@
#ifndef _LIBNODE
#define _LIBNODE
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
#include <ver.h>
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/*
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 int NDT_DataStruct_Type;
#define NDD_DS_LIST 0001 /* liste chaînée */
#define NDD_DS_TREE 0002 /* arbre binaire */
#define NDD_DS_MSK (NDD_DS_LIST | NDD_DS_TREE)
#define ND_IS_LIST(r) ((r)->Type & NDD_DS_LIST)
#define ND_IS_TREE(r) ((r)->Type & NDD_DS_TREE)
#define NDD_MN_FIFO 0010 /* principe de la file d'attente (First In First Out) */
#define NDD_MN_LILO NDD_MN_FIFO
#define NDD_MN_FILO 0020 /* principe de la pile (First In Last Out) */
#define NDD_MN_LIFO NDD_MN_FILO
#define NDD_MN_ORDERED 0040 /* liste triée */
#define NDD_MN_AUTO_EQU 0100 /* arbre auto-équilibré */
#define NDD_MN_MSK (NDD_MN_FIFO | NDD_MN_FILO | NDD_MN_ORDERED | NDD_MN_AUTO_EQU)
#define ND_IS_FIFO(r) ((r)->Type & NDD_MN_FIFO)
#define ND_IS_FILO(r) ((r)->Type & NDD_MN_FILO)
#define ND_IS_ORDERED(r) ((r)->Type & NDD_MN_ORDERED)
#define ND_IS_AUTO_EQU(r) ((r)->Type & NDD_MN_AUTO_EQU)
/* Commandes du manager */
typedef int NDT_Command;
#define NDD_CMD_MAKE_VALUE 1
#define NDD_CMD_COMP_VALUE 2
#define NDD_CMD_SUM_VALUES 3
#define NDD_CMD_PRINT_VALUE 4
#define NDD_CMD_DELETE_VALUE 5
#define NDD_CMD_PRINT_INFO 6
/* Types de réponse du manager ou code retour des diverses fonctions */
typedef int NDT_Status;
#define ND_ERROR(s) ((s) < 0) /* Tous les codes retour négatifs correspondent à des erreurs */
#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 */
/* Pointeur de fonction sur le manager */
typedef NDT_Status NDT_Manager (va_list);
/* Pointeur de fonction sur l'allocateur */
typedef NDT_Status NDT_Allocator (size_t, void **, void *);
/* Pointeur de fonction sur le désallocateur */
typedef NDT_Status NDT_Desallocator (void *, void *);
/* Structure racine */
typedef struct NDT_Root {
NDT_DataStruct_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 */
char Manager [50]; /* Nom de la fonction manager */
char Allocator [50]; /* Nom de la fonction d'allocation */
char Desallocator [50]; /* Nom de la fonction de désallocation */
struct NDT_Node * Head; /* Noeud de tête */
struct NDT_Node * Queue; /* Noeud de queue */
struct NDT_Node * Save; /* Pointeur de sauvegarde (utile pour la fonction de restauration) */
void * User; /* Pointeur utilisable librement par l'utilisateur */
short int Own_Value; /* Indique si la structure est propriétaire de ses valeurs */
} NDT_Root;
/* Structure de noeud */
typedef struct NDT_Node {
struct NDT_Root * Root;
struct NDT_Node * Parent;
struct NDT_Node * Left;
struct NDT_Node * Right;
void * Value;
} NDT_Node;
char ND_Error_Msg [512];
/* 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_Reorg ND_DataStruct_Reorg_I
#define ND_DataStruct_Traverse ND_DataStruct_Traverse_I
#define ND_DataStruct_Convert ND_DataStruct_Convert_I
#define ND_DataStruct_Info_Print ND_DataStruct_Info_Print_I
#define ND_DataStruct_Print ND_DataStruct_Print_I
#define ND_DataStruct_Check ND_DataStruct_Check_I
#define ND_DataStruct_Dump ND_DataStruct_Dump_I
#define ND_Node_Root_Get ND_Node_Root_Get_I
#define ND_Node_First_Get ND_Node_First_Get_I
#define ND_Node_Last_Get ND_Node_Last_Get_I
#define ND_Node_Next_Get ND_Node_Next_Get_I
#define ND_Node_Previous_Get ND_Node_Previous_Get_I
#define ND_Node_Add ND_Node_Add_I
#define ND_Node_Remove ND_Node_Remove_I
#define ND_Node_Find ND_Node_Find_I
#define ND_Value_Alloc ND_Value_Alloc_I
#define ND_Value_Add ND_Value_Add_I
#define ND_Value_Remove ND_Value_Remove_I
#define ND_Value_Free ND_Value_Free_I
#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_Reorg ND_DataStruct_Reorg_C
#define ND_DataStruct_Traverse ND_DataStruct_Traverse_C
#define ND_DataStruct_Convert ND_DataStruct_Convert_C
#define ND_DataStruct_Info_Print ND_DataStruct_Info_Print_C
#define ND_DataStruct_Print ND_DataStruct_Print_C
#define ND_DataStruct_Check ND_DataStruct_Check_C
#define ND_DataStruct_Dump ND_DataStruct_Dump_C
#define ND_Node_Root_Get ND_Node_Root_Get_C
#define ND_Node_First_Get ND_Node_First_Get_C
#define ND_Node_Last_Get ND_Node_Last_Get_C
#define ND_Node_Next_Get ND_Node_Next_Get_C
#define ND_Node_Previous_Get ND_Node_Previous_Get_C
#define ND_Node_Add ND_Node_Add_C
#define ND_Node_Remove ND_Node_Remove_C
#define ND_Node_Find ND_Node_Find_C
#define ND_Value_Alloc ND_Value_Alloc_C
#define ND_Value_Add ND_Value_Add_C
#define ND_Value_Remove ND_Value_Remove_C
#define ND_Value_Free ND_Value_Free_C
#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
/*------------------------------------------------------------------------------*/
/* Initialisation du contexte de la librairie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Library_Open_I ( int Debug_Mode );
NDT_Status ND_Library_Open_C ( int Debug_Mode );
/*------------------------------------------------------------------------------*/
/* Fermeture du contexte de la librairie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Library_Close_I ( void );
NDT_Status ND_Library_Close_C ( void );
/*------------------------------------------------------------------------------*/
/* Définition de la sortie standard des messages d'erreur de la librairie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Library_Stderr_Set_I ( FILE * Out );
NDT_Status ND_Library_Stderr_Set_C ( FILE * Out );
/*------------------------------------------------------------------------------*/
/* Création d'une nouvelle structure de données */
/*------------------------------------------------------------------------------*/
/* (O) Root: adresse d'un pointeur sur la racine de la nouvelle structure */
/* (I) Type: type de la structure.de données (liste ou arbre binaire) */
/* (I) Allocator: pointeur vers la fonction d'allocation */
/* (I) Desallocator: pointeur vers la fonction de désallocation */
/* (I) Data : pointeur de données utiles à l'allocateur */
/* (I) Own_Value : indique si la structure est propriétaire de ses valeurs */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Open_I ( NDT_Root ** Root, NDT_DataStruct_Type Type, \
const char * Allocator, \
const char * Desallocator, \
void * Data, int Own_Value );
NDT_Status ND_DataStruct_Open_C ( NDT_Root ** Root, NDT_DataStruct_Type Type, \
const char * Allocator, \
const char * Desallocator, \
void * Data, int Own_Value );
/*------------------------------------------------------------------------------*/
/* Destruction d'une structure de données */
/*------------------------------------------------------------------------------*/
/* (O) Root: pointeur sur la racine de la structure de données */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Close_I ( NDT_Root * Root );
NDT_Status ND_DataStruct_Close_C ( NDT_Root * Root );
/*------------------------------------------------------------------------------*/
/* Réorganisation d'une structure de données : */
/* - ordonnancement d'une liste non ordonnée */
/* - réquilibrage d'un arbre non auto-équilibré */
/*------------------------------------------------------------------------------*/
/* (I) Root: pointeur sur la racine de la structure de données */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Reorg_I ( NDT_Root * Root );
NDT_Status ND_DataStruct_Reorg_C ( NDT_Root * Root );
/*------------------------------------------------------------------------------*/
/* Parcours de tous les noeuds d'une structure de données et exécution d'une */
/* commande sur chacun d'eux */
/*------------------------------------------------------------------------------*/
/* (I) Root: pointeur sur la racine de la structure de données */
/* (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, NDT_Command Command, \
void * Data );
NDT_Status ND_DataStruct_Traverse_C ( NDT_Root * Root, NDT_Command Command, \
void * Data );
/*------------------------------------------------------------------------------*/
/* Conversion d'une structure de données d'un type en un autre */
/*------------------------------------------------------------------------------*/
/* (I) Root: pointeur sur la racine de la structure de données */
/* (I) Target_Type: type de structure cible */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Convert_I ( NDT_Root * Root, \
NDT_DataStruct_Type Target_Type );
NDT_Status ND_DataStruct_Convert_C ( NDT_Root * Root, \
NDT_DataStruct_Type Target_Type );
/*------------------------------------------------------------------------------*/
/* Affichage d'informations sur une structure de données */
/*------------------------------------------------------------------------------*/
/* (I) Root: pointeur sur la racine de la structure de données */
/* (I) Out : flux de sortie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Info_Print_I ( NDT_Root * Root, FILE * Out );
NDT_Status ND_DataStruct_Info_Print_C ( NDT_Root * Root, FILE * Out );
/*------------------------------------------------------------------------------*/
/* 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 */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Print_I ( NDT_Root * Root, FILE * Out );
NDT_Status ND_DataStruct_Print_C ( NDT_Root * Root, FILE * 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 */
/* (O) Nb_Corrected : pointeur sur le nombre d'erreurs */
/* (I) Out : flux de sortie du rapport */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Check_I ( NDT_Root * Root, int * Nb_Detected, \
int * Nb_Corrected, FILE * Out );
NDT_Status ND_DataStruct_Check_C ( NDT_Root * Root, int * Nb_Detected, \
int * Nb_Corrected, FILE * Out );
/*------------------------------------------------------------------------------*/
/* Affiche la structure de données et ses informations statistiques */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure */
/* (I) Out : flux de sortie */
/*------------------------------------------------------------------------------*/
NDT_Status ND_DataStruct_Dump_I ( NDT_Root * Root, FILE * Out );
NDT_Status ND_DataStruct_Dump_C ( NDT_Root * Root, FILE * Out );
/*------------------------------------------------------------------------------*/
/* Récupération de la racine d'une structure */
/*------------------------------------------------------------------------------*/
/* (O) Root: Adresse du pointeur sur la racine à récupérer */
/* (I) Node: pointeur sur le noeud dont on cherche la racine */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Node_Root_Get_I ( NDT_Root ** Root, NDT_Node * Node );
NDT_Status ND_Node_Root_Get_C ( NDT_Root ** Root, NDT_Node * 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 */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Node_First_Get_I ( NDT_Root * Root, NDT_Node ** Node );
NDT_Status ND_Node_First_Get_C ( NDT_Root * Root, NDT_Node ** Node );
/*------------------------------------------------------------------------------*/
/* 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 */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Node_Last_Get_I ( NDT_Root * Root, NDT_Node ** Node );
NDT_Status ND_Node_Last_Get_C ( NDT_Root * Root, NDT_Node ** Node );
/*------------------------------------------------------------------------------*/
/* 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 */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Node_Next_Get_I ( NDT_Node * Node, NDT_Node ** Next_Node );
NDT_Status ND_Node_Next_Get_C ( NDT_Node * Node, NDT_Node ** Next_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 */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Node_Previous_Get_I ( NDT_Node * Node, NDT_Node **Prev_Node );
NDT_Status ND_Node_Previous_Get_C ( NDT_Node * Node, NDT_Node **Prev_Node );
/*------------------------------------------------------------------------------*/
/* Ajout d'un noeud à une structure de données */
/*------------------------------------------------------------------------------*/
/* (I) Root: pointeur sur la racine de la structure de données */
/* (I) Node: pointeur sur le noeud à ajouter */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Node_Add_I ( NDT_Root * Root, NDT_Node * Node );
NDT_Status ND_Node_Add_C ( NDT_Root * Root, NDT_Node * Node );
/*------------------------------------------------------------------------------*/
/* Suppression d'un noeud dans une structure de données */
/*------------------------------------------------------------------------------*/
/* (I) Node: pointeur sur le noeud à supprimer de la structure de données */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Node_Remove_I ( NDT_Node * Node);
NDT_Status ND_Node_Remove_C ( NDT_Node * 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 */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Node_Find_I ( NDT_Root * Root, NDT_Node ** Node, void * Value, void * Data );
NDT_Status ND_Node_Find_C ( NDT_Root * Root, NDT_Node ** Node, void * Value, void * Data );
/*------------------------------------------------------------------------------*/
/* Allocation d'une valeur d'une structure de données */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de données */
/* (O) Value : adresse d'un pointeur sur la valeur à allouer */
/* (I) ... : arguments relatifs à l'allocation de la valeur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Value_Alloc_I ( NDT_Root * Root, void ** Value, ... );
NDT_Status ND_Value_Alloc_C ( NDT_Root * Root, void ** Value, ... );
/*------------------------------------------------------------------------------*/
/* 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 */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Value_Add_I ( NDT_Root * Root, void * Value );
NDT_Status ND_Value_Add_C ( NDT_Root * Root, void * Value );
/*------------------------------------------------------------------------------*/
/* Suppression du premier noeud correspondant à une valeur donnée */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de la structure de données */
/* (I) Reference_Value : pointeur sur la valeur de référence */
/* (I) Removed_Value : adresse d'un pointeur sur la valeur supprimée */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Value_Remove_I ( NDT_Root * Root, void * Reference_Value, void ** Removed_Value );
NDT_Status ND_Value_Remove_C ( NDT_Root * Root, void * Reference_Value, void ** Removed_Value );
/*------------------------------------------------------------------------------*/
/* Désallocation d'une valeur d'une structure de données */
/*------------------------------------------------------------------------------*/
/* (I) Root: pointeur sur la racine de la structure de données */
/* (I) Value: pointeur sur la valeur à désallouer */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Value_Free_I ( NDT_Root * Root, void * Value );
NDT_Status ND_Value_Free_C ( NDT_Root * Root, void * Value );
/*------------------------------------------------------------------------------*/
/* Exécution d'une fonction Manager dont le nom est passé en paramètre */
/*------------------------------------------------------------------------------*/
/* (I) Function : nom de la fonction manager à exécuter */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Manager_Exec_I ( const char * Function, ... );
NDT_Status ND_Manager_Exec_C ( const char * Function, ... );
/*------------------------------------------------------------------------------*/
/* 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 */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Allocator_Exec_I ( const char * Function, void ** Ptr, \
size_t Size, void * Data );
NDT_Status ND_Allocator_Exec_C ( const char * Function, void ** Ptr, \
size_t Size, void * Data );
/*------------------------------------------------------------------------------*/
/* 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) Ptr : adresse de la zone à désallouer */
/* (I) Data : pointeur de données utiles au désallocateur */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Desallocator_Exec_I ( const char * Function, void * Ptr, \
void * Data );
NDT_Status ND_Desallocator_Exec_C ( const char * Function, void * Ptr, \
void * Data );
#ifdef __cplusplus
}
#endif
#endif

2674
lib/libnode.c Normal file

File diff suppressed because it is too large Load Diff

243
lib/libnode.h Normal file
View File

@ -0,0 +1,243 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <dlfcn.h>
#include <node.h>
#define HUGE_LONG 0xFFFFFFL
#ifndef min
#define min(A,B) ((A > B) ? B : A)
#endif
#ifndef max
#define max(A,B) ((A < B) ? B : A)
#endif
/* Sortie standard des messages d'erreur */
FILE * ND_stderr;
/* Table des symboles locale */
struct Symbol {
void * Ptr;
char * Name;
struct Symbol * Next;
} * Symbol_Table = NULL;
NDT_Root * Tmp_Root;
extern char * strdup (const char *);
extern int sigrelse (int sig);
int Sig_Trapped;
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* 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 Default_Manager (va_list Arguments);
/*------------------------------------------------------------------------------*/
/* Redéfinition de la fonction malloc() avec retour de type NDT_Status */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Malloc (size_t Size, void ** ptr, void * User);
/*------------------------------------------------------------------------------*/
/* Redéfinition de la fonction free() avec retour de type NDT_Status */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Free (void * ptr);
/*------------------------------------------------------------------------------*/
/* 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 * Root, NDT_Node * Node);
/*------------------------------------------------------------------------------*/
/* 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_Root_Alloc (NDT_Root ** Root, NDT_DataStruct_Type Type, \
const char * Allocator, const char * Desallocator, \
void * Data);
/*------------------------------------------------------------------------------*/
/* Destruction d'une racine */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine à détruire */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Root_Free (NDT_Root * 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 * Root, NDT_Node * New_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 * Root, void * Value);
/*------------------------------------------------------------------------------*/
/* Ajout d'un noeud à un arbre binaire */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de l'arbre */
/* (I) Value : pointeur sur la valeur à ajouter */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Tree_Value_Add (NDT_Root * Root, void * Value);
/*------------------------------------------------------------------------------*/
/* Supprime le noeud d'une liste */
/*------------------------------------------------------------------------------*/
/* (I) Node : pointeur sur le noeud à supprimer */
/*------------------------------------------------------------------------------*/
NDT_Status ND_List_Node_Remove (NDT_Node * 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 * Root);
/*------------------------------------------------------------------------------*/
/* Recherche une valeur dans une liste et retourne le noeud correspondant */
/*------------------------------------------------------------------------------*/
NDT_Node * ND_List_Node_Find (NDT_Root * Root, void * Value, void * Data);
/*------------------------------------------------------------------------------*/
/* Recherche un noeud dans un arbre et retourne le pointeur sur le noeud */
/*------------------------------------------------------------------------------*/
NDT_Node * ND_Tree_Node_Find (NDT_Root * Root, void * Value, void * Data);
/*------------------------------------------------------------------------------*/
/* 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 * Root);
/*------------------------------------------------------------------------------*/
/* Equilibrage d'un arbre */
/*------------------------------------------------------------------------------*/
/* (I) Root : pointeur sur la racine de l'arbre */
/*------------------------------------------------------------------------------*/
NDT_Status ND_Tree_Equalize (NDT_Root * Root);
/*------------------------------------------------------------------------------*/
/* 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);
/*------------------------------------------------------------------------------*/
/* 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);
/*------------------------------------------------------------------------------*/
/* 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 * Root, NDT_Node * 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 * Tree_Root, NDT_Root * List_Root);
/*------------------------------------------------------------------------------*/
/* Fonction de comparaison de noeuds (pour le quick sort) */
/*------------------------------------------------------------------------------*/
int ND_Node_Compare (void ** Node1, void ** Node2);
/*------------------------------------------------------------------------------*/
/* 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 * Root);
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* Fonctions et procédures privées de la librairie (bas niveau) */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
void ND_List_Check (NDT_Root *, int *, int *, FILE *);
void ND_List_Link_Check (NDT_Root *, int *, int *, FILE *);
void ND_Value_Check (NDT_Root *, int *, int *, FILE *);
void ND_Tree_Check (NDT_Root *, int *, int *, FILE *);
void ND_Tree_Link_Check (NDT_Root *, int *, int *, FILE *);
NDT_Status ND_List_Recursive_Make (NDT_Node *, NDT_Root *);
NDT_Node * ND_Tree_Recursive_Make (long, long, NDT_Node *);
void ND_Tree_Node_Recursive_Add (NDT_Root *, NDT_Node *, NDT_Node **, long , NDT_Node *);
NDT_Node * ND_Tree_Node_First_Recursive_Get (NDT_Node * Node);
NDT_Node * ND_Tree_Node_Last_Recursive_Get (NDT_Node * Node);
NDT_Node * ND_Tree_Node_Recursive_Find (NDT_Node * Node, void * Value, void * Data);
NDT_Node * ND_Tree_Parent_Next_Recursive_Get (NDT_Node * Node);
NDT_Node * ND_Tree_Parent_Previous_Recursive_Get (NDT_Node * Node);
void ND_Tree_Recursive_Print (NDT_Node * Node, long Depth, FILE *);
void ND_Tree_Link_Recursive_Check (NDT_Node * Node, int *, int *, FILE *);
void * ND_Symbol_Find (const char *);
void ND_Error_Print (void);
void ND_Signal_Trap (int);
NDT_Status ND_Address_Check (void * Address);

469
util/ndbench.c Normal file
View File

@ -0,0 +1,469 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <stdarg.h>
#define ND_MODE 1
#include <node.h>
VER_INFO_EXPORT (ndbench, "$Revision: 1.1 $", "$Name: $", __FILE__, "$Author: smas $")
#define USAGE "Usage : %s [ --help | --version [-v] ]\n"
#define QUIT 0
#define ADD_VALUE 1
#define REMOVE_VALUE 2
#define FIND_VALUE 3
#define CHG_LIST_TYPE 4
#define CONVERT_TO_TREE 5
#define CONVERT_TO_LIST 6
#define REORG 7
#define INFO 8
#define SHOW 9
#define CHECK 10
char menu [1000];
char buf [100];
NDT_Root * Root;
long int random (void);
NDT_Status Module_Manager (va_list);
void init_menu (void);
int print_menu (void);
extern char * strdup (const char *);
/* Mesure des temps d'exécution */
typedef struct {
double sec;
struct timeval start;
struct timeval stop;
} cpt;
#define t_start(x){ gettimeofday (&(x.start), NULL);}
#define t_stop(x){ gettimeofday (&(x.stop), NULL); x.sec = (double)(x.stop.tv_sec) - (double)(x.start.tv_sec) + ((double)(x.stop.tv_usec) - (double)(x.start.tv_usec)) / 1000000;}
cpt t_exec;
/* Définition des valeurs attachées aux noeuds de la structure */
typedef struct {
int Id;
char * Nom;
} T_Module;
int main (int argc, char ** argv)
{
char * tmp;
int n, m, i, j, choice, nb_removed, Nb_Detected, Nb_Corrected;
T_Module Ref_Module, * Module;
int Debug = TRUE;
/* Lancement de commande en mode batch */
if (argc >= 2)
{
if (!strcmp (argv[1], "--help"))
{
fprintf (stderr, USAGE, argv[0]);
return 1;
}
else if (!strcmp (argv[1], "--version"))
{
if (argc >= 3 && !strcmp (argv[2], "-v"))
return VER_Object_Print (stdout, VERD_VERBOSE);
else
return VER_Object_Print (stdout, VERD_MINIMAL);
}
else
{
fprintf (stderr, USAGE, argv[0]);
return 0;
}
}
/* Lancement du menu intercatif */
ND_Library_Open (Debug);
printf ("\nCréation d'une structure de type liste FIFO...\n");
ND_DataStruct_Open (&Root, NDD_DS_LIST | NDD_MN_FIFO, NULL, NULL, NULL, TRUE);
strcpy (Root->Manager, "Module_Manager");
choice = print_menu ();
while (choice != QUIT)
{
switch (choice)
{
case FIND_VALUE:
fprintf (stdout, "\nPlage de recherche (?->?) : ");
gets (buf);
tmp = strstr (buf, "->");
if (tmp != NULL)
{
*tmp = '\0';
n = atoi (buf);
tmp++;
tmp++;
m = atoi (tmp);
if (m < n)
{
printf ("\nEntrées non valides\n");
break;
}
}
else
{
printf ("\nEntrées non valides\n");
break;
}
i = n;
j = m + 1;
t_start (t_exec);
while (i < j)
{
NDT_Node *Node;
Ref_Module.Id = n + (random () % m);
ND_Node_Find (Root, &Node, &Ref_Module, NULL);
i++;
}
t_stop (t_exec);
fprintf (stdout, "\n%d valeur(s) recherchée(s) en %.4f sec (%.2f select/sec)\n",\
m - n + 1, t_exec.sec, (m - n + 1) / t_exec.sec );
break;
case ADD_VALUE:
fprintf (stdout, "\nPlage des valeurs à ajouter (?->?) : ");
gets (buf);
tmp = strstr (buf, "->");
if (tmp != NULL)
{
*tmp = '\0';
n = atoi (buf);
tmp++;
tmp++;
m = atoi (tmp);
if (m < n)
{
printf ("\nEntrées non valides\n");
break;
}
}
else
{
printf ("\nEntrées non valides\n");
break;
}
fprintf (stdout, "\nOrdre d'ajout (croissant=0 décroissant=1) ? ");
gets (buf);
choice = atoi (buf);
if (choice == 0)
{
i = n;
j = m + 1;
t_start (t_exec);
while (i < j)
{
if (ND_Value_Alloc (Root, (void **)&Module, "x", i) == NDS_OK)
ND_Value_Add (Root, Module);
i++;
}
t_stop (t_exec);
}
else
{
i = m;
j = n - 1;
t_start (t_exec);
while (i > j)
{
if (ND_Value_Alloc (Root, (void **)&Module, "x", i) == NDS_OK)
ND_Value_Add (Root, Module);
i--;
}
t_stop (t_exec);
}
fprintf (stdout, "\n%d valeur(s) ajoutée(s) en %.4f sec (%.2f ajouts/sec)\n", \
m - n + 1, t_exec.sec, (m - n + 1) / t_exec.sec );
break;
case REMOVE_VALUE:
nb_removed = 0;
fprintf (stdout, "\nPlage des valeurs à supprimer (?->?) : ");
gets (buf);
tmp = strstr (buf, "->");
if (tmp != NULL)
{
*tmp = '\0';
n = atoi (buf);
tmp++;
tmp++;
m = atoi (tmp);
if (m < n)
{
printf ("\nEntrées non valides\n");
break;
}
}
else
{
printf ("\nEntrées non valides\n");
break;
}
fprintf (stdout, "\nOrdre de suppression (croissant=0 décroissant=1) ? ");
gets (buf);
choice = atoi (buf);
if (choice == 0)
{
i = n;
j = m + 1;
t_start (t_exec);
while (i < j)
{
Ref_Module.Id = i;
if (ND_Value_Remove (Root, &Ref_Module, (void **)&Module) == NDS_OK)
{
nb_removed++;
ND_Value_Free (Root, Module);
}
i++;
}
t_stop (t_exec);
}
else
{
i = m;
j = n - 1;
t_start (t_exec);
while (i > j)
{
Ref_Module.Id = i;
if (ND_Value_Remove (Root, &Ref_Module, (void **)&Module) == NDS_OK)
{
nb_removed++;
ND_Value_Free (Root, Module);
}
i--;
}
t_stop (t_exec);
}
fprintf (stdout, "\n%d valeur(s) supprimée(s) en %.4f sec (%.2f suppressions/sec)\n", \
m - n + 1, t_exec.sec, (m - n + 1) / t_exec.sec );
break;
case CHG_LIST_TYPE:
fprintf (stdout, "\nType de liste (FIFO=0 ; FILO=1 ; triée=2) ? ");
gets (buf);
choice = atoi (buf);
switch (choice)
{
case 0:
Root->Type = NDD_DS_LIST | NDD_MN_FIFO;
break;
case 1:
Root->Type = NDD_DS_LIST | NDD_MN_FILO;
break;
case 2:
Root->Type = NDD_DS_LIST | NDD_MN_ORDERED;
break;
default:
printf ("\nChoix non valide\n");
break;
}
break;
case REORG:
t_start (t_exec);
ND_DataStruct_Reorg (Root);
t_stop (t_exec);
fprintf (stdout, "\nRéorganisation de la structure en %.4f sec\n", t_exec.sec);
break;
case CONVERT_TO_LIST:
t_start (t_exec);
ND_DataStruct_Convert (Root, NDD_DS_LIST | NDD_MN_ORDERED);
t_stop (t_exec);
fprintf (stdout, "\nConversion arbre vers liste en %.4f sec\n", t_exec.sec);
break;
case CONVERT_TO_TREE:
t_start (t_exec);
ND_DataStruct_Convert (Root, NDD_DS_TREE | NDD_MN_AUTO_EQU);
t_stop (t_exec);
fprintf (stdout, "\nConversion liste vers arbre en %.4f sec\n", t_exec.sec);
break;
case INFO:
ND_DataStruct_Info_Print (Root, stdout);
break;
case SHOW:
ND_DataStruct_Dump (Root, stdout);
break;
case CHECK:
Nb_Corrected = Nb_Detected = 0;
ND_DataStruct_Check (Root, &Nb_Detected, &Nb_Corrected, stderr);
break;
default:
fprintf (stdout, "\nChoix %d non défini\n", choice);
}
choice = print_menu ();
}
fprintf (stdout, "\nDestruction de la structure... ");
printf ("%s\n\n", (ND_DataStruct_Close (Root) == NDS_OK ? "OK" : "NOK"));
ND_Library_Close ();
return 0;
}
NDT_Status Module_Manager (va_list args_ptr)
{
NDT_Command Command = (NDT_Command)va_arg (args_ptr, NDT_Command);
if (Command == NDD_CMD_MAKE_VALUE)
{
NDT_Root * Current_Root = va_arg (args_ptr, NDT_Root *);
T_Module ** Module = va_arg (args_ptr, T_Module **);
va_list Args = va_arg (args_ptr, va_list);
char * Nom = va_arg (Args, char *);
int Id = va_arg (Args, int);
*Module = (T_Module *)malloc (sizeof (T_Module));
(*Module)->Nom = strdup (Nom);
(*Module)->Id = Id;
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_VALUE)
{
T_Module * Module = (T_Module *)va_arg (args_ptr, void *);
FILE * Out = va_arg (args_ptr, FILE *);
fprintf (Out, "Id=%d\tNom=\"%s\"", Module->Id, Module->Nom);
return NDS_OK;
}
if (Command == NDD_CMD_DELETE_VALUE)
{
NDT_Root * Current_Root = va_arg (args_ptr, NDT_Root *);
T_Module * Module = (T_Module *)va_arg (args_ptr, void *);
free (Module->Nom);
free (Module);
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_INFO)
{
NDT_Root * Current_Root = va_arg (args_ptr, NDT_Root *);
FILE * Out = va_arg (args_ptr, FILE *);
char Root_Type[100];
switch ((int) (Current_Root->Type & NDD_DS_MSK))
{
case NDD_DS_LIST :
switch ((int) (Current_Root->Type & NDD_MN_MSK))
{
case NDD_MN_ORDERED : strcpy (Root_Type, "liste triée"); break;
case NDD_MN_FILO : strcpy (Root_Type, "liste FILO"); break;
case NDD_MN_FIFO : strcpy (Root_Type, "liste FIFO"); break;
default: strcpy (Root_Type, "inconnu"); break;
}
break;
case NDD_DS_TREE :
switch ((int) (Current_Root->Type & NDD_MN_MSK))
{
case NDD_MN_AUTO_EQU : strcpy (Root_Type, "arbre auto-équilibré"); break;
default: strcpy (Root_Type, "arbre non auto-équilibré"); break;
}
break;
default: strcpy (Root_Type, "inconnu"); break;
}
fprintf (Out, "\nStructure de type %s :\n\t- Nombre de noeuds = %ld\n", Root_Type, Current_Root->Node_Number);
if ((Current_Root->Type & NDD_DS_MSK) == NDD_DS_TREE)
fprintf (Out, "\t- Profondeur maxi = %ld\n\t- Profondeur mini = %ld\n\t- Différence maximale autorisée = %ld\n\t- Nombre d'équilibrages = %ld\n", \
Current_Root->Max_Depth, Current_Root->Min_Depth, Current_Root->Max_Dif, Current_Root->Nb_Equ);
return (NDS_OK);
}
if (Command == NDD_CMD_COMP_VALUE)
{
T_Module * Value1, * Value2;
long comp;
Value1 = (T_Module *)va_arg (args_ptr, void *);
Value2 = (T_Module *)va_arg (args_ptr, void *);
va_end (args_ptr);
comp = Value1->Id - Value2->Id;
if (comp < 0) return NDS_LOWER;
if (comp > 0) return NDS_GREATER;
return NDS_EQUAL;
}
va_end (args_ptr);
return (NDS_OK);
}
void init_menu (void)
{
sprintf (menu, "Menu :\n");
sprintf (buf, "\t- %d) %-30s\n", QUIT, "Quitter"); strcat (menu, buf);
sprintf (buf, "\t- %d) %-30s", ADD_VALUE, "Ajout de valeurs"); strcat (menu, buf);
sprintf (buf, "\t- %d) %-30s\n", REMOVE_VALUE, "Suppression de valeurs"); strcat (menu, buf);
sprintf (buf, "\t- %d) %-30s\n", FIND_VALUE, "Recherche de valeurs aléatoires"); strcat (menu, buf);
if (ND_IS_LIST(Root))
{
sprintf (buf, "\t- %d) %-30s", CHG_LIST_TYPE, "Changement de type de liste"); strcat (menu, buf);
sprintf (buf, "\t- %d) %-30s\n", CONVERT_TO_TREE, "Conversion en arbre"); strcat (menu, buf);
}
else
{
sprintf (buf, "\t- %d) %-30s\n", CONVERT_TO_LIST, "Conversion en liste triée"); strcat (menu, buf);
}
sprintf (buf, "\t- %d) %-30s\n", REORG, "Réorganisation"); strcat (menu, buf);
sprintf (buf, "\t- %d) %-30s", INFO, "Informations sur la structure"); strcat (menu, buf);
sprintf (buf, "\t- %d) %-30s\n", SHOW, "Affichage de la structure"); strcat (menu, buf);
sprintf (buf, "\t- %d) %-30s\n", CHECK, "Vérification de la structure"); strcat (menu, buf);
}
int print_menu (void)
{
int choice;
init_menu ();
fprintf (stdout, "\n-----------------------------------------------------------------------\n");
fprintf (stdout, menu);
*buf = (char)0;
while (!*buf)
{
printf ("\nChoice ? ");
gets (buf);
}
choice = atoi (buf);
return choice;
}

BIN
util/ndbench.xls Normal file

Binary file not shown.