#include "prehtml.h"

#define NOMFINFICHIER "/tmp/prehtml_fingenerate_XXXXXX"
static char nomfinfichier[]=NOMFINFICHIER;

static generate *premier,*dernier;
int engenerate; /* 0=pas de générate, 1=dans générate
		 * 2=/generate passé */

void init_generate(void){
  engenerate=0;
}

void remplitgenerate(char *s){ /* partie commune à la 1ère fois et aux autres*/
  dernier->nom=strdup(s);
  dernier->nomtemp=monalloc(strlen(s)+6);
  strcpy(dernier->nomtemp,s);
  strcat(dernier->nomtemp,".tmp");
  creetemp(dernier->nomtemp); /* fichier à effacer si arrêt d'urgence */
  sortie=fopen(dernier->nomtemp,"w");
  if (!sortie) erreur("<generate>: pas pu créer '%s'",dernier->nomtemp);
  dernier->suivant=NULL;
}

void genere(char *s){
  int i;
  generate *suit;
  if (!(*s)) erreur("<generate> avec une chaîne vide!");
  if (engenerate==1)erreur("Impossible de générer %s car on n'a pas"
			   " refermé le <generate> précédent",s);
  else if (engenerate==0){ /* premier passage par <generate> */
    fclose(sortie); /* on ferme le fichier en cours, c'est le début de tous */
    engenerate=1;
    premier=monalloc(sizeof(generate));
    dernier=premier; /* c'est comme dans l'évangile */
    remplitgenerate(s);
  }
  else if (engenerate==2){ /* </generate> est passé, et on en fait un autre */
    /* d'abord, on vérifie que le nom donné n'a pas déjà été donné par un
     * <generate> précedent */
    suit=premier; 
    i=1;
    while (suit){
      if (!strcmp(s,suit->nom))
	erreur("<generate %s>: La commande <generate> n°%d voulait déjà "
	       "créer le fichier %s, or il est impossible de créer deux "
	       "fois le même fichier dans le même fichier .phtml",
	       s,i,s);
      suit=suit->suivant;
      i++;
    }
    /* on va vérifier que le fichier "suite" est bien vide
     * Attention: il faut avoir été créé avec "w+" !*/
    fseek(sortie,0,SEEK_SET);
    while(1){
      i=getc(sortie);
      if (i==EOF) break;
      if (!strchr(" \t\n\r",i)) 
	erreur("<GENERATE %s> alors que des caractères non-blancs ('%c') "
	       "sont passés depuis le dernier </GENERATE>",s,i);
    }
    fclose(sortie); /* si c'est bon, on ferme et on efface le fichier de fin */
    unlink(nomfinfichier);
    dernier->suivant=monalloc(sizeof(generate));
    dernier=dernier->suivant;
    remplitgenerate(s);
    engenerate=1;
  }
  else erreur("Erreur interne dans genere(): engenerate=%d",engenerate);
}

void degenere(void){ /* fonction appelée quand </generate> arrive */
  if (engenerate==0) erreur("</GENERATE> sans aucun <GENERATE> avant");
  else if (engenerate==2) 
    erreur("</GENERATE> trouvé alors qu'il y en a déjà eu un avant");
  else if (engenerate==1){ /* OK, on est bien dans un <GENERATE>*/
    fclose(sortie);
    strcpy(nomfinfichier,NOMFINFICHIER);
    mktemp(nomfinfichier);
    creetemp(nomfinfichier); /* fichier à effacer si arrêt d'urgence */
    sortie=fopen(nomfinfichier,"w+"); /* le "+" est indispensable, on va le relire*/
    if (!sortie) erreur("</GENERATE>: pas pu créer le fichier de fin %s",
			nomfinfichier);
    engenerate=2;
  }
  else erreur("Erreur interne dans degenere(): engenerate=%d",engenerate);
}

void fin_generate(void){ /* choses à faire à la fin du fichier principal pour
			  * finaliser les <GENERATE> éventuels */
  char fichtempgene[]="/tmp/fichtempgenerateXXXXXX";
  FILE *fin,*fout,*f1,*f2;
  int i,i1,i2;
  
  if (engenerate==0) return; /* rien à faire */
  if (engenerate==1) erreur("EOF rencontré à l'intérieur d'un <GENERATE>");
  /* donc engenerate==2: on a des choses à faire */
  mktemp(fichtempgene);
  creetemp(fichtempgene); /* fichier à effacer si arrêt d'urgence */
  while (premier){ /* on parcours tous les fichiers générés */
    fout=fopen(fichtempgene,"wb");
    if (!fout)erreur("Finalisation des <generate>: impossible de créer %s",
		     fichtempgene);
    fin=fopen(fich_temp,"rb"); /* c'est finalement le fichier de début */
    if (!fin)erreur("Finalisation des <generate>: impossible de lire "
		    "le début dans %s",fich_temp);
    while ((i=fgetc(fin))!=EOF) putc(i,fout);
    fclose(fin);
    fin=fopen(premier->nomtemp,"rb"); /* milieu */
    if (!fin)erreur("Finalisation des <generate>: impossible de lire "
		    "le milieu dans %s",premier->nomtemp);
    while ((i=fgetc(fin))!=EOF) putc(i,fout);
    fclose(fin);
    unlink(premier->nomtemp);
    fin=fopen(nomfinfichier,"rb"); /* fin */
    if (!fin)erreur("Finalisation des <generate>: impossible de lire "
		    "la fin dans %s",nomfinfichier);
    while ((i=fgetc(fin))!=EOF) putc(i,fout);
    fclose(fin);
    fclose(fout);
    /* on va comparer le fichier créé avec celui existant [s'il existe] */
    f1=fopen(premier->nom,"rb");
    i1=0;i1=1;
    if (f1){
      f2=fopen(fichtempgene,"rb");
      if (!f2) erreur("Le fichier %s n'a pas été créé",fichtempgene);
      do{
	i1=getc(f1); i2=getc(f2);
      }while(i1==i2 && i1!=EOF);
      fclose(f2);fclose(f1);
    }
    if (i1!=i2){
      if (rename(fichtempgene,premier->nom))
      erreur("Fin GENERATE: Impossible de renommer %s en %s",
	     fichtempgene,premier->nom);
    }
    else unlink(fichtempgene); /* fichiers identiques: je l'enlève
				* pour ne pas changer la date */
    premier=premier->suivant;
  }
  unlink(fich_temp); /* n'a plus d'utilité, ce n'était que le début */
  unlink(nomfinfichier); /* n'a plus d'utilité, ce n'était que la fin */
}
