commit 2d372e4ae1dfe438d0d8500dcf914b5b77290fdd
parent 4c845ad81e7ded88b812e4d0a5bfb0da386a06db
Auteur: Loïc Daignault-Pichette <loic@asteride.xyz>
Date: Wed, 8 Apr 2026 21:52:07 -0400
Interpréter le segmenteur
Diffstat:
| M | interp.c | | | 29 | +++++++++++++++++++++++++++-- |
| M | itfd.c | | | 67 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- |
| M | itfd.h | | | 15 | ++++++++++++--- |
3 fichiers modifiés, 99 insertions(+), 12 suppressions(-)
diff --git a/interp.c b/interp.c
@@ -1,19 +1,44 @@
#include <fcntl.h>
#include <stddef.h>
-/*#include <stdio.h>*/
+#include <stdio.h>
+#include <string.h>
#include "itfd.h"
int
-main(void)
+main(int argc, char **argv)
{
int df;
struct itfd *itfd;
+ uint16_t symbs[256];
+ size_t nsymbs;
+ size_t lngr;
+ size_t i;
if ((df = open("a", O_RDONLY)) < 0)
return 1;
if ((itfd = itfd_ouvrir(df)) == NULL)
return 1;
+ if (argc != 2)
+ return 1;
+
+ if ((lngr = strlen(argv[1])) > 256)
+ return 1;
+
+ nsymbs = segmenter(itfd, (uint8_t *)argv[1], lngr, symbs);
+
+ for (i = 0; i < nsymbs; i++) {
+ if (symbs[i] & 0x01) {
+ printf("*%c (%d)\n", symbs[i] >> 1, symbs[i] >> 1);
+ } else {
+ fwrite(itfd->symbs + 1 + (symbs[i] >> 1),
+ 1,
+ itfd->symbs[symbs[i] >> 1],
+ stdout);
+ printf(" (%d)\n", symbs[i] >> 1);
+ }
+ }
+
return 0;
}
diff --git a/itfd.c b/itfd.c
@@ -8,8 +8,7 @@
#include "itfd.h"
#include "tfd.h"
-#include <stdio.h>
-
+/* Lire du tampon tp au décalage dec 16 ou 32 bits. */
#define LIRE_16(tp, dec) (*(uint16_t *)((tp) + (dec)))
#define LIRE_32(tp, dec) (*(uint32_t *)((tp) + (dec)))
@@ -56,16 +55,16 @@ itfd_ouvrir(int df)
goto erreur2;
/* Lire les informations sur les segments. */
- itfd->symbs_pos = itfd->f + LIRE_32(itfd->f, 0x06);
+ itfd->symbs = itfd->f + LIRE_32(itfd->f, 0x06);
itfd->symbs_lngr = LIRE_32(itfd->f, 0x0A);
- itfd->segm_pos = itfd->f + LIRE_32(itfd->f, 0x0E);
+ itfd->segm = itfd->f + LIRE_32(itfd->f, 0x0E);
itfd->segm_lngr = LIRE_32(itfd->f, 0x12);
- itfd->trans_pos = itfd->f + LIRE_32(itfd->f, 0x16);
+ itfd->trans = itfd->f + LIRE_32(itfd->f, 0x16);
itfd->trans_lngr = LIRE_32(itfd->f, 0x1A);
- if (itfd->symbs_pos + itfd->symbs_lngr != itfd->segm_pos)
+ if (itfd->symbs + itfd->symbs_lngr != itfd->segm)
goto erreur2;
- //if (itfd->segm_pos + itfd->segm_lngr != itfd->trans_pos)
+ //if (itfd->segm + itfd->segm_lngr != itfd->trans)
//goto erreur2;
return itfd;
@@ -91,3 +90,57 @@ itfd_fermer(struct itfd *itfd)
return 0;
}
+
+size_t
+segmenter(struct itfd *itfd, uint8_t *cc, size_t lngrcc, uint16_t *symbs)
+{
+ size_t i, pi; /* Indice et prochain indice dans le segmenteur. */
+ uint16_t base, orig;
+ uint16_t (*segm)[2];
+ uint8_t *prch; /* Fin du dernier symbole trouvé. */
+ uint8_t *fin; /* Fin de cc. */
+ int symb; /* Identifiant du dernier symbole trouvé. */
+ size_t nsymbs; /* Nombre de symboles. */
+
+ assert(itfd);
+ assert(cc);
+
+ fin = cc + lngrcc;
+ segm = (uint16_t (*)[2])itfd->segm;
+ nsymbs = 0;
+
+ while (cc < fin) {
+ symb = (*cc << 1) | 0x01;
+ prch = cc + 1;
+
+ for (i = 0; cc < fin; cc++) {
+ pi = (segm[i][0] >> 1) + *cc;
+
+ base = segm[pi][0];
+ orig = segm[pi][1];
+
+ /* Vérifier. */
+ if (orig & 0x01 || orig >> 0x01 != i) {
+ cc = prch;
+ break;
+ }
+
+ i = pi;
+
+ /* Si état final. */
+ if (base & 0x01) {
+ i = base >> 1;
+ orig = segm[i][1];
+ symb = (orig >> 1) << 1;
+ prch = cc + 1;
+ }
+ }
+
+ cc = prch;
+ *symbs++ = symb;
+ nsymbs++;
+ }
+
+ assert(nsymbs <= lngrcc);
+ return nsymbs;
+}
diff --git a/itfd.h b/itfd.h
@@ -10,11 +10,11 @@ struct itfd {
uint8_t *f; /* Contenu du fichier. */
off_t lngr; /* Longueur du fichier, en octets. */
int version; /* Version du format tfd. */
- uint8_t *symbs_pos; /* Position de la liste de symboles. */
+ uint8_t *symbs; /* Position de la liste de symboles. */
size_t symbs_lngr; /* Longueur de la liste de symboles. */
- uint8_t *segm_pos; /* Position du segmenteur. */
+ uint8_t *segm; /* Position du segmenteur. */
size_t segm_lngr; /* Longueur du segmenteur. */
- uint8_t *trans_pos; /* Position du transducteur. */
+ uint8_t *trans; /* Position du transducteur. */
size_t trans_lngr; /* Longueur du transducteur. */
};
@@ -26,4 +26,13 @@ struct itfd *itfd_ouvrir(int df);
* Renvoie 0, ou -1 en cas d’erreur. */
int itfd_fermer(struct itfd *itfd);
+/* Segmenter le tampon tp de longueur lngr selon itfd et en placer les
+ * identifiants de symbole dans symbs.
+ * Le tampon symbs doit être au moins aussi grand que lngrcc. Puisqu’un
+ * symbole compte pour au moins un caractère, il ne peut jamais y avoir plus de
+ * lngrcc symboles dans symbs.
+ * Renvoie le nombre de symboles placés dans symbs. */
+size_t segmenter(struct itfd *itfd, uint8_t *cc, size_t lngrcc,
+ uint16_t *symbs);
+
#endif