commit 1992fd6c95b5a9fd5ab3b0e23e8dfef4f8092879
parent 3062d7c4c818f8420f02cb0f1b2e8c701b86a223
Auteur: Loïc Daignault-Pichette <loic@asteride.xyz>
Date: Sat, 25 Apr 2026 23:24:04 -0400
Peaufiner mishka
Diffstat:
| M | mishka.c | | | 158 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------- |
1 fichier modifié, 114 insertions(+), 44 suppressions(-)
diff --git a/mishka.c b/mishka.c
@@ -1,72 +1,142 @@
+#define _POSIX_C_SOURCE 200809L
+
+#include <assert.h>
#include <fcntl.h>
-#include <stddef.h>
+#include <stdint.h>
#include <stdio.h>
-#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
#include "itfd.h"
+char *nomprog;
+
+/* Écrire l’utilisation dans le fichier f. */
+static void utilisation(FILE *f);
+
+/* Faire passer entree dans le transducteur contenu dans le fichier désigné par
+ * tfd et en écrire le résultat dans sortie.
+ * Renvoie 0, ou -1 en cas d’erreur. */
+static int transductionner(int tfd, FILE *entree, FILE *sortie);
+
int
main(int argc, char **argv)
{
- int df;
- struct itfd *itfd;
- uint16_t symbs[256];
- size_t nsymbs;
- size_t lngr;
- size_t i;
- struct interp *interp;
- ssize_t rv;
+ int tfd; /* Descripteur de fichier du transducteur fini. */
- if ((df = open("a", O_RDONLY)) < 0)
- return 1;
- if ((itfd = itfd_ouvrir(df)) == NULL)
+ nomprog = argv[0];
+
+ if (argc != 2) {
+ utilisation(stderr);
return 1;
+ }
- if (argc != 2)
+ if ((tfd = open(argv[1], O_RDONLY)) < 0) {
+ fprintf(stderr, "%s: impossible d’ouvrir %s\n",
+ nomprog, argv[1]);
return 1;
+ }
- if ((lngr = strlen(argv[1])) > 256)
+ if (transductionner(tfd, stdin, stdout) < 0) {
+ fprintf(stderr, "%s: une erreur est survenue\n", nomprog);
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);
- }
+static void
+utilisation(FILE *f)
+{
+ assert(f);
+
+ fprintf(f, "Utilisation: %s <[mots]\n", nomprog);
+}
+
+static int
+transductionner(int tfd, FILE *entree, FILE *sortie)
+{
+ struct itfd *itfd;
+ struct interp *interp;
+ char *le; /* Tampon contenant la ligne d’entrée. */
+ size_t lelngr; /* Longueur du tampon le. */
+ uint16_t *symbs; /* Tampon contenant la chaîne de symboles. */
+ size_t symbslngr; /* Longueur du tampon symbs. */
+ ssize_t clus; /* Nombre de caractères lus. */
+ size_t nsymbs; /* Nombre de symboles segmentés. */
+ ssize_t vr; /* Valeur renvoyée. */
+ size_t isymb; /* Indice dans la chaîne de symboles. */
+ bool esp; /* Afficher un espace? */
+
+ assert(tfd > 0);
+ assert(entree);
+ assert(sortie);
+
+ /* Ouvrir tfd. */
+ if ((itfd = itfd_ouvrir(tfd)) == NULL) {
+ fprintf(stderr, "%s: impossible d’ouvrir le transducteur\n",
+ nomprog);
+ return -1;
}
- if ((interp = interp_init(itfd)) == NULL)
- return 1;
+ /* Initialiser l’interpréteur. */
+ if ((interp = interp_init(itfd)) == NULL) {
+ fprintf(stderr, "%s: erreur\n", nomprog);
+ return -1;
+ }
+
+ le = NULL;
+ lelngr = 0;
+ symbslngr = 64;
+ if ((symbs = malloc(symbslngr * sizeof(uint16_t))) == NULL) {
+ fprintf(stderr, "%s: malloc(3)\n", nomprog);
+ return -1;
+ }
+
+ /* Parcourir les lignes. */
+ while ((clus = getline(&le, &lelngr, entree)) > 0) {
+ /* Ignorer la nouvelle ligne. */
+ clus--;
+ /* Assurer que symbs soit assez grand. */
+ if ((size_t)clus > symbslngr) {
+ symbslngr *= 2;
+ if ((symbs = realloc(symbs, symbslngr * sizeof(uint16_t)))
+ == NULL) {
+ fprintf(stderr, "%s: malloc(3)\n", nomprog);
+ return -1;
+ }
+ }
- printf("---\n");
+ /* Segmenter. */
+ nsymbs = segmenter(itfd, (uint8_t *)le, clus, symbs);
- while ((rv = interpreter(interp, symbs, nsymbs)) > 0) {
- printf("\n");
- for (i = 0; i < ((size_t)rv - 1); i++) {
- if (!(interp->css[i] & 0x01)) {
- printf("*%c (%d)\n", interp->css[i] >> 1, interp->css[i] >> 1);
- } else {
- fwrite(itfd->symbs + 1 + (interp->css[i] >> 1),
+ /* Interpréter. */
+ esp = 0;
+ while ((vr = interpreter(interp, symbs, nsymbs)) > 0) {
+ if (esp) putc(' ', sortie);
+ for (isymb = 0; isymb < (size_t)vr - 1; isymb++) {
+ if ((interp->css[isymb] & 0x01) == ITFD_SYMB_REC) {
+ fwrite(itfd->symbs + 1 + (interp->css[isymb] >> 1),
1,
- itfd->symbs[interp->css[i] >> 1],
- stdout);
- printf(" (%d)\n", interp->css[i] >> 1);
+ itfd->symbs[interp->css[isymb] >> 1],
+ sortie);
+ } else {
+ putc(interp->css[isymb] >> 1, sortie);
+ }
}
+ esp = 1;
+ }
+ putc('\n', sortie);
+ if (interp_reinit(interp, itfd) < 0)
+ return -1;
+ if (vr < 0) {
+ fprintf(stderr, "%s: erreur\n", nomprog);
+ return -1;
}
}
- if (rv == -1)
- return 1;
+
+ free(le);
interp_libr(interp);
- if (itfd_fermer(itfd) < 0)
- return 1;
+ itfd_fermer(itfd);
return 0;
}