commit 74e8ad8e7f1602e4f118e4fedde48df7a6adac27
parent 6bba0ec8dc617d4f59aeda294d4c7282a31e4e47
Auteur: Loïc Daignault-Pichette <loic@asteride.xyz>
Date: Tue, 7 Apr 2026 10:40:11 -0400
Augmenter et mieux documenter tampex
Les fonctions tampex_empl() et tampex_dpl() ont été ajoutées pour simplifier
l’ajout et le retrait d’éléments en fin de tampon. Les fonctions susceptible de
déplacer un tampon prennent maintenant un double pointeur, ce qui leur permet
de rendre ce déplacement plus subtile.
Diffstat:
| M | tampex.c | | | 102 | +++++++++++++++++++++++++++++++++++++++++++++++++------------------------------ |
| M | tampex.h | | | 28 | ++++++++++++++++++++-------- |
2 fichiers modifiés, 84 insertions(+), 46 suppressions(-)
diff --git a/tampex.c b/tampex.c
@@ -9,7 +9,7 @@
#define ENTETE(te) ((Entete *)te - 1)
/* Calculer l’adresse du tampon d’un tampex. */
-#define TAMPON(ent) (ent + 1)
+#define TAMPON(ent) ((void *)(ent + 1))
/* Tester la cohérence d’un tampex. */
#define TAMPINF_COHERENT(te) \
@@ -25,16 +25,16 @@
/* La structure du tampon extensible a été conçue pour que son utilisation
* ressemble le plus possible à celle des tampons renvoyés par malloc(3). C’est
* donc sous cette forme qu’ils se présentent à l’utilisateur. Or, une partie
- * de la réalité lui est cachée, car sous le tampon qui lui est renvoyé se
- * trouve une entête contenant l’information nécessaire au bon fonctionnement
- * des fonctions de cette bilbiothèque: la taille des éléments du tampon,
- * exprimée en octets, la longueur du tampon, excluant l’entête et exprimée en
- * multiples de la taille, et enfin le nombre d’éléments que contient le
- * tampon. */
+ * de la réalité lui est cachée, car immédiatement sous le tampon qui lui est
+ * renvoyé se trouve une entête contenant l’information nécessaire au bon
+ * fonctionnement des fonctions de cette bilbiothèque: la taille des éléments
+ * du tampon, exprimée en octets, la longueur du tampon, excluant l’entête et
+ * exprimée en multiples de la taille, et enfin le nombre d’éléments que
+ * contient le tampon. */
/* Entête d’un tampex.
* L’union assure que l’entête occupe un multiple de sizeof(long) octets. Cette
- * solution vient de la seconde édition de The C Programming Language. */
+ * solution vient de la seconde édition de « The C Programming Language ». */
typedef union entete {
struct {
size_t tll; /* Taille des éléments. */
@@ -68,54 +68,58 @@ tampex_init(size_t lngr, size_t tll)
}
void
-tampex_reinit(void *ti)
+tampex_reinit(void *te)
{
- TAMPINF_COHERENT(ti);
+ TAMPINF_COHERENT(te);
- memset(ti, 0, ENTETE(ti)->s.tll * ENTETE(ti)->s.lngr);
+ /* Il faut réinitialiser tout le tampon, non seulement la portion sous
+ * nelem, puisque nelem peut diminuer. Par exemple, tampex_dpl() retire
+ * un élément sans le réinitialiser à zéro. */
+ memset(te, 0, ENTETE(te)->s.tll * ENTETE(te)->s.lngr);
- ENTETE(ti)->s.nelem = 0;
+ ENTETE(te)->s.nelem = 0;
}
void
-tampex_libr(void *ti)
+tampex_libr(void *te)
{
- TAMPINF_COHERENT(ti);
+ TAMPINF_COHERENT(te);
- free(ENTETE(ti));
+ free(ENTETE(te));
}
-void *
-tampex_minim(void *ti, size_t i)
+ssize_t
+tampex_minim(void **te, size_t i)
{
size_t nlngr; /* Nouvelle longueur. */
Entete *nent; /* Nouvelle entête. */
size_t nnelem; /* Nouveau nombre d’éléments. */
- TAMPINF_COHERENT(ti);
+ assert(te);
+ TAMPINF_COHERENT(*te);
/* Mettre à jour le nombre d’éléments, mais ne pas lui permettre de
* décroître. */
- nnelem = ENTETE(ti)->s.nelem;
+ nnelem = ENTETE(*te)->s.nelem;
if (nnelem < i + 1)
nnelem = i + 1;
/* Ne pas agrandir le tampon s’il est déjà assez grand. */
- if (ENTETE(ti)->s.lngr > i) {
- ENTETE(ti)->s.nelem = nnelem;
- TAMPINF_COHERENT(ti);
- return ti;
+ if (ENTETE(*te)->s.lngr > i) {
+ ENTETE(*te)->s.nelem = nnelem;
+ TAMPINF_COHERENT(*te);
+ return i;
}
/* Doubler la longueur jusqu’à ce qu’elle soit supérieure ou égale à la
* longueur recherchée. */
- for (nlngr = ENTETE(ti)->s.lngr; nlngr <= i; nlngr *= 2)
+ for (nlngr = ENTETE(*te)->s.lngr; nlngr <= i; nlngr *= 2)
;
- /* Agrandir le tampon et en initialiser à zéro la nouvelle partie. */
- if ((nent = realloc(ENTETE(ti),
- sizeof(Entete) + nlngr * ENTETE(ti)->s.tll)) == NULL)
- return NULL;
+ /* Agrandir le tampon et initialiser à zéro la nouvelle partie. */
+ if ((nent = realloc(ENTETE(*te),
+ sizeof(Entete) + nlngr * ENTETE(*te)->s.tll)) == NULL)
+ return -1;
memset((char *)TAMPON(nent) + nent->s.lngr * nent->s.tll, 0,
(nlngr - nent->s.lngr) * nent->s.tll);
nent->s.lngr = nlngr;
@@ -123,31 +127,53 @@ tampex_minim(void *ti, size_t i)
TAMPINF_COHERENT(TAMPON(nent));
- return TAMPON(nent);
+ *te = TAMPON(nent);
+
+ return i;
+}
+
+ssize_t
+tampex_empl(void **te)
+{
+ assert(te);
+ TAMPINF_COHERENT(*te);
+
+ return tampex_minim(te, ENTETE(*te)->s.nelem);
+}
+
+size_t
+tampex_dpl(void *te)
+{
+ TAMPINF_COHERENT(te);
+
+ /* Il doit rester quelque chose à dépiler. */
+ assert(ENTETE(te)->s.nelem > 0);
+
+ return --ENTETE(te)->s.nelem;
}
size_t
-tampex_nelem(void *ti)
+tampex_nelem(void *te)
{
- TAMPINF_COHERENT(ti);
+ TAMPINF_COHERENT(te);
- return ENTETE(ti)->s.nelem;
+ return ENTETE(te)->s.nelem;
}
size_t
-tampex_esp(void *ti)
+tampex_esp(void *te)
{
- TAMPINF_COHERENT(ti);
+ TAMPINF_COHERENT(te);
- return ENTETE(ti)->s.nelem * ENTETE(ti)->s.tll;
+ return ENTETE(te)->s.nelem * ENTETE(te)->s.tll;
}
bool
-tampex_dedans(void *ti, size_t i)
+tampex_dedans(void *te, size_t i)
{
- TAMPINF_COHERENT(ti);
+ TAMPINF_COHERENT(te);
- if (i < ENTETE(ti)->s.nelem)
+ if (i < ENTETE(te)->s.nelem)
return 1;
return 0;
}
diff --git a/tampex.h b/tampex.h
@@ -12,7 +12,7 @@
/* Initialiser un tampon pouvant contenir au moins lngr objets de tll octets
* chacun.
- * Le tampon est initialisé à zéro.
+ * Le contenu du tampon est initialisé à zéro.
* Renvoie le tampon, ou NULL en cas d’erreur. */
void *tampex_init(size_t lngr, size_t tll);
@@ -24,13 +24,25 @@ void tampex_reinit(void *te);
void tampex_libr(void *te);
/* Assurer que le tampon te soit assez grand pour contenir un élément à l’index
- * i.
- * Renvoie l’adresse du tampon, ou NULL en cas d’erreur.
- * Il est possible, si le tampex doit être agrandi, que le tampon doivent être
- * déplacé. Il est donc important de toujours sauvegarder l’adresse renvoyée.
- * Il s’en suit aussi que toute référence au contenu d’un tampex doit être
- * relative à la position en mémoire du tampon. */
-void *tampex_minim(void *te, size_t i);
+ * i et l’agrandir si nécessaire.
+ * Renvoie i, ou -1 en cas d’erreur.
+ * En cas d’erreur, *te est laissé intact.
+ * Le champ nelem du tampex est augmenté à i + 1, si cette nouvelle valeur le
+ * fait vraiment augmenter. Il est possible, si le tampex doit être agrandi,
+ * que le tampon doive être déplacé. te est alors modifié en conséquence. Il
+ * s’en suit que toute référence au contenu d’un tampex doit être relative à la
+ * position en mémoire du tampon. */
+ssize_t tampex_minim(void **te, size_t i);
+
+/* Augmenter nelem d’un et agrandir le tampon si besoin.
+ * Renvoie le nombre d’éléments contenus dans le tampon, ou -1 en cas
+ * d’erreur. */
+ssize_t tampex_empl(void **te);
+
+/* Diminuer nelem d’un.
+ * Renvoie l’indice de l’éléments dépilé.
+ * Prend pour acquis que le tampex contient au moins un élément. */
+size_t tampex_dpl(void *te);
/* Obtenir le nombre d’éléments contenus dans le tampon te.
* Ce nombre correspond à la valeur de i la plus élevée donnée à