#include #include #include #include #include #include #include #include #include #include "proto.h" #include "proto.m" /* Sépare en plusieurs fichiers une série de prototype de fonction membres */ static void near splitcp_one (const char *path, const char *ext, int verbose) { CPLUS cplus; char locpath[MAXSIZ_PATH]; if (path[0] == '\0'){ path_getcwd (locpath,MAXSIZ_PATH); path_splitlex (locpath,NULL,locpath); file_chgext (locpath,locpath,".pm"); path = locpath; } if (verbose >= 1) printf ("%s\t-> *%s\n",path,ext); cplus_parse (&cplus,path); cplus_makepp (&cplus,ext,verbose); cplus_end (&cplus); } /* Combine des prototypes de fonction membres dans un header */ static void near splitcp_merge0 ( const char *dest, /* Header à produire */ const char *head, /* Header à lire */ const char *from, /* Fichier de prototypes C++ */ int verbose) { CPLUS cplus; int ret = 0; int srcisdst = path_cmp (dest,head) == 0; char headtmp[MAXSIZ_PATH]; char headwrk[MAXSIZ_PATH]; if (verbose) printf ("%s + %s -> %s\n",head,from,dest); cplus_parse (&cplus,from); if (vfilebak_before (dest,".old",headtmp,headwrk,true) != -1){ /* #Spécification: Fichiers / fonctions membres / Répertoire virtuels Lors de la mise à jour d'un fichier contenant des déclaration de classe (insertion des prototypes), le fichier est localisé et lue à partir du makefile.dat. Si le fichier n'existait pas réellement et qu'il n'est pas modifié, le fichier résultat est éliminé. */ int dest_exist = file_exist (dest); /* Existe réellement ? */ FILE *fin = vfopen_err (srcisdst ? headtmp : head,"r",1); { struct stat st; if (stat(headwrk,&st)!=-1){ // fprintf (stderr,"chmod: %s\n",headwrk); chmod (headwrk,st.st_mode | 0200); } } FILE *fout = fopen_err (headwrk ,"w",1); char line[300]; int diff = 0; char *strnew = (char*)malloc_err (30000,1); char *strold = (char*)malloc_err (30000,1); while (fgets(line,sizeof(line)-1,fin)!=NULL){ char *pt = str_skip (line); if (strncmp(pt,"/*~PROTOBEG~",12)==0){ char cls[100]; char *ptcls = cls; pt = str_skip (pt+12); while (isalnum(*pt) || *pt == '_' || *pt == ':'){ *ptcls++ = *pt++; } *ptcls = '\0'; fputs (line,fout); cplus_merge (&cplus,cls,strnew); /* Attention: Borland fputs retourne dernier caractère écrit. Si la chaine est vide, retourne le caractère avant la chaine (transformé en int), donc peut-être EOF. */ if (strnew[0] != '\0'){ ret |= proto_fputs (strnew,fout) == -1 ? -1 : 0; } { int ok = 0; char *ptold = strold; *ptold = '\0'; while (fgets(line,sizeof(line)-1,fin)!=NULL){ char *pt = str_skip (line); if (strncmp(pt,"/*~PROTOEND~",12)==0){ ok = 1; fputs (line,fout); break; }else if (line[0] == '}' && line[1] == ';'){ fprintf (stderr,MSG_B(E_MISSPROTOEND ,"Fichier %s classe %s: }; " "rencontré avant /*~PROTOEND~\n" "Abandonne révision\n" ,"File %s class %s: }; " "met before /*~PROTOEND~\n" "Abort revision\n") ,head,cls); ok = 1; /* Note que erreur déjà signalé */ ret = -1; }else{ ptold = stpcpy (ptold,line); } } { int diffcls = strcmp_nocr(strnew,strold); if (diffcls && verbose) printf ("\t! %s\n",cls); diff |= diffcls; } if (!ok){ ret = -1; fprintf (stderr,MSG_B(E_NOPROTOEND ,"Marqueur /*~PROTOBEG~ %s */ " "sans marqueur /*~PROTOEND~ */ correspondant\n" ,"/*~PROTOBEG~ %s */ marker without " "corresponding /*~PROTOEND~ */\n"),cls); } } }else{ fputs (line,fout); } } free (strold); free (strnew); fclose (fin); fclose (fout); if (ret != -1 && diff){ vfilebak_ok (dest,".old",headtmp,headwrk); if (verbose){ file_chgext (dest,headtmp,".old"); printf ("\t(%s->%s)\n",dest,headtmp); } }else{ if (ret == -1){ fprintf (stderr,MSG_B(E_WRITING ,"Erreur d'écriture du fichier %s\nRétablit l'état initial\n" ,"write error on file %s\nrestoring state\n"),head); } vfilebak_abort (dest,".old",headtmp,headwrk); if (!dest_exist) file_unlink (dest); } }else if (!vdir_exist (dest,NULL)){ fprintf (stderr,MSG_B(E_NOFILE ,"Fichier %s n'existe pas\n" "traitement -b%s+%s=%s annulé\n" ,"File %s does not exist\n" "-b%s+%s=%s aborted") ,dest,head,from,dest); }else if (!file_writeok (dest)){ fprintf (stderr,MSG_B(E_CANTMODIFY ,"Ne peut pas modifier le fichier %s: Problème de permission ?\n" "traitement -b%s+%s=%s annulé\n" ,"Can't update File %s: Possible permission problem\n" "-b%s+%s=%s aborted") ,dest,head,from,dest); }else{ fprintf (stderr,MSG_B(E_CANTPRESERVE ,"Ne peut pas préserver une version .old du fichier %s\n" "traitement -b%s+%s=%s annulé\n" ,"Can't preserve a .old version of file %s\n" "-b%s+%s=%s aborted") ,dest,head,from,dest); } cplus_end (&cplus); } /* Combine des prototypes de fonction membres dans un header */ static void near splitcp_merge (char *cmd, int verbose) { const char *head = cmd; if (head[0] == '\0'){ char headf[MAXSIZ_PATH]; char fromf[MAXSIZ_NAME]; path_getcwd (headf,MAXSIZ_PATH); path_splitlex (headf,NULL,headf); strcpy (fromf,headf); file_chgext (headf,headf,".hpp"); file_chgext (fromf,fromf,".pm"); if (file_exist (headf)){ splitcp_merge0 (headf,headf,fromf,verbose); }else{ file_chgext (headf,headf,".h"); if (file_exist (headf)){ splitcp_merge0 (headf,headf,fromf,verbose); }else{ fprintf (stderr,MSG_B(E_FINDFILE ,"Ne trouve pas le fichier à composer %s\n" ,"Can't locate file to compose %s\n"),headf); } } }else{ char *from = strchr(cmd,'+'); if (from == NULL){ char fromf[MAXSIZ_PATH]; file_chgext (head,fromf,".pm"); splitcp_merge0(head,head,fromf,verbose); }else{ char *dest = strchr (from+1,'='); *from++ = '\0'; if (dest == NULL){ splitcp_merge0(head,head,from,verbose); }else{ *dest++ = '\0'; splitcp_merge0(dest,head,from,verbose); } } } } static char *tb[20]; static char *tbext[20]; static char tbopr[20]; static int nbdo=0; void splitcp_do (int verbose) /* 0,1,2 */ { int i; for (i=0; i