aplat

Documents structurés pour Unix
git clone git://git.asteride.xyz/~ldp/aplat.git
Journaux | Fichiers | Références | LISEZ-MOI | LICENCE

commit 7a17c0a0b97d9c62d22090a04528fad5d277dbc0
parent 90c70c6eab5c66f7c7d7339013abc49dc785f9cb
Auteur: Selve <selve@asteride.xyz>
Date:   Fri, 22 Mar 2024 19:16:03 -0400

naissance d'accumuler(1)

Diffstat:
MMakefile | 7+++++--
Aaccumuler.c | 116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Maplat.c | 16+++-------------
Mchangements.txt | 3+++
Mgeneral.c | 48+++++++++++++++++++++++++++++++++++++++++++++++-
Mgeneral.h | 2++
Mtampon.c | 21+++++++++++++++++++++
Mtampon.h | 2+-
8 files changed, 198 insertions(+), 17 deletions(-)

diff --git a/Makefile b/Makefile @@ -26,11 +26,14 @@ FCH_MO != find ${DOS_PO} -name '*.po' | sed 's/\.po$$/\.mo/' .po.mo: msgfmt -o "$@" "$<" -all: aplat traductions +all: aplat accumuler traductions aplat: aplat.o tampon.o general.o ${CC} ${COPTS} ${LDOPTS} -o "$@" aplat.o tampon.o general.o ${LIBS} +accumuler: accumuler.o tampon.o general.o + ${CC} ${COPTS} ${LDOPTS} -o "$@" accumuler.o tampon.o general.o ${LIBS} + traductions: ${FCH_MO} maj_trad: @@ -69,4 +72,4 @@ uninstall: find "${MAN_DOS}" -type f -name 'a?plat.[123456789]' | xargs rm -f clean: - rm -f aplat *.o *.core po/*.mo + rm -f aplat accumuler *.o *.core po/*.mo diff --git a/accumuler.c b/accumuler.c @@ -0,0 +1,116 @@ +#include <stdio.h> + +#ifdef __OpenBSD__ +#include <unistd.h> +#endif + +#include <libintl.h> +#include <locale.h> + +#include "general.h" +#include "tampon.h" + +#define ETQ_TLL 1024 /* taile initiale du tampon à étiquettes */ + +#define DRAP_OUV 01 /* parenthèse ouvrante */ +#define DRAP_FRM 02 /* parenthèse fermante */ + +static void utilisation(void); +static int accumuler(FILE *); + +char *prog_nom; /* nom du programme */ + +struct tampon etq; + +int +main(int argc, char **argv) +{ + prog_nom = trouv_prog_nom(argv, "aplat"); + + if (i18n_init() < 0) + return 1; + + if (pledge_envlp("stdio rpath", NULL) < 0) + return 1; + + if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'V' + && argv[1][2] == '\0') { + printf("accumuler %s\n", VERSION); + return 0; + } else if (argc > 1) { + utilisation(); + return 1; + } + + /* initialiser le tampon */ + if (tp_init(&etq, ETQ_TLL) < 0) + return 1; + + if (accumuler(stdin) < 0) + return 1; + + return 0; +} + +static void +utilisation(void) +{ + printf(_("Utilisation: %s <[fichier]\n"), prog_nom); +} + +static int +accumuler(FILE *f) +{ + int c; + int draps; + + tp_ecr(':', &etq); + +deb_ligne: + if ((c = getc(f)) == EOF) + return 0; + draps = 0; + for (;;) { + putc(c, stdout); + switch (c) { + case '(': + draps |= DRAP_OUV; + break; + case ')': + draps |= DRAP_FRM; + break; + case '\t': + goto etq; + case EOF: + goto invalide; + } + c = getc(f); + } + +etq: + while ((c = getc(f)) != '\t') { + if (c == EOF) + goto invalide; + tp_ecr(c, &etq); + } + if (draps & DRAP_OUV) + tp_ecr(':', &etq); + tp_ecr('\0', &etq); + printf("\t%s\t", tp_tp(&etq)); + tp_rec(&etq); + if (draps & DRAP_FRM) { + tp_rec(&etq); + if (tp_eff_etq(&etq) < 0) + goto invalide; + } + + while ((c = getc(f)) != EOF) { + putc(c, stdout); + if (c == '\n') + goto deb_ligne; + } + +invalide: + fprintf(stderr, "%s: entrée invalide\n", prog_nom); + return -1; +} diff --git a/aplat.c b/aplat.c @@ -42,21 +42,11 @@ main(int argc, char **argv) { prog_nom = trouv_prog_nom(argv, "aplat"); - setlocale(LC_ALL, ""); - bindtextdomain(I18N_DOMAINE, I18N_DOS); - textdomain(I18N_DOMAINE); - -#ifdef __OpenBSD__ - if (unveil(I18N_DOS, "r") < 0 || - unveil("/usr/share/locale/UTF-8/LC_CTYPE", "r") < 0) { - fprintf(stderr, _("%s: erreur avec unveil()\n"), prog_nom); + if (i18n_init() < 0) return 1; - } - if (pledge("stdio rpath", NULL) < 0) { - fprintf(stderr, _("%s: erreur avec pledge()\n"), prog_nom); + + if (pledge_envlp("stdio rpath", NULL) < 0) return 1; - } -#endif if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'V' && argv[1][2] == '\0') { diff --git a/changements.txt b/changements.txt @@ -11,6 +11,9 @@ Version 2.0 (???) * aplat(1): Correction d'un problème où le deux-points d'une étiquette n'était pas interprété comme il faut lorsque placé entre guillemets ou dans un bloc. * aplat(1): La nouvelle option -V affiche la version du programme. +* accumuler(1): Ajout d'un programme qui, à la manière de la sortie de la + version 1.0 d'aplat(1), accumule dans le champ des étiquettes toutes les + étiquettes parentes d'un domaine. Version 1.0 (2024/01/25) ----------- diff --git a/general.c b/general.c @@ -1,14 +1,60 @@ -#include "stdlib.h" +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +#ifdef __OpenBSD__ +#include <unistd.h> +#endif + +#include <libintl.h> +#include <locale.h> #include "general.h" +extern char *prog_nom; + char * trouv_prog_nom(char **argv, char *nom) { char *n; + assert(argv != NULL); + assert(nom != NULL); + if ((n = argv[0]) == NULL || n[0] == '\0') return nom; return n; } + +int +i18n_init(void) +{ + setlocale(LC_ALL, ""); + bindtextdomain(I18N_DOMAINE, I18N_DOS); + textdomain(I18N_DOMAINE); + +#ifdef __OpenBSD__ + if (unveil(I18N_DOS, "r") < 0 || + unveil("/usr/share/locale/UTF-8/LC_CTYPE", "r") < 0) { + fprintf(stderr, _("%s: erreur avec unveil()\n"), prog_nom); + return -1; + } +#endif + return 0; +} + +/* enveloppe pour pledge */ +int +pledge_envlp(char *prom, char *execprom) +{ + assert(prom != NULL); + +#ifdef __OpenBSD__ + if (pledge(prom, execprom) < 0) { + fprintf(stderr, _("%s: erreur avec pledge()\n"), prog_nom); + return -1; + } +#endif + return 0; +} diff --git a/general.h b/general.h @@ -5,5 +5,7 @@ #define _(c) gettext(c) char *trouv_prog_nom(char **, char *); +int i18n_init(void); +int pledge_envlp(char *, char *); #endif diff --git a/tampon.c b/tampon.c @@ -123,6 +123,27 @@ tp_eff_ligne(struct tampon *tp) INVARIANTS_TP(tp); } +/* effacer le dernier deux-points et les caractères qui le suivent */ +int +tp_eff_etq(struct tampon *tp) +{ + INVARIANTS_TP(tp); + + assert(*tp->tp == ':'); + assert(tp->pc - tp->tp > 0); + + if (tp->pc == tp->tp + 1) + return -1; + + while (*--tp->pc != ':') + ; + tp->pc++; + + INVARIANTS_TP(tp); + + return 0; +} + /* supprimer le dernier caractère d'un tampon */ char tp_rec(struct tampon *tp) diff --git a/tampon.h b/tampon.h @@ -16,10 +16,10 @@ int tp_init(struct tampon *, size_t); int tp_ecr(char, struct tampon *); char tp_rec(struct tampon *); void tp_eff(struct tampon *); +int tp_eff_etq(struct tampon *); void tp_eff_ligne(struct tampon *); size_t tp_ncar(struct tampon *); char *tp_tp(struct tampon *); void tp_deb(struct tampon *tp, size_t deb); - #endif