#include #include #include #include #include "projetx.m" #include "projet.h" /* Efface le fichier du projet. */ PUBLIC void INTEGRE_FILE::efface() { /* #Sp‚cification: fusion / ‚dition / efface Lorsqu'on choisit d'effacer un fichier d'un projet, on ajoute simplement son nom au makefile.del. Si le fichier existe localement, on change son extension pour .old. Si le .old existe d‚j…, on demande la permission … l'usager de r‚ellement effacer le fichier. */ FILE *fout = fopen_err ("makefile.del","a",1); fprintf (fout,"%s\n",fname); fclose (fout); done = 1; if (file_exist(fname)){ char buf[1000]; snprintf (buf,sizeof(buf)-1,MSG_U(Q_CONFIRMDEL ,"Le fichier %s ne peut pas être renommé\n" "à .old. Voulez vous effacer ce fichier"),fname); if (file_renameext (fname,"old",0)==-1 && xconf_yesno (MSG_U(T_CONFIRM,"Confirmation"),buf,help_nil)==MENU_YES){ file_unlink (fname); } } } /* S‚lectionne une r‚vision d'un fichier comme version courante. Corrige le makefile.dat */ PUBLIC void INTEGRE_FILE::select_tra( const USERINFO *user, int select, MAKEFILE *mkf) { INTG_TRANS *tra = getitem(select); if (tra->oper == INTEGRE_EFFACE){ efface(); }else{ char *path = tra->path; char tmppath[MAXSIZ_PATH]; if (!path_isabs(path)){ user->makombpath(path,tmppath); path = tmppath; } long date = file_dosdate (path); REVISION newrev (tra->revs.fichier); fuslog_add (user,"S‚lectionne %s r‚vision %s\n" ,fname,tra->revs.fichier); if (newrev.isnull()){ /* #Sp‚cification: fusion / ‚dition / s‚lection Lorsqu'il y a s‚lection sans correction d'un fichier qui n'a pas encore ‚t‚ livr‚ (encore dans l'environnement usager), le fichier est duplicat‚ dans la r‚vision cible. De plus, sa date de r‚vision est corrig‚. Le programmeur n'a qu'… faire un make et tout devrait recompiler correctement. */ file_copyp (path,fname); file_touch (fname,0); }else{ /* #Sp‚cification: fusion / ‚dition / s‚lection Lorsqu'on s‚lectionne une r‚vision particuliŠre, il y a simplement correction du makefile.dat de la r‚vision cible de la fusion. C'est un simple jeu de pointeurs. Aucun fichier n'est copier. S'il y avait copie locale du fichier, on la renomme a .bak. S'il y avait d‚j… un .bak, on l'efface. De plus, un fichier *.bld est cr‚‚ … partir du nom de base du fichier s‚lectionn‚. Cela force une recompilation du fichier source grace … une rŠgle sp‚ciale de make (voir adm/rules/compile.mak). */ if (date == 0){ xconf_error (MSG_U(E_NODATE ,"Ne peut obtenir la date du fichier\n" "%s\n(voir error.log)") ,path); user->logerr ("Ne peut obtenir la date du fichier %s\n",path); } { char bldname[MAXSIZ_NAME]; file_chgext (fname,bldname,".bld"); file_touch (user,bldname,1); } if (file_exist(fname)){ char bakname[MAXSIZ_NAME]; file_chgext (fname,bakname,".bak"); file_unlink (bakname); if (file_rename (fname,bakname)==-1){ xconf_error (MSG_U(E_NORENAMEF ,"Ne peut pas renommer le fichier\n%s\n à\n" "%s") ,fname,bakname); user->logerr ("Ne peut renommer %s -> %s\n" ,fname,bakname); } } mkf->setabsrev (fname,date,&newrev); } } done = 1; } static unsigned selintg = 0; static MAKEFILE *ptmkf; struct INTGDAT1_INFO { INTEGRE_DAT *intg; USERINFO *user; }; #ifdef MISSING /* Pr‚sente le travail pour un seul fichier. Retourne PAGE_VAL_USER1 si le fichier a ‚t‚ int‚gr‚. */ static PAGE_VAL intg_fct ( void *data) { INTGDAT1_INFO *info = (INTGDAT1_INFO *)data; INTEGRE_FILE *file = info->intg->item(selintg); PAGE_VAL ret = PAGE_VAL_NULL; if (file!=NULL) { // soyons un peu defensif... if (strchr(file->getfname(),'/')!=NULL){ // C'est un sous-r‚pertoire if (file->menudir(mskwin,cmd,but)) ret = PAGE_VAL_USER1; }else{ if (file->menu(mskwin,cmd,but,ptmkf,info->user)){ ret = PAGE_VAL_USER1; } } } return ret; } #endif /* Op‚ration sur fichier … int‚grer. */ PUBLIC void INTEGRE_DAT::menu ( USERINFO *user) { if (getnb() == 0){ xconf_error (MSG_U(E_NOINTG,"Rien a intégrer")); }else{ #ifdef MISSING PAGE_EDIT page ("integre menu"); char dir[MAXSIZ_PATH]; path_splitlex (fname,dir,NULL); path_splitlex (dir,NULL,dir); page_setuptitre (&page,MSGTIT_INTGDIR,dir); PAGE_EDIT spt (""); // Sous-page titre des colonnes page_setupfixestr (&spt,-1,MSGTIT_STATUT,-1); page_setupfixestr (&spt,-1,MSGTIT_AUTEUR,8); page_setupfixestr (&spt,-1,MSGTIT_REVISION,MAXSIZ_REVISION); page_setupfixestr (&spt,-1,MSGTIT_FICHIER,15); char sample = 1; page_setupenumvc (&spt,-1,&sample,1,"",0); spt.setboxtype (WINBOX_NO); spt.linedesign(); page.setup (-1,&spt,0); PAGE_PICK pick ("",14,&selintg); for (int i=0; iconflit(); if (file_exist (file->getfname())) conf = 3; static char *tbstatut[]={"++","-+","--","**"}; page_setupfixestr0 (sp,-1,tbstatut[conf],-1); if (conf == 3){ page_setupfixestr0 (sp,-1,"...",-1); page_setupfixestr0 (sp,-1,"...",-1); }else{ INTG_TRANS *tra = file->item(0); const char *rev_dir = tra->getrevdir(); page_setupfixestr0 (sp,-1,intgdat_rev2prog(rev_dir) ,-1); page_setupfixestr0 (sp,-1,rev_dir,-1); } // Si l'integration concerne un sous-r‚pertoire // soit la cr‚ation ou destruction, le r‚pertoire // est montr‚ avec un / … la fin pour le diff‚rencier // des fichiers. char fname[2*MAXSIZ_NAME]; strcpy (fname,file->getfname()); char *pt = strchr(fname,'/'); if (pt != NULL) pt[1] = '\0'; page_setupfixestr0 (sp,-1,fname,-1); page_setupenumvc (sp,-1,&file->done,1,"",0); sp->designlike (&spt); pick.setup (-1,sp,1); } } page.setup (-1,&pick,0); struct INTGDAT1_INFO inf; inf.intg = this; inf.user = user; int still_to_do = getnb(); int no = page_setupint (&page,MSGTIT_STILLTODO,&still_to_do,0,1000,0); page.setprotect (1,no); bouton_setupstd (&page,"cancel"); bouton_setupfct (&page,MSGBUT_INTG,K_ENTER,intg_fct,&inf); bouton_setupuser (&page,MSGBUT_EFFACE,K_NULL,PAGE_VAL_USER2); bouton_setupuser (&page,MSGBUT_SIMPLE,K_NULL,PAGE_VAL_USER3); bouton_setupuser (&page,MSGBUT_CLEAN,K_NULL,PAGE_VAL_USER4); fuslog_setbutton (&page,user); page.coldesign(); page.setspec (but); page.draw(); while (getnb()>0){ still_to_do = 0; for (i=0; idone) still_to_do++; } selintg = min(selintg,getnb()); page.reload(); page.drawitem(no); PAGE_VAL ret = page.edit(mskwin,cmd); if (cmd->is_load) break; if (ret == PAGE_VAL_USER1){ pick.reload(); pick.drawitem (selintg); }else if (ret == PAGE_VAL_USER2){ item(selintg)->efface(); pick.reload(); pick.drawitem (selintg); break; }else if (ret == PAGE_VAL_USER3){ for (i=0; iconflit(); if (conf < 2 && ! file_exist (file->getfname())){ file->select_tra (user,0,ptmkf); pick.reload(); pick.drawitem (i); } } }else if (ret == PAGE_VAL_USER4){ /* #Sp‚cification: fusion / ‚dition / marquage Chaque fichier … fusionner a un indicateur. Cela d‚termine si on a ou pas traiter ce fichier. De plus un compteur indique combien il reste de fichier … traiter. Un bouton "menage" permet d'‚liminer de la liste les fichiers d‚j… traiter. */ for (i=0; idone){ delet(i); pick.delfield(i); i--; } } if (getnb() != 0) pick.draw(); }else{ break; // cancel } } #endif } } static unsigned selitem=0; static char **pttb; #ifdef MISSING /* Pr‚sente le travail … faire pour un r‚pertoire. */ static PAGE_VAL projet_fct ( void *data) { USERINFO *user = (USERINFO *)data; char *fdat = pttb[selitem]; char path[MAXSIZ_PATH]; path_splitlex (fdat,path,NULL); SAVEPATH push; PAGE_VAL ret = PAGE_VAL_NULL; INTEGRE_DAT intg(fdat); fuslog_settitre(path); if (path_pushdir (user,path,&push)!=-1){ MAKEFILE mkf ("makefile.dat",1,path,user); ptmkf = &mkf; intg.menu(mskwin,cmd,but,user); mkf.save(); ret = intg.getnb() == 0 ? PAGE_VAL_USER1 : PAGE_VAL_NULL; path_popdir (&push); } return ret; } #endif /* Trouve tous les r‚pertoires o— ils y a des conflits … r‚gler et laisse interactivement l'usager faire le reste. */ void integre_do (USERINFO *user) { xconf_notice ("missing integre_do"); #ifdef MISSING char newpath[MAXSIZ_PATH]; // D‚pendant si c'est un USERBUILD ou USERINFO, on travaille dans // /kit/build ou dans l'environnement de l'usager user->makusrpath ("",newpath); SAVEPATH push; if (path_pushdir (user,newpath,&push)!=-1){ char *tb[1000]; pttb = tb; /* #Sp‚cification: fusion / ‚dition On balaye tous les r‚pertoires d'une r‚vision … la recherche des fichiers integre.dat. On cherche soit dans /kit/build si c'est l'‚dition d'une int‚gration, ou dans l'environnement usager si c'est une fusion "rattrapage" d'un usager. */ int nb = dir_getlistp ("integre.dat",100,tb,1000); if (nb <= 0){ xconf_error (MSG_R(E_NOINTG)); }else{ PAGE_EDIT page ("integre"); page_setuptitre (&page,MSGTIT_INTGALL); PAGE_PICK pick ("",15,&selitem); for (int i=0; iis_load) break; if (ret == PAGE_VAL_USER1){ // Ce r‚pertoire a ‚t‚ traiter complŠtement. // On l'‚limine de la liste. pick.delfield (selitem); free (tb[selitem]); memmove (tb+selitem,tb+selitem+1,(nb-selitem)*sizeof(tb[0])); nb--; if (pick.nbfield()==0) break; pick.draw(); }else{ break; // cancel } } } tbstr_free (tb,nb); path_popdir (&push); } #endif }