mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-08 18:40:55 +03:00
605 lines
19 KiB
PkgConfig
605 lines
19 KiB
PkgConfig
/*
|
|
Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
|
|
This file is part of Open CASCADE Technology software library.
|
|
|
|
This library is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU Lesser General Public License version 2.1 as published
|
|
by the Free Software Foundation, with special exception defined in the file
|
|
OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
distribution for complete text of the license and disclaimer of any warranty.
|
|
|
|
Alternatively, this file may be used under the terms of Open CASCADE
|
|
commercial license or contractual agreement.
|
|
*/
|
|
|
|
#include "stdio.h"
|
|
#include "string.h"
|
|
#include "stdlib.h"
|
|
#if (!defined(_WIN32) && !defined(__APPLE__))
|
|
#include "malloc.h"
|
|
#endif
|
|
#include "recfile.ph"
|
|
/* enregistrement d'un fichier d'interface sous forme de records
|
|
gere les scopes
|
|
|
|
Ce fichier comprend 3 parties
|
|
- les routines traitant les char*, avec la notion de texte courant
|
|
- les declarations des donnees de travail proprement dites pour le fichier
|
|
- le corps des programmes d'enregistrement
|
|
*/
|
|
|
|
|
|
/* ROUTINES UTILITAIRES de traitement des textes (char*) */
|
|
|
|
/* Gestion du texte courant : c'est un texte alloue dynamiquement
|
|
rec_restext en alloue un (jete le precedent alloue si pas lu)
|
|
rec_gettext lit le texte en cours, qui ne sera pas desalloue ensuite
|
|
rec_settext en force un autre en jetant le precedent (idem rec_newtext)
|
|
tandis que rec_newtext alloue un texte, sans lien avec le courant
|
|
*/
|
|
|
|
#define Maxcar 50000
|
|
|
|
static struct carpage {
|
|
struct carpage* next; /* chainage des pages de caracteres */
|
|
int used; /* place deja prise */
|
|
char cars[Maxcar+1]; /* page de caracteres */
|
|
} *onecarpage;
|
|
|
|
static char* restext = NULL ; /* texte courant (allocation dynamique) */
|
|
/* static int resalloc = 0 ;*/ /* alloue (memoire a liberer) ou non */
|
|
|
|
static char txt_cart_p[] = "CARTESIAN_POINT";
|
|
|
|
void rec_restext(char* newtext, int lentext) /* destine a etre appele de l'exterieur */
|
|
{
|
|
char *res, *text;
|
|
if(strcmp(newtext,txt_cart_p)==0) {
|
|
restext = txt_cart_p;
|
|
return;
|
|
}
|
|
|
|
if (onecarpage->used > Maxcar-lentext-1) { /* allouer nouvelle page */
|
|
struct carpage *newpage;
|
|
int sizepage = sizeof(struct carpage);
|
|
if (lentext >= Maxcar) sizepage += (lentext+1 - Maxcar);
|
|
newpage = (struct carpage*) malloc (sizepage);
|
|
newpage->next = onecarpage;
|
|
onecarpage = newpage;
|
|
onecarpage->used = 0;
|
|
}
|
|
restext = onecarpage->cars + onecarpage->used;
|
|
onecarpage->used += (lentext + 1);
|
|
/* strcpy */
|
|
res = restext ; text = newtext;
|
|
while (*text != '\0') { *res=*text ; res++ ; text++ ; }
|
|
*res = '\0' ;
|
|
}
|
|
|
|
void rec_gettext(char* *r)
|
|
/* Le resultat retourne (pointeur) est destine a etre inclus dans un struct */
|
|
{ *r = restext; }
|
|
|
|
void rec_settext(char* s)
|
|
/* substituer le texte courant par un autre deja alloue */
|
|
{ restext = s ; }
|
|
|
|
char* rec_newtext(char* r)
|
|
/* routine utilitaire creant une chaine dynamique a partir d'un char[] */
|
|
{
|
|
char* savrestext;
|
|
char* s0;
|
|
savrestext = restext;
|
|
rec_restext(r,(int)strlen(r));
|
|
s0 = restext;
|
|
restext = savrestext;
|
|
return (s0);
|
|
}
|
|
|
|
|
|
|
|
static int modeprint = 0 ; /* CONTROLE D'IMPRESSION (pour appel depuis yacc)*/
|
|
|
|
/* DECLARATIONS des donnees de travail (en cours d'enregistrement) */
|
|
|
|
static int typarg ; /* type du dernier argument lu */
|
|
static int nbrec = 0; /* nombre total d'enregistrements de donnees */
|
|
static int nbhead = 0; /* nb de records pris par le Header */
|
|
static int nbpar = 0; /* nb de parametres lus au total */
|
|
static int yarec = 0; /* presence Record deja cree (1 apres Ident) */
|
|
|
|
static struct rec { /* DESCRIPTION D'UN RECORD */
|
|
char* ident ; /* identifieur du record (en #12345...) ou scope-end */
|
|
char* type ; /* type du record (peut etre sublist) */
|
|
/* int nbarg ; nombre de parametres (arguments) du record, not used */
|
|
struct unarg* first ; /* 1er argument */
|
|
/* struct unarg* last ;dernier argument, not used */
|
|
struct rec* next ; /* record suivant */
|
|
} *currec ; /* currec meme : record courant */
|
|
|
|
#define Maxrec 5000
|
|
static struct recpage {
|
|
struct recpage* next;
|
|
int used;
|
|
struct rec args[Maxrec+1];
|
|
} *onerecpage;
|
|
|
|
static struct rec* firstrec ; /* 1er record du fichier */
|
|
static struct rec* lastrec ; /* dernier record du fichier */
|
|
|
|
static char* curtype; /* type dernier record (ou = sublist) */
|
|
static char* subarg ; /* ident dernier record (sub-list eventuel) */
|
|
static int numsub ; /* numero de sous-liste en cours */
|
|
|
|
|
|
static struct unarg { /* DESCRIPTION D'UN ARGUMENT */
|
|
int type ; /* type de l'arg, dans une liste courte : entier, reel ... */
|
|
char* val ; /* valeur alphanum de l'arg */
|
|
struct unarg* next ; /* argument suivant dans la liste pour ce record */
|
|
} *curarg ;
|
|
|
|
#define Maxarg 10000
|
|
static struct argpage { /* Allocation optimisee des arguments */
|
|
struct argpage* next;
|
|
int used;
|
|
struct unarg args[Maxarg+1];
|
|
} *oneargpage;
|
|
|
|
|
|
static struct scope { /* DESCRIPTION D'UN SCOPE */
|
|
/* les scopes sont empilables sans limite */
|
|
struct scope* prev; /* scope precedent, auquel il faudra revenir */
|
|
struct rec* rec; /* record interrompu par le scope (a reprendre) */
|
|
} *curscope ; /* curscope est le scope en cours */
|
|
|
|
|
|
/* Constantes litterales */
|
|
static char txt_sublist[] = "/* (SUB) */" ;
|
|
static char txt_scope[] = "SCOPE" ;
|
|
static char txt_endscope[] = "ENDSCOPE" ;
|
|
static char txt_nil[] = " " ;
|
|
static char sub1[] = "$1" ; /* optimisation ... */
|
|
static char sub2[] = "$2" ;
|
|
static char argtype1[] = "(IF#TnEHBx"; /* types arguments (2 1es lettres) */
|
|
static char argtype2[] = ")nlIxdnxix";
|
|
static char idzero[] = "#0";
|
|
|
|
|
|
/* Trace pour controle */
|
|
void recfile_modeprint(int mode)
|
|
{ modeprint = mode; }
|
|
|
|
static int lastno;
|
|
extern int steplineno;
|
|
extern int modcom;
|
|
extern int modend;
|
|
|
|
void rec_inityyll ()
|
|
{
|
|
steplineno = 0;
|
|
modcom = 0;
|
|
modend = 0;
|
|
lastno = -1;
|
|
}
|
|
|
|
|
|
/* INITIALISATION */
|
|
|
|
void rec_debfile()
|
|
{
|
|
/*initialization of recpage*/
|
|
onerecpage = (struct recpage*) malloc ( sizeof(struct recpage) );
|
|
onerecpage->used = 0; onerecpage->next = NULL;
|
|
|
|
onecarpage = (struct carpage*) malloc ( sizeof(struct carpage) );
|
|
onecarpage->used = 0; onecarpage->next = NULL; restext = NULL;
|
|
yarec = 0; nbhead = nbrec = nbpar = 0 ; firstrec = NULL ; lastrec = NULL ;
|
|
curtype = txt_sublist;
|
|
currec = NULL ; curarg = NULL ;
|
|
curscope = NULL ;
|
|
oneargpage = (struct argpage*) malloc ( sizeof(struct argpage) );
|
|
oneargpage->next = NULL; oneargpage->used = 0;
|
|
rec_inityyll();
|
|
}
|
|
|
|
/* INTERMEDIAIRE : passage de Header a Data */
|
|
void rec_finhead() { nbhead = nbrec; }
|
|
|
|
/* CONCLUSION : actuellement, ne fait rien */
|
|
|
|
void rec_finfile() { }
|
|
|
|
|
|
/* GESTION DES RECORDS */
|
|
|
|
/* ENREGISTRER UN RECORD (deja pret) */
|
|
static void rec_new(struct rec* newrec)
|
|
/* nouveau record a enregistrer */
|
|
{
|
|
nbrec ++ ;
|
|
if ( firstrec == NULL ) firstrec = newrec ;
|
|
if ( lastrec != NULL ) lastrec->next = newrec ;
|
|
lastrec = newrec ;
|
|
}
|
|
|
|
/* type du dernier argument lu */
|
|
void rec_typarg(int argtype)
|
|
{ typarg = argtype; }
|
|
|
|
/* ENREGISTRER UNE ENTITE (record courant) */
|
|
void rec_newent()
|
|
{
|
|
rec_new(currec) ; /* le record courant (currec) est enregistre */
|
|
|
|
/* gestion des sous-listes : si currec a un suivant note (cf pointeur suite),
|
|
alors c'est une sous-liste et le suivant est son contenant
|
|
EN CE CAS, il faut memoriser cette sous-liste en argument courant
|
|
En effet, d'une part la liste est reconnue comme un argument, d'autre part
|
|
part elle se termine par ")" : c'est donc ici qu'elle sera enregistree */
|
|
|
|
rec_typarg (rec_argSub) ;
|
|
|
|
subarg = currec->ident ; /* si sous-liste, sera argument du contenant */
|
|
/* rec_check(1) ; */
|
|
currec = currec->next ; /* si nul, c'est qu'une autre entite suit */
|
|
lastrec->next = NULL ;
|
|
}
|
|
|
|
|
|
static struct rec*rec_newrec()
|
|
{
|
|
struct rec* newrec;
|
|
if (onerecpage->used >= Maxrec) {
|
|
struct recpage* newrecpage;
|
|
newrecpage = (struct recpage*) malloc ( sizeof (struct recpage) );
|
|
newrecpage->next = onerecpage;
|
|
onerecpage = newrecpage;
|
|
onerecpage->used = 0;
|
|
}
|
|
newrec = &(onerecpage->args[onerecpage->used]);
|
|
onerecpage->used++;
|
|
|
|
return newrec;
|
|
}
|
|
|
|
|
|
/* RECORD COURANT : */
|
|
|
|
/* creer et preciser l'identifieur */
|
|
void rec_ident()
|
|
{
|
|
currec = rec_newrec();
|
|
/*currec = (struct rec*) malloc (sizeof (struct rec)) ;*/
|
|
/*currec->nbarg = 0 ;*/
|
|
rec_gettext(&(currec->ident)) ;
|
|
currec->next = NULL ; currec->first = NULL ; /*currec->last = NULL ;*/
|
|
yarec = 1;
|
|
}
|
|
|
|
/* preciser le type ; demarrage de la description de l'entite */
|
|
void rec_type()
|
|
{
|
|
/* Pour le header : pas d'ident, donc en simuler un : derive de rec_ident */
|
|
if (!yarec) {
|
|
/*currec = (struct rec*) malloc (sizeof (struct rec)) ;*/
|
|
currec = rec_newrec();
|
|
/*currec->nbarg = 0 ;*/
|
|
currec->ident = idzero; /* Ident bidon (il en faut un ...) */
|
|
currec->next = NULL ; currec->first = NULL ; /*currec->last = NULL ;*/
|
|
}
|
|
rec_gettext(&(currec->type)) ;
|
|
yarec = numsub = 0 ; /* debut de l'entite */
|
|
}
|
|
|
|
/* type d une liste qui n est pas une entite mais un argument
|
|
par defaut (cf rec_deblist) il n est pas defini donc mis = "/ (SUB) /" */
|
|
void rec_listype()
|
|
{ rec_gettext(&(curtype)); }
|
|
|
|
/* ajouter un argument (type & valeur deja connus) */
|
|
void rec_newarg()
|
|
{
|
|
struct unarg *newarg;
|
|
nbpar ++;
|
|
/*currec->nbarg ++ ;*/
|
|
/* newarg = (struct unarg*) malloc (sizeof (struct unarg)) ; */
|
|
if (oneargpage->used >= Maxarg) {
|
|
struct argpage* newargpage;
|
|
newargpage = (struct argpage*) malloc ( sizeof(struct argpage) );
|
|
newargpage->next = oneargpage;
|
|
oneargpage = newargpage;
|
|
oneargpage->used = 0;
|
|
}
|
|
newarg = &(oneargpage->args[oneargpage->used]);
|
|
oneargpage->used ++;
|
|
|
|
newarg->type = typarg ;
|
|
if (typarg == rec_argSub) newarg->val = subarg ;
|
|
else rec_gettext (&(newarg->val));
|
|
|
|
/* if (currec->first == NULL) currec->first = newarg;
|
|
else currec->last->next = newarg;
|
|
currec->last = newarg;*/
|
|
if (currec->first == NULL) currec->first = newarg;
|
|
else {
|
|
struct unarg* nextarg = currec->first;
|
|
while(nextarg->next != NULL)
|
|
nextarg = nextarg->next;
|
|
nextarg->next = newarg;
|
|
|
|
}
|
|
newarg->next = NULL ;
|
|
/* rec_check(0) ; */
|
|
}
|
|
|
|
/* Ajouter une sous-liste
|
|
|
|
Une ouverture de parentheses A L'INTERIEUR d'une liste de parametres
|
|
signale une sous-liste : c'est une entite non identifiee, directement
|
|
utilisee comme argument de la liste contenante) d'un type reserve(SUB)
|
|
|
|
Elle est enregistree avec un identifieur special : '$' suivi d'un numero
|
|
de sous-liste dans l'entite en cours.
|
|
|
|
Son enregistrement consiste a definir un nouveau record courant, pour la
|
|
sous-liste, qui note comme suivant l'ancien courant, qui est son contenant
|
|
A la fin de la sous-liste, elle est enregistree comme toute entite (cf
|
|
rec_new) mais le suivant devient le nouveau courant dont l'enregistrement
|
|
des parametres continue
|
|
|
|
La premiere ouverture de parentheses dans l'entite est celle de la liste
|
|
principale de parametres et non d'une sous-liste
|
|
*/
|
|
|
|
void rec_deblist()
|
|
{
|
|
if (numsub > 0) { /* enregistrement d'une sous-liste */
|
|
/* int i ; */ struct rec* subrec ;
|
|
/* creation du nouvel enregistrement et chainage au precedent */
|
|
subrec = rec_newrec();
|
|
/*subrec = (struct rec*) malloc (sizeof (struct rec)) ;*/
|
|
switch (numsub) {
|
|
case 1: subrec->ident = sub1; break;
|
|
case 2: subrec->ident = sub2; break;
|
|
default: {
|
|
char bufsub[10];
|
|
if (numsub > 9) sprintf (bufsub,"$%d",numsub) ;
|
|
else { bufsub[0] = '$'; bufsub[1] = (char)(numsub + 48); bufsub[2] = '\0'; }
|
|
subrec->ident = rec_newtext(bufsub) ;
|
|
}
|
|
}
|
|
subrec->type = curtype ;
|
|
curtype = txt_sublist; /* type reserve par defaut */
|
|
/*subrec->nbarg = 0 ;*/ subrec->next = currec ;
|
|
subrec->first = NULL ; /*subrec->last = NULL ;*/
|
|
/* les arguments de la sous-liste vont suivre ;
|
|
elle meme est argument de son contenant, ce qui est pris en compte
|
|
a la fermeture de la parenthese */
|
|
currec = subrec ; /* substitution finale */
|
|
}
|
|
numsub ++ ; /* numero de la prochaine sous-liste (la principale est en 0) */
|
|
/* rec_check(0) ; */
|
|
}
|
|
|
|
|
|
/* Affichage du contenu d'un record */
|
|
void rec_print(struct rec* unrec)
|
|
{
|
|
int numa = 0; int numl = 0; int argl = 0;
|
|
if (unrec == NULL) { printf ("Non defini\n") ; return; }
|
|
printf ("Ident : %s Type : %s Nb.Arg.s : %s\n",
|
|
unrec->ident,unrec->type, (unrec->first ? unrec->first->val : "")) ;
|
|
if (modeprint < 2) return ;
|
|
curarg = unrec->first ;
|
|
while (curarg != NULL) {
|
|
numa ++;
|
|
argl = (int)strlen(curarg->val) + 18;
|
|
numl += argl;
|
|
if (numl > 132) { printf("\n"); numl = argl; }
|
|
printf (" - Arg.%d[%c%c] : %s",
|
|
numa,argtype1[curarg->type],argtype2[curarg->type],curarg->val);
|
|
curarg = curarg->next ;
|
|
}
|
|
if (argl > 0) printf("\n");
|
|
return ;
|
|
}
|
|
|
|
/* GESTION DES SCOPES */
|
|
|
|
/* Ouverture de scope :
|
|
un scope est un record particulier (pas de type ni d'argument)
|
|
d'une part il est enregistre, d'autre part il faut gerer le record en cours
|
|
En effet, une entite step etait en cours d'enregistrement (ident deja connu),
|
|
mais son type et ses arguments seront fournis apres fermeture du scope ...
|
|
Il faut donc la mettre de cote (c'est currec), pour la restaurer ensuite
|
|
|
|
Mais ATTENTION, il y a l'EXPORT : au ENDSCOPE, peut etre attachee une liste
|
|
d'Idents : ce sont les idents internes au SCOPE mais declares visibles de
|
|
l'exterieur du SCOPE (en plus de l''entite sur laquelle il porte)
|
|
*/
|
|
|
|
void scope_debut()
|
|
{
|
|
/* ouverture du scope et sauvegarde de l'entite en cours */
|
|
struct scope* newscope; struct rec* unscope;
|
|
newscope = (struct scope*) malloc (sizeof (struct scope)) ;
|
|
newscope->rec = currec ;
|
|
newscope->prev = curscope ;
|
|
curscope = newscope ;
|
|
|
|
/* enregistrement de ce scope comme un record */
|
|
unscope = rec_newrec();
|
|
/*unscope = (struct rec*) malloc (sizeof (struct rec)) ;*/
|
|
unscope->ident = txt_scope ;
|
|
unscope->type = txt_nil ;
|
|
unscope->first = NULL;
|
|
/*unscope->nbarg = 0 ;*/
|
|
rec_new(unscope) ;
|
|
}
|
|
|
|
/* Fermeture de scope :
|
|
La fin de scope est, comme son debut, un enregistrement special.
|
|
Il faut donc l'enregistrer.
|
|
Il faut aussi restaurer l'entite concernee par le scope, afin de terminer
|
|
son enregistrement (manquent ses arguments) */
|
|
|
|
void scope_fin()
|
|
{ struct scope* oldscope ; struct rec* unscope;
|
|
if (curscope == NULL) return ; /* cela dit, c'est anormal ... */
|
|
|
|
/* enregistrement de cette fin de scope comme un record */
|
|
unscope = rec_newrec();
|
|
/* unscope = (struct rec*) malloc (sizeof (struct rec)) ;*/
|
|
unscope->ident = txt_endscope ;
|
|
unscope->type = txt_nil ;
|
|
unscope->first = NULL;
|
|
/*unscope->nbarg = 0 ;*/
|
|
|
|
/* Si on doit prendre en compte une Export List ... */
|
|
if (subarg[0] == '$') {
|
|
if (modeprint > 0) {
|
|
printf("Export List : (List in Record n0 %d) -- ",nbrec);
|
|
rec_print(lastrec);
|
|
}
|
|
currec = unscope;
|
|
typarg = rec_argSub;
|
|
rec_newarg();
|
|
}
|
|
rec_new(unscope) ;
|
|
|
|
/* fermeture effective du scope */
|
|
currec = curscope->rec ; /* restaurer l'entite en cours d'enreg. */
|
|
yarec = 1;
|
|
oldscope = curscope ;
|
|
curscope = oldscope->prev ; /* restauration de l'etat precedent */
|
|
free (oldscope) ; /* suppression "physique" */
|
|
}
|
|
|
|
|
|
/* CONCLUSION : retour des valeurs pour constituer la liste des records,
|
|
sous forme de directory / tableau
|
|
|
|
La liberation de la memoire est faite par lir_file_fin, en une fois
|
|
*/
|
|
|
|
void lir_file_nbr(int* nbh, int* nbr, int* nbp)
|
|
/* initialise le traitement et retourne la taille du directory et du header */
|
|
{
|
|
currec = firstrec ;
|
|
/* rec_check(0) ; */
|
|
*nbh = nbhead; *nbr = nbrec; *nbp = nbpar;
|
|
}
|
|
|
|
void lir_file_fin(int mode)
|
|
/* fin du traitement : regroupe les liberations de memoire en une phase */
|
|
/* mode = 1 : rec+arg. 2 : carpage; 3 : 1+2 */
|
|
{
|
|
if (mode & 1) {
|
|
while(onerecpage != NULL) {
|
|
struct recpage* newpage; newpage = onerecpage->next;
|
|
free(onerecpage);
|
|
onerecpage = newpage;
|
|
}
|
|
|
|
|
|
/* struct rec* oldrec;
|
|
oldrec = NULL;
|
|
currec = firstrec;
|
|
while (currec != NULL) {
|
|
oldrec = currec;
|
|
currec = currec->next;*/
|
|
/* liberation memoire pour type & ident : si scope-endscope rien a liberer
|
|
si sous-liste : type pas a liberer, ident partage aussi par l'argument sera
|
|
libere par lui ... donc ici aussi, rien a liberer. CQFD */
|
|
/* free (oldrec) ;
|
|
}*/
|
|
while (oneargpage != NULL) {
|
|
struct argpage* newpage; newpage = oneargpage->next;
|
|
free (oneargpage);
|
|
oneargpage = newpage;
|
|
}
|
|
}
|
|
if (mode & 2) {
|
|
while (onecarpage != NULL) {
|
|
struct carpage* newpage; newpage = onecarpage->next;
|
|
free (onecarpage);
|
|
onecarpage = newpage;
|
|
}
|
|
}
|
|
}
|
|
|
|
int lir_file_rec(char* *ident, char* *type, int *nbarg)
|
|
/* retourne les parametres du record courant
|
|
retour de fonction ; 1 si ok, 0 si liste epuisee */
|
|
{
|
|
if (currec == NULL) return (0) ;
|
|
/* rec_check(2) ; */
|
|
*ident = currec->ident ;
|
|
*type = currec->type ;
|
|
*nbarg = (currec->first != NULL);
|
|
curarg = currec->first ; /* prepare lecture arg.s */
|
|
return (1) ;
|
|
}
|
|
|
|
void lir_file_finrec()
|
|
/* fait le menage et passe au record suivant
|
|
ne pas appeler apres l'indication de fin mais apres chaque record ok ! */
|
|
{
|
|
currec = currec->next ;
|
|
/* rec_check(2) ; */
|
|
}
|
|
|
|
int lir_file_arg(int* type, char* *val)
|
|
/* lit l'argument courant (au debut le 1er), fait le menage, prepare suivant
|
|
retourne 1 si ok, 0 si c'est fini
|
|
attention, suppose que nbarg > 0 ... (bref, pas de protection) */
|
|
{
|
|
if (curarg == NULL) return (0) ;
|
|
*type = curarg->type ;
|
|
*val = curarg->val ;
|
|
curarg = curarg->next ;
|
|
return (1) ;
|
|
}
|
|
|
|
|
|
/* Verification de l'integrite des donnees */
|
|
|
|
/* Affiche ce qui ne va pas, mais aussi accede a tout : ainsi, les adresses
|
|
verolees aparaissent au grand jour du dbx */
|
|
|
|
void rec_check(int mode)
|
|
/* mode=1 pas de controle nbrec (en cours d'enregistrement) */
|
|
{
|
|
struct rec* lerec ; struct unarg* larg ; int nr,na ;
|
|
lerec = firstrec ;
|
|
if (mode == 2) lerec = currec ;
|
|
nr = 0 ;
|
|
while (lerec != NULL) {
|
|
nr ++ ;
|
|
if (lerec->ident == NULL) printf("Record %d : ident null\n",nr) ;
|
|
if (lerec->type == NULL) printf("Record %d : type null\n",nr) ;
|
|
/*if (mode < 2 && (lerec->nbarg < 0 || lerec->nbarg > 10) ) printf
|
|
("N.B.: Record %d : nbarg pas entre 0 & 10, vaut %d\n",nr,lerec->nbarg);
|
|
*/
|
|
na = 0 ;
|
|
larg = lerec->first ;
|
|
while (larg != NULL) {
|
|
na ++ ;
|
|
if (larg->type < 0 || larg->type > 9) printf
|
|
("Record %d , Arg. %d : type incorrect : %d\n",nr,na,larg->type) ;
|
|
if (larg->val == NULL) printf("Record %d , Arg %d : val null\n",nr,na) ;
|
|
larg = larg->next ;
|
|
}
|
|
/*if (na != lerec->nbarg) printf
|
|
("Record %d : arglist pourrie, nb note %d relu %d\n",nr,lerec->nbarg,na) ;*/
|
|
lerec = lerec->next ;
|
|
}
|
|
if (mode == 0 && nr != nbrec) printf
|
|
("Liste des records pourrie, nb note %d relu %d\n",nbrec,nr) ;
|
|
}
|
|
|
|
void steperror (char *mess);
|
|
int steplex (void);
|
|
|