Annotation of rpl/src/gestion_variables.c, revision 1.72
1.1 bertrand 1: /*
2: ================================================================================
1.69 bertrand 3: RPL/2 (R) version 4.1.13
1.68 bertrand 4: Copyright (C) 1989-2013 Dr. BERTRAND Joël
1.1 bertrand 5:
6: This file is part of RPL/2.
7:
8: RPL/2 is free software; you can redistribute it and/or modify it
9: under the terms of the CeCILL V2 License as published by the french
10: CEA, CNRS and INRIA.
11:
12: RPL/2 is distributed in the hope that it will be useful, but WITHOUT
13: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14: FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License
15: for more details.
16:
17: You should have received a copy of the CeCILL License
18: along with RPL/2. If not, write to info@cecill.info.
19: ================================================================================
20: */
21:
22:
1.14 bertrand 23: #include "rpl-conv.h"
1.1 bertrand 24:
25:
26: /*
27: ================================================================================
1.33 bertrand 28: Fonction de debug
29: ================================================================================
30: Entrée :
31: --------------------------------------------------------------------------------
32: Sortie :
33: --------------------------------------------------------------------------------
34: Effets de bords : néant
35: ================================================================================
36: */
37:
38: static void
39: liste_variables_par_niveaux(struct_processus *s_etat_processus)
40: {
41: int c;
42:
43: logical1 fin;
44:
45: struct_liste_variables *l;
46:
47: struct_liste_chainee *e;
48:
1.38 bertrand 49: printf("=========================================================="
50: "======================\n");
1.33 bertrand 51: printf(" Liste des variables par niveaux\n");
1.38 bertrand 52: printf("=========================================================="
53: "======================\n");
1.33 bertrand 54:
1.34 bertrand 55: if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
56: {
1.38 bertrand 57: printf("=========================================================="
58: "======================\n");
1.34 bertrand 59: return;
60: }
61:
1.33 bertrand 62: printf("Backward\n");
63: l = (*s_etat_processus).l_liste_variables_par_niveau;
64: c = 0;
65: fin = d_faux;
66:
67: do
68: {
69: l = l->precedent;
70: e = l->liste;
71:
72: while(e != NULL)
73: {
1.38 bertrand 74: printf("%s (%p->%p, %d) ", ((struct_variable *) e->donnee)->nom,
75: e, e->donnee, ((struct_variable *) e->donnee)->niveau);
1.33 bertrand 76: e = e->suivant;
77: c++;
78: if (c > 100)
79: {
80: fin = d_vrai;
81: break;
82: }
83: }
84:
85: printf("\n");
86:
87: } while(l != (*s_etat_processus).l_liste_variables_par_niveau);
88:
89: printf("Forward\n");
90: l = (*s_etat_processus).l_liste_variables_par_niveau;
91: c = 0;
92:
93: do
94: {
95: e = l->liste;
96:
97: while(e != NULL)
98: {
1.38 bertrand 99: printf("%s (%p->%p, %d) ", ((struct_variable *) e->donnee)->nom,
100: e, e->donnee, ((struct_variable *) e->donnee)->niveau);
1.33 bertrand 101: e = e->suivant;
102: c++;
103: if (c > 100) exit(0);
104: }
105:
106: printf("\n");
107:
108: l = l->suivant;
109: } while(l != (*s_etat_processus).l_liste_variables_par_niveau);
110:
1.38 bertrand 111: printf("=========================================================="
112: "======================\n");
1.33 bertrand 113:
114: if (fin == d_vrai) exit(0);
115:
116: return;
117: }
118:
119: static void
120: liste_variables_tas(struct_processus *s_etat_processus,
121: struct_arbre_variables *arbre)
122: {
123: int c;
124: int i;
125:
126: logical1 fin;
127:
128: struct_liste_variables *l;
129:
130: fin = d_faux;
131:
1.34 bertrand 132: if (arbre == NULL)
133: {
134: return;
135: }
136:
137: printf(">>> Position : %d\n",
138: (*arbre).indice_tableau_pere);
139: printf(">>> Nombre de noeuds utilisés : %u\n",
140: (*arbre).noeuds_utilises);
141: printf(">>> Noeuds fils : ");
142:
143: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
144: {
145: if ((*arbre).noeuds[i] != NULL)
146: {
147: printf("%d ", i);
148: }
149: }
150:
151: printf("\b\n");
152:
1.33 bertrand 153: if ((*arbre).feuille != NULL)
154: {
1.34 bertrand 155: printf("Feuille %p [%d]\n", (*arbre).feuille, (*arbre).noeuds_utilises);
1.33 bertrand 156:
157: printf(" Backward\n");
158:
159: l = (*arbre).feuille;
160: c = 0;
161: fin = d_faux;
162:
163: do
164: {
165: l = l->precedent;
166: c++;
167: if (c > 100)
168: {
169: fin = d_vrai;
170: break;
171: }
172: printf(" %s (%p, %d)\n", l->variable->nom, l->variable,
173: l->variable->niveau);
174: } while((*arbre).feuille != l);
175:
176: printf(" Forward\n");
177:
178: l = (*arbre).feuille;
179: c = 0;
180:
181: do
182: {
183: c++;
184: if (c > 100) exit(0);
185: printf(" %s (%p, %d)\n", l->variable->nom, l->variable,
186: l->variable->niveau);
187: l = l->suivant;
188: } while((*arbre).feuille != l);
189: }
190:
1.38 bertrand 191: printf("----------------------------------------------------------"
192: "----------------------\n");
1.34 bertrand 193:
1.33 bertrand 194: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
195: {
196: if ((*arbre).noeuds[i] != NULL)
197: {
1.34 bertrand 198:
1.33 bertrand 199: liste_variables_tas(s_etat_processus, (*arbre).noeuds[i]);
200: }
201: }
202:
203: if (fin == d_vrai) exit(0);
204:
205: return;
206: }
207:
208:
209: static void
210: liste_variables_par_feuilles(struct_processus *s_etat_processus)
211: {
1.38 bertrand 212: printf("=========================================================="
213: "======================\n");
1.33 bertrand 214: printf(" Liste des variables sur le tas\n");
1.38 bertrand 215: printf("=========================================================="
216: "======================\n");
1.33 bertrand 217:
218: liste_variables_tas(s_etat_processus,
219: (*s_etat_processus).s_arbre_variables);
220:
1.38 bertrand 221: printf("=========================================================="
222: "======================\n");
1.33 bertrand 223:
224: return;
225: }
226:
227:
228: /*
229: ================================================================================
1.40 bertrand 230: Routine de gestion du cache mémoire sur l'arbre des variables
231: ================================================================================
232: Entrée :
233: --------------------------------------------------------------------------------
234: Sortie :
235: --------------------------------------------------------------------------------
236: Effets de bords : néant
237: ================================================================================
238: */
239:
1.61 bertrand 240: struct_arbre_variables *
1.40 bertrand 241: allocation_noeud(struct_processus *s_etat_processus)
242: {
243: struct_arbre_variables *objet;
244:
245: if ((*s_etat_processus).pointeur_variables_noeud > 0)
246: {
247: objet = (*s_etat_processus).variables_noeud
248: [--(*s_etat_processus).pointeur_variables_noeud];
249: }
250: else
251: {
252: objet = malloc(sizeof(struct_arbre_variables));
253: }
254:
255: return(objet);
256: }
257:
258: static inline void
259: liberation_noeud(struct_processus *s_etat_processus,
260: struct_arbre_variables *objet)
261: {
262: if ((*s_etat_processus).pointeur_variables_noeud < TAILLE_CACHE)
263: {
264: (*s_etat_processus).variables_noeud
265: [(*s_etat_processus).pointeur_variables_noeud++] = objet;
266: }
267: else
268: {
269: free(objet);
270: }
271:
272: return;
273: }
274:
1.61 bertrand 275: struct_arbre_variables **
1.40 bertrand 276: allocation_tableau_noeuds(struct_processus *s_etat_processus)
277: {
278: struct_arbre_variables **objet;
279:
280: if ((*s_etat_processus).pointeur_variables_tableau_noeuds > 0)
281: {
282: objet = (*s_etat_processus).variables_tableau_noeuds
283: [--(*s_etat_processus).pointeur_variables_tableau_noeuds];
284: }
285: else
286: {
1.70 bertrand 287: objet = malloc(((size_t) (*s_etat_processus)
288: .nombre_caracteres_variables)
1.40 bertrand 289: * sizeof(struct_arbre_variables *));
290: }
291:
292: return(objet);
293: }
294:
295: static inline void
296: liberation_tableau_noeuds(struct_processus *s_etat_processus,
297: struct_arbre_variables **objet)
298: {
299: if ((*s_etat_processus).pointeur_variables_tableau_noeuds < TAILLE_CACHE)
300: {
301: (*s_etat_processus).variables_tableau_noeuds
302: [(*s_etat_processus).pointeur_variables_tableau_noeuds++] =
303: objet;
304: }
305: else
306: {
307: free(objet);
308: }
309:
310: return;
311: }
312:
313: static inline struct_liste_variables *
314: allocation_feuille(struct_processus *s_etat_processus)
315: {
316: struct_liste_variables *objet;
317:
318: if ((*s_etat_processus).pointeur_variables_feuille > 0)
319: {
320: objet = (*s_etat_processus).variables_feuille
321: [--(*s_etat_processus).pointeur_variables_feuille];
322: }
323: else
324: {
325: objet = malloc(sizeof(struct_liste_variables));
326: }
327:
328: return(objet);
329: }
330:
331: static inline void
332: liberation_feuille(struct_processus *s_etat_processus,
333: struct_liste_variables *objet)
334: {
335: if ((*s_etat_processus).pointeur_variables_feuille < TAILLE_CACHE)
336: {
337: (*s_etat_processus).variables_feuille
338: [(*s_etat_processus).pointeur_variables_feuille++] = objet;
339: }
340: else
341: {
342: free(objet);
343: }
344:
345: return;
346: }
347:
348: static inline struct_variable *
349: allocation_variable(struct_processus *s_etat_processus)
350: {
351: struct_variable *objet;
352:
353: if ((*s_etat_processus).pointeur_variables_variable > 0)
354: {
355: objet = (*s_etat_processus).variables_variable
356: [--(*s_etat_processus).pointeur_variables_variable];
357: }
358: else
359: {
360: objet = malloc(sizeof(struct_variable));
361: }
362:
363: return(objet);
364: }
365:
366: static inline void
367: liberation_variable(struct_processus *s_etat_processus,
368: struct_variable *objet)
369: {
370: if ((*s_etat_processus).pointeur_variables_variable < TAILLE_CACHE)
371: {
372: (*s_etat_processus).variables_variable
373: [(*s_etat_processus).pointeur_variables_variable++] = objet;
374: }
375: else
376: {
377: free(objet);
378: }
379:
380: return;
381: }
382:
383:
384: /*
385: ================================================================================
1.1 bertrand 386: Routine de création d'une nouvelle variable
1.33 bertrand 387: ================================================================================
388: Entrée : autorisation_creation_variable_statique vaut 'v' ou 's'.
389: dans le cas 'v', la variable est volatile.
390: dans le cas 's', elle est statique.
391: Entrée : autorisation_creation_variable_partagee vaut 'p' ou 's'.
392: dans le cas 'p', la variable est privée.
393: dans le cas 's', elle est partagée.
1.1 bertrand 394: --------------------------------------------------------------------------------
395: Sortie :
396: --------------------------------------------------------------------------------
397: Effets de bords : néant
398: ================================================================================
399: */
400:
1.25 bertrand 401: static logical1
402: ajout_variable(struct_processus *s_etat_processus, struct_variable *s_variable)
1.1 bertrand 403: {
1.25 bertrand 404: int i;
405:
1.33 bertrand 406: logical1 niveau_acceptable;
407:
1.25 bertrand 408: struct_liste_variables *l_nouvelle_variable;
409: struct_liste_variables *l_variable_candidate;
1.33 bertrand 410:
1.28 bertrand 411: struct_arbre_variables *l_variable_courante;
412: struct_arbre_variables *l_variable_precedente;
1.1 bertrand 413:
1.25 bertrand 414: struct_liste_chainee *l_nouvel_element;
1.1 bertrand 415:
1.25 bertrand 416: unsigned char *ptr;
1.1 bertrand 417:
1.31 bertrand 418: void *pointeur_variable_cree;
419:
1.25 bertrand 420: if ((*s_etat_processus).s_arbre_variables == NULL)
1.1 bertrand 421: {
1.25 bertrand 422: if (((*s_etat_processus).s_arbre_variables =
1.40 bertrand 423: allocation_noeud(s_etat_processus)) == NULL)
1.25 bertrand 424: {
425: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
426: return(d_erreur);
427: }
428:
429: (*(*s_etat_processus).s_arbre_variables).feuille = NULL;
1.58 bertrand 430: (*(*s_etat_processus).s_arbre_variables).feuille_statique = NULL;
1.25 bertrand 431: (*(*s_etat_processus).s_arbre_variables).noeuds_utilises = 0;
1.31 bertrand 432: (*(*s_etat_processus).s_arbre_variables).indice_tableau_pere = -1;
1.28 bertrand 433: (*(*s_etat_processus).s_arbre_variables).noeud_pere = NULL;
1.1 bertrand 434:
1.30 bertrand 435: if (((*(*s_etat_processus).s_arbre_variables).noeuds =
1.60 bertrand 436: allocation_tableau_noeuds(s_etat_processus)) == NULL)
1.1 bertrand 437: {
1.25 bertrand 438: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
439: return(d_erreur);
440: }
441:
442: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
443: {
1.28 bertrand 444: (*(*s_etat_processus).s_arbre_variables).noeuds[i] = NULL;
1.25 bertrand 445: }
446: }
447:
1.28 bertrand 448: l_variable_precedente = NULL;
1.25 bertrand 449: l_variable_courante = (*s_etat_processus).s_arbre_variables;
450: ptr = (*s_variable).nom;
451:
452: while((*ptr) != d_code_fin_chaine)
453: {
454: BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
1.40 bertrand 455: uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
1.25 bertrand 456: *ptr));
457:
1.28 bertrand 458: if ((*l_variable_courante).noeuds[(*s_etat_processus)
1.25 bertrand 459: .pointeurs_caracteres_variables[*ptr]] == NULL)
460: {
1.31 bertrand 461: // Le noeud n'existe pas encore, on le crée et on le marque
462: // comme utilisé dans la structure parente.
1.25 bertrand 463:
1.28 bertrand 464: if (((*l_variable_courante).noeuds[(*s_etat_processus)
1.25 bertrand 465: .pointeurs_caracteres_variables[*ptr]] =
1.40 bertrand 466: allocation_noeud(s_etat_processus)) == NULL)
1.25 bertrand 467: {
468: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
469: return(d_erreur);
470: }
471:
1.28 bertrand 472: (*l_variable_courante).noeuds_utilises++;
1.31 bertrand 473:
474: // La feuille est par défaut vide et aucun élément du tableau noeuds
475: // (les branches qui peuvent être issues de ce nouveau noeud)
476: // n'est encore utilisée.
477:
1.28 bertrand 478: (*(*l_variable_courante).noeuds[(*s_etat_processus)
1.25 bertrand 479: .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
1.28 bertrand 480: (*(*l_variable_courante).noeuds[(*s_etat_processus)
1.58 bertrand 481: .pointeurs_caracteres_variables[*ptr]]).feuille_statique
482: = NULL;
483: (*(*l_variable_courante).noeuds[(*s_etat_processus)
1.25 bertrand 484: .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
1.31 bertrand 485:
486: // Le champ noeud_pere de la structure créée pointe sur
487: // la structure parente et l'indice tableau_pere correspond à la
488: // position réelle dans le tableau noeuds[] de la structure parente
489: // du noeud courant. Cette valeur sera utilisée lors de la
490: // destruction du noeud pour annuler le pointeur contenu dans
491: // le tableau noeuds[] de la structure parente.
492:
1.28 bertrand 493: (*(*l_variable_courante).noeuds[(*s_etat_processus)
494: .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
1.31 bertrand 495: l_variable_courante;
496: (*(*l_variable_courante).noeuds[(*s_etat_processus)
497: .pointeurs_caracteres_variables[*ptr]])
498: .indice_tableau_pere = (*s_etat_processus)
499: .pointeurs_caracteres_variables[*ptr];
500:
501: // Allocation du tableau noeuds[] et initialisation à zéro de
502: // tous les pointeurs.
1.25 bertrand 503:
1.28 bertrand 504: if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
505: .pointeurs_caracteres_variables[*ptr]]).noeuds =
1.40 bertrand 506: allocation_tableau_noeuds(s_etat_processus)) == NULL)
1.25 bertrand 507: {
508: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
509: return(d_erreur);
510: }
511:
512: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
513: {
1.28 bertrand 514: (*(*l_variable_courante).noeuds[(*s_etat_processus)
515: .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
516: = NULL;
1.25 bertrand 517: }
518: }
519:
1.28 bertrand 520: l_variable_precedente = l_variable_courante;
521: l_variable_courante = (*l_variable_courante).noeuds
1.25 bertrand 522: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
523: ptr++;
524: }
525:
526: if ((*l_variable_courante).feuille == NULL)
527: {
528: // Aucune variable de même nom préexiste. On alloue le premier
529: // élément de la liste doublement chaînée contenant toutes les
530: // variables de même nom. Cette liste boucle en premier lieu sur
531: // elle-même.
532:
1.40 bertrand 533: if (((*l_variable_courante).feuille = allocation_feuille(
534: s_etat_processus)) == NULL)
1.25 bertrand 535: {
536: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
537: return(d_erreur);
538: }
539:
1.34 bertrand 540: (*l_variable_courante).noeuds_utilises++;
541:
1.25 bertrand 542: (*(*l_variable_courante).feuille).suivant =
543: (*l_variable_courante).feuille;
544: (*(*l_variable_courante).feuille).precedent =
545: (*l_variable_courante).feuille;
1.28 bertrand 546: (*(*l_variable_courante).feuille).noeud_pere = l_variable_precedente;
1.32 bertrand 547: (*(*l_variable_courante).feuille).noeud = l_variable_courante;
1.25 bertrand 548:
549: // Allocation de la variable sur l'élément de la liste.
550:
551: if (((*(*l_variable_courante).feuille).variable =
1.40 bertrand 552: allocation_variable(s_etat_processus)) == NULL)
1.25 bertrand 553: {
554: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
555: return(d_erreur);
556: }
557:
558: (*((struct_variable *) (*(*l_variable_courante).feuille).variable)) =
559: (*s_variable);
1.31 bertrand 560: pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
1.25 bertrand 561: }
562: else
563: {
1.40 bertrand 564: if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
1.28 bertrand 565: == NULL)
566: {
567: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
568: return(d_erreur);
569: }
570:
1.25 bertrand 571: if ((*s_variable).niveau > 1)
572: {
573: // Cas d'une variable locale
574:
575: // Si le niveau de la dernière variable de même nom est
576: // supérieur au niveau de la variable locale que l'on veut
577: // enregistrer dans la liste, cette liste est incohérente.
578:
579: BUG((*(*(*l_variable_courante).feuille).variable).niveau >=
580: (*s_variable).niveau,
1.40 bertrand 581: uprintf("Variable=\"%s\"\n", (*s_variable).nom));
1.25 bertrand 582:
583: // On ajoute la variable à la liste existante.
584:
585: (*l_nouvelle_variable).suivant = (*l_variable_courante).feuille;
586: (*l_nouvelle_variable).precedent = (*(*l_variable_courante).feuille)
587: .precedent;
1.28 bertrand 588: (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
1.33 bertrand 589: (*l_nouvelle_variable).noeud = l_variable_courante;
1.25 bertrand 590: (*(*(*l_variable_courante).feuille).precedent).suivant =
591: l_nouvelle_variable;
592: (*(*l_variable_courante).feuille).precedent =
593: l_nouvelle_variable;
594: (*l_variable_courante).feuille = l_nouvelle_variable;
595:
596: if (((*(*l_variable_courante).feuille).variable =
1.40 bertrand 597: allocation_variable(s_etat_processus)) == NULL)
1.25 bertrand 598: {
599: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
600: return(d_erreur);
601: }
602:
603: (*((struct_variable *) (*(*l_variable_courante).feuille).variable))
604: = (*s_variable);
1.31 bertrand 605: pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
1.1 bertrand 606: }
607: else
608: {
1.25 bertrand 609: // Cas d'une variable globale (niveau 0 [définitions] ou 1
610: // [variables globales])
611:
612: l_variable_candidate = (*l_variable_courante).feuille;
613:
614: do
615: {
616: // S'il y a déjà une variable de même niveau, la pile
617: // est incohérente.
618:
619: BUG((*(*l_variable_candidate).variable).niveau ==
620: (*s_variable).niveau,
1.40 bertrand 621: uprintf("Variable=\"%s\"\n", (*s_variable).nom));
1.25 bertrand 622:
623: l_variable_candidate = (*l_variable_candidate).precedent;
624: } while((l_variable_candidate != (*l_variable_courante).feuille) &&
625: ((*(*l_variable_candidate).variable).niveau <= 1));
626:
1.34 bertrand 627: BUG((*s_variable).niveau == 0,
628: uprintf("Attempt to create a level-0 variable!\n"));
629:
1.25 bertrand 630: if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
631: .niveau > 1)
632: {
1.34 bertrand 633: // La variable précédente est de niveau strictement supérieur
634: // à 1. Il ne peut donc y avoir aucune variable de niveau
635: // inférieur ou égal à 1 puisque la boucle est triée.
636: // On insère donc directement la variable en queue.
1.25 bertrand 637: }
638: else
1.1 bertrand 639: {
1.34 bertrand 640: // Le niveau de la variable précédente dans la boucle est
641: // inférieur ou égal à 1.
1.25 bertrand 642: l_variable_candidate = (*(*l_variable_courante).feuille)
643: .precedent;
644: }
645:
646: (*l_nouvelle_variable).suivant = l_variable_candidate;
647: (*l_nouvelle_variable).precedent = (*l_variable_candidate)
648: .precedent;
1.28 bertrand 649: (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
1.33 bertrand 650: (*l_nouvelle_variable).noeud = l_variable_courante;
1.25 bertrand 651: (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
652: (*l_variable_candidate).precedent = l_nouvelle_variable;
653:
1.34 bertrand 654: // Si la variable suivant la variable que l'on vient d'insérer
655: // dans la boucle est de niveau 0, la variable insérée est par
656: // construction de niveau 1 et il convient de modifier le
657: // pointeur de feuille pointant sur l'élément de plus haut niveau
658: // de la boucle.
659:
660: if ((*(*(*l_nouvelle_variable).precedent).variable).niveau == 0)
661: {
662: (*(*l_nouvelle_variable).noeud).feuille = l_nouvelle_variable;
663: }
664:
1.25 bertrand 665: if (((*l_nouvelle_variable).variable =
1.40 bertrand 666: allocation_variable(s_etat_processus)) == NULL)
1.25 bertrand 667: {
668: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
669: return(d_erreur);
670: }
671:
672: (*(*l_nouvelle_variable).variable) = (*s_variable);
1.31 bertrand 673: pointeur_variable_cree = (*l_nouvelle_variable).variable;
1.1 bertrand 674: }
1.25 bertrand 675: }
676:
677: // Ajout de la variable nouvellement créée à la liste par niveaux.
678: // Le pointeur contenu dans la structure de description du processus indique
679: // toujours le plus haut niveau utilisé.
680:
681: if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
682: {
683: // Le niveau courant n'existe pas. Il est créé.
684:
1.40 bertrand 685: if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
1.25 bertrand 686: == NULL)
687: {
688: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
689: return(d_erreur);
690: }
691:
692: (*l_nouvelle_variable).suivant = l_nouvelle_variable;
693: (*l_nouvelle_variable).precedent = l_nouvelle_variable;
1.28 bertrand 694: (*l_nouvelle_variable).noeud_pere = NULL;
1.31 bertrand 695: (*l_nouvelle_variable).liste = NULL;
1.25 bertrand 696:
697: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
1.33 bertrand 698:
699: // Ajout de la variable en tête de la liste
700:
1.40 bertrand 701: if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
1.33 bertrand 702: {
703: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
704: return(d_erreur);
705: }
706:
707: (*l_nouvel_element).suivant = (*(*s_etat_processus)
708: .l_liste_variables_par_niveau).liste;
709: (*l_nouvel_element).donnee = pointeur_variable_cree;
710: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
711: l_nouvel_element;
1.25 bertrand 712: }
713: else if ((*s_variable).niveau > (*((struct_variable *)
714: (*(*(*s_etat_processus).l_liste_variables_par_niveau).liste)
715: .donnee)).niveau)
716: {
717: // Le niveau courant n'existe pas. Il est créé.
1.1 bertrand 718:
1.40 bertrand 719: if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
1.25 bertrand 720: == NULL)
1.1 bertrand 721: {
722: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
723: return(d_erreur);
724: }
725:
1.25 bertrand 726: (*l_nouvelle_variable).suivant = (*s_etat_processus)
727: .l_liste_variables_par_niveau;
728: (*l_nouvelle_variable).precedent = (*(*s_etat_processus)
729: .l_liste_variables_par_niveau).precedent;
1.28 bertrand 730: (*l_nouvelle_variable).noeud_pere = NULL;
1.31 bertrand 731: (*l_nouvelle_variable).liste = NULL;
1.25 bertrand 732: (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent)
733: .suivant = l_nouvelle_variable;
1.33 bertrand 734: (*(*s_etat_processus).l_liste_variables_par_niveau)
735: .precedent = l_nouvelle_variable;
1.25 bertrand 736:
737: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
1.33 bertrand 738:
739: // Ajout de la variable en tête de la liste
740:
1.40 bertrand 741: if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
1.33 bertrand 742: {
743: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
744: return(d_erreur);
745: }
746:
747: (*l_nouvel_element).suivant = (*(*s_etat_processus)
748: .l_liste_variables_par_niveau).liste;
749: (*l_nouvel_element).donnee = pointeur_variable_cree;
750: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
751: l_nouvel_element;
1.25 bertrand 752: }
1.31 bertrand 753: else if ((*s_variable).niveau <= 1)
1.25 bertrand 754: {
1.33 bertrand 755: // Création d'une variable de niveau 0 ou 1. Il convient de
756: // chercher dans la liste si un niveau 0 ou 1 préexiste. Pour cela, on
757: // regarde la position courante et les deux précédentes.
758:
759: l_variable_candidate = (*s_etat_processus).l_liste_variables_par_niveau;
760: niveau_acceptable = d_faux;
1.25 bertrand 761:
1.33 bertrand 762: for(i = 0; i <= 2; i++)
763: {
764: if ((*l_variable_candidate).liste == NULL)
765: {
766: continue;
767: }
768:
769: if ((*((struct_variable *) (*(*l_variable_candidate)
770: .liste).donnee)).niveau == (*s_variable).niveau)
771: {
772: niveau_acceptable = d_vrai;
773: break;
774: }
775:
776: l_variable_candidate = (*l_variable_candidate).precedent;
777: }
778:
779: if (niveau_acceptable == d_faux)
1.28 bertrand 780: {
1.40 bertrand 781: if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
1.33 bertrand 782: == NULL)
783: {
784: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
785: return(d_erreur);
786: }
787:
788: l_variable_candidate =
789: (*(*s_etat_processus).l_liste_variables_par_niveau)
790: .precedent;
791:
792: // On ne peut créer qu'une variable de niveau supérieur ou égal à
793: // 1 lors de l'exécution normale d'un programme. Les variables
794: // de niveau 0 sont créées à l'initialisation et relèvent du
795: // cas précédent car il n'existe lors de leur création aucun
796: // niveau non nul.
797:
798: BUG((*s_variable).niveau == 0,
799: uprintf("Attempt to create a level-0 variable!\n"));
800:
801: (*l_nouvelle_variable).suivant = l_variable_candidate;
802: (*l_nouvelle_variable).precedent = (*l_variable_candidate)
803: .precedent;
804: (*l_nouvelle_variable).noeud_pere = NULL;
805: (*l_nouvelle_variable).liste = NULL;
806: (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
807: (*l_variable_candidate).precedent = l_nouvelle_variable;
808:
809: l_variable_candidate = l_nouvelle_variable;
1.28 bertrand 810: }
811:
1.33 bertrand 812: // Ajout de la variable en tête de la liste l_variable_candidate.
1.25 bertrand 813:
1.40 bertrand 814: if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
1.25 bertrand 815: {
1.33 bertrand 816: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
817: return(d_erreur);
1.25 bertrand 818: }
819:
1.33 bertrand 820: (*l_nouvel_element).suivant = (*l_variable_candidate).liste;
821: (*l_nouvel_element).donnee = pointeur_variable_cree;
822: (*l_variable_candidate).liste = l_nouvel_element;
1.25 bertrand 823: }
1.33 bertrand 824: else
825: {
826: // Ajout de la variable en tête de la liste
1.25 bertrand 827:
1.40 bertrand 828: if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
1.33 bertrand 829: {
830: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
831: return(d_erreur);
832: }
1.25 bertrand 833:
1.33 bertrand 834: (*l_nouvel_element).suivant = (*(*s_etat_processus)
835: .l_liste_variables_par_niveau).liste;
836: (*l_nouvel_element).donnee = pointeur_variable_cree;
837: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
838: l_nouvel_element;
1.1 bertrand 839: }
840:
1.25 bertrand 841: return(d_absence_erreur);
842: }
843:
1.31 bertrand 844:
1.25 bertrand 845: logical1
846: creation_variable(struct_processus *s_etat_processus,
847: struct_variable *s_variable,
848: unsigned char autorisation_creation_variable_statique,
849: unsigned char autorisation_creation_variable_partagee)
850: {
1.1 bertrand 851: if ((*s_etat_processus).mode_execution_programme == 'Y')
852: {
853: (*s_variable).origine = 'P';
854: }
855: else
856: {
857: (*s_variable).origine = 'E';
858: }
859:
860: if ((*s_variable).niveau == 0)
861: {
862: // Un point d'entrée de définition est verrouillé.
863:
864: if ((*s_variable).origine == 'P')
865: {
866: (*s_variable).variable_statique.adresse = 0;
867: (*s_variable).variable_partagee.adresse = 0;
868: }
869: else
870: {
871: (*s_variable).variable_statique.pointeur = NULL;
872: (*s_variable).variable_partagee.pointeur = NULL;
873: }
874:
875: (*s_variable).variable_verrouillee = d_vrai;
876: }
877: else if ((*s_variable).niveau == 1)
878: {
879: // Une variable globale ne peut être statique.
880:
881: if ((*s_variable).origine == 'P')
882: {
883: (*s_variable).variable_statique.adresse = 0;
884: (*s_variable).variable_partagee.adresse = 0;
885: }
886: else
887: {
888: (*s_variable).variable_statique.pointeur = NULL;
889: (*s_variable).variable_partagee.pointeur = NULL;
890: }
891:
892: (*s_variable).variable_verrouillee = d_faux;
893: }
894: else
895: {
896: // 0 -> variable volatile
897: // adresse de création -> variable statique
898:
899: if (autorisation_creation_variable_statique == 'V')
900: {
901: if (autorisation_creation_variable_partagee == 'S')
902: {
903: // On force la création d'une variable partagée
904:
905: if ((*s_variable).origine == 'P')
906: {
907: (*s_variable).variable_statique.adresse = 0;
908: (*s_variable).variable_partagee.adresse =
909: (*s_etat_processus).position_courante;
910: }
911: else
912: {
913: (*s_variable).variable_statique.pointeur = NULL;
914: (*s_variable).variable_partagee.pointeur =
915: (*s_etat_processus).objet_courant;
916: }
917: }
918: else
919: {
920: // On force la création d'une variable volatile
921:
922: if ((*s_variable).origine == 'P')
923: {
924: (*s_variable).variable_statique.adresse = 0;
925: (*s_variable).variable_partagee.adresse = 0;
926: }
927: else
928: {
929: (*s_variable).variable_statique.pointeur = NULL;
930: (*s_variable).variable_partagee.pointeur = NULL;
931: }
932: }
933: }
934: else
935: {
936: // On force la création d'une variable statique.
937:
938: if ((*s_variable).origine == 'P')
939: {
940: (*s_variable).variable_statique.adresse =
941: (*s_etat_processus).position_courante;
942: (*s_variable).variable_partagee.adresse = 0;
943: }
944: else
945: {
946: (*s_variable).variable_statique.pointeur =
947: (*s_etat_processus).objet_courant;
948: (*s_variable).variable_partagee.pointeur = 0;
949: }
950: }
951:
952: (*s_variable).variable_verrouillee = d_faux;
953: }
954:
955: /*
1.25 bertrand 956: * Recherche de la feuille correspondante dans l'arbre des variables.
957: * Si cette feuille n'existe pas, elle est créée.
1.1 bertrand 958: */
959:
1.25 bertrand 960: if (ajout_variable(s_etat_processus, s_variable) == d_erreur)
961: {
962: return(d_erreur);
963: }
964:
965: return(d_absence_erreur);
966: }
967:
968:
969: /*
970: ================================================================================
971: Procédure de recherche d'une variable par son nom dans la base
972: ================================================================================
973: Entrée :
974: --------------------------------------------------------------------------------
975: Sortie :
976: --------------------------------------------------------------------------------
977: Effets de bord : néant
978: ================================================================================
979: */
980:
981: logical1
982: recherche_variable(struct_processus *s_etat_processus,
983: unsigned char *nom_variable)
984: {
985: int pointeur;
986:
987: struct_arbre_variables *l_variable_courante;
988: struct_liste_pile_systeme *l_element_courant;
989:
990: unsigned char *ptr;
991:
1.70 bertrand 992: integer8 niveau_appel;
1.1 bertrand 993:
1.25 bertrand 994: if ((*s_etat_processus).s_arbre_variables == NULL)
1.1 bertrand 995: {
1.25 bertrand 996: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1.30 bertrand 997: return(d_faux);
1.1 bertrand 998: }
1.25 bertrand 999:
1.28 bertrand 1000: l_variable_courante = (*s_etat_processus).s_arbre_variables;
1.25 bertrand 1001: ptr = nom_variable;
1002:
1003: while((*ptr) != d_code_fin_chaine)
1.1 bertrand 1004: {
1.25 bertrand 1005: pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
1006:
1007: if (pointeur < 0)
1008: {
1009: // Caractère hors de l'alphabet des variables
1.30 bertrand 1010:
1011: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1012: return(d_faux);
1.25 bertrand 1013: }
1014:
1.28 bertrand 1015: if ((*l_variable_courante).noeuds[pointeur] == NULL)
1.1 bertrand 1016: {
1.25 bertrand 1017: // Le chemin de la variable candidate n'existe pas.
1.30 bertrand 1018: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1019: return(d_faux);
1.1 bertrand 1020: }
1021:
1.28 bertrand 1022: l_variable_courante = (*l_variable_courante).noeuds[pointeur];
1.25 bertrand 1023: ptr++;
1024: }
1025:
1026: if ((*l_variable_courante).feuille != NULL)
1027: {
1028: // Il existe une pile de variables de même nom. Le sommet de la
1029: // pile est la variable de niveau le plus haut.
1030:
1031: l_element_courant = (*s_etat_processus).l_base_pile_systeme;
1032:
1033: if (l_element_courant == NULL)
1.12 bertrand 1034: {
1.25 bertrand 1035: // Problème : la pile système est vide !
1036: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
1.30 bertrand 1037: return(d_faux);
1.12 bertrand 1038: }
1.25 bertrand 1039:
1040: while((*l_element_courant).retour_definition != 'Y')
1.12 bertrand 1041: {
1.25 bertrand 1042: l_element_courant = (*l_element_courant).suivant;
1.12 bertrand 1043:
1.25 bertrand 1044: if (l_element_courant == NULL)
1.12 bertrand 1045: {
1.25 bertrand 1046: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
1.30 bertrand 1047: return(d_faux);
1.12 bertrand 1048: }
1.25 bertrand 1049: }
1050:
1051: niveau_appel = (*l_element_courant).niveau_courant;
1.12 bertrand 1052:
1.25 bertrand 1053: if (niveau_appel < (*(*(*l_variable_courante).feuille).variable).niveau)
1054: {
1055: // Une variable locale est accessible puisque créée dans la
1056: // fonction courante.
1057:
1058: (*s_etat_processus).pointeur_variable_courante =
1059: (*(*l_variable_courante).feuille).variable;
1060: (*s_etat_processus).pointeur_feuille_courante =
1061: (*l_variable_courante).feuille;
1.30 bertrand 1062: return(d_vrai);
1.25 bertrand 1063: }
1064: else
1065: {
1066: // Aucune variable locale n'est accessible depuis la fonction.
1067: // Dans ce cas, on prend la variable de niveau le plus bas
1068: // si ce niveau est inférieur ou égal à 1 (variable globale
1069: // ou fonction définie par l'utilisateur). Si le niveau de la
1.27 bertrand 1070: // plus ancienne variable est strictement supérieur à 1, il
1.25 bertrand 1071: // s'agit d'une variable locale inaccessible.
1072:
1073: if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
1074: .niveau <= 1)
1075: {
1076: (*s_etat_processus).pointeur_variable_courante =
1077: (*(*(*l_variable_courante).feuille).precedent).variable;
1078: (*s_etat_processus).pointeur_feuille_courante =
1.33 bertrand 1079: (*(*l_variable_courante).feuille).precedent;
1.27 bertrand 1080:
1081: // S'il existe une variable de niveau 0 et une seconde de
1082: // niveau 1, la variable de niveau 0 (fonction) est masquée
1083: // par celle de niveau 1.
1084:
1.33 bertrand 1085: if (((*(*(*(*l_variable_courante).feuille).precedent)
1086: .variable).niveau == 0) && ((*(*(*(*
1087: (*l_variable_courante).feuille).precedent).precedent)
1.27 bertrand 1088: .variable).niveau == 1))
1089: {
1090: (*s_etat_processus).pointeur_variable_courante =
1.33 bertrand 1091: (*(*(*(*l_variable_courante).feuille).precedent)
1092: .precedent).variable;
1093: (*s_etat_processus).pointeur_feuille_courante =
1.27 bertrand 1094: (*(*(*l_variable_courante).feuille).precedent)
1.33 bertrand 1095: .precedent;
1.27 bertrand 1096: }
1097:
1.30 bertrand 1098: return(d_vrai);
1.12 bertrand 1099: }
1100: }
1.1 bertrand 1101: }
1102:
1.30 bertrand 1103: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1104: return(d_faux);
1.1 bertrand 1105: }
1106:
1107:
1.29 bertrand 1108: logical1
1109: recherche_variable_globale(struct_processus *s_etat_processus,
1110: unsigned char *nom)
1111: {
1112: logical1 presence_variable;
1113:
1114: presence_variable = recherche_variable(s_etat_processus, nom);
1115:
1116: if (presence_variable == d_vrai)
1117: {
1118: switch((*(*s_etat_processus).pointeur_variable_courante).niveau)
1119: {
1120: case 0:
1121: {
1.33 bertrand 1122: // La variable est une définition.
1.29 bertrand 1123: presence_variable = d_faux;
1124: break;
1125: }
1126:
1127: case 1:
1128: {
1129: break;
1130: }
1131:
1132: default:
1133: {
1134: if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
1135: .precedent).variable).niveau == 1)
1136: {
1137: (*s_etat_processus).pointeur_feuille_courante =
1138: (*(*s_etat_processus).pointeur_feuille_courante)
1139: .precedent;
1140: (*s_etat_processus).pointeur_variable_courante =
1141: (*(*s_etat_processus).pointeur_feuille_courante)
1142: .variable;
1143: }
1144: else if ((*(*(*(*(*s_etat_processus).pointeur_feuille_courante)
1145: .precedent).precedent).variable).niveau == 1)
1146: {
1147: (*s_etat_processus).pointeur_feuille_courante =
1148: (*(*(*s_etat_processus).pointeur_feuille_courante)
1149: .precedent).precedent;
1150: (*s_etat_processus).pointeur_variable_courante =
1151: (*(*s_etat_processus).pointeur_feuille_courante)
1152: .variable;
1153: }
1154: else
1155: {
1156: presence_variable = d_faux;
1157: }
1158:
1159: break;
1160: }
1161: }
1162: }
1163:
1164: if (presence_variable == d_vrai)
1165: {
1166: if ((*(*s_etat_processus).pointeur_variable_courante).objet == NULL)
1167: {
1168: // La variable n'est pas globale, elle est partagée.
1169: presence_variable = d_faux;
1170: (*s_etat_processus).erreur_execution = d_ex_variable_partagee;
1171: }
1172: }
1173:
1174: return(presence_variable);
1175: }
1176:
1177:
1.1 bertrand 1178: /*
1179: ================================================================================
1180: Procédure de retrait d'une variable de la base
1181: ================================================================================
1182: Entrée : type 'G' ou 'L' selon que l'on retire une variable locale (incluant
1183: les globales) ou strictement globale.
1184: --------------------------------------------------------------------------------
1185: Sortie :
1186: --------------------------------------------------------------------------------
1187: Effets de bord : néant
1188: ================================================================================
1189: */
1190:
1191: logical1
1192: retrait_variable(struct_processus *s_etat_processus,
1193: unsigned char *nom_variable, unsigned char type)
1194: {
1.28 bertrand 1195: logical1 erreur;
1.34 bertrand 1196: logical1 variable_supprimee;
1.28 bertrand 1197:
1198: struct_arbre_variables *s_arbre_a_supprimer;
1199: struct_arbre_variables *s_arbre_courant;
1200:
1201: struct_liste_chainee *l_element_courant;
1202: struct_liste_chainee *l_element_precedent;
1203:
1204: struct_liste_variables *variable_a_supprimer;
1205: struct_liste_variables *variables_par_niveau;
1206:
1.70 bertrand 1207: integer8 niveau;
1.1 bertrand 1208:
1.36 bertrand 1209: (*s_etat_processus).niveau_supprime = d_faux;
1210:
1.1 bertrand 1211: if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
1212: {
1.25 bertrand 1213: // Une variable correspondant au nom recherché est accessible.
1214:
1.1 bertrand 1215: if (type == 'G')
1216: {
1.25 bertrand 1217: if ((*(*s_etat_processus).pointeur_variable_courante).niveau > 1)
1218: {
1219: // La variable obtenue est une variable locale. il faut
1220: // s'assurer qu'il existe une variable de niveau 1 de même
1221: // nom sur la feuille.
1222:
1.27 bertrand 1223: if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
1224: .precedent).variable).niveau <= 1)
1.1 bertrand 1225: {
1.27 bertrand 1226: (*s_etat_processus).pointeur_feuille_courante =
1227: (*(*s_etat_processus).pointeur_feuille_courante)
1228: .precedent;
1229: (*s_etat_processus).pointeur_variable_courante =
1230: (*(*s_etat_processus).pointeur_feuille_courante)
1231: .variable;
1232:
1233: // Si la variable retournée est de niveau 0, on regarde
1234: // un peu plus loin si une variable de niveau 1 existe.
1235:
1236: if (((*(*(*s_etat_processus).pointeur_feuille_courante)
1237: .variable).niveau == 0) &&
1238: ((*(*(*(*s_etat_processus)
1239: .pointeur_feuille_courante).precedent).variable)
1240: .niveau == 1))
1.1 bertrand 1241: {
1.27 bertrand 1242: (*s_etat_processus).pointeur_feuille_courante =
1243: (*(*s_etat_processus).pointeur_feuille_courante)
1244: .precedent;
1245: (*s_etat_processus).pointeur_variable_courante =
1246: (*(*s_etat_processus).pointeur_feuille_courante)
1247: .variable;
1.1 bertrand 1248: }
1249: }
1.27 bertrand 1250: else
1251: {
1252: // Aucune variable globale (niveau 1) n'existe.
1.1 bertrand 1253:
1.27 bertrand 1254: erreur = d_erreur;
1255: (*s_etat_processus).erreur_execution =
1256: d_ex_variable_non_definie;
1257: return(erreur);
1258: }
1.1 bertrand 1259: }
1260:
1.27 bertrand 1261: if ((*(*s_etat_processus).pointeur_variable_courante)
1.1 bertrand 1262: .variable_verrouillee == d_vrai)
1263: {
1264: erreur = d_erreur;
1265: (*s_etat_processus).erreur_execution =
1266: d_ex_variable_verrouillee;
1.28 bertrand 1267: return(erreur);
1.1 bertrand 1268: }
1269: }
1270:
1.27 bertrand 1271: // Suppression de la variable de la liste.
1272: // Deux cas peuvent survenir :
1273: // 1/ les pointeurs sur la variable et la variable suivante
1274: // sont identiques et on supprime la variable ainsi que la feuille
1275: // associée ;
1276: // 2/ ces deux pointeurs sont différents et se contente de retirer
1277: // la structure décrivant la variable.
1.1 bertrand 1278:
1.28 bertrand 1279: if ((*s_etat_processus).pointeur_feuille_courante ==
1280: (*(*s_etat_processus).pointeur_feuille_courante).suivant)
1281: {
1282: // Cas 1 :
1283: // On retire la variable du noeud en décrémentant le nombre
1284: // de feuilles de ce noeud. Si le nombre de feuilles du noeud
1285: // est nul, on retire les noeuds récursivement jusqu'à obtenir
1286: // un nombre non nul de feuilles utilisées (ou la racine des
1287: // variables).
1288:
1289: variable_a_supprimer = (*s_etat_processus)
1290: .pointeur_feuille_courante;
1.34 bertrand 1291: s_arbre_courant = (*variable_a_supprimer).noeud;
1.28 bertrand 1292: BUG((*s_arbre_courant).noeuds_utilises == 0,
1293: uprintf("Freed node !\n"));
1294: (*s_arbre_courant).noeuds_utilises--;
1.1 bertrand 1295:
1.34 bertrand 1296: (*((*(*variable_a_supprimer).noeud_pere).noeuds
1297: [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
1298: .feuille = NULL;
1299:
1.58 bertrand 1300: while(((*s_arbre_courant).noeuds_utilises == 0) &&
1.65 bertrand 1301: ((*s_arbre_courant).feuille_statique == NULL))
1.28 bertrand 1302: {
1303: s_arbre_a_supprimer = s_arbre_courant;
1304: s_arbre_courant = (*s_arbre_courant).noeud_pere;
1.1 bertrand 1305:
1.28 bertrand 1306: if (s_arbre_courant == NULL)
1307: {
1.40 bertrand 1308: liberation_tableau_noeuds(s_etat_processus,
1309: (*s_arbre_a_supprimer).noeuds);
1310: liberation_noeud(s_etat_processus, s_arbre_a_supprimer);
1.34 bertrand 1311:
1312: (*s_etat_processus).s_arbre_variables = NULL;
1.28 bertrand 1313: break;
1314: }
1315:
1.31 bertrand 1316: // s_arbre_a_supprimer contient la structure de feuille qui
1317: // vient d'être libérée. Il s'agit maintenant
1318: // d'annuler le pointeur dans le tableau noeuds de la structure
1319: // pointée par noeud_pere, soit s_arbre_courant.
1320:
1321: BUG((*s_arbre_a_supprimer).indice_tableau_pere < 0,
1322: uprintf("Invalid pointer !\n"));
1323: (*s_arbre_courant).noeuds[(*s_arbre_a_supprimer)
1324: .indice_tableau_pere] = NULL;
1325:
1.40 bertrand 1326: liberation_tableau_noeuds(s_etat_processus,
1327: (*s_arbre_a_supprimer).noeuds);
1328: liberation_noeud(s_etat_processus, s_arbre_a_supprimer);
1.31 bertrand 1329:
1.28 bertrand 1330: BUG((*s_arbre_courant).noeuds_utilises == 0,
1331: uprintf("Freed node !\n"));
1332: (*s_arbre_courant).noeuds_utilises--;
1333: }
1334: }
1335: else
1.1 bertrand 1336: {
1.28 bertrand 1337: // Cas 2 :
1338: // On retire la variable de la liste.
1339:
1340: variable_a_supprimer = (*s_etat_processus)
1341: .pointeur_feuille_courante;
1342:
1343: (*(*(*s_etat_processus).pointeur_feuille_courante).precedent)
1344: .suivant = (*(*s_etat_processus).pointeur_feuille_courante)
1345: .suivant;
1346: (*(*(*s_etat_processus).pointeur_feuille_courante).suivant)
1347: .precedent = (*(*s_etat_processus)
1348: .pointeur_feuille_courante).precedent;
1.32 bertrand 1349:
1.33 bertrand 1350: // Mise à jour du pointeur dans l'arbre des variables. Cette
1351: // mise à jour n'est nécessaire que dans le cas où la variable
1352: // supprimée est en tête de la liste.
1353:
1354: if (variable_a_supprimer == (*((*(*variable_a_supprimer).noeud_pere)
1355: .noeuds[(*(*variable_a_supprimer).noeud)
1356: .indice_tableau_pere])).feuille)
1357: {
1358: (*((*(*variable_a_supprimer).noeud_pere).noeuds
1359: [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
1360: .feuille = (*(*((*(*variable_a_supprimer).noeud_pere)
1361: .noeuds[(*(*variable_a_supprimer).noeud)
1362: .indice_tableau_pere])).feuille).suivant;
1363: }
1364:
1365: (*s_etat_processus).pointeur_feuille_courante =
1366: (*(*s_etat_processus).pointeur_feuille_courante).suivant;
1367: (*s_etat_processus).pointeur_variable_courante =
1368: (*(*s_etat_processus).pointeur_feuille_courante).variable;
1.1 bertrand 1369: }
1370:
1.28 bertrand 1371: // Dans tous les cas, on retire la variable de la liste des variables
1372: // par niveau.
1373:
1374: niveau = (*(*variable_a_supprimer).variable).niveau;
1375: variables_par_niveau = (*s_etat_processus).l_liste_variables_par_niveau;
1.34 bertrand 1376: variable_supprimee = d_faux;
1.28 bertrand 1377:
1.31 bertrand 1378: if (variables_par_niveau != NULL)
1.28 bertrand 1379: {
1.31 bertrand 1380: do
1381: {
1382: l_element_courant = (*variables_par_niveau).liste;
1.28 bertrand 1383:
1.31 bertrand 1384: if (l_element_courant != NULL)
1.28 bertrand 1385: {
1.31 bertrand 1386: if ((*((struct_variable *) (*l_element_courant).donnee))
1387: .niveau == niveau)
1388: {
1389: // On parcourt le bon niveau.
1.28 bertrand 1390:
1.31 bertrand 1391: l_element_precedent = NULL;
1.28 bertrand 1392:
1.31 bertrand 1393: while(l_element_courant != NULL)
1.28 bertrand 1394: {
1.31 bertrand 1395: // Tant que l_element_courant est non nul, il reste
1396: // des variables à explorer dans le niveau courant.
1.28 bertrand 1397:
1.31 bertrand 1398: if ((*l_element_courant).donnee ==
1399: (void *) (*variable_a_supprimer).variable)
1.28 bertrand 1400: {
1.31 bertrand 1401: // On a trouvé la variable à supprimer.
1402:
1403: if (l_element_precedent == NULL)
1404: {
1405: (*variables_par_niveau).liste =
1406: (*l_element_courant).suivant;
1407: }
1408: else
1409: {
1410: (*l_element_precedent).suivant =
1411: (*l_element_courant).suivant;
1412: }
1413:
1.40 bertrand 1414: liberation_maillon(s_etat_processus,
1415: l_element_courant);
1.34 bertrand 1416:
1417: if ((*variables_par_niveau).liste == NULL)
1418: {
1.36 bertrand 1419: (*s_etat_processus).niveau_supprime =
1420: d_vrai;
1421:
1.34 bertrand 1422: if ((*s_etat_processus)
1423: .l_liste_variables_par_niveau
1424: == variables_par_niveau)
1425: {
1426: // On retire l'élément de la liste
1427: // pointé par
1428: // l_liste_variable_par_niveau
1429:
1430: (*s_etat_processus)
1431: .l_liste_variables_par_niveau =
1432: (*variables_par_niveau).suivant;
1433: }
1434:
1435: (*(*variables_par_niveau).precedent)
1436: .suivant =
1437: (*variables_par_niveau).suivant;
1438: (*(*variables_par_niveau).suivant)
1439: .precedent =
1440: (*variables_par_niveau)
1441: .precedent;
1.40 bertrand 1442: liberation_feuille(s_etat_processus,
1443: variables_par_niveau);
1.34 bertrand 1444: }
1445:
1446: variable_supprimee = d_vrai;
1.31 bertrand 1447: break;
1.28 bertrand 1448: }
1.31 bertrand 1449:
1450: l_element_precedent = l_element_courant;
1451: l_element_courant = (*l_element_courant).suivant;
1.28 bertrand 1452: }
1453: }
1454: }
1455:
1.34 bertrand 1456: if (variable_supprimee == d_vrai)
1457: {
1458: break;
1459: }
1460:
1.31 bertrand 1461: variables_par_niveau = (*variables_par_niveau).suivant;
1462:
1463: } while(variables_par_niveau != (*s_etat_processus)
1464: .l_liste_variables_par_niveau);
1.28 bertrand 1465: }
1466:
1467: // Puis on libère le contenu de la variable.
1468:
1469: free((*(*variable_a_supprimer).variable).nom);
1470: liberation(s_etat_processus, (*(*variable_a_supprimer).variable).objet);
1.40 bertrand 1471: liberation_variable(s_etat_processus, (*variable_a_supprimer).variable);
1472: liberation_feuille(s_etat_processus, variable_a_supprimer);
1.28 bertrand 1473:
1.1 bertrand 1474: erreur = d_absence_erreur;
1475: }
1476: else
1477: {
1.25 bertrand 1478: // Aucune variable n'est accessible depuis le point courant du
1479: // programme.
1480:
1.1 bertrand 1481: erreur = d_erreur;
1482: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1483: }
1484:
1.25 bertrand 1485: return(erreur);
1.1 bertrand 1486: }
1487:
1488:
1489: /*
1490: ================================================================================
1491: Procédure de retrait des variables de niveau strictement supérieur au
1492: niveau courant
1493: ================================================================================
1494: Entrée :
1495: --------------------------------------------------------------------------------
1496: Sortie :
1497: --------------------------------------------------------------------------------
1498: Effets de bord : néant
1499: ================================================================================
1500: */
1501:
1502: logical1
1.59 bertrand 1503: retrait_variables_par_niveau(struct_processus *s_etat_processus)
1.1 bertrand 1504: {
1.31 bertrand 1505: struct_liste_variables *l_element_a_supprimer;
1506:
1.28 bertrand 1507: // Utilisation du champ (*s_etat_processus).liste_variables_par_niveau.
1508: // La tête de la pile contient toujours les variables de plus haut niveau
1509: // créées.
1.1 bertrand 1510:
1.28 bertrand 1511: while((*s_etat_processus).l_liste_variables_par_niveau != NULL)
1.1 bertrand 1512: {
1.28 bertrand 1513: if ((*(*s_etat_processus).l_liste_variables_par_niveau).liste == NULL)
1.1 bertrand 1514: {
1.28 bertrand 1515: // Si le niveau ne contient aucune variable, on le détruit.
1516: // Le pointeur sur la chaîne est déjà nul et il ne reste rien à
1517: // faire.
1.1 bertrand 1518: }
1519: else
1520: {
1.28 bertrand 1521: // Le niveau contient des variables.
1522:
1523: if ((*((struct_variable *) (*(*(*s_etat_processus)
1524: .l_liste_variables_par_niveau).liste).donnee)).niveau
1525: <= (*s_etat_processus).niveau_courant)
1.1 bertrand 1526: {
1.28 bertrand 1527: // On a retiré de l'arbre des variables toutes les
1528: // variables de niveau strictement supérieur au niveau
1529: // courant.
1.1 bertrand 1530:
1.28 bertrand 1531: break;
1.1 bertrand 1532: }
1.28 bertrand 1533:
1534: while((*(*s_etat_processus).l_liste_variables_par_niveau).liste
1535: != NULL)
1.1 bertrand 1536: {
1.34 bertrand 1537: // Nécessaire car le pointeur sur la tête de la pile
1538: // peut être modifié par retrait_variable().
1.28 bertrand 1539: // Sauvegarde des variables statiques.
1540:
1541: if ((*((struct_variable *) (*(*(*s_etat_processus)
1542: .l_liste_variables_par_niveau).liste).donnee)).origine
1543: == 'P')
1.1 bertrand 1544: {
1.28 bertrand 1545: if ((*((struct_variable *) (*(*(*s_etat_processus)
1546: .l_liste_variables_par_niveau).liste).donnee))
1547: .variable_statique.adresse != 0)
1.1 bertrand 1548: {
1.28 bertrand 1549: if (recherche_variable_statique(s_etat_processus,
1550: (*((struct_variable *) (*(*(*s_etat_processus)
1551: .l_liste_variables_par_niveau).liste).donnee))
1552: .nom, (*((struct_variable *)
1553: (*(*(*s_etat_processus)
1554: .l_liste_variables_par_niveau).liste).donnee))
1555: .variable_statique, ((*s_etat_processus)
1556: .mode_execution_programme
1.59 bertrand 1557: == 'Y') ? 'P' : 'E') != NULL)
1.28 bertrand 1558: {
1.59 bertrand 1559: (*(*s_etat_processus)
1560: .pointeur_variable_statique_courante)
1561: .objet = (*((struct_variable *)
1.28 bertrand 1562: (*(*(*s_etat_processus)
1563: .l_liste_variables_par_niveau).liste)
1564: .donnee)).objet;
1565: }
1566: else
1567: {
1568: (*s_etat_processus).erreur_systeme =
1569: d_es_variable_introuvable;
1570: }
1571:
1572: (*((struct_variable *) (*(*(*s_etat_processus)
1573: .l_liste_variables_par_niveau).liste).donnee))
1574: .objet = NULL;
1.1 bertrand 1575: }
1.28 bertrand 1576: }
1577: else
1578: {
1579: if ((*((struct_variable *) (*(*(*s_etat_processus)
1580: .l_liste_variables_par_niveau).liste).donnee))
1581: .variable_statique.pointeur != NULL)
1.1 bertrand 1582: {
1.28 bertrand 1583: /*
1584: * Gestion des variables statiques
1585: */
1586:
1587: if (recherche_variable_statique(s_etat_processus,
1588: (*((struct_variable *) (*(*(*s_etat_processus)
1589: .l_liste_variables_par_niveau).liste).donnee))
1590: .nom, (*((struct_variable *)
1591: (*(*(*s_etat_processus)
1592: .l_liste_variables_par_niveau).liste).donnee))
1593: .variable_statique, ((*s_etat_processus)
1594: .mode_execution_programme
1.59 bertrand 1595: == 'Y') ? 'P' : 'E') != NULL)
1.28 bertrand 1596: {
1.59 bertrand 1597: (*(*s_etat_processus)
1598: .pointeur_variable_statique_courante)
1.28 bertrand 1599: .objet = (*((struct_variable *)
1600: (*(*(*s_etat_processus)
1601: .l_liste_variables_par_niveau).liste)
1602: .donnee)).objet;
1603: }
1604: else
1605: {
1606: (*s_etat_processus).erreur_systeme =
1607: d_es_variable_introuvable;
1608: return(d_erreur);
1609: }
1610:
1611: (*((struct_variable *) (*(*(*s_etat_processus)
1612: .l_liste_variables_par_niveau).liste).donnee))
1613: .objet = NULL;
1.1 bertrand 1614: }
1.28 bertrand 1615: }
1.1 bertrand 1616:
1.28 bertrand 1617: if (retrait_variable(s_etat_processus,
1618: (*((struct_variable *) (*(*(*s_etat_processus)
1619: .l_liste_variables_par_niveau).liste).donnee)).nom,
1620: 'L') == d_erreur)
1621: {
1622: return(d_erreur);
1.1 bertrand 1623: }
1.34 bertrand 1624:
1625: if ((*((struct_variable *) (*(*(*s_etat_processus)
1626: .l_liste_variables_par_niveau).liste).donnee)).niveau
1627: <= (*s_etat_processus).niveau_courant)
1628: {
1629: // On a retiré de l'arbre des variables toutes les
1630: // variables de niveau strictement supérieur au niveau
1631: // courant.
1632:
1633: return(d_absence_erreur);
1634: }
1.1 bertrand 1635: }
1636: }
1637:
1.31 bertrand 1638: // On retire l'élément de la liste doublement chaînée et circulaire.
1639:
1640: (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent).suivant
1641: = (*(*s_etat_processus).l_liste_variables_par_niveau).suivant;
1642: (*(*(*s_etat_processus).l_liste_variables_par_niveau).suivant).precedent
1643: = (*(*s_etat_processus).l_liste_variables_par_niveau).precedent;
1644:
1645: l_element_a_supprimer = (*s_etat_processus)
1646: .l_liste_variables_par_niveau;
1647: (*s_etat_processus).l_liste_variables_par_niveau =
1648: (*l_element_a_supprimer).suivant;
1.40 bertrand 1649: liberation_feuille(s_etat_processus, l_element_a_supprimer);
1.1 bertrand 1650: }
1651:
1652: return(d_absence_erreur);
1653: }
1654:
1.23 bertrand 1655:
1656: /*
1657: ================================================================================
1.24 bertrand 1658: Procédure de retrait des toutes les variables locales et globales
1659: ================================================================================
1660: Entrée : drapeau indiquant s'il faut retirer les définitions (variables
1661: de niveau 0)
1662: --------------------------------------------------------------------------------
1663: Sortie :
1664: --------------------------------------------------------------------------------
1665: Effets de bord : néant
1666: ================================================================================
1667: */
1668:
1669: void
1670: liberation_arbre_variables(struct_processus *s_etat_processus,
1671: struct_arbre_variables *arbre, logical1 retrait_definitions)
1672: {
1.58 bertrand 1673: int i;
1674:
1675: struct_liste_chainee *l_element_courant_liste;
1676: struct_liste_chainee *l_element_suivant_liste;
1.24 bertrand 1677:
1.58 bertrand 1678: struct_liste_variables *l_element_courant;
1679: struct_liste_variables *l_element_suivant;
1.28 bertrand 1680:
1.58 bertrand 1681: struct_liste_variables_statiques *l_element_statique_courant;
1682: struct_liste_variables_statiques *l_element_statique_suivant;
1.28 bertrand 1683:
1684: // Libération de l'arbre des variables. Le contenu des variables n'est
1685: // pas détruit par cette opération, il sera détruit lors de la libération
1686: // de la liste des variables par niveau.
1.24 bertrand 1687:
1.34 bertrand 1688: if (arbre == NULL)
1689: {
1690: return;
1691: }
1692:
1.31 bertrand 1693: l_element_courant = (*arbre).feuille;
1694:
1695: if (l_element_courant != NULL)
1696: {
1697: do
1698: {
1699: l_element_suivant = (*l_element_courant).suivant;
1.40 bertrand 1700: liberation_feuille(s_etat_processus, l_element_courant);
1.31 bertrand 1701: l_element_courant = l_element_suivant;
1702: } while(l_element_courant != (*arbre).feuille);
1.38 bertrand 1703:
1704: (*arbre).feuille = NULL;
1.31 bertrand 1705: }
1706:
1.58 bertrand 1707: l_element_statique_courant = (*arbre).feuille_statique;
1708:
1709: while(l_element_statique_courant != NULL)
1710: {
1711: l_element_statique_suivant = (*l_element_statique_courant).suivant;
1712:
1713: free((*(*l_element_statique_courant).variable).nom);
1714: liberation(s_etat_processus, (*(*l_element_statique_courant)
1715: .variable).objet);
1.61 bertrand 1716: free((*l_element_statique_courant).variable);
1717: free(l_element_statique_courant);
1.58 bertrand 1718:
1719: l_element_statique_courant = l_element_statique_suivant;
1720: }
1721:
1.24 bertrand 1722: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1723: {
1.28 bertrand 1724: if ((*arbre).noeuds[i] != NULL)
1.24 bertrand 1725: {
1.28 bertrand 1726: liberation_arbre_variables(s_etat_processus, (*arbre).noeuds[i],
1727: retrait_definitions);
1.38 bertrand 1728: (*arbre).noeuds[i] = NULL;
1.28 bertrand 1729: }
1730: }
1731:
1732: // Suppression de la liste des variables par niveau.
1733:
1734: if (arbre == (*s_etat_processus).s_arbre_variables)
1735: {
1736: l_element_courant = (*s_etat_processus).l_liste_variables_par_niveau;
1737:
1.31 bertrand 1738: if (l_element_courant != NULL)
1.28 bertrand 1739: {
1.31 bertrand 1740: do
1741: {
1742: l_element_courant_liste = (*l_element_courant).liste;
1.24 bertrand 1743:
1.31 bertrand 1744: while(l_element_courant_liste != NULL)
1.24 bertrand 1745: {
1.31 bertrand 1746: if ((retrait_definitions == d_vrai) ||
1747: ((*((struct_variable *) (*l_element_courant_liste)
1748: .donnee)).niveau >= 1))
1749: {
1750: liberation(s_etat_processus, (*((struct_variable *)
1751: (*l_element_courant_liste).donnee)).objet);
1752: free((*((struct_variable *) (*l_element_courant_liste)
1753: .donnee)).nom);
1754: }
1755:
1756: l_element_suivant_liste =
1757: (*l_element_courant_liste).suivant;
1.40 bertrand 1758: liberation_variable(s_etat_processus, (struct_variable *)
1759: (*l_element_courant_liste).donnee);
1760: liberation_maillon(s_etat_processus,
1761: l_element_courant_liste);
1.31 bertrand 1762: l_element_courant_liste = l_element_suivant_liste;
1.24 bertrand 1763: }
1764:
1.31 bertrand 1765: l_element_suivant = (*l_element_courant).suivant;
1.40 bertrand 1766: liberation_feuille(s_etat_processus, l_element_courant);
1.31 bertrand 1767: l_element_courant = l_element_suivant;
1768: } while(l_element_courant != (*s_etat_processus)
1769: .l_liste_variables_par_niveau);
1.24 bertrand 1770: }
1771: }
1772:
1.40 bertrand 1773: liberation_tableau_noeuds(s_etat_processus, (*arbre).noeuds);
1774: liberation_noeud(s_etat_processus, arbre);
1.38 bertrand 1775: arbre = NULL;
1.24 bertrand 1776:
1777: return;
1778: }
1779:
1.28 bertrand 1780:
1.24 bertrand 1781: /*
1782: ================================================================================
1.33 bertrand 1783: Procédure renvoyant les variables dans un tableau
1784: ================================================================================
1785: Entrée :
1786: --------------------------------------------------------------------------------
1787: Sortie :
1788: --------------------------------------------------------------------------------
1789: Effets de bord : néant
1790: ================================================================================
1791: */
1792:
1.70 bertrand 1793: static integer8
1.65 bertrand 1794: nombre_variables_locales(struct_processus *s_etat_processus,
1.33 bertrand 1795: struct_arbre_variables *l_element_courant)
1796: {
1.70 bertrand 1797: integer8 i;
1798: integer8 n;
1.33 bertrand 1799:
1.60 bertrand 1800: struct_liste_variables *l_variable;
1801: struct_liste_variables_statiques *l_variable_statique;
1.33 bertrand 1802:
1.65 bertrand 1803: if (l_element_courant == NULL)
1804: {
1805: return(0);
1806: }
1807:
1.33 bertrand 1808: n = 0;
1809:
1810: if ((*l_element_courant).feuille != NULL)
1811: {
1812: l_variable = (*l_element_courant).feuille;
1813:
1814: do
1815: {
1816: n++;
1817: l_variable = (*l_variable).suivant;
1818: } while(l_variable != (*l_element_courant).feuille);
1819: }
1820:
1.60 bertrand 1821: if ((*l_element_courant).feuille_statique != NULL)
1822: {
1823: l_variable_statique = (*l_element_courant).feuille_statique;
1824:
1825: do
1826: {
1827: // Si le pointeur est nul, la variable est accessible et a été
1828: // copiée dans l'arbre des variables.
1829:
1830: if ((*(*l_variable_statique).variable).objet != NULL)
1831: {
1832: n++;
1833: }
1834:
1835: l_variable_statique = (*l_variable_statique).suivant;
1836: } while(l_variable_statique != NULL);
1837: }
1838:
1.33 bertrand 1839: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1840: {
1841: if ((*l_element_courant).noeuds[i] != NULL)
1842: {
1.65 bertrand 1843: n += nombre_variables_locales(s_etat_processus,
1844: (*l_element_courant).noeuds[i]);
1845: }
1846: }
1847:
1848: return(n);
1849: }
1850:
1851:
1.70 bertrand 1852: static integer8
1.65 bertrand 1853: nombre_variables_partagees(struct_processus *s_etat_processus,
1854: struct_arbre_variables_partagees *l_element_courant)
1855: {
1.70 bertrand 1856: integer8 i;
1857: integer8 n;
1.65 bertrand 1858:
1859: struct_liste_variables_partagees *l_variable;
1860:
1861: if (l_element_courant == NULL)
1862: {
1863: return(0);
1864: }
1865:
1866: if (pthread_mutex_lock(&((*l_element_courant).mutex_feuille)) != 0)
1867: {
1868: (*s_etat_processus).erreur_systeme = d_es_processus;
1869: return(0);
1870: }
1871:
1872: n = 0;
1873:
1874: if ((*l_element_courant).feuille != NULL)
1875: {
1876: l_variable = (*l_element_courant).feuille;
1877:
1878: do
1879: {
1880: n++;
1881: l_variable = (*l_variable).suivant;
1882: } while(l_variable != NULL);
1883: }
1884:
1885: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1886: {
1887: if ((*l_element_courant).noeuds[i] != NULL)
1888: {
1889: n += nombre_variables_partagees(s_etat_processus,
1.33 bertrand 1890: (*l_element_courant).noeuds[i]);
1891: }
1892: }
1893:
1894: return(n);
1895: }
1896:
1.53 bertrand 1897:
1.70 bertrand 1898: integer8
1.65 bertrand 1899: nombre_variables(struct_processus *s_etat_processus)
1900: {
1901: return(nombre_variables_locales(s_etat_processus,
1902: (*s_etat_processus).s_arbre_variables)
1903: + nombre_variables_partagees(s_etat_processus,
1904: (*(*s_etat_processus).s_arbre_variables_partagees)));
1905: }
1906:
1907:
1908: void
1909: liberation_mutexes_arbre_variables_partagees(struct_processus *s_etat_processus,
1910: struct_arbre_variables_partagees *l_element_courant)
1911: {
1912: int i;
1913:
1914: if (l_element_courant == NULL)
1915: {
1916: return;
1917: }
1918:
1919: if (pthread_mutex_trylock(&((*l_element_courant).mutex_feuille)) != 0)
1920: {
1921: (*s_etat_processus).erreur_systeme = d_es_processus;
1922: return;
1923: }
1924:
1925: if (pthread_mutex_unlock(&((*l_element_courant).mutex_feuille)) != 0)
1926: {
1927: (*s_etat_processus).erreur_systeme = d_es_processus;
1928: return;
1929: }
1930:
1931: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1932: {
1933: if ((*l_element_courant).noeuds[i] != NULL)
1934: {
1935: liberation_mutexes_arbre_variables_partagees(s_etat_processus,
1936: (*l_element_courant).noeuds[i]);
1937: }
1938: }
1939:
1940: return;
1941: }
1942:
1943:
1.70 bertrand 1944: static integer8
1.65 bertrand 1945: liste_variables_locales(struct_processus *s_etat_processus,
1.70 bertrand 1946: struct_tableau_variables *tableau, integer8 position,
1.33 bertrand 1947: struct_arbre_variables *l_element_courant)
1948: {
1.70 bertrand 1949: integer8 i;
1.33 bertrand 1950:
1.60 bertrand 1951: struct_liste_variables *l_variable;
1952: struct_liste_variables_statiques *l_variable_statique;
1.33 bertrand 1953:
1.65 bertrand 1954: if (l_element_courant == NULL)
1955: {
1.72 ! bertrand 1956: return(position);
1.65 bertrand 1957: }
1958:
1.33 bertrand 1959: if ((*l_element_courant).feuille != NULL)
1960: {
1961: l_variable = (*l_element_courant).feuille;
1962:
1963: do
1964: {
1965: tableau[position].origine = (*(*l_variable).variable).origine;
1966: tableau[position].nom = (*(*l_variable).variable).nom;
1967: tableau[position].niveau = (*(*l_variable).variable).niveau;
1968: tableau[position].objet = (*(*l_variable).variable).objet;
1969: tableau[position].variable_verrouillee =
1970: (*(*l_variable).variable).variable_verrouillee;
1971: tableau[position].variable_statique =
1972: (*(*l_variable).variable).variable_statique;
1973: tableau[position].variable_partagee =
1974: (*(*l_variable).variable).variable_partagee;
1.60 bertrand 1975: tableau[position].variable_masquee = d_faux;
1.72 ! bertrand 1976: tableau[position].mutex = NULL;
1.33 bertrand 1977:
1978: position++;
1.72 ! bertrand 1979:
1.33 bertrand 1980: l_variable = (*l_variable).suivant;
1981: } while(l_variable != (*l_element_courant).feuille);
1982: }
1983:
1.60 bertrand 1984: if ((*l_element_courant).feuille_statique != NULL)
1985: {
1986: l_variable_statique = (*l_element_courant).feuille_statique;
1987:
1988: do
1989: {
1990: if ((*(*l_variable_statique).variable).objet != NULL)
1991: {
1992: tableau[position].origine = 'E';
1993: tableau[position].nom = (*(*l_variable_statique).variable).nom;
1994: tableau[position].niveau =
1995: (*(*l_variable_statique).variable).niveau;
1.72 ! bertrand 1996: tableau[position].objet = (*(*l_variable_statique).variable)
! 1997: .objet;
1.60 bertrand 1998: tableau[position].variable_verrouillee = d_faux;
1999: tableau[position].variable_statique =
2000: (*(*l_variable_statique).variable).variable_statique;
2001: tableau[position].variable_partagee.pointeur = NULL;
2002: tableau[position].variable_masquee = d_vrai;
2003:
2004: position++;
2005: }
2006:
2007: l_variable_statique = (*l_variable_statique).suivant;
2008: } while(l_variable_statique != NULL);
2009: }
2010:
1.33 bertrand 2011: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
2012: {
2013: if ((*l_element_courant).noeuds[i] != NULL)
2014: {
1.65 bertrand 2015: position = liste_variables_locales(s_etat_processus,
2016: tableau, position, (*l_element_courant).noeuds[i]);
2017: }
2018: }
2019:
2020: return(position);
2021: }
2022:
2023:
1.70 bertrand 2024: static integer8
1.65 bertrand 2025: liste_variables_partagees(struct_processus *s_etat_processus,
1.70 bertrand 2026: struct_tableau_variables *tableau, integer8 position,
1.65 bertrand 2027: struct_arbre_variables_partagees *l_element_courant)
2028: {
1.70 bertrand 2029: integer8 i;
1.65 bertrand 2030:
2031: struct_liste_variables_partagees *l_variable;
2032:
2033: if (l_element_courant == NULL)
2034: {
1.72 ! bertrand 2035: return(position);
1.65 bertrand 2036: }
2037:
1.71 bertrand 2038: // mutex_liste_variables_partagees
2039: // et (*l_variable_courante).mutex_feuille
1.65 bertrand 2040: if ((*l_element_courant).feuille != NULL)
2041: {
2042: l_variable = (*l_element_courant).feuille;
2043:
2044: do
2045: {
2046: tableau[position].origine = 'E';
2047: tableau[position].nom = (*(*l_variable).variable).nom;
2048: tableau[position].niveau = (*(*l_variable).variable).niveau;
2049: tableau[position].objet = (*(*l_variable).variable).objet;
2050: tableau[position].variable_verrouillee = d_faux;
2051: tableau[position].variable_partagee =
2052: (*(*l_variable).variable).variable_partagee;
2053: tableau[position].variable_partagee.pointeur = NULL;
2054: tableau[position].variable_masquee = d_faux;
1.72 ! bertrand 2055: tableau[position].mutex = &((*(*l_variable).variable).mutex);
1.65 bertrand 2056:
2057: position++;
2058:
2059: l_variable = (*l_variable).suivant;
2060: } while(l_variable != NULL);
2061: }
2062:
2063: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
2064: {
2065: if ((*l_element_courant).noeuds[i] != NULL)
2066: {
2067: position = liste_variables_partagees(s_etat_processus,
1.33 bertrand 2068: tableau, position, (*l_element_courant).noeuds[i]);
2069: }
2070: }
2071:
1.72 ! bertrand 2072: if (pthread_mutex_unlock(&((*l_element_courant).mutex_feuille)) != 0)
! 2073: {
! 2074: (*s_etat_processus).erreur_systeme = d_es_processus;
! 2075: return(0);
! 2076: }
! 2077:
1.33 bertrand 2078: return(position);
2079: }
2080:
1.47 bertrand 2081:
1.65 bertrand 2082: static int
2083: fonction_ordre_variables(const void *argument_1, const void *argument_2)
2084: {
2085: int comparaison;
2086:
2087: struct_tableau_variables *a1;
2088: struct_tableau_variables *a2;
2089:
2090: a1 = (struct_tableau_variables *) argument_1;
2091: a2 = (struct_tableau_variables *) argument_2;
2092:
2093: comparaison = strcmp((*a1).nom, (*a2).nom);
2094:
2095: if (comparaison != 0)
2096: {
2097: return(comparaison);
2098: }
2099: else
2100: {
1.70 bertrand 2101: return(((((*a1).niveau - (*a2).niveau)) > 0) ? 1 : -1);
1.65 bertrand 2102: }
2103: }
2104:
2105:
1.70 bertrand 2106: integer8
1.65 bertrand 2107: liste_variables(struct_processus *s_etat_processus,
2108: struct_tableau_variables *tableau)
2109: {
1.70 bertrand 2110: integer8 nombre_elements;
1.65 bertrand 2111:
2112: nombre_elements = liste_variables_locales(s_etat_processus,
2113: tableau, 0, (*s_etat_processus).s_arbre_variables);
1.72 ! bertrand 2114: nombre_elements = liste_variables_partagees(s_etat_processus,
1.65 bertrand 2115: tableau, nombre_elements, (*(*s_etat_processus)
2116: .s_arbre_variables_partagees));
2117:
1.70 bertrand 2118: qsort(tableau, (size_t) nombre_elements, sizeof(struct_tableau_variables),
1.65 bertrand 2119: fonction_ordre_variables);
2120:
2121: return(nombre_elements);
2122: }
2123:
2124:
1.33 bertrand 2125: /*
2126: ================================================================================
1.23 bertrand 2127: Procédure de copie de l'arbre des variables
2128: ================================================================================
2129: Entrée :
2130: --------------------------------------------------------------------------------
2131: Sortie :
2132: --------------------------------------------------------------------------------
2133: Effets de bord : néant
2134: ================================================================================
2135: */
2136:
1.38 bertrand 2137: void
2138: copie_arbre_variables(struct_processus *s_etat_processus, struct_processus
2139: *s_nouvel_etat_processus)
1.23 bertrand 2140: {
2141: // Les définitions sont partagées entre tous les threads et ne sont pas
2142: // copiées.
1.28 bertrand 2143: //
2144: // NB : on ne copie que les variables de niveaux 0 et 1, les autres
2145: // variables locales étant masquées par le processus de création de thread
1.38 bertrand 2146: // ou de processus, elles seront inaccessibles de tous les points
2147: // du fil d'exécution fils.
2148:
2149: // Pour copier ces variables, on récupère les variables depuis la liste par
2150: // niveaux (niveaux 0 et 1) et on ajoute les variables dans la nouvelle
2151: // structure. Les variables de niveau 0 étant non modifiables, elles
2152: // ne sont pas dupliquées.
2153:
1.60 bertrand 2154: int i;
1.38 bertrand 2155:
1.60 bertrand 2156: logical1 niveau_0_traite;
2157: logical1 niveau_1_traite;
1.47 bertrand 2158:
1.60 bertrand 2159: struct_arbre_variables *l_variable_courante;
1.38 bertrand 2160:
1.60 bertrand 2161: struct_liste_chainee *l_element_courant;
1.38 bertrand 2162:
1.60 bertrand 2163: struct_liste_variables *l_niveau_courant;
2164: struct_liste_variables_statiques *l_element_statique_courant;
2165:
2166: struct_variable s_variable;
1.63 bertrand 2167: struct_variable_statique s_variable_statique;
1.60 bertrand 2168:
2169: unsigned char *ptr;
1.38 bertrand 2170:
2171: (*s_nouvel_etat_processus).s_arbre_variables = NULL;
2172: (*s_nouvel_etat_processus).l_liste_variables_par_niveau = NULL;
2173:
2174: l_niveau_courant = (*s_etat_processus).l_liste_variables_par_niveau;
2175:
2176: // Si la variable en tête n'est pas une variable de niveau 0, le niveau
1.47 bertrand 2177: // 0, s'il existe est le niveau précédent la valeur courante dans la
1.38 bertrand 2178: // boucle.
2179:
2180: if ((*((struct_variable *) (*(*l_niveau_courant).liste).donnee)).niveau
2181: != 0)
2182: {
2183: l_niveau_courant = (*l_niveau_courant).precedent;
2184: }
2185:
2186: // Les variables de niveaux 0 et 1 sont accessibles en au plus trois
2187: // itérations (par construction).
1.28 bertrand 2188:
1.47 bertrand 2189: niveau_0_traite = d_faux;
2190: niveau_1_traite = d_faux;
2191:
1.38 bertrand 2192: for(i = 0; i <= 2; i++)
2193: {
2194: if ((*((struct_variable *) (*(*l_niveau_courant).liste)
2195: .donnee)).niveau == 0)
2196: {
1.47 bertrand 2197: if (niveau_0_traite == d_faux)
2198: {
2199: l_element_courant = (*l_niveau_courant).liste;
1.23 bertrand 2200:
1.47 bertrand 2201: while(l_element_courant != NULL)
1.38 bertrand 2202: {
1.47 bertrand 2203: if (ajout_variable(s_nouvel_etat_processus,
2204: (struct_variable *) (*l_element_courant).donnee)
2205: == d_erreur)
2206: {
2207: return;
2208: }
2209:
2210: l_element_courant = (*l_element_courant).suivant;
1.38 bertrand 2211: }
2212:
1.47 bertrand 2213: niveau_0_traite = d_vrai;
1.38 bertrand 2214: }
2215: }
2216: else if ((*((struct_variable *) (*(*l_niveau_courant).liste)
2217: .donnee)).niveau == 1)
2218: {
1.47 bertrand 2219: if (niveau_1_traite == d_faux)
1.38 bertrand 2220: {
1.47 bertrand 2221: l_element_courant = (*l_niveau_courant).liste;
1.38 bertrand 2222:
1.47 bertrand 2223: while(l_element_courant != NULL)
1.38 bertrand 2224: {
1.47 bertrand 2225: s_variable = (*((struct_variable *)
2226: (*l_element_courant).donnee));
1.38 bertrand 2227:
1.47 bertrand 2228: if ((s_variable.nom = strdup((*((struct_variable *)
2229: (*l_element_courant).donnee)).nom)) == NULL)
2230: {
2231: (*s_nouvel_etat_processus).erreur_systeme =
2232: d_es_allocation_memoire;
2233: return;
2234: }
2235:
2236: if ((s_variable.objet = copie_objet(s_nouvel_etat_processus,
2237: (*((struct_variable *) (*l_element_courant).donnee))
2238: .objet, 'P')) == NULL)
2239: {
2240: (*s_nouvel_etat_processus).erreur_systeme =
2241: d_es_allocation_memoire;
2242: return;
2243: }
2244:
2245: if (ajout_variable(s_nouvel_etat_processus, &s_variable)
2246: == d_erreur)
2247: {
2248: return;
2249: }
1.38 bertrand 2250:
1.47 bertrand 2251: l_element_courant = (*l_element_courant).suivant;
1.38 bertrand 2252: }
2253:
1.47 bertrand 2254: niveau_1_traite = d_vrai;
1.38 bertrand 2255: }
2256:
2257: // Les variables de niveau 0 ayant déjà été copiées, on
2258: // peut sortir de la boucle car toutes les variables sont
2259: // maintenant disponibles dans le fil d'exécution fils.
2260:
2261: break;
2262: }
2263:
2264: l_niveau_courant = (*l_niveau_courant).precedent;
2265: }
2266:
1.60 bertrand 2267: // Copie des variables statiques
2268:
2269: l_element_statique_courant = (*s_etat_processus)
2270: .l_liste_variables_statiques;
2271:
2272: while(l_element_statique_courant != NULL)
2273: {
2274: // Création des branches de l'arbre si nécessaire.
2275:
2276: if ((*s_nouvel_etat_processus).s_arbre_variables == NULL)
2277: {
2278: if (((*s_nouvel_etat_processus).s_arbre_variables =
2279: allocation_noeud(s_nouvel_etat_processus)) == NULL)
2280: {
2281: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2282: return;
2283: }
2284:
2285: (*(*s_nouvel_etat_processus).s_arbre_variables).feuille = NULL;
2286: (*(*s_nouvel_etat_processus).s_arbre_variables).feuille_statique
2287: = NULL;
2288: (*(*s_nouvel_etat_processus).s_arbre_variables).noeuds_utilises = 0;
2289: (*(*s_nouvel_etat_processus).s_arbre_variables).indice_tableau_pere
2290: = -1;
2291: (*(*s_nouvel_etat_processus).s_arbre_variables).noeud_pere = NULL;
2292:
2293: if (((*(*s_nouvel_etat_processus).s_arbre_variables).noeuds =
2294: allocation_tableau_noeuds(s_nouvel_etat_processus)) == NULL)
2295: {
2296: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2297: return;
2298: }
2299:
2300: for(i = 0; i < (*s_nouvel_etat_processus)
2301: .nombre_caracteres_variables; i++)
2302: {
2303: (*(*s_nouvel_etat_processus).s_arbre_variables).noeuds[i]
2304: = NULL;
2305: }
2306: }
2307:
2308: l_variable_courante = (*s_nouvel_etat_processus).s_arbre_variables;
2309: ptr = (*(*l_element_statique_courant).variable).nom;
2310:
2311: while((*ptr) != d_code_fin_chaine)
2312: {
2313: BUG((*s_nouvel_etat_processus).pointeurs_caracteres_variables
2314: [*ptr] < 0, uprintf("Variable=\"%s\", (*ptr)='%c'\n",
2315: (*(*l_element_statique_courant).variable).nom, *ptr));
2316:
2317: if ((*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2318: .pointeurs_caracteres_variables[*ptr]] == NULL)
2319: {
2320: // Le noeud n'existe pas encore, on le crée et on le marque
2321: // comme utilisé dans la structure parente.
2322:
2323: if (((*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2324: .pointeurs_caracteres_variables[*ptr]] =
2325: allocation_noeud(s_nouvel_etat_processus)) == NULL)
2326: {
2327: (*s_etat_processus).erreur_systeme =
2328: d_es_allocation_memoire;
2329: return;
2330: }
2331:
2332: (*l_variable_courante).noeuds_utilises++;
2333:
2334: // La feuille est par défaut vide et aucun élément du tableau
2335: // noeuds (les branches qui peuvent être issues de ce nouveau
2336: // noeud) n'est encore utilisée.
2337:
2338: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2339: .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
2340: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2341: .pointeurs_caracteres_variables[*ptr]]).feuille_statique
2342: = NULL;
2343: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2344: .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises
2345: = 0;
2346:
2347: // Le champ noeud_pere de la structure créée pointe sur
2348: // la structure parente et l'indice tableau_pere correspond à la
2349: // position réelle dans le tableau noeuds[] de la structure
2350: // parente du noeud courant. Cette valeur sera utilisée lors de
2351: // la destruction du noeud pour annuler le pointeur contenu dans
2352: // le tableau noeuds[] de la structure parente.
2353:
2354: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2355: .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
2356: l_variable_courante;
2357: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2358: .pointeurs_caracteres_variables[*ptr]])
2359: .indice_tableau_pere = (*s_nouvel_etat_processus)
2360: .pointeurs_caracteres_variables[*ptr];
2361:
2362: // Allocation du tableau noeuds[] et initialisation à zéro de
2363: // tous les pointeurs.
2364:
2365: if (((*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2366: .pointeurs_caracteres_variables[*ptr]]).noeuds =
2367: allocation_tableau_noeuds(s_nouvel_etat_processus))
2368: == NULL)
2369: {
2370: (*s_etat_processus).erreur_systeme
2371: = d_es_allocation_memoire;
2372: return;
2373: }
2374:
2375: for(i = 0; i < (*s_nouvel_etat_processus)
2376: .nombre_caracteres_variables; i++)
2377: {
2378: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2379: .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
2380: = NULL;
2381: }
2382: }
2383:
2384: l_variable_courante = (*l_variable_courante).noeuds
2385: [(*s_nouvel_etat_processus).pointeurs_caracteres_variables
2386: [*ptr]];
2387:
2388: ptr++;
2389: }
2390:
1.63 bertrand 2391: // Il faut copier la variable pour la dissocier de la variable
2392: // restant dans le thread parent.
2393:
2394: s_variable_statique = (*(*l_element_statique_courant).variable);
2395:
2396: if (copie_objet(s_etat_processus, s_variable_statique.objet, 'P')
2397: == NULL)
2398: {
2399: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2400: return;
2401: }
2402:
2403: if ((s_variable_statique.nom = malloc((strlen(
2404: (*(*l_element_statique_courant).variable).nom) + 1) *
2405: sizeof(unsigned char))) == NULL)
1.60 bertrand 2406: {
2407: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2408: return;
2409: }
2410:
1.63 bertrand 2411: strcpy(s_variable_statique.nom, (*(*l_element_statique_courant)
2412: .variable).nom);
2413:
2414: if (creation_variable_statique(s_nouvel_etat_processus,
2415: &s_variable_statique) == d_erreur)
1.62 bertrand 2416: {
2417: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2418: return;
2419: }
2420:
1.60 bertrand 2421: l_element_statique_courant = (*l_element_statique_courant).suivant;
2422: }
2423:
1.38 bertrand 2424: return;
1.23 bertrand 2425: }
2426:
2427:
2428: /*
2429: ================================================================================
2430: Procédure d'initialisation de la table de correspondance des variables
2431: ================================================================================
2432: Entrée :
2433: --------------------------------------------------------------------------------
2434: Sortie :
2435: --------------------------------------------------------------------------------
2436: Effets de bord : néant
2437: ================================================================================
2438: */
2439:
2440: /*
2441: * Caractères autorisés dans les instructions
2442: *
2443: * A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
2444: * a b c d e f g h i j k l m n o p q r s t u v w x y z
2445: * _
2446: * 1 2 3 4 5 6 7 8 9 0
2447: */
2448:
2449: void
2450: initialisation_variables(struct_processus *s_etat_processus)
2451: {
2452: int decalage;
2453: int i;
2454: int longueur_tableau;
2455:
2456: unsigned char caractere;
2457:
2458: // Récupération de la longueur d'un unsigned char
2459:
2460: longueur_tableau = 1;
2461: decalage = 0;
2462: caractere = 1;
2463:
2464: while((1L << decalage) == (long) ((unsigned char) (caractere << decalage)))
2465: {
2466: decalage++;
2467: longueur_tableau *= 2;
2468: }
2469:
2470: if (((*s_etat_processus).pointeurs_caracteres_variables =
1.70 bertrand 2471: malloc(((size_t) longueur_tableau) * sizeof(int))) == NULL)
1.23 bertrand 2472: {
2473: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2474: return;
2475: }
2476:
2477: for(i = 0; i < longueur_tableau; i++)
2478: {
2479: (*s_etat_processus).pointeurs_caracteres_variables[i] = -1;
2480: }
2481:
2482: (*s_etat_processus).nombre_caracteres_variables = 0;
2483:
2484: #define DECLARATION_CARACTERE(c) \
2485: do { (*s_etat_processus).pointeurs_caracteres_variables[c] = \
2486: (*s_etat_processus).nombre_caracteres_variables++; } while(0)
2487:
2488: DECLARATION_CARACTERE('A');
2489: DECLARATION_CARACTERE('B');
2490: DECLARATION_CARACTERE('C');
2491: DECLARATION_CARACTERE('D');
2492: DECLARATION_CARACTERE('E');
2493: DECLARATION_CARACTERE('F');
2494: DECLARATION_CARACTERE('G');
2495: DECLARATION_CARACTERE('H');
2496: DECLARATION_CARACTERE('I');
2497: DECLARATION_CARACTERE('J');
2498: DECLARATION_CARACTERE('K');
2499: DECLARATION_CARACTERE('L');
2500: DECLARATION_CARACTERE('M');
2501: DECLARATION_CARACTERE('N');
2502: DECLARATION_CARACTERE('O');
2503: DECLARATION_CARACTERE('P');
2504: DECLARATION_CARACTERE('Q');
2505: DECLARATION_CARACTERE('R');
2506: DECLARATION_CARACTERE('S');
2507: DECLARATION_CARACTERE('T');
2508: DECLARATION_CARACTERE('U');
2509: DECLARATION_CARACTERE('V');
2510: DECLARATION_CARACTERE('W');
2511: DECLARATION_CARACTERE('X');
2512: DECLARATION_CARACTERE('Y');
2513: DECLARATION_CARACTERE('Z');
2514:
2515: DECLARATION_CARACTERE('a');
2516: DECLARATION_CARACTERE('b');
2517: DECLARATION_CARACTERE('c');
2518: DECLARATION_CARACTERE('d');
2519: DECLARATION_CARACTERE('e');
2520: DECLARATION_CARACTERE('f');
2521: DECLARATION_CARACTERE('g');
2522: DECLARATION_CARACTERE('h');
2523: DECLARATION_CARACTERE('i');
2524: DECLARATION_CARACTERE('j');
2525: DECLARATION_CARACTERE('k');
2526: DECLARATION_CARACTERE('l');
2527: DECLARATION_CARACTERE('m');
2528: DECLARATION_CARACTERE('n');
2529: DECLARATION_CARACTERE('o');
2530: DECLARATION_CARACTERE('p');
2531: DECLARATION_CARACTERE('q');
2532: DECLARATION_CARACTERE('r');
2533: DECLARATION_CARACTERE('s');
2534: DECLARATION_CARACTERE('t');
2535: DECLARATION_CARACTERE('u');
2536: DECLARATION_CARACTERE('v');
2537: DECLARATION_CARACTERE('w');
2538: DECLARATION_CARACTERE('x');
2539: DECLARATION_CARACTERE('y');
2540: DECLARATION_CARACTERE('z');
2541:
2542: DECLARATION_CARACTERE('_');
2543:
2544: DECLARATION_CARACTERE('1');
2545: DECLARATION_CARACTERE('2');
2546: DECLARATION_CARACTERE('3');
2547: DECLARATION_CARACTERE('4');
2548: DECLARATION_CARACTERE('5');
2549: DECLARATION_CARACTERE('6');
2550: DECLARATION_CARACTERE('7');
2551: DECLARATION_CARACTERE('8');
2552: DECLARATION_CARACTERE('9');
2553: DECLARATION_CARACTERE('0');
2554: #undef DECLARATION_CARACTERE
2555:
2556: return;
2557: }
1.25 bertrand 2558:
1.1 bertrand 2559: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>