/* A partir d'un fichier contenant des prototypes et des commentaires, produit un index permutte dans un fichier Chaque ligne de l'index aura le format suivant chaine index 60 caractere de long, index a la colonne 30 Separateur " : " nom_fonction a la suite fichier source a la suite de nom_fonction separee par un espace librairie source a la suite de fichier source Le fichier ne contiendra aucun tab */ #include #include #include #include #include #include #include #include "permut.h" #include "nadoc.m" #define NAPERM_VERSION 2 #define NAPERM_RELEASE 9 static void showver() { fprintf (stderr,"naperm %d.%d (linuxconf-tools %d.%d)\n" ,NAPERM_VERSION,NAPERM_RELEASE ,TOOLS_VERSION,TOOLS_RELEASE); } static void near usage (const char *argv0) { showver(); static const char *msg = MSG_B(I_USAGEPERM ,"Usage : naperm [-f] [-m[dir]] [-s] [-v]\n" " [Prototypes Index [Sommaire] [historique]]\n" "\n" " Prototypes est produit par proto.exe.\n" " L'option '-c__d de proto.exe a été utilisée.\n" "\n\n" " Index sera un index permutté.\n" " Sommaire sera un résumé de fichier_prototype.\n" " Historique retrace l'évolutions des fonctions.\n" " d'un système.\n" " prototype, Index et Sommaire peuvent être des listes.\n" " ex: naperm *.nap *.nai *.nas *.nah\n" " Si Index == '-', pas d'index permutté produit.\n" " Si Sommaire == '-', pas de sommaire produit.\n" " -f : Index, Sommaire et Historique seront produit même si\n" " Prototypes est moins récent.\n" " -m : Extensions standards\n" " naperm -m -> naperm *.nap *.nai *.nas\n" " naperm -mxxx -> naperm xxx/*.nap xxx/*.nai xxx/*.nas\n" " xxx/*.nah\n" " -s : Ne signale pas les fonctions qui n'ont pas de sommaire.\n" " -v : N'affiche pas d'information sur traitement.\n" "\n" " Exemple:\n" " proto -cod -fprojet.nap *.c\n" " naperm projet.nap projet.nai projet.nas projet.nah\n" ,"Usage : naperm [-f] [-m[dir]] [-s] [-v]\n" " [Prototypes Index [Sommary] [historic]]\n\n" "\n" " Prototypes are extracted using PROTO.exe.\n" " proto's option '-c__d' requiered.\n" "\n\n" " Index will be a permutted index.\n" " Summary will be a function quick reference.\n" " Historic will trace the evolution of the functions.\n" " prototype, Index, Summary and Historic may be wildcard.\n" " ex: naperm *.nap *.nai *.nas *.nah\n" " If Index == '-', no index generated.\n" " If Summary == '-', no summary generated.\n" " -f : Index, Summary and Historic are produced even\n" " if Prototypes are older.\n" " -m : Standard operation.\n" " naperm -m -> naperm *.nap *.nai *.nas *.nah\n" " naperm -mxxx -> naperm xxx/*.nap xxx/*.nai xxx/*.nas\n" " xxx/*.nah\n" " -s : No warning for function without documentation.\n" " -v : Silent processing.\n" "\n" " Example:\n" " proto -cod -fproject.nap *.c\n" " naperm project.nap project.nai project.nas project.nah\n" ); fputs (msg,stderr); } static char librairie[100]; static FILE *fout; static void output (char *index, char *info) { fprintf (fout,"%s : %s %s\n",index,info,librairie); } /* La prochaine ligne doit commencer par un commentaire. Si ce n'est pas le cas, retourne -1 Si c'est le cas, buffer contiendra la premiere ligne de ce commentaire. Retourne 0 pour ok */ static int near getindex (FILE *fin, char *buffer) { int ok = -1; if (fgets(buffer,200,fin)!=NULL && (strncmp(buffer,"/*",2)==0 || strncmp(buffer,"//",2)==0)){ char *pt = buffer+2; do{ pt = str_skip(pt); if (*pt != '\0'){ char *last = pt + strlen(pt)-2; if (strcmp (last,"*/")==0) *last = '\0'; strcpy (buffer,pt); ok = 0; break; } pt = buffer; }while (fgets(buffer,200,fin)!=NULL); } return (ok); } /* lit le fichier source et retrouve le premier commentaire de chaque declaration. Pour chaque ligne retrouve, note aussi de quel fichier source il provenait Retourne le nombre de ligne lue */ static int collect ( const char *file, PERMUT_LINE *lines, int signal) /* != 0 : imprime message pour sommaire manquant */ { int nbline = 0; FILE *fin = vfopen_err (file,"r",1); char buffer[200]; char fichier[100]; char fonction[100]; while (fgets (buffer,sizeof(buffer),fin)!=NULL){ /* Cherche une ligne avec le format *~fonction! fichier * ou *~fonction: fichier * (vieux fichiers) Peut rencontrer un format analogue avec une date a la place d'une fonction */ if (strncmp(buffer,"/*~",3)==0 && !isdigit(buffer[4])){ char *pt = strchr (buffer,'!'); if (pt==NULL) pt = strchr(buffer,':'); if (pt!=NULL){ char info[100]; *pt = '\0'; strcpy (fonction,buffer+3); strcpy (fichier,pt+2); fichier[strlen(fichier)-4] = '\0'; sprintf (info,"%s %s",fonction,fichier); /* un commentaire (index) suit immediatement (il peut etre manquant) */ if (getindex (fin,buffer)!=-1){ permut_cnvtxt (buffer); lines->txt = strdup_err (buffer,1); lines->info = strdup_err (info,1); lines++; nbline++; }else{ lines->txt = strdup_err ("",1); lines->info = strdup_err (info,1); lines++; nbline++; if (signal){ printf ("*** Sommaire : %s\n",info); } } } } } fclose (fin); return (nbline); } /* Genere index permutte pour un fichier source Retourne -1 si erreur, 0 si ok */ static int near permpaire ( PERMUT_LINE *lines, /* ligne à permutter */ int nbline, /* nombre de lignes dans lines */ const char *dest) /* fichier à produire */ { int ok = -1; fout = fopen_err (dest,"w",0); if (fout != NULL){ PERMUT_ITEM *items = (PERMUT_ITEM*) malloc_err (8000 * sizeof (PERMUT_ITEM),1); int i; int nbitem = 0; PERMUT_ITEM *ptitem = items; PERMUT_LINE *ptline = lines; for (i=0; iinfo,pt2->info)); } /* produit un fichier sommaire */ static int makesomm ( PERMUT_LINE *lines, int nbline, const char *somm) { int ok = 0; FILE *fout = fopen_err (somm,"w",0); if (fout == NULL){ ok = -1; }else{ hsort (lines,nbline,sizeof(PERMUT_LINE),cmp); { int i; int maxlen = 0; for (i=0; imaxlen) maxlen = len; } for (i=0; i file_date(source)) ok = 1; } return (ok); } /* Produit l'index permutté et le sommaire pour un fichier source Retourne 0 si ok, !=0 si erreur */ static int produit ( const char *source, const char *index, const char *somm, const char *histo, int condit, int verbose, int signal) { int ret = 0; int okperm = dest_isok(source,index,condit); int oksomm = dest_isok(source,somm,condit); int okhist = dest_isok(source,histo,condit); PERMUT_LINE *lines=NULL; int nbline = 0; if (okperm == 0 || oksomm == 0){ lines = (PERMUT_LINE*) malloc_err (1000 * sizeof(PERMUT_LINE),1); nbline = collect (source,lines,signal); } { if (oksomm>=0){ const char *res = "[ok]"; if (oksomm==0){ int err = makesomm (lines,nbline,somm); ret |= err; res = err ? "err" : "ok"; } if (verbose) printf ("%s %s %s\n",source,somm,res); } if (okperm>=0){ const char *res = "[ok]"; if (okperm==0){ int err = permpaire (lines,nbline,index); ret |= err; res = err ? "err" : "ok"; } if (verbose) printf ("%s %s %s\n",source,index,res); } if (okhist>=0){ const char *res = "[ok]"; if (okhist==0){ int err = histo_update (histo,source); ret |= err; res = err ? "err" : "ok"; } if (verbose) printf ("%s %s %s\n",source,histo,res); } } { int i; for (i=0; i %s\n" ,"**** No connection %s -> %s\n") ,lst[i],index); ok = -1; } } if (somm[0] != '-'){ if (file_correspond (source,lst[i],somm,fsomm)==-1){ fprintf (stderr,MSG_R(E_NOCONNECTION) ,lst[i],somm); ok = -1; } } if (histo[0] != '-'){ if (file_correspond (source,lst[i],histo,fhisto)==-1){ fprintf (stderr,MSG_R(E_NOCONNECTION),lst[i],histo); ok = -1; } } ok = produit (lst[i],findex,fsomm,fhisto,condit,verbose,signal); free (lst[i]); } }else{ ok |= produit (source,index,somm,histo,condit,verbose,signal); } return ok; } int main (int argc,char *argv[]) { etc_loadmsg(); int ok = -1; ARGP argp[26]; argc = anlparm (argc,argv,argp,"fmsv"); if (argc == 0){ usage (argv[0]); }else{ int verbose = argp['v'-'a'].ptr == NULL; int condit = argp['f'-'a'].ptr == NULL; int signal = argp['s'-'a'].ptr == NULL; char *ptm = argp['m'-'a'].ptr; if (ptm != NULL){ char source[MAXSIZ_PATH]; char index[MAXSIZ_PATH]; char somm[MAXSIZ_PATH]; char histo[MAXSIZ_PATH]; path_make (ptm,"*.nap",source); path_make (ptm,"*.nai",index); path_make (ptm,"*.nas",somm); path_make (ptm,"*.nah",histo); ok = dofile (source,index,somm,histo ,condit,verbose,signal); } if (argc > 1){ if (argc > 2){ ok = dofile (argv[1],argv[2],argc >= 4 ? argv[3] : "-" ,argc == 5 ? argv[4] : "-" ,condit,verbose,signal); }else{ fprintf (stderr,MSG_B(E_IVLDARG ,"Argument invalide\n","Invalid argument\n")); ok = -1; } }else if (ptm == NULL){ usage(argv[0]); } } return ok; }