#include #include #include #include #include "projet.h" #include "projetx.m" /* Lecture et initialisation du makefile.dat */ PRIVATE void MAKEFILE::init ( const char *_fname, // Si NULL -> makefile.dat dans espace usager // Sinon, considŠre que c'est un path complet. // Si c'est un r‚pertoire ajoute makefile.dat bool silence, // Ne g‚nŠre pas de message si // _fname n'existe pas. const char *_projet, // Nom du projet ou sous-projet const USERINFO *_user) // Programmeur { is_modif = 0; user = _user; strcpy (projet,_projet); if (_fname == NULL){ _fname = "makefile.dat"; user->makusrpath (projet,fname); path_make (fname,_fname,fname); }else if (file_type(_fname)==1){ path_make (_fname,"makefile.dat",fname); }else{ strcpy (fname,_fname); } tbfile = new MAKEFILE_FILE[450]; assert(tbfile != NULL); nbfile = 0; positer = 0; moi = NULL; FILE *fin; if (silence){ fin = fopen (fname,"r"); }else{ fin = fopen_err (fname,"r",0); } int add_moi = 0; // Ajoute une entr‚e pour le makefile.dat lui-mˆme if (fin != NULL){ char buf[300]; MAKEFILE_FILE *file = tbfile; readok = 1; while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ strip_end (buf); if (buf[0] != '\0'){ char datestr[11]; char timestr[9]; char path[MAXSIZ_PATH]; char revision[MAXSIZ_REVISION+1]; int nbf = sscanf (buf,"%s %s %s %s %s %s %s %s %s %s" ,file->nom,datestr,timestr ,path,revision ,file->tbhist[0],file->tbhist[1],file->tbhist[2] ,file->tbhist[3],file->tbhist[4]); if (nbf >= 5){ unsigned long date = date_a2u(datestr); unsigned time = time_a2u(timestr); assert (nbfile < 500); file->date = (date << 16) + time; if (strncmp("$(KITOMBRE)/",path,12)==0){ file->path = strdup_err (path+12); file->archive = 1; }else{ file->path = strdup_err (path); file->archive = 0; } file->nbhist = nbf - 5; file->efface = 0; file->mark = 0; file->rev.set (revision); file->is_dir = 0; if (strchr(file->nom,'/') != NULL || strchr(file->nom,'\\') != NULL){ // Le fichier est en fait un sous-r‚pertoire file->is_dir = 1; } if (strcmp(file->nom,"makefile.dat")==0){ moi = file; } nbfile++; file++; }else{ xconf_error (MSG_U(E_MAKEFILE ,"Contenu invalide, fichier %s\n%s") ,fname,buf); readok = 0; } } } fclose (fin); if (moi == NULL){ /* #Sp‚cification: makefile.dat / vide Un makefile.dat sans entr‚e pour lui-mˆme est un erreur. Un message d'erreur est affich‚ et la ligne manquante est ajout‚e. La provenance de ce problŠme n'est pas connue. (on suspecte des manipulations manuelles de l'archive...). */ xconf_error (MSG_U(E_MAKEFILEMOI ,"makefile.dat %s inconsistent\n" "Pas de ligne indiquant sa révision\n" "Une ligne bidon a été ajoutée...") ,fname); add_moi = 1; } }else{ readok = 0; add_moi = 1; } if (add_moi){ moi = tbfile + nbfile; nbfile++; path_splitlex (fname,NULL,moi->nom); moi->rev.set ("1"); moi->date = 0; moi->path = NULL; moi->setombpath(projet); moi->is_dir = 0; moi->efface = 0; moi->archive = 1; moi->nbhist = 0; } /* #Specification: repertoire virtuel Le contenu d'un r‚pertoire virtuel est donn‚ par l'‚quation suivante: makefile.dat - makefile.del + contenu r‚el. */ char pathdel[MAXSIZ_PATH]; file_chgext (fname,pathdel,".del"); FILE *fdel = fopen (pathdel,"r"); if (fdel != NULL){ char buf[300]; while (fgets(buf,sizeof(buf)-1,fdel)!=NULL){ strip_end (buf); if (buf[0] != '\0') delfil (buf); } fclose (fdel); } } /* Ecrit le makefile.dat dans un fichier quelquoncques */ PUBLIC int MAKEFILE::ecrit ( const char *fichier, int archivable) // Ecrit seulement les fichiers archivable ? { int ret = -1; /* On ecrit en binaire parce que ca va plus vite, surtout avec NFS. On place simplement un \r\n au lieu d'un \n. Plusieurs fois plus vite. Sur un reseau comme novell, ca limite l'activite sur le reseau de facon importante. */ FILE *fout = fopen_binerr (fichier,"w",0); if (fout == NULL) user->logerr ("Ne peut ecrire le fichier %s\n",fichier); if (fout != NULL){ setvbuf (fout,NULL,_IOFBF,4096); // 4096 obtenu par essai erreur // avec PC-NFS. MAKEFILE_FILE *file = tbfile; for (int i=0; iisdel() && (!archivable || file->archive)){ char datestr[20]; date_u2a ((unsigned)(file->date >> 16),datestr); char timestr[20]; time_u2a ((unsigned)(file->date & 0xffff),timestr); char revstr[MAXSIZ_REVISION+1]; file->rev.format (revstr); fprintf (fout,"%-15s %s %s %s%s %s %s %s %s %s %s\r\n" ,file->nom,datestr,timestr ,file->archive ? "$(KITOMBRE)/" : "" ,file->path,revstr ,file->tbhist[0],file->tbhist[1],file->tbhist[2] ,file->tbhist[3],file->tbhist[4]); } } if (fclose (fout) != 0){ char absfname[MAXSIZ_PATH]; path_setabs (fichier,absfname); xconf_error (MSG_U(E_ECRITURE ,"Ecriture incomplète du fichier %s") ,absfname); user->logerr ("Ecriture incomplete du fichier %s\n",absfname); ret = -1; }else{ ret = 0; } } return ret; } /* Ecrit le fichier MAKEFILE.DAT sur disque (o— il a ‚t‚ lue). Cette fonction est g‚n‚ralement appel‚ aprŠs que tous les sources ont ‚t‚ archiv‚s, juste avant l'archivage du MAKEFILE.DAT lui-mˆme. */ PUBLIC int MAKEFILE::ecrit( int archivable) // Ecrit seulement les fichiers archivable ? { return ecrit (fname,archivable); } /* Sauve conditionnellement le fichier makefile.dat s'il a ‚t‚ modifi‚ Retourne -1 si erreur, 0 si sauve pas, 1 si sauve ok. Si sauve, un fichier makefile.old est produit mˆme si le makefile.dat n'existait pas. Si le fichier makefile.old existe, il est conserv‚ tel quel. Le makefile.old doit contenir la r‚vision original du makefile.dat. */ PUBLIC int MAKEFILE::save () { int ret = 0; if (is_modif){ char nameold[MAXSIZ_PATH]; file_chgext (fname,nameold,"old"); if (!file_exist(nameold)){ if (file_exist(fname)){ ret = file_rename (fname,nameold); }else{ ret = file_touch (nameold,1); } } if (ret != -1){ ret = ecrit (0); if (ret != -1) ret = 1; } } return ret; }