#pragma implementation /* #Spécification: classe / Présentation Après avoir extrait la composition des classes avec proto (option -q) on construit un joli rapport présentant sous forme d'arbre la relation entre les classes. */ #include #include #include #include #include #include "clsinfo.h" #include "nadoc.m" PUBLIC CLS_INFO::CLS_INFO(const char *_nom) { nom = strdup_err (_nom,1); nbbase = 0; nbprint = 0; } PUBLIC CLS_INFO::~CLS_INFO() { free (nom); } PUBLIC CLS_DERIVE::CLS_DERIVE( CLS_INFO *_info, CLS_INFO *_base, const char *_opt) { info = _info; base = _base; opt = strdup_err (_opt,1); info->nbbase++; } PUBLIC CLS_DERIVE::~CLS_DERIVE() { free (opt); } PUBLIC CLS_INFO *CLS_INFOS::getitem (int no) const { return (CLS_INFO*)ARRAY::getitem(no); } PUBLIC CLS_DERIVE *CLS_DERIVES::getitem (int no) const { return (CLS_DERIVE*)ARRAY::getitem(no); } PUBLIC CLS_INHER *CLS_INHERS::getitem (int no) const { return (CLS_INHER*)ARRAY::getitem(no); } PUBLIC CLSFORM::CLSFORM () { /* Assure que la classe racine est la première enregistrée */ /* Pour clsform_unknown */ addclass ("-"); } PUBLIC CLSFORM::~CLSFORM () { } /* Ajoute un record pour une classe. Si la classe est deja la, retourne son record sans ajouter. Retourne pas si manque de place. */ PUBLIC CLS_INFO *CLSFORM::addclass (const char *nom) { CLS_INFO *ret = NULL; int nbinfo = infos.getnb(); for (int i=0; inom,nom)==0){ ret = inf; break; } } if (ret == NULL){ ret = new CLS_INFO (nom); infos.add (ret); } return ret; } /* Ajoute de l'information sur une dérivation. */ PUBLIC void CLSFORM::addder ( CLS_INFO *info, /* Classe a documenter */ CLS_INFO *base, /* Classe de base d'où provient info */ const char *opt) /* Option de dérivation */ { ders.add (new CLS_DERIVE (info,base,opt)); } /* Lit un fichier produit par option -q de proto. Cette fonction peut être appelée plusieurs fois. Retourne -1 si erreur, nombre de ligne lue sinon. */ PUBLIC int CLSFORM::read (const char *fname) { int ret = 0; FILE *fin = fopen_err (fname,"r",1); char buf[300]; while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ char cls_cur[100]; char cls_base[100]; char exp[100]; char virt[100]; int nb = sscanf(buf,"%s %s %s %s",cls_cur,cls_base,exp,virt); if (nb == 4){ char option[100]; CLS_INFO *info = addclass (cls_cur); CLS_INFO *base = addclass (cls_base); if (virt[0] == '-'){ if (exp[0] == '-'){ option[0] = '\0'; }else{ strcpy (option,exp); } }else{ sprintf (option,"%s %s",exp,virt); } addder (info,base,option); ret++; }else if (nb > 0){ fprintf (stderr,MSG_U(E_IVLDFORMATLINE ,"File %s, line %d: invalid format\n\t\n") ,fname,ret+1,buf); ret = -1; break; } } fclose (fin); return ret; } /* Ajoute des définitions bidons pour les classes de base inconnue. On ajoute simplement qu'elle sont dérivée de la racine. */ PUBLIC void CLSFORM::unknown () { int nbinfo = infos.getnb(); CLS_INFO *first = infos.getitem(0); for (int i=1; inbbase == 0){ addder (ptinfo,first,""); } } } #if 0 static int cmp (const void *p1, const void *p2) { CLS_INFO *d1 = (CLS_INFO *)p1; CLS_INFO *d2 = (CLS_INFO *)p2; return strcmp(d1->nom,d2->nom); } /* Trie les classes en ordre alphabétique */ PUBLIC void CLSFORM::sort () { hsort (tbinfo+1,nbinfo-1,sizeof(CLS_INFO),cmp); } #endif