Documentation de CListes.c

par Jean-Luc Mounier
Laboratoire d'Informatique de Paris 6

SOMMAIRE

Types

CListe
Fonctions de création, destruction
ListeInit
CreerListe
ViderListe
DetruireListe
Fonctions d'ajout, suppression
AjoutListe
AjoutFinListe
AjoutUListe
AjoutUFinListe
EnleveElement
EnleveElementSiExiste
Fonctions diverses
ChercheElement
ListePremier
ListeDernier
UnSeulElement
NbElementListe
Fonctions de parcours
ParcoursListe
ParcoursInverse
ParcoursInsereAvant
ParcoursSuivant
ParcoursPrecedent
EnleveElementCourant
Fonctions d'accès rapide
FindInList
Fonction de hachage
LiNew

Le module CListes.c fait partie de la librairie libTools.a, il contient les primitives de gestion de listes.

Introduction

Le module CListes.c gère des listes de pointeurs de données sans aucune connaissance de l'élément pointé (void *). Ces éléments ne sont connus que par leurs accés: ajout, parcours recherche.

Pour utiliser les CListes inclure le fichier CListes.h précédé de Types.h pour la définition du type Boolean (ou FkBoolean si FRAME_KIT est défini). (à revoir).

Types

CListe

CListe est un pointeur sur une tête de liste créée par CreerListe.

P_ListElem

P_ListElem est un pointeur sur une structure interne du gestionnaire de liste correspondant à un élément ajouté dans une liste.

ParcoursProcPtr

ParcoursProcPtr est un pointeur sur une fonction appelée lors des parcours de listes.

#include <CListes.h>
typedef void *(*ParcoursProcPtr)(void *pData, ...);

pData

Le pointeur sur la donnée en cours dans la liste.

...

Jusqu'à 8 paramètre de type pointeurs

LiDataType

LiDataType indique si la donnée est de type pointeur ou handle (pointeur de pointeur).

#include <CListes.h>
typedef enum { IS_HANDLE=true, IS_POINTER=false } LiDataType;

Fonctions de création, destruction

ListeInit

Initialisation du module de gestion des listes, à n'appeler qu'une seule fois en début de programme.

PROTOTYPE

#include <CListes.h>
void ListeInit(void);

Attention:

Si vous développez dans l'environnement FrameKit, ListeInit a déjà été appelé.


CreerListe

CreerListe crée une liste et rend le pointeur sur la tête de liste.

PROTOTYPE

#include <CListes.h>
CListe CreerListe(void);

RÉSULTAT

Pointeur vers la structure de donnée décrivant une liste. NULL si on ne peut pas allouer de la mémoire.

CAS D'ERREURS

  • NULL si on ne peut pas allouer de la mémoire.

Attention:

Si CreerListe rend une erreur, si vous développez dans l'environnement FrameKit la fonction FkAbort est appelée sinon c'est directement abort() sauf sur MacOS ou un message d'erreur est affiché dans la fenêtre d'historique.

Voir aussi la création de listes avec table de hachage.


ViderListe

ViderListe vide la liste mais ne supprime pas les éléments. On obtient une liste comme celle après CreerListe.

PROTOTYPE

#include <CListes.h>
void ViderListe(CListe cListe);

cListe

la liste à vider.

RÉSULTAT

pas de résultat.

CAS D'ERREURS

  • cListe est NULL.
  • cListe n'est pas un pointeur de liste.
  • On est en train de parcourir cette liste (voir les parcours de liste).

Attention:

Si la fonction rend une erreur, si vous développez dans l'environnement FrameKit la fonction FkAbort est appelée sinon c'est directement abort() sauf sur MacOS ou un message d'erreur est affiché dans la fenêtre d'historique.


DetruireListe

DetruireListe détuit la tête de liste. Cela libère la mémoire utilisée par CreerListe.

PROTOTYPE

#include <CListes.h>
void DetruireListe(CListe cListe);

cListe

la liste à détruire.

RÉSULTAT

pas de résultat.

CAS D'ERREURS

  • cListe est NULL.
  • cListe n'est pas un pointeur de liste.
  • cListe n'est pas vide.

Attention:

Si la fonction rend une erreur, si vous développez dans l'environnement FrameKit la fonction FkAbort est appelée sinon c'est directement abort() sauf sur MacOS ou un message d'erreur est affiché dans la fenêtre d'historique.

Fonctions d'ajout, suppression

AjoutListe

AjoutListe ajoute l'élément pData au début de la liste cListe.

PROTOTYPE

#include <CListes.h>
P_ListElem AjoutListe(CListe cListe,void *pData);

cListe

la liste.

pData

Le pointeur sur la donnée à ajouter dans la liste.

RÉSULTAT

Pointeur sur un élément de liste (structure de donnée interne au gestionnaire de liste).

CAS D'ERREURS

  • cListe est NULL.
  • cListe n'est pas un pointeur de liste.
  • pData est NULL.
  • Il n'y a plus de mémoire disponible.

Attention:

Si la fonction rend une erreur, si vous développez dans l'environnement FrameKit la fonction FkAbort est appelée sinon c'est directement abort() sauf sur MacOS ou un message d'erreur est affiché dans la fenêtre d'historique.


AjoutFinListe

AjoutFinListe ajoute l'élément pData à la fin de la liste cListe.

PROTOTYPE

#include <CListes.h>
P_ListElem AjoutFinListe(CListe cListe,void *pData);

cListe

la liste.

pData

Le pointeur sur la donnée à ajouter dans la liste.

RÉSULTAT

Pointeur sur un élément de liste (structure de donnée interne au gestionnaire de liste).

CAS D'ERREURS

  • cListe est NULL.
  • cListe n'est pas un pointeur de liste.
  • pData est NULL.
  • Il n'y a plus de mémoire disponible.

Attention:

Si la fonction rend une erreur, si vous développez dans l'environnement FrameKit la fonction FkAbort est appelée sinon c'est directement abort() sauf sur MacOS ou un message d'erreur est affiché dans la fenêtre d'historique.


AjoutUListe

AjoutUListe est similaire à AjoutListe mais il ajoute pData de manière unique (que si le pointeur sur la donnée n'est pas déjà dans la liste).

PROTOTYPE

#include <CListes.h>
FkBoolean AjoutUListe(CListe cListe,void *pData);

RÉSULTAT

rend kFk_True si l'élément a été ajouté à la liste.

CAS D'ERREURS

voir AjoutListe.

Attention:

La fonction ne compare pas le contenu pointé par hDonnee elle vérifie si le même pointeur se trouve dèjà dans la liste.


AjoutUFinListe

AjoutUFinListe est similaire à AjoutFinListe mais il ajoute pData de manière unique (que si le pointeur sur la donnée n'est pas déjà dans la liste).

PROTOTYPE

#include <CListes.h>
FkBoolean AjoutUFinListe(CListe cListe,void *pData);

RÉSULTAT

rend kFk_True si l'élément a été ajouté à la liste.

CAS D'ERREURS

voir AjoutListe.

Attention:

La fonction ne compare pas le contenu pointé par hDonnee elle vérifie si le même pointeur se trouve déjà dans la liste.


EnleveElement

EnleveElement supprime l'élement pData de la liste. Cette fonction ne doit être appelée que si vous savez que l'élément appartient bien à la liste sinon il faut utiliser EnleveElementSiExiste.

PROTOTYPE

#include <CListes.h>
void EnleveElement(CListe cListe,void *pData);

cListe

la liste.

pData

Le pointeur sur la donnée à enlever de la liste.

RÉSULTAT

Aucun.

CAS D'ERREURS

  • cListe est NULL.
  • cListe n'est pas un pointeur de liste.
  • l'élément n'appartient pas à la liste.

Attention:

Si la fonction rend une erreur, si vous développez dans l'environnement FrameKit la fonction FkAbort est appelée sinon c'est directement abort() sauf sur MacOS ou un message d'erreur est affiché dans la fenêtre d'historique.


EnleveElementSiExiste

EnleveElementSiExiste supprime l'élement pData de la liste si il existe.

PROTOTYPE

#include <CListes.h>
FkBoolean EnleveElementSiExiste(CListe cListe,void *pData);

cListe

la liste.

pData

Le pointeur sur la donnée à enlever de la liste.

RÉSULTAT

rend kFk_True si l'élément a été enlevé de à la liste.

CAS D'ERREURS

  • cListe est NULL.
  • cListe n'est pas un pointeur de liste.

Attention:

Si la fonction rend une erreur, si vous développez dans l'environnement FrameKit la fonction FkAbort est appelée sinon c'est directement abort() sauf sur MacOS ou un message d'erreur est affiché dans la fenêtre d'historique.

Fonctions diverses

ChercheElement

ChercheElement cherche un élement dans la liste si il existe.

PROTOTYPE

#include <CListes.h>
P_ListElem ChercheElement(CListe cListe,void *pData);

cListe

la liste.

pData

Le pointeur sur la donnée recherchée.

RÉSULTAT

Pointeur sur un élément de liste (structure de donnée interne au gestionnaire de liste) ou NULL si l'élément n'est pas trouvé.

CAS D'ERREURS

Pas de test d'erreur.

ListePremier

ListePremier rend le premier élément de la liste.

PROTOTYPE

#include <CListes.h>
void * ListePremier(CListe cListe);

cListe

la liste.

RÉSULTAT

Pointeur la première donnée disponible dans la liste ou NULL la liste est vide.

CAS D'ERREURS

  • cListe est NULL.
  • cListe n'est pas un pointeur de liste.

Attention:

Si la fonction rend une erreur, si vous développez dans l'environnement FrameKit la fonction FkAbort est appelée sinon c'est directement abort() sauf sur MacOS ou un message d'erreur est affiché dans la fenêtre d'historique.


ListeDernier

ListeDernier rend le dernier élément de la liste.

PROTOTYPE

#include <CListes.h>
void * ListeDernier(CListe cListe);

cListe

la liste.

RÉSULTAT

Pointeur la dernière donnée disponible dans la liste ou NULL la liste est vide.

CAS D'ERREURS

  • cListe est NULL.
  • cListe n'est pas un pointeur de liste.

Attention:

Si la fonction rend une erreur, si vous développez dans l'environnement FrameKit la fonction FkAbort est appelée sinon c'est directement abort() sauf sur MacOS ou un message d'erreur est affiché dans la fenêtre d'historique.


UnSeulElement

UnSeulElement rend vrai si il n'y a qu'un seul élément dans la liste.

PROTOTYPE

#include <CListes.h>
FkBoolean UnSeulElement(CListe cListe);

cListe

la liste.

RÉSULTAT

rend kFk_True si il n'y a qu'un seul élément dans la liste.

CAS D'ERREURS

  • cListe est NULL.
  • cListe n'est pas un pointeur de liste.

Attention:

Si la fonction rend une erreur, si vous développez dans l'environnement FrameKit la fonction FkAbort est appelée sinon c'est directement abort() sauf sur MacOS ou un message d'erreur est affiché dans la fenêtre d'historique.


NbElementListe

NbElementListe rend ne nombre d'élement de la liste.

PROTOTYPE

#include <CListes.h>
short NbElementListe(CListe cListe);

cListe

la liste.

RÉSULTAT

le nombre d'élement de la liste.

CAS D'ERREURS

  • cListe est NULL.
  • cListe n'est pas un pointeur de liste.

Attention:

Si la fonction rend une erreur, si vous développez dans l'environnement FrameKit la fonction FkAbort est appelée sinon c'est directement abort() sauf sur MacOS ou un message d'erreur est affiché dans la fenêtre d'historique.

Fonctions de parcours

ParcoursListe

ParcoursListe permet de parcourir une liste en appelant une fonction Action passée en paramètre pour chaque élement de la liste.
La fonction ParcoursListe a un nombre paramètres variable (deux paramètres oblicatoires et 8 paramètres facultatifs).
La fonction Action est appelée avec comme premier paramètre, un pointeur sur l'élement de la liste et les paramètres facultatifs passés à ParcoursListe.
Dans la fonction appelée (Action), il faut indiquer si on veut arrêter le parcours ou si on continue. Pour continuer le parcours, la fonction Action doit rendre NULL. Dans ce cas, la fonction Action est appelée avec l'élément suivant de la liste.

PROTOTYPE

#include <CListes.h>
void ParcoursListe(CListe cListe,ParcoursProcPtr Action,...);

cListe

la liste à parcourir.

Action

Fonction à appeler pour chaque élément

...

Jusqu'à 8 paramètre de type pointeurs

RÉSULTAT

  • Lorsque l'on arrête le parcours, le résultat de ParcoursListe sera le résultat de la fonction Action.
  • Si on continue le parcours jursqu'à la fin de la liste, ParcoursListe rend NULL.

CAS D'ERREURS

  • cListe est NULL.
  • cListe n'est pas un pointeur de liste.

Attention:

Si la fonction rend une erreur, si vous développez dans l'environnement FrameKit la fonction FkAbort est appelée sinon c'est directement abort() sauf sur MacOS ou un message d'erreur est affiché dans la fenêtre d'historique.

CONSIDÉRATIONS

Il faut noter qu'il est possible de supprimer des éléments et d'en ajouter à une liste pendant le parcours de cette même liste.

Voir Exemple d'utilisation en Annexe 1.


ParcoursInverse

ParcoursInverse est similaire à ParcoursListe sauf que le parcours se fait à partir de la fin de la liste en ordre inverse.

PROTOTYPE

#include <CListes.h>
void ParcoursInverse(CListe cListe,ParcoursProcPtr Action,...);

cListe

la liste à parcourir.

Action

Fonction à appeler pour chaque élément

...

Jusqu'à 8 paramètre de type pointeurs

RÉSULTAT

CAS D'ERREURS


ParcoursInsereAvant

Pendant les ParcoursListe, un pointeur sur l'élément courant est maintenu. La fonction ParcoursInsereAvant utilise ce pointeur. ParcoursInsereAvant insère l'élément pData avant l'élément courant (permet par exemple de fabriquer une liste d'élément rangés par ordre aphabétique).

PROTOTYPE

#include <CListes.h>
void ParcoursInverse(void *pData);

pData

Le pointeur sur la donnée à ajouter dans la liste.

RÉSULTAT

  • aucun.

CAS D'ERREURS

  • On n'est pas en ParcoursListe.
  • Il n'y a plus de mémoire.

Attention:

Ces fonctions n'ayant pas de référence vers la CListe, elle font appel à une variable globale unique (index), ces fonctions doivent donc être appelée qu'en début d'Action (ParcoursProcPtr) avant tout autre ParcoursListe.

CONSIDÉRATIONS

la variable globale (index) n'est maintenue à la sortie de ParcoursListe, ainsi que par ListePremier et ListeDernier. Attention, la fonction ParcoursSuivant ne change pas la valeur de l'index.


ParcoursSuivant

Pendant les ParcoursListe, un pointeur sur l'élément courant est maintenu. La fonction ParcoursSuivant utilise ce pointeur. ParcoursSuivant rend l'élément suivant de la liste parcourue.

PROTOTYPE

#include <CListes.h>
void *ParcoursSuivant(void);

RÉSULTAT

  • l'élément suivant.

CAS D'ERREURS

  • On n'est pas en ParcoursListe.

Attention:

Ces fonctions n'ayant pas de référence vers la CListe, elle font appel à une variable globale unique (index), ces fonctions doivent donc être appelée qu'en début d'Action (ParcoursProcPtr) avant tout autre ParcoursListe.

CONSIDÉRATIONS

la variable globale (index) n'est maintenue à la sortie de ParcoursListe, ainsi que par ListePremier et ListeDernier. Attention, la fonction ParcoursSuivant ne change pas la valeur de l'index.


ParcoursPrecedent

Pendant les ParcoursListe, un pointeur sur l'élément courant est maintenu. La fonction ParcoursPrecedent utilise ce pointeur. ParcoursPrecedent rend l'élément précédent de la liste parcourue.

PROTOTYPE

#include <CListes.h>
void *ParcoursPrecedent(void);

RÉSULTAT

  • l'élément précédent.

CAS D'ERREURS

  • On n'est pas en ParcoursListe.

Attention:

Ces fonctions n'ayant pas de référence vers la CListe, elle font appel à une variable globale unique (index), ces fonctions doivent donc être appelée qu'en début d'Action (ParcoursProcPtr) avant tout autre ParcoursListe.

CONSIDÉRATIONS

la variable globale (index) n'est maintenue à la sortie de ParcoursListe, ainsi que par ListePremier et ListeDernier. Attention, la fonction ParcoursSuivant ne change pas la valeur de l'index.


EnleveElementCourant

Pendant les ParcoursListe, un pointeur sur l'élément courant est maintenu. La fonction EnleveElementCourant utilise ce pointeur. EnleveElementCourant enlève de la liste l'élément en cours.

PROTOTYPE

#include <CListes.h>
void EnleveElementCourant(void);

RÉSULTAT

  • enlève l'élément, aucun résultat.

CAS D'ERREURS

  • On n'est pas en ParcoursListe.
  • L'élément a déjà été supprimé.

Attention:

Ces fonctions n'ayant pas de référence vers la CListe, elle font appel à une variable globale unique (index), ces fonctions doivent donc être appelée qu'en début d'Action (ParcoursProcPtr) avant tout autre ParcoursListe.

Fonctions d'accès rapide

Le principe des fonctions d'accès rapide est le suivant :

  • On suppose que les pointeurs stockées dans la liste pointent vers des éléments de même type.
  • Dans ce cas, il est possible de rechercher une donnée dans la structure pointée.

Ces procédures sont particulièrement adaptées à rechercher une donnée numérique dans une liste.
Dans l'exemple ci-dessus, la donnée recherchée se trouve dans chaque structure pointée à une distance : offset du début de la structure. La donnée pointée à une taille size.

FindInList

FindInList recherche dans la liste cListe, la première donnée pointée par pRecherche de taille size et à la distance offset du début de chaque élément de la liste.

PROTOTYPE

#include <CListes.h>
void *FindInList(CListe cListe,LiDataType isHandle
const void *pRecherche,size_t size,size_t offset);

cListe

la liste à parcourir pour la recherche.

isHandle

Booléen indiquant si les pointeurs contenus dans la cListe sont des pointeurs simple ou des Handle (au sens MacOS), c'est à dire des pointeurs de pointeurs.

pRecherche

Pointeur sur la donnée recherchée.

size

Taille de la donnée recherchée.

offset

Distance entre le début de la structure de chaque élément de la liste et la position de la donnée recherchée.

RÉSULTAT

  • Pointeur sur l'élément trouvé ou NULL.

CAS D'ERREURS

  • cListe est NULL.
  • cListe n'est pas un pointeur de liste.

Attention:

Il est interdit de comparer une zone plus grande qu'un champs d'une structure car des champs successifs ne sont pas forcément ni successifs, ni consécutifs en mémoire (cela dépends des machines et des compilateurs).
Voir Exemple d'utilisation en Annexe 2.

Fonction de hachage

Le principe des fonctions d'accès rapide est le suivant : On suppose que les pointeurs stockées dans la liste pointent vers des éléments de même type.
Actuellement le seul algorithme de hachage a été implémenté pour un accès à des données numériques (typiquement des numéro CAMI dans Macao et FrameKit).

Pour utiliser les listes hachées, la seule différence est la création de la liste. Il faut utiliser LiNew au lieu de CreerListe. Les autres fonctions sont identiques par contre la fonction la plus accélérée est FindInList.

LiListType

LiListType défini le type de liste : liste standard ou listes avec hachage sur donnée numérique de type long.

#include <CListes.h>
typedef enum { LiStandard=0, LiHashULong } LiListType;

LiNew

LiNew crée une liste avec table de hachage et rend le pointeur sur la tête de liste.

PROTOTYPE

#include <CListes.h>
CListe LiNew(LiListType liListType, LiDataType isHandle,size_t offset);

RÉSULTAT

Pointeur vers la structure de donnée décrivant une liste. NULL si on ne peut pas allouer de la mémoire.

CAS D'ERREURS

  • NULL si on ne peut pas allouer de la mémoire.

Attention:

Si la fonction rend une erreur, si vous développez dans l'environnement FrameKit la fonction FkAbort est appelée sinon c'est directement abort() sauf sur MacOS ou un message d'erreur est affiché dans la fenêtre d'historique.


Annexe 1

Ajout et recherche d'éléments dans une liste

struct Data
	{
	short		a;		// first element
	short		b;		// second element
	}
typedef struct Data Data;
typedef Data *PData; 
static void AddElement(CListe cListe,short a,short b)
	{
	PData		pData;
	pData=(PData)NewPtr(sizeof(Data));	// équivalent à malloc
	if (pData==NULL) { ERREUR("No more memory"); return; }
	pData->a=a;
	pData->b=b;
	AjoutListe(cListe, pData);
	} 
	static void *Cherche(PData pData,short *pValue)
		{
		if (pData->b == *pValue) return(pData);
		return(NULL);
		} 
// main
{
PData	pData;
short	value;
CListe	cListe;	// head of liste global variable
ListeInit();		// only once
cListe=CreerListe();	// init
AddElement(cListe, 1, 100);
AddElement(cListe, 2, 123);
AddElement(cListe, 3, 456);
// recherche l'élément dont la deuxième composante b=123
value=123; // pour en passer l'adresse
pData=ParcoursListe(cListe, (ParcoursProcPtr)Cherche, &value);

// va appeler Cherche successivement avec comme pData d3 puis d2
// la valeur recherchée sera trouvée pour d2 donc pData<-d2
// traiter l'élément

ViderListe(cListe);
Attention, les éléments ne sont pas détruits, pour les détruire, au lieu d'appeler ViderListe:
•	soit faire un ParcoursListe en appelant EnleveElement sur chaque élément.
•	soit faire une boucle EnleveElement(cListe ,ListePremier(cListe));
	tant que ListePremier(cListe) non nul 
DetruireListe(cListe);
// Attention cListe ne pointe plus sur une liste !

}

Annexe 2

Recherche du premier élément dont la valeur b est égale à 123.

struct Data
	{
	short		a;		// first element
	short		b;		// second element
	}
typedef struct Data Data;
typedef Data *PData; 
{
PData	pData;
short	value;
value=123; // pour en passer l'adresse
pData = FindInList(cListe, false, &value, sizeof(short),  (size_t)&pData->b - (size_t)pData); }

API de Framekit en C | FrameKit
Mise à jour : Version originale 03-mars-1988 puis 03-mai-1993
Mise à jour : 04-nov-1999