/* lecture et gestion de déclaration de prototype */ #include #include #include #include "assert.h" #include #include #include #include #include #include "proto.h" #include "proto.m" /* Lecture d'un bloc de plus de 32k Retourne nombre de byte lue ou -1 */ static long near readl (int fd, char *buf, long size) { char *debbuf = buf; long nbread = 0; while (size > 0){ int sizer = size > 32000 ? 32000 : (int)size; size -= sizer; sizer = read(fd,buf,sizer); if (sizer > 0){ nbread += sizer; buf = debbuf +nbread; }else{ nbread = -1; break; } } return (nbread); } /* Initialise la lecture d'un fichier .p .nap ou .nar Le fichier est lue au complet dans un buffer Le buffer sera termine par un 0 Retourne 0 si ok, -1 si erreur */ static int filep_read (TXTTB *txttb, const char *fpath) { int ok = -1; long size = vdir_size (fpath,NULL); #if 0 if (size > 0 && size < 64000l){ #endif if (size > 0){ int fd = vopen (fpath,O_RDONLY,0); if (fd != -1){ long newsiz; txttb->buf = (char*) farmalloc_err (size+1,1); txttb->tb = (TXTPTR*) malloc_err(sizeof(TXTPTR)*400,1); if ((newsiz=readl(fd,txttb->buf,size))> 0){ char *pt = txttb->buf + newsiz; *pt = '\0'; ok = 0; } close (fd); } } return (ok); } /* Convertit la date d'un entete pt pointe sur le premier caractère de la date */ static unsigned long near filep_getdate (const char *pt) { return ((unsigned long)date_a2u(pt)<<16) + time_a2u0(pt+9,'.'); } static void near filep_realloc (TXTTB *txttb, int nbsrc) { txttb->nbsrc = nbsrc; txttb->tb = (TXTPTR*) realloc(txttb->tb,(nbsrc+1)*sizeof(TXTPTR)); assert (txttb->tb!=NULL); } /* lit en mémoire un fichier de prototypes .p retourne le nombre de source contenu dans fpath si ok, -1 si erreur */ int filep_readp (TXTTB *txttb, const char *fpath) { int nbsrc = -1; if (filep_read(txttb,fpath)==0){ char *pt = txttb->buf; char *lastpt = ""; TXTPTR *ptr = txttb->tb; int first = 1; nbsrc = 0; while (pt != NULL){ char *finnom = strchr (pt+3,' '); if (strncmp(pt,"/* ",3)!=0 || finnom == NULL){ fprintf (stderr,MSG_B(E_IVLDFORMAT ,"Format invalide, fichier %s\n\t%60.60s\n" ,"Invalid format, file %s\n\t%60.60s\n") ,fpath,pt); exit (-1); }else if (nbsrc>=400){ fprintf (stderr, MSG_B(E_TOOMANYSRC ,"Trop de fichier source dans %s\n" ,"Too many source file in %s\n"),fpath); exit (-1); }else{ if (!first){ *(pt-1) = '\0'; } first = 0; *finnom = '\0'; strcpy (ptr->nomf,pt+3); *finnom = ' '; ptr->txt = lastpt = pt; ptr->date = filep_getdate(finnom+1); ptr++; nbsrc++; pt = strstr (finnom+22,"/*"); } } str_strip (lastpt,lastpt); filep_realloc(txttb,nbsrc); } return (nbsrc); } /* Trouve un entete fonction fichier et identifie le fichier finnom pointe sur le caractère avant la date Retourne ptr vers debut de l'entete */ static char * near findnapfct (char *pt, char *nomsrc, const char *fpath) { char *entete = pt; while (1){ entete = strchr (entete,'~'); if (entete != NULL){ entete -= 2; if (strncmp(entete,"/*~",3)==0){ char *debnom = strchr(entete,'!'); if (debnom == NULL){ debnom = strchr(entete,':'); if (debnom != NULL){ *debnom = '!'; }else{ fprintf (stderr,MSG_B(E_IVLFORMAT ,"Fichier %s: format invalide\n" ,"File %s: invalid format\n"),fpath); exit (-1); } } assert (debnom != NULL); debnom += 2; while (*debnom != ' ') *nomsrc++ = *debnom++; *nomsrc = '\0'; break; }else{ /* le ~ a ete place par le programmeur dans ses commentaires */ entete +=3; } }else{ break; } } return entete; } /* lit en mémoire un fichier de prototypes .nap retourne le nombre de source contenu dans fpath si ok, -1 si erreur */ int filep_readnap (TXTTB *txttb, const char *fpath) { int nbsrc = -1; if (filep_read(txttb,fpath)==0){ char *pt = txttb->buf; char *lastpt=""; TXTPTR *ptr = txttb->tb; char nomsrc[20]; nbsrc = 0; pt = findnapfct (pt,ptr->nomf,fpath); if (pt != NULL){ ptr->txt = pt; ptr->date = filep_getdate(pt+3); pt += 10; /* arbitraire */ while ((pt = findnapfct (pt,nomsrc,fpath)) != NULL){ if (strcmp(ptr->nomf,nomsrc)!=0){ /* nouvelle fonction */ *(pt-1) = '\0'; /* termine chaine pour source */ /* precedant */ ptr++; assert (nbsrc<400); nbsrc++; strcpy (ptr->nomf,nomsrc); ptr->txt = lastpt = pt; ptr->date = filep_getdate(pt+3); } pt = pt + 10; } nbsrc++; /* dernier source accumule */ } str_strip (lastpt,lastpt); filep_realloc (txttb,nbsrc); } return (nbsrc); } /* Trouve le nom du source dans une ligne de fichier nar. Corrige au passage le : (mark) pour un ! (nouveau séparateur). Retourne NULL si fin de fichier, pointeur sur début de ligne sinon. */ static char *near findnarfct ( char *pt, /* Pointe au début de la ligne */ char *nomsrc, /* Contiendra le nom du fichier source */ char mark, /* Marqueur entourant le nom de la fonction */ const char *fpath) /* Nom du fichier pour message d'erreur */ { char *deblin = NULL; if (pt[0] >= ' ' && pt[1] == mark){ pt[1] = '!'; deblin = pt; pt = strchr (pt+3,mark); if (pt == NULL){ fprintf (stderr,MSG_R(E_IVLFORMAT),fpath); exit(-1); } pt[0] = '!'; pt += 2; while (*pt > ' ') *nomsrc++ = *pt++; *nomsrc = '\0'; } return (deblin); } /* lit en mémoire un fichier de prototypes .nar retourne le nombre de source contenu dans fpath si ok, -1 si erreur */ int filep_readnar (TXTTB *txttb, const char *fpath) { int nbsrc = -1; if (filep_read (txttb,fpath)!=-1){ char *pt = txttb->buf; char *lastpt = pt; char mark = pt[1]; /* Détermine dynamiquement le séparateur */ TXTPTR *ptr = txttb->tb; nbsrc = 0; if (mark != '!' && mark != ':'){ fprintf (stderr,MSG_R(E_IVLFORMAT),fpath); exit (-1); } if ((pt = findnarfct(pt,ptr->nomf,mark,fpath))!=NULL){ char nomsrc[20]; ptr->txt = pt; ptr->date = filep_getdate(pt+2); pt = strchr(pt,'\n')+1; while ((pt = findnarfct(pt,nomsrc,mark,fpath))!=NULL){ if (strcmp(ptr->nomf,nomsrc)!=0){ /* nouvelle fonction */ *(pt-1) = '\0'; /* termine chaine pour source */ /* precedant */ ptr++; assert (nbsrc<400); nbsrc++; strcpy (ptr->nomf,nomsrc); ptr->txt = lastpt = pt; ptr->date = filep_getdate(pt+2); } pt = strchr(pt,'\n')+1; } nbsrc++; /* dernier source accumule */ } str_strip (lastpt,lastpt); /* ellimine dernier \n */ filep_realloc (txttb,nbsrc); } return (nbsrc); } /* Localise le nom d'un source dans un fichier *.p précédemment lue Retourne -1 si trouve pas, indice d'accès sinon (>=0) */ int filep_locate ( TXTTB *tb, const char *nomsrc, unsigned long *date) /* Contiendra la date du source lorsque le */ /* .p,.nap,etc... a été construit ou -1 */ { int ok = -1; int nbsrc = tb->nbsrc; TXTPTR *ptr = tb->tb; int nosrc; *date = (unsigned long)-1; for (nosrc=0; nosrcnomf,nomsrc)==0){ ok = nosrc; *date = ptr->date; break; } } return ok; } /* Réécrit dans un fichier *.p le contenu précédemmant lue pour un source Le source a été localisée avec filep_locate() */ void filep_write (FILE *fout, TXTTB *tb, int nosrc) { if (nosrc >= 0) fprintf (fout,"%s\n",tb->tb[nosrc].txt); } #ifdef TEST static TXTTB lstp; static TXTTB lstnap; static TXTTB lstnar; static void near test (const char *nomfct) { filep_write (MODE_ORDIN,&lstp ,nomfct); filep_write (MODE_ORDIN|MODE_COMMENT,&lstnap,nomfct); filep_write (MODE_ORDIN|MODE_INDEX,&lstnar,nomfct); } void main(void) { if (filep_readp (&lstp,"proto.p")!=-1 && filep_readnap (&lstnap,"proto.nap")!=-1 && filep_readnar (&lstnar,"proto.nar")!=-1){ protof_defmode (MODE_ORDIN); protof_open ("toto.p","w"); protof_defmode (MODE_ORDIN|MODE_COMMENT); protof_open ("toto.nap","w"); protof_defmode (MODE_ORDIN|MODE_INDEX); protof_open ("toto.nar","w"); test ("CPROTO.C"); test ("OUTSRC.C"); protof_close (); } } #endif