trafi

Transducteurs finis
git clone git://git.asteride.xyz/trafi.git
Journaux | Fichiers | Références

commit 440c9c750c430bc7f0ab55db0e1625dea0f738fc
parent c854ce34459acf777d0c39b035d719e4169a7c20
Auteur: Loïc Daignault-Pichette <loic@asteride.xyz>
Date:   Wed,  8 Apr 2026 10:36:14 -0400

Ouvrir et fermer un tfd pour l’interpréter

Diffstat:
MMakefile | 7+++++--
Ainterp.c | 19+++++++++++++++++++
Aitfd.c | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aitfd.h | 29+++++++++++++++++++++++++++++
4 fichiers modifiés, 146 insertions(+), 2 suppressions(-)

diff --git a/Makefile b/Makefile @@ -7,10 +7,13 @@ COPTS = -Wall -Wextra -Wpedantic -std=c99 -O0 #-DNDEBUG -O3 -flto .c.o: ${CC} ${COPTS} ${CPPOPTS} -c "$<" -tout: attvtfd +tout: attvtfd interp attvtfd: attvtfd.o tampex.o tfm.o att.o tfd.o ${CC} ${COPTS} -o "$@" attvtfd.o tampex.o tfm.o att.o tfd.o +interp: interp.o itfd.o + ${CC} ${COPTS} -o "$@" interp.o itfd.o + net: - rm -rf attvtfd *.o *.core + rm -rf attvtfd interp *.o *.core diff --git a/interp.c b/interp.c @@ -0,0 +1,19 @@ +#include <fcntl.h> +#include <stddef.h> +/*#include <stdio.h>*/ + +#include "itfd.h" + +int +main(void) +{ + int df; + struct itfd *itfd; + + if ((df = open("a", O_RDONLY)) < 0) + return 1; + if ((itfd = itfd_ouvrir(df)) == NULL) + return 1; + + return 0; +} diff --git a/itfd.c b/itfd.c @@ -0,0 +1,93 @@ +#include <assert.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <sys/mman.h> +#include <sys/stat.h> + +#include "itfd.h" +#include "tfd.h" + +#include <stdio.h> + +#define LIRE_16(tp, dec) (*(uint16_t *)((tp) + (dec))) +#define LIRE_32(tp, dec) (*(uint32_t *)((tp) + (dec))) + +struct itfd * +itfd_ouvrir(int df) +{ + struct itfd *itfd; + struct stat stat; + uint32_t n; + + assert(df > 0); + + if ((itfd = malloc(sizeof(struct itfd))) == NULL) + return NULL; + + if (fstat(df, &stat) < 0) + goto erreur1; + + if ((itfd->f = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, df, 0)) + == MAP_FAILED) + goto erreur1; + + itfd->df = df; + itfd->lngr = stat.st_size; + + /* Vérifier le nombre magique. */ + n = itfd->f[0x00]; + n <<= 8; + n |= itfd->f[0x01]; + + if (n != TFD_MAGIQUE) + goto erreur2; + + /* Vérifier la version. */ + n = itfd->f[0x02]; + n <<= 8; + n |= itfd->f[0x03]; + if (n != 0) + goto erreur2; + itfd->version = n; + + /* Vérifier le boutisme. */ + if ((n = LIRE_16(itfd->f, 0x04)) != TFD_TEMOIN) + goto erreur2; + + /* Lire les informations sur les segments. */ + itfd->symbs_pos = 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_lngr = LIRE_32(itfd->f, 0x12); + itfd->trans_pos = 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) + goto erreur2; + //if (itfd->segm_pos + itfd->segm_lngr != itfd->trans_pos) + //goto erreur2; + + return itfd; + +erreur2: + itfd_fermer(itfd); + return NULL; +erreur1: + free(itfd); + return NULL; +} + +int +itfd_fermer(struct itfd *itfd) +{ + assert(itfd); + assert(itfd->f); + + if (munmap(itfd->f, itfd->lngr) < 0) + return -1; + + free(itfd); + + return 0; +} diff --git a/itfd.h b/itfd.h @@ -0,0 +1,29 @@ +#ifndef ITFD_H +#define ITFD_H + +#include <stdint.h> + +/* Interpréter un transducteur fini sur le disque. */ + +struct itfd { + int df; /* Descripteur de fichier. */ + 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. */ + size_t symbs_lngr; /* Longueur de la liste de symboles. */ + uint8_t *segm_pos; /* Position du segmenteur. */ + size_t segm_lngr; /* Longueur du segmenteur. */ + uint8_t *trans_pos; /* Position du transducteur. */ + size_t trans_lngr; /* Longueur du transducteur. */ +}; + +/* Ouvrir un fichier tfd pour l’interpréter. + * Renvoie un pointeur vers une structure itfd, ou NULL en cas d’erreur. */ +struct itfd *itfd_ouvrir(int df); + +/* Fermer un fichier tfd. + * Renvoie 0, ou -1 en cas d’erreur. */ +int itfd_fermer(struct itfd *itfd); + +#endif