#include #include #include "projet.h" #include "projetx.m" #include "fusion.h" struct TBREV { VERSION_ONE *tb[400]; int nb; }; /* Ajoute une r‚vision dans un tableau. InsŠre en ordre de r‚vision. Si la r‚vision est d‚j… l…, elle est retir‚e. Retourne le nouveau nombre de r‚vision dans la table. */ static int near bfusion_addrev ( TBREV &revs, VERSION_ONE *newone, int &change, // Indique quel item de la table a chang‚e int &efface, // Indique que l'item a ‚t‚ effac‚ int doefface) // Efface si deja la ou conserve ? { int noins = 0; change = -1; efface = 0; const REVISION *newrev = newone->getrev(); int i; for (i=0; icmp(revs.tb[i]->getrev()); if (cmp==0){ noins = 1; if (doefface){ revs.nb--; for (; ii; r--) revs.tb[r] = revs.tb[r-1]; revs.tb[i] = newone; change = i; revs.nb++; } } return revs.nb; } /* Programme une grille d'‚dition dans un page. Permet d'associe des r‚vision (revs.tb) a des r‚f‚rences (refs.tb). (une r‚f‚rence par r‚vision). */ static void near bfusion_setgrille ( PAGE_EDIT &page, TBREV &revs, // Lignes TBREV &refs, // Colonnes char rev2ref[]) { char buf[100]; if (refs.nb == 0){ buf[0] = ' '; buf[1] = '\0'; }else{ char *ptbuf = buf; for (int i=0; igetrev()->format (ptbuf); strcat (ptbuf," "); ptbuf += strlen(ptbuf); } } int lenbuf = strlen(buf); page.zap(); page_setuptitre (&page,MSGTIT_GRILLE); PAGE_EDIT *sp1 = new PAGE_EDIT (""); sp1->setboxtype (WINBOX_NO); page_setupfixestr0 (sp1,-1,"",MAXSIZ_REVISION); page_setupfixestr0 (sp1,-1,buf,lenbuf); sp1->linedesign(); page.setup (-1,sp1,1); PAGE_EDIT *sp2 = new PAGE_EDIT (""); sp2->setboxtype (WINBOX_NO); sp2->setscrollv (9); for (int i=0; igetrev()->format(revstr); page_setupfixestr0 (sp2,-1,revstr,MAXSIZ_REVISION); if (refs.nb > 0){ page_setupenumvc (sp2,-1,&rev2ref[i],refs.nb,buf,0); }else{ page_setupfixestr0 (sp2,-1,"",lenbuf); } } // S'assure que la page sp2 n'est jamais vide et de largeur // identique a sp1. On ajoute des champs bidon a la fin. page_setupfixestr0 (sp2,-1,"",MAXSIZ_REVISION); page_setupfixestr0 (sp2,-1,"",lenbuf); sp2->linedesign0(2); page.setup (-1,sp2,1); page.coldesign(); } /* Lit un fichier memo et preprogramme une partie de la grille de s‚lection */ static void bfusion_readmemo ( USERINFO *user, VERSION_DAT &version, TBREV &revs, TBREV &refs, char rev2ref[]) { /* #Sp‚cification: fusion / composition / fichier preset Avec le nombre de programmeur qui augmente, la s‚lection des composantes pour une int‚gration devient plus hasardeuse. Sp‚cialement dans le cas o— on doit int‚grer des r‚visions relative … une r‚f‚rence relativement vieille. On a souvent le sc‚nario suivant. "Salut! Je suis le programmeur X et je viens de livrer 4.10.40.2. 4.10.40.1 avait ‚t‚ int‚grer dans 4.11. Pourrait tu t'assurer que ces corrections seront fusionn‚es dans 4.30. Merci!" Voici une solution qui permet d'aider l'int‚grateur. Lors de l'int‚gration de 4.30, projetp consulte le fichier /kit/build/_430.itg. Si pr‚sent, il s'en servira pour initialiser la grille de s‚lection de l'int‚gration. Dans le cas d'une fusion dans l'espace usager, le meme fichier sera consult‚ mais dans le HOME de l'usager. Ce fichier est en format texte. Il contient une paire de revision par ligne. Les r‚visions sont en format "lisible" (x.x.x.x). La premiŠre est la r‚vision a int‚grer. La seconde est la r‚f‚rence a utiliser. Dans l'exemple pr‚c‚dant, l'int‚grateur inscrirait simplement 4.10.40.2 4.10.40.1 Ce fichier supporte les commentaires … la makefile avec le #. */ char path[MAXSIZ_PATH]; user->makusrpath ("",path); file_chgext (path,path,".itg"); // Ce fichier est optionnel. Pas d'erreur si absent FILE *fin = fopen (path,"r"); if (fin != NULL){ char buf[200]; struct { VERSION_ONE *rev; VERSION_ONE *ref; }tb[200]; int nb = 0; while (fgets_strip(buf,sizeof(buf)-1,fin,'\\','#',NULL)!=NULL){ char *ptrev = str_skip (buf); char *pt = str_skipword (ptrev); if (*pt != '\0'){ *pt++ = '\0'; pt = str_skip (pt); REVISION rev (ptrev); REVISION ref (pt); VERSION_ONE *onerev = version.get(&rev); if (onerev == NULL){ error_showdef (MSGERR_IVLDREVISION,ptrev); }else{ VERSION_ONE *oneref = version.get(&ref); if (oneref == NULL){ error_showdef (MSGERR_IVLDREVISION,pt); }else{ tb[nb].rev = onerev; tb[nb].ref = oneref; nb++; } } } } fclose (fin); int change,efface; for (int i=0; iis_load){ break; }else{ page.save(); VERSION_ONE *one = version.get (select); if (val == PAGE_VAL_ABORT){ break; }else if (val == PAGE_VAL_OK){ if (revs.nb == 0 || refs.nb == 0){ error_showdef (MSGERR_NOREV); }else{ VERSION_PAIRE *ptp = tbpaires; for (int i=0; ivar = revs.tb[i]; // Attention, un champs enum doit ˆtre interpr‚t‚ // diff‚remment quand il y a un seul choix. // On s'en fout, parce que s'il y a une seule // r‚f‚rence elle est s‚lectionn‚ pour toutes // les r‚visions. // Quand il y a plusieurs r‚f‚rences, le champs // agit comme un s‚lecteur et non comme un booleen. ptp->ref = refs.nb == 1 ? refs.tb[0] : refs.tb[rev2ref[i]]; } ret = revs.nb; break; } }else{ int change_ref = -1; int change_rev = -1; if (val == PAGE_VAL_USER2){ int efface; bfusion_addrev (revs,one,change_rev,efface,1); if (change_rev >=0){ // On a ajout‚ ou retirer une ligne // Il faut donc synchroniser rev2rev if (efface){ for (int i=change_rev; ichange_rev; i--){ rev2ref[i] = rev2ref[i-1]; } rev2ref[change_rev] = 0; } } }else if (val == PAGE_VAL_USER3){ int efface; bfusion_addrev (refs,one,change_ref,efface,1); if (change_ref >=0){ // On a ajout‚ ou retirer une colonne // Il faut donc synchroniser rev2rev int add = efface ? -1 : 1; for (int i=0; i= change_ref){ rev2ref[i] += add; } } } } if (change_ref >= 0 || change_rev >= 0){ if (change_ref >= 0){ page.closewin(); }else{ combine.closewin(); } bfusion_setgrille(combine,revs,refs,rev2ref); if (change_ref >= 0){ sp.linedesign(); page.coldesign(); page.draw(); }else{ combine.draw(); } } } } } return ret; }