#include "flux.h" #include #include #include typedef enum { Normal, Nor_oblique, Nor_controblique, Chaine, Cha_controblique, Caractere, Car_controblique, Commentaire, Com_etoile, Fin_de_fichier } flu_etat; typedef enum { Etoile = '*', Oblique = '/', Controblique = '\\', Quote = '\'', Guillemets = '"', Fin_ligne = '\n' } cara; struct flux { flu_mode mode; FILE *fichier; flu_etat etat; }; void flu_ecrire (flux f, char *chaine) { assert (f != NULL && f->mode == Ecriture); fputs (chaine, f->fichier); } void flu_detruire (flux * f) { assert (f != NULL && *f != NULL); fclose ((*f)->fichier); free (*f); *f = NULL; } flux flu_creer (char *nom, flu_mode mode) { flux f = (flux) malloc (sizeof (struct flux)); assert (f != NULL); f->etat = Normal; f->mode = mode; f->fichier = (nom != NULL) ? fopen (nom, mode == Lecture ? "r" : "w" ) : mode == Lecture ? stdin : stdout; assert(f->fichier); return f ; } int flu_lire_caractere (flux f) { if (f->etat == Fin_de_fichier) return EOF; while (1) { int c = fgetc (f->fichier); if (c == EOF) { f->etat = Fin_de_fichier; return EOF; } switch (f->etat) { case Normal: switch (c) { case Quote: f->etat = Caractere; return c; case Guillemets: f->etat = Chaine; return c; case Oblique: f->etat = Nor_oblique; continue; case Controblique: f->etat = Nor_controblique; continue; default: return c; } case Nor_oblique: switch (c) { case Etoile: f->etat = Commentaire; continue; case Oblique: return Oblique; default: f->etat = Normal; ungetc (c, f->fichier); return Oblique; } case Nor_controblique: switch (c) { case Fin_ligne: f->etat = Normal; continue; case Controblique: return c; default: f->etat = Normal; ungetc (c, f->fichier); return Controblique; } case Chaine: case Caractere: if (c == ((f->etat == Chaine) ? Guillemets : Quote)) f->etat = Normal; else if (c == Controblique) { f->etat = ((f->etat == Chaine) ? Cha_controblique : Car_controblique); continue; } return c; case Cha_controblique: case Car_controblique: switch (c) { case Fin_ligne: f->etat = (f->etat == Cha_controblique) ? Chaine : Caractere; continue; case Controblique: return c; default: f->etat = (f->etat == Cha_controblique) ? Chaine : Caractere; return c; } case Commentaire: if (c == Fin_ligne) return c; if (c == Etoile) f->etat = Com_etoile; continue; case Com_etoile: switch (c) { case Oblique: f->etat = Normal; continue; case Etoile: continue; case Fin_ligne: f->etat = Commentaire; return c; default: f->etat = Commentaire; continue; } case Fin_de_fichier: return EOF; } } } /* int test () { int c = 0; flux entree, sortie; entree = flu_creer (NULL, Lecture); sortie = flu_creer (NULL, Ecriture); while ((c = flu_lire_caractere (entree)) != EOF) flu_ecrire (sortie, (char *) &c); flu_detruire (&entree); flu_detruire (&sortie); return 0; } */