aplat

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

commit 8c85428fd00e9f17b7790941685c53e09fb50c06
parent 93502476599fa0d54c56c4b87bda392eb99af195
Auteur: Selve <selve@asteride.xyz>
Date:   Tue, 14 Nov 2023 12:59:32 -0500

exclusion d'exclure

Diffstat:
MMakefile | 11+++--------
Dexclure.c | 438-------------------------------------------------------------------------------
Dmeta.c | 88-------------------------------------------------------------------------------
Dmeta.h | 19-------------------
4 files changed, 3 insertions(+), 553 deletions(-)

diff --git a/Makefile b/Makefile @@ -6,21 +6,16 @@ PREFIX = "/usr/local/bin" .c.o: ${CC} ${COPT} -c "$<" -all: aplat exclure +all: aplat aplat: aplat.o tampon.o ${CC} ${COPT} -o "$@" aplat.o tampon.o -exclure: exclure.o meta.o tampon.o - ${CC} ${COPT} -o "$@" exclure.o meta.o tampon.o - -install: aplat exclure +install: aplat install -m 755 aplat ${PREFIX}/aplat - install -m 755 exclure ${PREFIX}/exclure uninstall: rm -f ${PREFIX}/aplat - rm -f ${PREFIX}/exclure clean: - rm -f aplat exclure *.o + rm -f aplat *.o diff --git a/exclure.c b/exclure.c @@ -1,438 +0,0 @@ -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> - -#include "meta.h" -#include "tampon.h" - -#define MAX_VARS 32 /* nombre maximal de variables */ -#define TLL_VAR 32 /* taille initiale du tampon à variable */ -#define TLL_META 64 /* taille initiale du tampon à métadonnées */ -#define TLL_PLS 16 /* taille des piles */ - -/* drapeaux */ -#define DRAP_DEB 01 -#define DRAP_FIN 02 - -/* types d'étiquette*/ -#define TP_RIEN 0 -#define TP_COND 1 -#define TP_A 2 -#define TP_SI 3 - -/* opérateurs */ -/* en ordre de priorité */ -#define OP_OU 0 -#define OP_ET 1 -#define OP_NON 2 -#define OP_PAR 3 - -struct pl { - int ctn[TLL_PLS]; - int tete; -}; - -struct vars { - char *vars[MAX_VARS]; - int prch; -}; - -int valider_var(char *); -int noter_var(char *); -int filtrer(void); -int valider_etqs(struct meta *); -int trv_base(struct meta *); -int ana_draps(struct meta *); -void aff_etq(struct meta *); -int evaluer(char *); -int val_var(char **); -int appliquer(int); -int ign_bloc(FILE *); -void utilisation(FILE *); - -struct tampon tamp_var; -struct meta tamp_meta; - -struct vars pl_vars = { {}, 0 }; -struct pl pl_vals = { {}, -1 }; -struct pl pl_ops = { {}, -1 }; - -char *nom_prog; - -int -main(int argc, char **argv) -{ - int c; - - if (m_init(&tamp_meta, TLL_META) < 0 || - t_init(&tamp_var, TLL_VAR) < 0) - return 1; - - nom_prog = *argv; - while ((c = getopt(argc, argv, "v:h")) != -1) { - switch (c) { - case 'v': - if (valider_var(optarg) < 0) - return 1; - if (noter_var(optarg) < 0) - return 1; - break; - case 'h': - utilisation(stdout); - return 0; - break; - default: - utilisation(stderr); - return 1; - } - } - - if (filtrer() < 0) - return -1; - exit(0); -} - -int -noter_var(char *arg) -{ - int i, j; - for (i = 0; i < pl_vars.prch; i++) - for (j = 0; pl_vars.vars[i][j] == arg[j]; j++) - if (arg[j] == '=' || arg[j+1] == '\0') { - pl_vars.vars[i] = arg; - return 0; - } - if (pl_vars.prch < MAX_VARS) { - pl_vars.vars[pl_vars.prch++] = arg; - return 0; - } - fprintf(stderr, "%s: trop de variables (maximum: %d)\n", - nom_prog, MAX_VARS); - return -1; -} - -int -valider_var(char *arg) -{ - char *c; - if (*arg == '=') { - fprintf(stderr, "%s: une variable ne peut commencer par «=»\n", - nom_prog); - return -1; - } - for (c = arg; *c != '\0'; c++) { - switch (*c) { - case '!': case '&': case '|': case ':': case '(': case ')': - fprintf(stderr, "%s: «%c» est un caractère réservé\n", - nom_prog, *c); - return -1; - } - } - return 0; -} - -int -filtrer(void) -{ - int c; - int draps; - int trouve = 0; - char *pc; - while (m_lire(stdin, &tamp_meta) > 0) { - if (valider_etqs(&tamp_meta) < 0) - return -1; - switch (trv_base(&tamp_meta)) { - case 0: - aff_etq(&tamp_meta); - goto afficher; - case 1: /* si */ - draps = ana_draps(&tamp_meta); - if (draps & DRAP_DEB) - trouve = 0; - aff_etq(&tamp_meta); - if (trouve == 0) { - if (draps & DRAP_FIN) - trouve = 1; - goto afficher; - } - putc('\n', stdout); - break; - case 2: /* @ */ - break; - case 3: /* # */ - draps = ana_draps(&tamp_meta); - if (trouve == 1 && draps & DRAP_DEB) { - ign_bloc(stdin); - break; - } - pc = tamp_meta.draps-2; - while (*--pc != '#') - ; - if (evaluer(pc+1)) { - trouve = 1; - aff_etq(&tamp_meta); - goto afficher; - } else { - ign_bloc(stdin); - } - break; - } - while ((c = getc(stdin)) != '\n') - if (c == EOF) - return 0; - continue; -afficher: - while ((c = putc(getc(stdin), stdout)) != '\n') - if (c == EOF) - return 0; - } - return 0; -} - -int -valider_etqs(struct meta *m) -{ - if (*(m->etqs) != ':') { - fprintf(stderr, "%s: fichier corrompu; le premier champ ne " - "commence pas par «:»\n", nom_prog); - return -1; - } - if (*(m->draps-2) != ':') { - fprintf(stderr, "%s: fichier corrompu; le premier champ ne se " - "termine pas par «:»\n", nom_prog); - return -1; - } - return 0; -} - -/* trouver la dernière occurence d'une étiquette */ -/* l'étiquette ne peut contenir «:» */ -int -trv_base(struct meta *m) -{ - char *c = m->draps-2; - int n = 0; - if (c == m->etqs) - return 0; - while (*--c != ':') - ; - c++; - if (*c == '#') { - c -= 2; - n++; - } - if (c - m->etqs < 4) - return 0; - if (*c == '@') { - c -= 3; - n++; - } - else if (n == 1) - return 0; - if (*(c-1) == ':' && *c == 's' && *(c+1) == 'i' && *(c+2) == ':') - return n+1; - return 0; -} - -int -ana_draps(struct meta *m) -{ - char *c; - int draps; - for (draps = 0, c = m->draps; *c != '\0'; c++) { - switch (*c) { - case '(': - draps |= DRAP_DEB; - break; - case ')': - draps |= DRAP_FIN; - break; - } - } - return draps; -} - -void -aff_etq(struct meta *m) -{ - char *c; - int fini = 0; - for (c = m->etqs; *c != '\0'; c++) { - fini = 0; - if (*c == ':') { - if (strncmp(c+1, "si:", 3) == 0) { - fini = 1; - c += 3; - if (strncmp(c+1, "@:", 2) == 0) { - c += 2; - if (*(c+1) == '#') { - for (c += 2; *c != ':'; c++) - ; - if (*(c+1) != '\0') { - c--; - continue; - } - } - } - } - } - putc(*c, stdout); - } - if (fini) { - putc('\t', stdout); - } else { - printf("\t%s", m->draps); - } -} - -/* ps doit pointer vers un '#' */ -int -evaluer(char *ps) -{ - int op; - char *s = ps; - for (;;s++) { - switch (*s) { - case '!': - op = OP_NON; - break; - case '&': - op = OP_ET; - break; - case '|': - op = OP_OU; - break; - case '(': - op = OP_PAR; - break; - case ')': - while (pl_ops.tete >= 0) { - if (pl_ops.ctn[pl_ops.tete] == OP_PAR) { - pl_ops.tete--; - goto sortie; - } - if (appliquer(pl_ops.ctn[pl_ops.tete--]) < 0) - return -1; - } - return -1; -sortie: - continue; - case ':': - while (pl_ops.tete >= 0) - if (appliquer(pl_ops.ctn[pl_ops.tete--]) < 0) - return -1; - if (pl_vals.tete != 0) - return -1; - return pl_vals.ctn[pl_vals.tete--]; - default: - if (++pl_vals.tete >= TLL_PLS) { - fprintf(stderr, "%s: expression trop " - "complexe\n", nom_prog); - return -1; - } - if ((pl_vals.ctn[pl_vals.tete] = val_var(&s)) < 0) - return -1; - continue; - } - while (pl_ops.tete >= 0 && pl_ops.ctn[pl_ops.tete] != OP_PAR && - pl_ops.ctn[pl_ops.tete] != OP_NON && - pl_ops.ctn[pl_ops.tete] >= op) { - if (appliquer(pl_ops.ctn[pl_ops.tete--]) < 0) - return -1; - } - if (++pl_ops.tete >= TLL_PLS) - return -1; - pl_ops.ctn[pl_ops.tete] = op; - } - return -1; -} - -int -val_var(char **ps) -{ - int i, j; - char *s = *ps; - t_eff(&tamp_var); - for (i = 0; *s != '\0'; i++, s++) { - switch (*s) { - case '!': case '&': case '|': case ':': case '(': case ')': - goto trouver; - } - t_ecr(*s, &tamp_var); - } - fprintf(stdin, "%s: le premier champ ne se termine pas par «:»\n", - nom_prog); - return -1; -trouver: - t_ecr('\0', &tamp_var); - - *ps = --s; - for (i = 0; i < pl_vars.prch; i++) { - for (j = 0; pl_vars.vars[i][j] == tamp_var.t[j]; j++) - if (tamp_var.t[j] == '\0') - return 1; - } - return 0; -} - -int -appliquer(int op) -{ - switch (op) { - case OP_NON: - if (pl_vals.tete >= 0) { - pl_vals.ctn[pl_vals.tete] = !pl_vals.ctn[pl_vals.tete]; - return 0; - } - break; - case OP_ET: - if (pl_vals.tete >=1) { - pl_vals.ctn[pl_vals.tete-1] = - pl_vals.ctn[pl_vals.tete-1] && - pl_vals.ctn[pl_vals.tete]; - pl_vals.tete--; - return 0; - } - break; - case OP_OU: - if (pl_vals.tete >= 1) { - pl_vals.ctn[pl_vals.tete-1] = - pl_vals.ctn[pl_vals.tete-1] || - pl_vals.ctn[pl_vals.tete]; - pl_vals.tete--; - return 0; - } - break; - } - fprintf(stderr, "%s: trop d'opérateurs\n", nom_prog); - return -1; -} - -int -ign_bloc(FILE *f) -{ - int draps; - int c; - int niveau = 0; - do { - draps = ana_draps(&tamp_meta); - if (draps & DRAP_DEB) - niveau++; - if (draps & DRAP_FIN) - niveau--; - if (niveau == 0) - break; - while ((c = getc(f)) != '\n') - if (c == EOF) - return 0; - } while (m_lire(f, &tamp_meta) > 0); - return 0; -} - -void -utilisation(FILE *f) -{ - fprintf(f, "UTILISATION: %s -v[variable][=valeur] [...] <[fichier]\n", - nom_prog); -} diff --git a/meta.c b/meta.c @@ -1,88 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> - -#include "meta.h" - -static int m_ecr(char, struct meta *); -static int m_plein(char, struct meta *); -static void m_reinit(struct meta *); - -/* initialiser un tampon m de taille tll */ -int -m_init(struct meta *m, size_t tll) -{ - if ((m->etqs = malloc(tll)) == NULL) - return -1; - m->draps = m->etqs; - m->pcar = m->etqs; - m->ncar = 0; - m->tll = tll; - return 0; -} - -/* renvoyer le dernier caractère lu - * une valeur positive indique le succès - * négative indique une erreur - * nulle indique EOF */ -int -m_lire(FILE *f, struct meta *m) -{ - char c; - m_reinit(m); - - /* lire les étiquettes */ - while ((c = getc(f)) != '\t' && c != '\n') { - if (c == EOF) - return 0; - if (m_ecr(c, m) < 0) - return -1; - } - m_ecr('\0', m); - - /* lire les drapeaux */ - m->draps = m->pcar; - if (c != '\n') { - while ((c = getc(f)) != '\t' && c != '\n') { - if (c == EOF) - return 0; - if (m_ecr(c, m) < 0) - return -1; - } - } - m_ecr('\0', m); - ungetc(c, stdin); - return 1; -} - -/* écrire un caractère dans le tampon */ -static int -m_ecr(char c, struct meta *m) -{ - return ((++m->ncar > m->tll) ? m_plein(c, m) : - (*m->pcar++ = c, (unsigned char) c)); -} - -/* agrandir le tampon et écrire un caractère */ -int -m_plein(char c, struct meta *m) -{ - char *tmp; - if ((tmp = realloc(m->etqs, m->tll * M_FACT_AGR)) == NULL) - return -1; - m->tll *= M_FACT_AGR; - if (tmp != m->etqs) { - m->draps = tmp + (m->draps - m->etqs); - m->pcar = tmp + m->ncar - 1; - m->etqs = tmp; - } - *m->pcar++ = c; - return (unsigned char) c; -} - -/* réinitaliser un tampon méta */ -void -m_reinit(struct meta *m) -{ - m->pcar = m->etqs; - m->ncar = 0; -} diff --git a/meta.h b/meta.h @@ -1,19 +0,0 @@ -#ifndef META_H -#define META_H - -#include <stdio.h> - -#define M_FACT_AGR 2 /* facteur d'agrandissement d'un tampon */ - -struct meta { - char *etqs; - char *draps; - char *pcar; - size_t ncar; - size_t tll; -}; - -int m_init(struct meta *, size_t); -int m_lire(FILE *, struct meta *); - -#endif