Annotation of rpl/src/gestion_variables.c, revision 1.58
1.1 bertrand 1: /*
2: ================================================================================
1.57 bertrand 3: RPL/2 (R) version 4.1.11
1.50 bertrand 4: Copyright (C) 1989-2012 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:
240: static inline struct_arbre_variables *
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:
275: static inline struct_arbre_variables **
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: {
287: objet = malloc((*s_etat_processus).nombre_caracteres_variables
288: * sizeof(struct_arbre_variables *));
289: }
290:
291: return(objet);
292: }
293:
294: static inline void
295: liberation_tableau_noeuds(struct_processus *s_etat_processus,
296: struct_arbre_variables **objet)
297: {
298: if ((*s_etat_processus).pointeur_variables_tableau_noeuds < TAILLE_CACHE)
299: {
300: (*s_etat_processus).variables_tableau_noeuds
301: [(*s_etat_processus).pointeur_variables_tableau_noeuds++] =
302: objet;
303: }
304: else
305: {
306: free(objet);
307: }
308:
309: return;
310: }
311:
312: static inline struct_liste_variables *
313: allocation_feuille(struct_processus *s_etat_processus)
314: {
315: struct_liste_variables *objet;
316:
317: if ((*s_etat_processus).pointeur_variables_feuille > 0)
318: {
319: objet = (*s_etat_processus).variables_feuille
320: [--(*s_etat_processus).pointeur_variables_feuille];
321: }
322: else
323: {
324: objet = malloc(sizeof(struct_liste_variables));
325: }
326:
327: return(objet);
328: }
329:
330: static inline void
331: liberation_feuille(struct_processus *s_etat_processus,
332: struct_liste_variables *objet)
333: {
334: if ((*s_etat_processus).pointeur_variables_feuille < TAILLE_CACHE)
335: {
336: (*s_etat_processus).variables_feuille
337: [(*s_etat_processus).pointeur_variables_feuille++] = objet;
338: }
339: else
340: {
341: free(objet);
342: }
343:
344: return;
345: }
346:
347: static inline struct_variable *
348: allocation_variable(struct_processus *s_etat_processus)
349: {
350: struct_variable *objet;
351:
352: if ((*s_etat_processus).pointeur_variables_variable > 0)
353: {
354: objet = (*s_etat_processus).variables_variable
355: [--(*s_etat_processus).pointeur_variables_variable];
356: }
357: else
358: {
359: objet = malloc(sizeof(struct_variable));
360: }
361:
362: return(objet);
363: }
364:
365: static inline void
366: liberation_variable(struct_processus *s_etat_processus,
367: struct_variable *objet)
368: {
369: if ((*s_etat_processus).pointeur_variables_variable < TAILLE_CACHE)
370: {
371: (*s_etat_processus).variables_variable
372: [(*s_etat_processus).pointeur_variables_variable++] = objet;
373: }
374: else
375: {
376: free(objet);
377: }
378:
379: return;
380: }
381:
382:
383: /*
384: ================================================================================
1.1 bertrand 385: Routine de création d'une nouvelle variable
1.33 bertrand 386: ================================================================================
387: Entrée : autorisation_creation_variable_statique vaut 'v' ou 's'.
388: dans le cas 'v', la variable est volatile.
389: dans le cas 's', elle est statique.
390: Entrée : autorisation_creation_variable_partagee vaut 'p' ou 's'.
391: dans le cas 'p', la variable est privée.
392: dans le cas 's', elle est partagée.
1.1 bertrand 393: --------------------------------------------------------------------------------
394: Sortie :
395: --------------------------------------------------------------------------------
396: Effets de bords : néant
397: ================================================================================
398: */
399:
1.25 bertrand 400: static logical1
401: ajout_variable(struct_processus *s_etat_processus, struct_variable *s_variable)
1.1 bertrand 402: {
1.25 bertrand 403: int i;
404:
1.33 bertrand 405: logical1 niveau_acceptable;
406:
1.25 bertrand 407: struct_liste_variables *l_nouvelle_variable;
408: struct_liste_variables *l_variable_candidate;
1.33 bertrand 409:
1.28 bertrand 410: struct_arbre_variables *l_variable_courante;
411: struct_arbre_variables *l_variable_precedente;
1.1 bertrand 412:
1.25 bertrand 413: struct_liste_chainee *l_nouvel_element;
1.1 bertrand 414:
1.25 bertrand 415: unsigned char *ptr;
1.1 bertrand 416:
1.31 bertrand 417: void *pointeur_variable_cree;
418:
1.25 bertrand 419: if ((*s_etat_processus).s_arbre_variables == NULL)
1.1 bertrand 420: {
1.25 bertrand 421: if (((*s_etat_processus).s_arbre_variables =
1.40 bertrand 422: allocation_noeud(s_etat_processus)) == NULL)
1.25 bertrand 423: {
424: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
425: return(d_erreur);
426: }
427:
428: (*(*s_etat_processus).s_arbre_variables).feuille = NULL;
1.58 ! bertrand 429: (*(*s_etat_processus).s_arbre_variables).feuille_statique = NULL;
1.25 bertrand 430: (*(*s_etat_processus).s_arbre_variables).noeuds_utilises = 0;
1.31 bertrand 431: (*(*s_etat_processus).s_arbre_variables).indice_tableau_pere = -1;
1.28 bertrand 432: (*(*s_etat_processus).s_arbre_variables).noeud_pere = NULL;
1.1 bertrand 433:
1.30 bertrand 434: if (((*(*s_etat_processus).s_arbre_variables).noeuds =
1.40 bertrand 435: allocation_tableau_noeuds(s_etat_processus)) == NULL)
1.1 bertrand 436: {
1.25 bertrand 437: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
438: return(d_erreur);
439: }
440:
441: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
442: {
1.28 bertrand 443: (*(*s_etat_processus).s_arbre_variables).noeuds[i] = NULL;
1.25 bertrand 444: }
445: }
446:
1.28 bertrand 447: l_variable_precedente = NULL;
1.25 bertrand 448: l_variable_courante = (*s_etat_processus).s_arbre_variables;
449: ptr = (*s_variable).nom;
450:
451: while((*ptr) != d_code_fin_chaine)
452: {
453: BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
1.40 bertrand 454: uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
1.25 bertrand 455: *ptr));
456:
1.28 bertrand 457: if ((*l_variable_courante).noeuds[(*s_etat_processus)
1.25 bertrand 458: .pointeurs_caracteres_variables[*ptr]] == NULL)
459: {
1.31 bertrand 460: // Le noeud n'existe pas encore, on le crée et on le marque
461: // comme utilisé dans la structure parente.
1.25 bertrand 462:
1.28 bertrand 463: if (((*l_variable_courante).noeuds[(*s_etat_processus)
1.25 bertrand 464: .pointeurs_caracteres_variables[*ptr]] =
1.40 bertrand 465: allocation_noeud(s_etat_processus)) == NULL)
1.25 bertrand 466: {
467: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
468: return(d_erreur);
469: }
470:
1.28 bertrand 471: (*l_variable_courante).noeuds_utilises++;
1.31 bertrand 472:
473: // La feuille est par défaut vide et aucun élément du tableau noeuds
474: // (les branches qui peuvent être issues de ce nouveau noeud)
475: // n'est encore utilisée.
476:
1.28 bertrand 477: (*(*l_variable_courante).noeuds[(*s_etat_processus)
1.25 bertrand 478: .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
1.28 bertrand 479: (*(*l_variable_courante).noeuds[(*s_etat_processus)
1.58 ! bertrand 480: .pointeurs_caracteres_variables[*ptr]]).feuille_statique
! 481: = NULL;
! 482: (*(*l_variable_courante).noeuds[(*s_etat_processus)
1.25 bertrand 483: .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
1.31 bertrand 484:
485: // Le champ noeud_pere de la structure créée pointe sur
486: // la structure parente et l'indice tableau_pere correspond à la
487: // position réelle dans le tableau noeuds[] de la structure parente
488: // du noeud courant. Cette valeur sera utilisée lors de la
489: // destruction du noeud pour annuler le pointeur contenu dans
490: // le tableau noeuds[] de la structure parente.
491:
1.28 bertrand 492: (*(*l_variable_courante).noeuds[(*s_etat_processus)
493: .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
1.31 bertrand 494: l_variable_courante;
495: (*(*l_variable_courante).noeuds[(*s_etat_processus)
496: .pointeurs_caracteres_variables[*ptr]])
497: .indice_tableau_pere = (*s_etat_processus)
498: .pointeurs_caracteres_variables[*ptr];
499:
500: // Allocation du tableau noeuds[] et initialisation à zéro de
501: // tous les pointeurs.
1.25 bertrand 502:
1.28 bertrand 503: if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
504: .pointeurs_caracteres_variables[*ptr]]).noeuds =
1.40 bertrand 505: allocation_tableau_noeuds(s_etat_processus)) == NULL)
1.25 bertrand 506: {
507: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
508: return(d_erreur);
509: }
510:
511: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
512: {
1.28 bertrand 513: (*(*l_variable_courante).noeuds[(*s_etat_processus)
514: .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
515: = NULL;
1.25 bertrand 516: }
517: }
518:
1.28 bertrand 519: l_variable_precedente = l_variable_courante;
520: l_variable_courante = (*l_variable_courante).noeuds
1.25 bertrand 521: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
522: ptr++;
523: }
524:
525: if ((*l_variable_courante).feuille == NULL)
526: {
527: // Aucune variable de même nom préexiste. On alloue le premier
528: // élément de la liste doublement chaînée contenant toutes les
529: // variables de même nom. Cette liste boucle en premier lieu sur
530: // elle-même.
531:
1.40 bertrand 532: if (((*l_variable_courante).feuille = allocation_feuille(
533: s_etat_processus)) == NULL)
1.25 bertrand 534: {
535: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
536: return(d_erreur);
537: }
538:
1.34 bertrand 539: (*l_variable_courante).noeuds_utilises++;
540:
1.25 bertrand 541: (*(*l_variable_courante).feuille).suivant =
542: (*l_variable_courante).feuille;
543: (*(*l_variable_courante).feuille).precedent =
544: (*l_variable_courante).feuille;
1.28 bertrand 545: (*(*l_variable_courante).feuille).noeud_pere = l_variable_precedente;
1.32 bertrand 546: (*(*l_variable_courante).feuille).noeud = l_variable_courante;
1.25 bertrand 547:
548: // Allocation de la variable sur l'élément de la liste.
549:
550: if (((*(*l_variable_courante).feuille).variable =
1.40 bertrand 551: allocation_variable(s_etat_processus)) == NULL)
1.25 bertrand 552: {
553: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
554: return(d_erreur);
555: }
556:
557: (*((struct_variable *) (*(*l_variable_courante).feuille).variable)) =
558: (*s_variable);
1.31 bertrand 559: pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
1.25 bertrand 560: }
561: else
562: {
1.40 bertrand 563: if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
1.28 bertrand 564: == NULL)
565: {
566: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
567: return(d_erreur);
568: }
569:
1.25 bertrand 570: if ((*s_variable).niveau > 1)
571: {
572: // Cas d'une variable locale
573:
574: // Si le niveau de la dernière variable de même nom est
575: // supérieur au niveau de la variable locale que l'on veut
576: // enregistrer dans la liste, cette liste est incohérente.
577:
578: BUG((*(*(*l_variable_courante).feuille).variable).niveau >=
579: (*s_variable).niveau,
1.40 bertrand 580: uprintf("Variable=\"%s\"\n", (*s_variable).nom));
1.25 bertrand 581:
582: // On ajoute la variable à la liste existante.
583:
584: (*l_nouvelle_variable).suivant = (*l_variable_courante).feuille;
585: (*l_nouvelle_variable).precedent = (*(*l_variable_courante).feuille)
586: .precedent;
1.28 bertrand 587: (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
1.33 bertrand 588: (*l_nouvelle_variable).noeud = l_variable_courante;
1.25 bertrand 589: (*(*(*l_variable_courante).feuille).precedent).suivant =
590: l_nouvelle_variable;
591: (*(*l_variable_courante).feuille).precedent =
592: l_nouvelle_variable;
593: (*l_variable_courante).feuille = l_nouvelle_variable;
594:
595: if (((*(*l_variable_courante).feuille).variable =
1.40 bertrand 596: allocation_variable(s_etat_processus)) == NULL)
1.25 bertrand 597: {
598: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
599: return(d_erreur);
600: }
601:
602: (*((struct_variable *) (*(*l_variable_courante).feuille).variable))
603: = (*s_variable);
1.31 bertrand 604: pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
1.1 bertrand 605: }
606: else
607: {
1.25 bertrand 608: // Cas d'une variable globale (niveau 0 [définitions] ou 1
609: // [variables globales])
610:
611: l_variable_candidate = (*l_variable_courante).feuille;
612:
613: do
614: {
615: // S'il y a déjà une variable de même niveau, la pile
616: // est incohérente.
617:
618: BUG((*(*l_variable_candidate).variable).niveau ==
619: (*s_variable).niveau,
1.40 bertrand 620: uprintf("Variable=\"%s\"\n", (*s_variable).nom));
1.25 bertrand 621:
622: l_variable_candidate = (*l_variable_candidate).precedent;
623: } while((l_variable_candidate != (*l_variable_courante).feuille) &&
624: ((*(*l_variable_candidate).variable).niveau <= 1));
625:
1.34 bertrand 626: BUG((*s_variable).niveau == 0,
627: uprintf("Attempt to create a level-0 variable!\n"));
628:
1.25 bertrand 629: if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
630: .niveau > 1)
631: {
1.34 bertrand 632: // La variable précédente est de niveau strictement supérieur
633: // à 1. Il ne peut donc y avoir aucune variable de niveau
634: // inférieur ou égal à 1 puisque la boucle est triée.
635: // On insère donc directement la variable en queue.
1.25 bertrand 636: }
637: else
1.1 bertrand 638: {
1.34 bertrand 639: // Le niveau de la variable précédente dans la boucle est
640: // inférieur ou égal à 1.
1.25 bertrand 641: l_variable_candidate = (*(*l_variable_courante).feuille)
642: .precedent;
643: }
644:
645: (*l_nouvelle_variable).suivant = l_variable_candidate;
646: (*l_nouvelle_variable).precedent = (*l_variable_candidate)
647: .precedent;
1.28 bertrand 648: (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
1.33 bertrand 649: (*l_nouvelle_variable).noeud = l_variable_courante;
1.25 bertrand 650: (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
651: (*l_variable_candidate).precedent = l_nouvelle_variable;
652:
1.34 bertrand 653: // Si la variable suivant la variable que l'on vient d'insérer
654: // dans la boucle est de niveau 0, la variable insérée est par
655: // construction de niveau 1 et il convient de modifier le
656: // pointeur de feuille pointant sur l'élément de plus haut niveau
657: // de la boucle.
658:
659: if ((*(*(*l_nouvelle_variable).precedent).variable).niveau == 0)
660: {
661: (*(*l_nouvelle_variable).noeud).feuille = l_nouvelle_variable;
662: }
663:
1.25 bertrand 664: if (((*l_nouvelle_variable).variable =
1.40 bertrand 665: allocation_variable(s_etat_processus)) == NULL)
1.25 bertrand 666: {
667: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
668: return(d_erreur);
669: }
670:
671: (*(*l_nouvelle_variable).variable) = (*s_variable);
1.31 bertrand 672: pointeur_variable_cree = (*l_nouvelle_variable).variable;
1.1 bertrand 673: }
1.25 bertrand 674: }
675:
676: // Ajout de la variable nouvellement créée à la liste par niveaux.
677: // Le pointeur contenu dans la structure de description du processus indique
678: // toujours le plus haut niveau utilisé.
679:
680: if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
681: {
682: // Le niveau courant n'existe pas. Il est créé.
683:
1.40 bertrand 684: if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
1.25 bertrand 685: == NULL)
686: {
687: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
688: return(d_erreur);
689: }
690:
691: (*l_nouvelle_variable).suivant = l_nouvelle_variable;
692: (*l_nouvelle_variable).precedent = l_nouvelle_variable;
1.28 bertrand 693: (*l_nouvelle_variable).noeud_pere = NULL;
1.31 bertrand 694: (*l_nouvelle_variable).liste = NULL;
1.25 bertrand 695:
696: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
1.33 bertrand 697:
698: // Ajout de la variable en tête de la liste
699:
1.40 bertrand 700: if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
1.33 bertrand 701: {
702: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
703: return(d_erreur);
704: }
705:
706: (*l_nouvel_element).suivant = (*(*s_etat_processus)
707: .l_liste_variables_par_niveau).liste;
708: (*l_nouvel_element).donnee = pointeur_variable_cree;
709: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
710: l_nouvel_element;
1.25 bertrand 711: }
712: else if ((*s_variable).niveau > (*((struct_variable *)
713: (*(*(*s_etat_processus).l_liste_variables_par_niveau).liste)
714: .donnee)).niveau)
715: {
716: // Le niveau courant n'existe pas. Il est créé.
1.1 bertrand 717:
1.40 bertrand 718: if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
1.25 bertrand 719: == NULL)
1.1 bertrand 720: {
721: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
722: return(d_erreur);
723: }
724:
1.25 bertrand 725: (*l_nouvelle_variable).suivant = (*s_etat_processus)
726: .l_liste_variables_par_niveau;
727: (*l_nouvelle_variable).precedent = (*(*s_etat_processus)
728: .l_liste_variables_par_niveau).precedent;
1.28 bertrand 729: (*l_nouvelle_variable).noeud_pere = NULL;
1.31 bertrand 730: (*l_nouvelle_variable).liste = NULL;
1.25 bertrand 731: (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent)
732: .suivant = l_nouvelle_variable;
1.33 bertrand 733: (*(*s_etat_processus).l_liste_variables_par_niveau)
734: .precedent = l_nouvelle_variable;
1.25 bertrand 735:
736: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
1.33 bertrand 737:
738: // Ajout de la variable en tête de la liste
739:
1.40 bertrand 740: if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
1.33 bertrand 741: {
742: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
743: return(d_erreur);
744: }
745:
746: (*l_nouvel_element).suivant = (*(*s_etat_processus)
747: .l_liste_variables_par_niveau).liste;
748: (*l_nouvel_element).donnee = pointeur_variable_cree;
749: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
750: l_nouvel_element;
1.25 bertrand 751: }
1.31 bertrand 752: else if ((*s_variable).niveau <= 1)
1.25 bertrand 753: {
1.33 bertrand 754: // Création d'une variable de niveau 0 ou 1. Il convient de
755: // chercher dans la liste si un niveau 0 ou 1 préexiste. Pour cela, on
756: // regarde la position courante et les deux précédentes.
757:
758: l_variable_candidate = (*s_etat_processus).l_liste_variables_par_niveau;
759: niveau_acceptable = d_faux;
1.25 bertrand 760:
1.33 bertrand 761: for(i = 0; i <= 2; i++)
762: {
763: if ((*l_variable_candidate).liste == NULL)
764: {
765: continue;
766: }
767:
768: if ((*((struct_variable *) (*(*l_variable_candidate)
769: .liste).donnee)).niveau == (*s_variable).niveau)
770: {
771: niveau_acceptable = d_vrai;
772: break;
773: }
774:
775: l_variable_candidate = (*l_variable_candidate).precedent;
776: }
777:
778: if (niveau_acceptable == d_faux)
1.28 bertrand 779: {
1.40 bertrand 780: if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
1.33 bertrand 781: == NULL)
782: {
783: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
784: return(d_erreur);
785: }
786:
787: l_variable_candidate =
788: (*(*s_etat_processus).l_liste_variables_par_niveau)
789: .precedent;
790:
791: // On ne peut créer qu'une variable de niveau supérieur ou égal à
792: // 1 lors de l'exécution normale d'un programme. Les variables
793: // de niveau 0 sont créées à l'initialisation et relèvent du
794: // cas précédent car il n'existe lors de leur création aucun
795: // niveau non nul.
796:
797: BUG((*s_variable).niveau == 0,
798: uprintf("Attempt to create a level-0 variable!\n"));
799:
800: (*l_nouvelle_variable).suivant = l_variable_candidate;
801: (*l_nouvelle_variable).precedent = (*l_variable_candidate)
802: .precedent;
803: (*l_nouvelle_variable).noeud_pere = NULL;
804: (*l_nouvelle_variable).liste = NULL;
805: (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
806: (*l_variable_candidate).precedent = l_nouvelle_variable;
807:
808: l_variable_candidate = l_nouvelle_variable;
1.28 bertrand 809: }
810:
1.33 bertrand 811: // Ajout de la variable en tête de la liste l_variable_candidate.
1.25 bertrand 812:
1.40 bertrand 813: if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
1.25 bertrand 814: {
1.33 bertrand 815: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
816: return(d_erreur);
1.25 bertrand 817: }
818:
1.33 bertrand 819: (*l_nouvel_element).suivant = (*l_variable_candidate).liste;
820: (*l_nouvel_element).donnee = pointeur_variable_cree;
821: (*l_variable_candidate).liste = l_nouvel_element;
1.25 bertrand 822: }
1.33 bertrand 823: else
824: {
825: // Ajout de la variable en tête de la liste
1.25 bertrand 826:
1.40 bertrand 827: if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
1.33 bertrand 828: {
829: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
830: return(d_erreur);
831: }
1.25 bertrand 832:
1.33 bertrand 833: (*l_nouvel_element).suivant = (*(*s_etat_processus)
834: .l_liste_variables_par_niveau).liste;
835: (*l_nouvel_element).donnee = pointeur_variable_cree;
836: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
837: l_nouvel_element;
1.1 bertrand 838: }
839:
1.25 bertrand 840: return(d_absence_erreur);
841: }
842:
1.31 bertrand 843:
1.25 bertrand 844: logical1
845: creation_variable(struct_processus *s_etat_processus,
846: struct_variable *s_variable,
847: unsigned char autorisation_creation_variable_statique,
848: unsigned char autorisation_creation_variable_partagee)
849: {
1.1 bertrand 850: if ((*s_etat_processus).mode_execution_programme == 'Y')
851: {
852: (*s_variable).origine = 'P';
853: }
854: else
855: {
856: (*s_variable).origine = 'E';
857: }
858:
859: if ((*s_variable).niveau == 0)
860: {
861: // Un point d'entrée de définition est verrouillé.
862:
863: if ((*s_variable).origine == 'P')
864: {
865: (*s_variable).variable_statique.adresse = 0;
866: (*s_variable).variable_partagee.adresse = 0;
867: }
868: else
869: {
870: (*s_variable).variable_statique.pointeur = NULL;
871: (*s_variable).variable_partagee.pointeur = NULL;
872: }
873:
874: (*s_variable).variable_verrouillee = d_vrai;
875: }
876: else if ((*s_variable).niveau == 1)
877: {
878: // Une variable globale ne peut être statique.
879:
880: if ((*s_variable).origine == 'P')
881: {
882: (*s_variable).variable_statique.adresse = 0;
883: (*s_variable).variable_partagee.adresse = 0;
884: }
885: else
886: {
887: (*s_variable).variable_statique.pointeur = NULL;
888: (*s_variable).variable_partagee.pointeur = NULL;
889: }
890:
891: (*s_variable).variable_verrouillee = d_faux;
892: }
893: else
894: {
895: // 0 -> variable volatile
896: // adresse de création -> variable statique
897:
898: if (autorisation_creation_variable_statique == 'V')
899: {
900: if (autorisation_creation_variable_partagee == 'S')
901: {
902: // On force la création d'une variable partagée
903:
904: if ((*s_variable).origine == 'P')
905: {
906: (*s_variable).variable_statique.adresse = 0;
907: (*s_variable).variable_partagee.adresse =
908: (*s_etat_processus).position_courante;
909: }
910: else
911: {
912: (*s_variable).variable_statique.pointeur = NULL;
913: (*s_variable).variable_partagee.pointeur =
914: (*s_etat_processus).objet_courant;
915: }
916: }
917: else
918: {
919: // On force la création d'une variable volatile
920:
921: if ((*s_variable).origine == 'P')
922: {
923: (*s_variable).variable_statique.adresse = 0;
924: (*s_variable).variable_partagee.adresse = 0;
925: }
926: else
927: {
928: (*s_variable).variable_statique.pointeur = NULL;
929: (*s_variable).variable_partagee.pointeur = NULL;
930: }
931: }
932: }
933: else
934: {
935: // On force la création d'une variable statique.
936:
937: if ((*s_variable).origine == 'P')
938: {
939: (*s_variable).variable_statique.adresse =
940: (*s_etat_processus).position_courante;
941: (*s_variable).variable_partagee.adresse = 0;
942: }
943: else
944: {
945: (*s_variable).variable_statique.pointeur =
946: (*s_etat_processus).objet_courant;
947: (*s_variable).variable_partagee.pointeur = 0;
948: }
949: }
950:
951: (*s_variable).variable_verrouillee = d_faux;
952: }
953:
954: /*
1.25 bertrand 955: * Recherche de la feuille correspondante dans l'arbre des variables.
956: * Si cette feuille n'existe pas, elle est créée.
1.1 bertrand 957: */
958:
1.25 bertrand 959: if (ajout_variable(s_etat_processus, s_variable) == d_erreur)
960: {
961: return(d_erreur);
962: }
963:
964: return(d_absence_erreur);
965: }
966:
967:
968: /*
969: ================================================================================
970: Procédure de recherche d'une variable par son nom dans la base
971: ================================================================================
972: Entrée :
973: --------------------------------------------------------------------------------
974: Sortie :
975: --------------------------------------------------------------------------------
976: Effets de bord : néant
977: ================================================================================
978: */
979:
980: logical1
981: recherche_variable(struct_processus *s_etat_processus,
982: unsigned char *nom_variable)
983: {
984: int pointeur;
985:
986: struct_arbre_variables *l_variable_courante;
987: struct_liste_pile_systeme *l_element_courant;
988:
989: unsigned char *ptr;
990:
991: unsigned long niveau_appel;
1.1 bertrand 992:
1.25 bertrand 993: if ((*s_etat_processus).s_arbre_variables == NULL)
1.1 bertrand 994: {
1.25 bertrand 995: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1.30 bertrand 996: return(d_faux);
1.1 bertrand 997: }
1.25 bertrand 998:
1.28 bertrand 999: l_variable_courante = (*s_etat_processus).s_arbre_variables;
1.25 bertrand 1000: ptr = nom_variable;
1001:
1002: while((*ptr) != d_code_fin_chaine)
1.1 bertrand 1003: {
1.25 bertrand 1004: pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
1005:
1006: if (pointeur < 0)
1007: {
1008: // Caractère hors de l'alphabet des variables
1.30 bertrand 1009:
1010: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1011: return(d_faux);
1.25 bertrand 1012: }
1013:
1.28 bertrand 1014: if ((*l_variable_courante).noeuds[pointeur] == NULL)
1.1 bertrand 1015: {
1.25 bertrand 1016: // Le chemin de la variable candidate n'existe pas.
1.30 bertrand 1017: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1018: return(d_faux);
1.1 bertrand 1019: }
1020:
1.28 bertrand 1021: l_variable_courante = (*l_variable_courante).noeuds[pointeur];
1.25 bertrand 1022: ptr++;
1023: }
1024:
1025: if ((*l_variable_courante).feuille != NULL)
1026: {
1027: // Il existe une pile de variables de même nom. Le sommet de la
1028: // pile est la variable de niveau le plus haut.
1029:
1030: l_element_courant = (*s_etat_processus).l_base_pile_systeme;
1031:
1032: if (l_element_courant == NULL)
1.12 bertrand 1033: {
1.25 bertrand 1034: // Problème : la pile système est vide !
1035: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
1.30 bertrand 1036: return(d_faux);
1.12 bertrand 1037: }
1.25 bertrand 1038:
1039: while((*l_element_courant).retour_definition != 'Y')
1.12 bertrand 1040: {
1.25 bertrand 1041: l_element_courant = (*l_element_courant).suivant;
1.12 bertrand 1042:
1.25 bertrand 1043: if (l_element_courant == NULL)
1.12 bertrand 1044: {
1.25 bertrand 1045: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
1.30 bertrand 1046: return(d_faux);
1.12 bertrand 1047: }
1.25 bertrand 1048: }
1049:
1050: niveau_appel = (*l_element_courant).niveau_courant;
1.12 bertrand 1051:
1.25 bertrand 1052: if (niveau_appel < (*(*(*l_variable_courante).feuille).variable).niveau)
1053: {
1054: // Une variable locale est accessible puisque créée dans la
1055: // fonction courante.
1056:
1057: (*s_etat_processus).pointeur_variable_courante =
1058: (*(*l_variable_courante).feuille).variable;
1059: (*s_etat_processus).pointeur_feuille_courante =
1060: (*l_variable_courante).feuille;
1.30 bertrand 1061: return(d_vrai);
1.25 bertrand 1062: }
1063: else
1064: {
1065: // Aucune variable locale n'est accessible depuis la fonction.
1066: // Dans ce cas, on prend la variable de niveau le plus bas
1067: // si ce niveau est inférieur ou égal à 1 (variable globale
1068: // ou fonction définie par l'utilisateur). Si le niveau de la
1.27 bertrand 1069: // plus ancienne variable est strictement supérieur à 1, il
1.25 bertrand 1070: // s'agit d'une variable locale inaccessible.
1071:
1072: if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
1073: .niveau <= 1)
1074: {
1075: (*s_etat_processus).pointeur_variable_courante =
1076: (*(*(*l_variable_courante).feuille).precedent).variable;
1077: (*s_etat_processus).pointeur_feuille_courante =
1.33 bertrand 1078: (*(*l_variable_courante).feuille).precedent;
1.27 bertrand 1079:
1080: // S'il existe une variable de niveau 0 et une seconde de
1081: // niveau 1, la variable de niveau 0 (fonction) est masquée
1082: // par celle de niveau 1.
1083:
1.33 bertrand 1084: if (((*(*(*(*l_variable_courante).feuille).precedent)
1085: .variable).niveau == 0) && ((*(*(*(*
1086: (*l_variable_courante).feuille).precedent).precedent)
1.27 bertrand 1087: .variable).niveau == 1))
1088: {
1089: (*s_etat_processus).pointeur_variable_courante =
1.33 bertrand 1090: (*(*(*(*l_variable_courante).feuille).precedent)
1091: .precedent).variable;
1092: (*s_etat_processus).pointeur_feuille_courante =
1.27 bertrand 1093: (*(*(*l_variable_courante).feuille).precedent)
1.33 bertrand 1094: .precedent;
1.27 bertrand 1095: }
1096:
1.30 bertrand 1097: return(d_vrai);
1.12 bertrand 1098: }
1099: }
1.1 bertrand 1100: }
1101:
1.30 bertrand 1102: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1103: return(d_faux);
1.1 bertrand 1104: }
1105:
1106:
1.29 bertrand 1107: logical1
1108: recherche_variable_globale(struct_processus *s_etat_processus,
1109: unsigned char *nom)
1110: {
1111: logical1 presence_variable;
1112:
1113: presence_variable = recherche_variable(s_etat_processus, nom);
1114:
1115: if (presence_variable == d_vrai)
1116: {
1117: switch((*(*s_etat_processus).pointeur_variable_courante).niveau)
1118: {
1119: case 0:
1120: {
1.33 bertrand 1121: // La variable est une définition.
1.29 bertrand 1122: presence_variable = d_faux;
1123: break;
1124: }
1125:
1126: case 1:
1127: {
1128: break;
1129: }
1130:
1131: default:
1132: {
1133: if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
1134: .precedent).variable).niveau == 1)
1135: {
1136: (*s_etat_processus).pointeur_feuille_courante =
1137: (*(*s_etat_processus).pointeur_feuille_courante)
1138: .precedent;
1139: (*s_etat_processus).pointeur_variable_courante =
1140: (*(*s_etat_processus).pointeur_feuille_courante)
1141: .variable;
1142: }
1143: else if ((*(*(*(*(*s_etat_processus).pointeur_feuille_courante)
1144: .precedent).precedent).variable).niveau == 1)
1145: {
1146: (*s_etat_processus).pointeur_feuille_courante =
1147: (*(*(*s_etat_processus).pointeur_feuille_courante)
1148: .precedent).precedent;
1149: (*s_etat_processus).pointeur_variable_courante =
1150: (*(*s_etat_processus).pointeur_feuille_courante)
1151: .variable;
1152: }
1153: else
1154: {
1155: presence_variable = d_faux;
1156: }
1157:
1158: break;
1159: }
1160: }
1161: }
1162:
1163: if (presence_variable == d_vrai)
1164: {
1165: if ((*(*s_etat_processus).pointeur_variable_courante).objet == NULL)
1166: {
1167: // La variable n'est pas globale, elle est partagée.
1168: presence_variable = d_faux;
1169: (*s_etat_processus).erreur_execution = d_ex_variable_partagee;
1170: }
1171: }
1172:
1173: return(presence_variable);
1174: }
1175:
1176:
1.1 bertrand 1177: /*
1178: ================================================================================
1179: Procédure de retrait d'une variable de la base
1180: ================================================================================
1181: Entrée : type 'G' ou 'L' selon que l'on retire une variable locale (incluant
1182: les globales) ou strictement globale.
1183: --------------------------------------------------------------------------------
1184: Sortie :
1185: --------------------------------------------------------------------------------
1186: Effets de bord : néant
1187: ================================================================================
1188: */
1189:
1190: logical1
1191: retrait_variable(struct_processus *s_etat_processus,
1192: unsigned char *nom_variable, unsigned char type)
1193: {
1.28 bertrand 1194: logical1 erreur;
1.34 bertrand 1195: logical1 variable_supprimee;
1.28 bertrand 1196:
1197: struct_arbre_variables *s_arbre_a_supprimer;
1198: struct_arbre_variables *s_arbre_courant;
1199:
1200: struct_liste_chainee *l_element_courant;
1201: struct_liste_chainee *l_element_precedent;
1202:
1203: struct_liste_variables *variable_a_supprimer;
1204: struct_liste_variables *variables_par_niveau;
1205:
1206: unsigned long niveau;
1.1 bertrand 1207:
1.36 bertrand 1208: (*s_etat_processus).niveau_supprime = d_faux;
1209:
1.1 bertrand 1210: if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
1211: {
1.25 bertrand 1212: // Une variable correspondant au nom recherché est accessible.
1213:
1.1 bertrand 1214: if (type == 'G')
1215: {
1.25 bertrand 1216: if ((*(*s_etat_processus).pointeur_variable_courante).niveau > 1)
1217: {
1218: // La variable obtenue est une variable locale. il faut
1219: // s'assurer qu'il existe une variable de niveau 1 de même
1220: // nom sur la feuille.
1221:
1.27 bertrand 1222: if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
1223: .precedent).variable).niveau <= 1)
1.1 bertrand 1224: {
1.27 bertrand 1225: (*s_etat_processus).pointeur_feuille_courante =
1226: (*(*s_etat_processus).pointeur_feuille_courante)
1227: .precedent;
1228: (*s_etat_processus).pointeur_variable_courante =
1229: (*(*s_etat_processus).pointeur_feuille_courante)
1230: .variable;
1231:
1232: // Si la variable retournée est de niveau 0, on regarde
1233: // un peu plus loin si une variable de niveau 1 existe.
1234:
1235: if (((*(*(*s_etat_processus).pointeur_feuille_courante)
1236: .variable).niveau == 0) &&
1237: ((*(*(*(*s_etat_processus)
1238: .pointeur_feuille_courante).precedent).variable)
1239: .niveau == 1))
1.1 bertrand 1240: {
1.27 bertrand 1241: (*s_etat_processus).pointeur_feuille_courante =
1242: (*(*s_etat_processus).pointeur_feuille_courante)
1243: .precedent;
1244: (*s_etat_processus).pointeur_variable_courante =
1245: (*(*s_etat_processus).pointeur_feuille_courante)
1246: .variable;
1.1 bertrand 1247: }
1248: }
1.27 bertrand 1249: else
1250: {
1251: // Aucune variable globale (niveau 1) n'existe.
1.1 bertrand 1252:
1.27 bertrand 1253: erreur = d_erreur;
1254: (*s_etat_processus).erreur_execution =
1255: d_ex_variable_non_definie;
1256: return(erreur);
1257: }
1.1 bertrand 1258: }
1259:
1.27 bertrand 1260: if ((*(*s_etat_processus).pointeur_variable_courante)
1.1 bertrand 1261: .variable_verrouillee == d_vrai)
1262: {
1263: erreur = d_erreur;
1264: (*s_etat_processus).erreur_execution =
1265: d_ex_variable_verrouillee;
1.28 bertrand 1266: return(erreur);
1.1 bertrand 1267: }
1268: }
1269:
1.27 bertrand 1270: // Suppression de la variable de la liste.
1271: // Deux cas peuvent survenir :
1272: // 1/ les pointeurs sur la variable et la variable suivante
1273: // sont identiques et on supprime la variable ainsi que la feuille
1274: // associée ;
1275: // 2/ ces deux pointeurs sont différents et se contente de retirer
1276: // la structure décrivant la variable.
1.1 bertrand 1277:
1.28 bertrand 1278: if ((*s_etat_processus).pointeur_feuille_courante ==
1279: (*(*s_etat_processus).pointeur_feuille_courante).suivant)
1280: {
1281: // Cas 1 :
1282: // On retire la variable du noeud en décrémentant le nombre
1283: // de feuilles de ce noeud. Si le nombre de feuilles du noeud
1284: // est nul, on retire les noeuds récursivement jusqu'à obtenir
1285: // un nombre non nul de feuilles utilisées (ou la racine des
1286: // variables).
1287:
1288: variable_a_supprimer = (*s_etat_processus)
1289: .pointeur_feuille_courante;
1.34 bertrand 1290: s_arbre_courant = (*variable_a_supprimer).noeud;
1.28 bertrand 1291: BUG((*s_arbre_courant).noeuds_utilises == 0,
1292: uprintf("Freed node !\n"));
1293: (*s_arbre_courant).noeuds_utilises--;
1.1 bertrand 1294:
1.34 bertrand 1295: (*((*(*variable_a_supprimer).noeud_pere).noeuds
1296: [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
1297: .feuille = NULL;
1298:
1.58 ! bertrand 1299: while(((*s_arbre_courant).noeuds_utilises == 0) &&
! 1300: ((*s_arbre_courant).feuille_statique == NULL))
1.28 bertrand 1301: {
1302: s_arbre_a_supprimer = s_arbre_courant;
1303: s_arbre_courant = (*s_arbre_courant).noeud_pere;
1.1 bertrand 1304:
1.28 bertrand 1305: if (s_arbre_courant == NULL)
1306: {
1.40 bertrand 1307: liberation_tableau_noeuds(s_etat_processus,
1308: (*s_arbre_a_supprimer).noeuds);
1309: liberation_noeud(s_etat_processus, s_arbre_a_supprimer);
1.34 bertrand 1310:
1311: (*s_etat_processus).s_arbre_variables = NULL;
1.28 bertrand 1312: break;
1313: }
1314:
1.31 bertrand 1315: // s_arbre_a_supprimer contient la structure de feuille qui
1316: // vient d'être libérée. Il s'agit maintenant
1317: // d'annuler le pointeur dans le tableau noeuds de la structure
1318: // pointée par noeud_pere, soit s_arbre_courant.
1319:
1320: BUG((*s_arbre_a_supprimer).indice_tableau_pere < 0,
1321: uprintf("Invalid pointer !\n"));
1322: (*s_arbre_courant).noeuds[(*s_arbre_a_supprimer)
1323: .indice_tableau_pere] = NULL;
1324:
1.40 bertrand 1325: liberation_tableau_noeuds(s_etat_processus,
1326: (*s_arbre_a_supprimer).noeuds);
1327: liberation_noeud(s_etat_processus, s_arbre_a_supprimer);
1.31 bertrand 1328:
1.28 bertrand 1329: BUG((*s_arbre_courant).noeuds_utilises == 0,
1330: uprintf("Freed node !\n"));
1331: (*s_arbre_courant).noeuds_utilises--;
1332: }
1333: }
1334: else
1.1 bertrand 1335: {
1.28 bertrand 1336: // Cas 2 :
1337: // On retire la variable de la liste.
1338:
1339: variable_a_supprimer = (*s_etat_processus)
1340: .pointeur_feuille_courante;
1341:
1342: (*(*(*s_etat_processus).pointeur_feuille_courante).precedent)
1343: .suivant = (*(*s_etat_processus).pointeur_feuille_courante)
1344: .suivant;
1345: (*(*(*s_etat_processus).pointeur_feuille_courante).suivant)
1346: .precedent = (*(*s_etat_processus)
1347: .pointeur_feuille_courante).precedent;
1.32 bertrand 1348:
1.33 bertrand 1349: // Mise à jour du pointeur dans l'arbre des variables. Cette
1350: // mise à jour n'est nécessaire que dans le cas où la variable
1351: // supprimée est en tête de la liste.
1352:
1353: if (variable_a_supprimer == (*((*(*variable_a_supprimer).noeud_pere)
1354: .noeuds[(*(*variable_a_supprimer).noeud)
1355: .indice_tableau_pere])).feuille)
1356: {
1357: (*((*(*variable_a_supprimer).noeud_pere).noeuds
1358: [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
1359: .feuille = (*(*((*(*variable_a_supprimer).noeud_pere)
1360: .noeuds[(*(*variable_a_supprimer).noeud)
1361: .indice_tableau_pere])).feuille).suivant;
1362: }
1363:
1364: (*s_etat_processus).pointeur_feuille_courante =
1365: (*(*s_etat_processus).pointeur_feuille_courante).suivant;
1366: (*s_etat_processus).pointeur_variable_courante =
1367: (*(*s_etat_processus).pointeur_feuille_courante).variable;
1.1 bertrand 1368: }
1369:
1.28 bertrand 1370: // Dans tous les cas, on retire la variable de la liste des variables
1371: // par niveau.
1372:
1373: niveau = (*(*variable_a_supprimer).variable).niveau;
1374: variables_par_niveau = (*s_etat_processus).l_liste_variables_par_niveau;
1.34 bertrand 1375: variable_supprimee = d_faux;
1.28 bertrand 1376:
1.31 bertrand 1377: if (variables_par_niveau != NULL)
1.28 bertrand 1378: {
1.31 bertrand 1379: do
1380: {
1381: l_element_courant = (*variables_par_niveau).liste;
1.28 bertrand 1382:
1.31 bertrand 1383: if (l_element_courant != NULL)
1.28 bertrand 1384: {
1.31 bertrand 1385: if ((*((struct_variable *) (*l_element_courant).donnee))
1386: .niveau == niveau)
1387: {
1388: // On parcourt le bon niveau.
1.28 bertrand 1389:
1.31 bertrand 1390: l_element_precedent = NULL;
1.28 bertrand 1391:
1.31 bertrand 1392: while(l_element_courant != NULL)
1.28 bertrand 1393: {
1.31 bertrand 1394: // Tant que l_element_courant est non nul, il reste
1395: // des variables à explorer dans le niveau courant.
1.28 bertrand 1396:
1.31 bertrand 1397: if ((*l_element_courant).donnee ==
1398: (void *) (*variable_a_supprimer).variable)
1.28 bertrand 1399: {
1.31 bertrand 1400: // On a trouvé la variable à supprimer.
1401:
1402: if (l_element_precedent == NULL)
1403: {
1404: (*variables_par_niveau).liste =
1405: (*l_element_courant).suivant;
1406: }
1407: else
1408: {
1409: (*l_element_precedent).suivant =
1410: (*l_element_courant).suivant;
1411: }
1412:
1.40 bertrand 1413: liberation_maillon(s_etat_processus,
1414: l_element_courant);
1.34 bertrand 1415:
1416: if ((*variables_par_niveau).liste == NULL)
1417: {
1.36 bertrand 1418: (*s_etat_processus).niveau_supprime =
1419: d_vrai;
1420:
1.34 bertrand 1421: if ((*s_etat_processus)
1422: .l_liste_variables_par_niveau
1423: == variables_par_niveau)
1424: {
1425: // On retire l'élément de la liste
1426: // pointé par
1427: // l_liste_variable_par_niveau
1428:
1429: (*s_etat_processus)
1430: .l_liste_variables_par_niveau =
1431: (*variables_par_niveau).suivant;
1432: }
1433:
1434: (*(*variables_par_niveau).precedent)
1435: .suivant =
1436: (*variables_par_niveau).suivant;
1437: (*(*variables_par_niveau).suivant)
1438: .precedent =
1439: (*variables_par_niveau)
1440: .precedent;
1.40 bertrand 1441: liberation_feuille(s_etat_processus,
1442: variables_par_niveau);
1.34 bertrand 1443: }
1444:
1445: variable_supprimee = d_vrai;
1.31 bertrand 1446: break;
1.28 bertrand 1447: }
1.31 bertrand 1448:
1449: l_element_precedent = l_element_courant;
1450: l_element_courant = (*l_element_courant).suivant;
1.28 bertrand 1451: }
1452: }
1453: }
1454:
1.34 bertrand 1455: if (variable_supprimee == d_vrai)
1456: {
1457: break;
1458: }
1459:
1.31 bertrand 1460: variables_par_niveau = (*variables_par_niveau).suivant;
1461:
1462: } while(variables_par_niveau != (*s_etat_processus)
1463: .l_liste_variables_par_niveau);
1.28 bertrand 1464: }
1465:
1466: // Puis on libère le contenu de la variable.
1467:
1468: free((*(*variable_a_supprimer).variable).nom);
1469: liberation(s_etat_processus, (*(*variable_a_supprimer).variable).objet);
1.40 bertrand 1470: liberation_variable(s_etat_processus, (*variable_a_supprimer).variable);
1471: liberation_feuille(s_etat_processus, variable_a_supprimer);
1.28 bertrand 1472:
1.1 bertrand 1473: erreur = d_absence_erreur;
1474: }
1475: else
1476: {
1.25 bertrand 1477: // Aucune variable n'est accessible depuis le point courant du
1478: // programme.
1479:
1.1 bertrand 1480: erreur = d_erreur;
1481: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1482: }
1483:
1.25 bertrand 1484: return(erreur);
1.1 bertrand 1485: }
1486:
1487:
1488: /*
1489: ================================================================================
1490: Procédure de retrait des variables de niveau strictement supérieur au
1491: niveau courant
1492: ================================================================================
1493: Entrée :
1494: --------------------------------------------------------------------------------
1495: Sortie :
1496: --------------------------------------------------------------------------------
1497: Effets de bord : néant
1498: ================================================================================
1499: */
1500:
1501: logical1
1502: retrait_variable_par_niveau(struct_processus *s_etat_processus)
1503: {
1.31 bertrand 1504: struct_liste_variables *l_element_a_supprimer;
1505:
1.28 bertrand 1506: // Utilisation du champ (*s_etat_processus).liste_variables_par_niveau.
1507: // La tête de la pile contient toujours les variables de plus haut niveau
1508: // créées.
1.1 bertrand 1509:
1.28 bertrand 1510: while((*s_etat_processus).l_liste_variables_par_niveau != NULL)
1.1 bertrand 1511: {
1.28 bertrand 1512: if ((*(*s_etat_processus).l_liste_variables_par_niveau).liste == NULL)
1.1 bertrand 1513: {
1.28 bertrand 1514: // Si le niveau ne contient aucune variable, on le détruit.
1515: // Le pointeur sur la chaîne est déjà nul et il ne reste rien à
1516: // faire.
1.1 bertrand 1517: }
1518: else
1519: {
1.28 bertrand 1520: // Le niveau contient des variables.
1521:
1522: if ((*((struct_variable *) (*(*(*s_etat_processus)
1523: .l_liste_variables_par_niveau).liste).donnee)).niveau
1524: <= (*s_etat_processus).niveau_courant)
1.1 bertrand 1525: {
1.28 bertrand 1526: // On a retiré de l'arbre des variables toutes les
1527: // variables de niveau strictement supérieur au niveau
1528: // courant.
1.1 bertrand 1529:
1.28 bertrand 1530: break;
1.1 bertrand 1531: }
1.28 bertrand 1532:
1533: while((*(*s_etat_processus).l_liste_variables_par_niveau).liste
1534: != NULL)
1.1 bertrand 1535: {
1.34 bertrand 1536: // Nécessaire car le pointeur sur la tête de la pile
1537: // peut être modifié par retrait_variable().
1.28 bertrand 1538: // Sauvegarde des variables statiques.
1539:
1540: if ((*((struct_variable *) (*(*(*s_etat_processus)
1541: .l_liste_variables_par_niveau).liste).donnee)).origine
1542: == 'P')
1.1 bertrand 1543: {
1.28 bertrand 1544: if ((*((struct_variable *) (*(*(*s_etat_processus)
1545: .l_liste_variables_par_niveau).liste).donnee))
1546: .variable_statique.adresse != 0)
1.1 bertrand 1547: {
1.28 bertrand 1548: if (recherche_variable_statique(s_etat_processus,
1549: (*((struct_variable *) (*(*(*s_etat_processus)
1550: .l_liste_variables_par_niveau).liste).donnee))
1551: .nom, (*((struct_variable *)
1552: (*(*(*s_etat_processus)
1553: .l_liste_variables_par_niveau).liste).donnee))
1554: .variable_statique, ((*s_etat_processus)
1555: .mode_execution_programme
1556: == 'Y') ? 'P' : 'E') == d_vrai)
1557: {
1558: (*s_etat_processus).s_liste_variables_statiques
1559: [(*s_etat_processus)
1560: .position_variable_statique_courante]
1561: .objet = (*((struct_variable *)
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
1595: == 'Y') ? 'P' : 'E') == d_vrai)
1596: {
1597: (*s_etat_processus).s_liste_variables_statiques
1598: [(*s_etat_processus)
1599: .position_variable_statique_courante]
1600: .objet = (*((struct_variable *)
1601: (*(*(*s_etat_processus)
1602: .l_liste_variables_par_niveau).liste)
1603: .donnee)).objet;
1604: }
1605: else
1606: {
1607: (*s_etat_processus).erreur_systeme =
1608: d_es_variable_introuvable;
1609: return(d_erreur);
1610: }
1611:
1612: (*((struct_variable *) (*(*(*s_etat_processus)
1613: .l_liste_variables_par_niveau).liste).donnee))
1614: .objet = NULL;
1.1 bertrand 1615: }
1.28 bertrand 1616: }
1.1 bertrand 1617:
1.28 bertrand 1618: if (retrait_variable(s_etat_processus,
1619: (*((struct_variable *) (*(*(*s_etat_processus)
1620: .l_liste_variables_par_niveau).liste).donnee)).nom,
1621: 'L') == d_erreur)
1622: {
1623: return(d_erreur);
1.1 bertrand 1624: }
1.34 bertrand 1625:
1626: if ((*((struct_variable *) (*(*(*s_etat_processus)
1627: .l_liste_variables_par_niveau).liste).donnee)).niveau
1628: <= (*s_etat_processus).niveau_courant)
1629: {
1630: // On a retiré de l'arbre des variables toutes les
1631: // variables de niveau strictement supérieur au niveau
1632: // courant.
1633:
1634: return(d_absence_erreur);
1635: }
1.1 bertrand 1636: }
1637: }
1638:
1.31 bertrand 1639: // On retire l'élément de la liste doublement chaînée et circulaire.
1640:
1641: (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent).suivant
1642: = (*(*s_etat_processus).l_liste_variables_par_niveau).suivant;
1643: (*(*(*s_etat_processus).l_liste_variables_par_niveau).suivant).precedent
1644: = (*(*s_etat_processus).l_liste_variables_par_niveau).precedent;
1645:
1646: l_element_a_supprimer = (*s_etat_processus)
1647: .l_liste_variables_par_niveau;
1648: (*s_etat_processus).l_liste_variables_par_niveau =
1649: (*l_element_a_supprimer).suivant;
1.40 bertrand 1650: liberation_feuille(s_etat_processus, l_element_a_supprimer);
1.1 bertrand 1651: }
1652:
1653: return(d_absence_erreur);
1654: }
1655:
1.23 bertrand 1656:
1657: /*
1658: ================================================================================
1.24 bertrand 1659: Procédure de retrait des toutes les variables locales et globales
1660: ================================================================================
1661: Entrée : drapeau indiquant s'il faut retirer les définitions (variables
1662: de niveau 0)
1663: --------------------------------------------------------------------------------
1664: Sortie :
1665: --------------------------------------------------------------------------------
1666: Effets de bord : néant
1667: ================================================================================
1668: */
1669:
1670: void
1671: liberation_arbre_variables(struct_processus *s_etat_processus,
1672: struct_arbre_variables *arbre, logical1 retrait_definitions)
1673: {
1.58 ! bertrand 1674: int i;
! 1675:
! 1676: struct_liste_chainee *l_element_courant_liste;
! 1677: struct_liste_chainee *l_element_suivant_liste;
1.24 bertrand 1678:
1.58 ! bertrand 1679: struct_liste_variables *l_element_courant;
! 1680: struct_liste_variables *l_element_suivant;
1.28 bertrand 1681:
1.58 ! bertrand 1682: struct_liste_variables_statiques *l_element_statique_courant;
! 1683: struct_liste_variables_statiques *l_element_statique_suivant;
1.28 bertrand 1684:
1685: // Libération de l'arbre des variables. Le contenu des variables n'est
1686: // pas détruit par cette opération, il sera détruit lors de la libération
1687: // de la liste des variables par niveau.
1.24 bertrand 1688:
1.34 bertrand 1689: if (arbre == NULL)
1690: {
1691: return;
1692: }
1693:
1.31 bertrand 1694: l_element_courant = (*arbre).feuille;
1695:
1696: if (l_element_courant != NULL)
1697: {
1698: do
1699: {
1700: l_element_suivant = (*l_element_courant).suivant;
1.40 bertrand 1701: liberation_feuille(s_etat_processus, l_element_courant);
1.31 bertrand 1702: l_element_courant = l_element_suivant;
1703: } while(l_element_courant != (*arbre).feuille);
1.38 bertrand 1704:
1705: (*arbre).feuille = NULL;
1.31 bertrand 1706: }
1707:
1.58 ! bertrand 1708: l_element_statique_courant = (*arbre).feuille_statique;
! 1709:
! 1710: while(l_element_statique_courant != NULL)
! 1711: {
! 1712: l_element_statique_suivant = (*l_element_statique_courant).suivant;
! 1713:
! 1714: free((*(*l_element_statique_courant).variable).nom);
! 1715: liberation(s_etat_processus, (*(*l_element_statique_courant)
! 1716: .variable).objet);
! 1717:
! 1718: l_element_statique_courant = l_element_statique_suivant;
! 1719: }
! 1720:
1.24 bertrand 1721: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1722: {
1.28 bertrand 1723: if ((*arbre).noeuds[i] != NULL)
1.24 bertrand 1724: {
1.28 bertrand 1725: liberation_arbre_variables(s_etat_processus, (*arbre).noeuds[i],
1726: retrait_definitions);
1.38 bertrand 1727: (*arbre).noeuds[i] = NULL;
1.28 bertrand 1728: }
1729: }
1730:
1731: // Suppression de la liste des variables par niveau.
1732:
1733: if (arbre == (*s_etat_processus).s_arbre_variables)
1734: {
1735: l_element_courant = (*s_etat_processus).l_liste_variables_par_niveau;
1736:
1.31 bertrand 1737: if (l_element_courant != NULL)
1.28 bertrand 1738: {
1.31 bertrand 1739: do
1740: {
1741: l_element_courant_liste = (*l_element_courant).liste;
1.24 bertrand 1742:
1.31 bertrand 1743: while(l_element_courant_liste != NULL)
1.24 bertrand 1744: {
1.31 bertrand 1745: if ((retrait_definitions == d_vrai) ||
1746: ((*((struct_variable *) (*l_element_courant_liste)
1747: .donnee)).niveau >= 1))
1748: {
1749: liberation(s_etat_processus, (*((struct_variable *)
1750: (*l_element_courant_liste).donnee)).objet);
1751: free((*((struct_variable *) (*l_element_courant_liste)
1752: .donnee)).nom);
1753: }
1754:
1755: l_element_suivant_liste =
1756: (*l_element_courant_liste).suivant;
1.40 bertrand 1757: liberation_variable(s_etat_processus, (struct_variable *)
1758: (*l_element_courant_liste).donnee);
1759: liberation_maillon(s_etat_processus,
1760: l_element_courant_liste);
1.31 bertrand 1761: l_element_courant_liste = l_element_suivant_liste;
1.24 bertrand 1762: }
1763:
1.31 bertrand 1764: l_element_suivant = (*l_element_courant).suivant;
1.40 bertrand 1765: liberation_feuille(s_etat_processus, l_element_courant);
1.31 bertrand 1766: l_element_courant = l_element_suivant;
1767: } while(l_element_courant != (*s_etat_processus)
1768: .l_liste_variables_par_niveau);
1.24 bertrand 1769: }
1770: }
1771:
1.40 bertrand 1772: liberation_tableau_noeuds(s_etat_processus, (*arbre).noeuds);
1773: liberation_noeud(s_etat_processus, arbre);
1.38 bertrand 1774: arbre = NULL;
1.24 bertrand 1775:
1776: return;
1777: }
1778:
1.28 bertrand 1779:
1.24 bertrand 1780: /*
1781: ================================================================================
1.33 bertrand 1782: Procédure renvoyant les variables dans un tableau
1783: ================================================================================
1784: Entrée :
1785: --------------------------------------------------------------------------------
1786: Sortie :
1787: --------------------------------------------------------------------------------
1788: Effets de bord : néant
1789: ================================================================================
1790: */
1791:
1792: int
1793: nombre_variables(struct_processus *s_etat_processus,
1794: struct_arbre_variables *l_element_courant)
1795: {
1796: int i;
1797: int n;
1798:
1799: struct_liste_variables *l_variable;
1800:
1801: n = 0;
1802:
1803: if ((*l_element_courant).feuille != NULL)
1804: {
1805: l_variable = (*l_element_courant).feuille;
1806:
1807: do
1808: {
1809: n++;
1810: l_variable = (*l_variable).suivant;
1811: } while(l_variable != (*l_element_courant).feuille);
1812: }
1813:
1814: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1815: {
1816: if ((*l_element_courant).noeuds[i] != NULL)
1817: {
1818: n += nombre_variables(s_etat_processus,
1819: (*l_element_courant).noeuds[i]);
1820: }
1821: }
1822:
1823: return(n);
1824: }
1825:
1.53 bertrand 1826:
1.33 bertrand 1827: int
1828: liste_variables(struct_processus *s_etat_processus,
1829: struct_tableau_variables *tableau, int position,
1830: struct_arbre_variables *l_element_courant)
1831: {
1832: int i;
1833:
1834: struct_liste_variables *l_variable;
1835:
1836: if ((*l_element_courant).feuille != NULL)
1837: {
1838: l_variable = (*l_element_courant).feuille;
1839:
1840: do
1841: {
1842: tableau[position].origine = (*(*l_variable).variable).origine;
1843: tableau[position].nom = (*(*l_variable).variable).nom;
1844: tableau[position].niveau = (*(*l_variable).variable).niveau;
1845: tableau[position].objet = (*(*l_variable).variable).objet;
1846: tableau[position].variable_verrouillee =
1847: (*(*l_variable).variable).variable_verrouillee;
1848: tableau[position].variable_statique =
1849: (*(*l_variable).variable).variable_statique;
1850: tableau[position].variable_partagee =
1851: (*(*l_variable).variable).variable_partagee;
1852:
1853: position++;
1854: l_variable = (*l_variable).suivant;
1855: } while(l_variable != (*l_element_courant).feuille);
1856: }
1857:
1858: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1859: {
1860: if ((*l_element_courant).noeuds[i] != NULL)
1861: {
1862: position = liste_variables(s_etat_processus,
1863: tableau, position, (*l_element_courant).noeuds[i]);
1864: }
1865: }
1866:
1867: return(position);
1868: }
1869:
1.47 bertrand 1870:
1.33 bertrand 1871: /*
1872: ================================================================================
1.23 bertrand 1873: Procédure de copie de l'arbre des variables
1874: ================================================================================
1875: Entrée :
1876: --------------------------------------------------------------------------------
1877: Sortie :
1878: --------------------------------------------------------------------------------
1879: Effets de bord : néant
1880: ================================================================================
1881: */
1882:
1.38 bertrand 1883: void
1884: copie_arbre_variables(struct_processus *s_etat_processus, struct_processus
1885: *s_nouvel_etat_processus)
1.23 bertrand 1886: {
1887: // Les définitions sont partagées entre tous les threads et ne sont pas
1888: // copiées.
1.28 bertrand 1889: //
1890: // NB : on ne copie que les variables de niveaux 0 et 1, les autres
1891: // variables locales étant masquées par le processus de création de thread
1.38 bertrand 1892: // ou de processus, elles seront inaccessibles de tous les points
1893: // du fil d'exécution fils.
1894:
1895: // Pour copier ces variables, on récupère les variables depuis la liste par
1896: // niveaux (niveaux 0 et 1) et on ajoute les variables dans la nouvelle
1897: // structure. Les variables de niveau 0 étant non modifiables, elles
1898: // ne sont pas dupliquées.
1899:
1900: int i;
1901:
1.47 bertrand 1902: logical1 niveau_0_traite;
1903: logical1 niveau_1_traite;
1904:
1.38 bertrand 1905: struct_liste_chainee *l_element_courant;
1906:
1907: struct_liste_variables *l_niveau_courant;
1908:
1909: struct_variable s_variable;
1910:
1911: (*s_nouvel_etat_processus).s_arbre_variables = NULL;
1912: (*s_nouvel_etat_processus).l_liste_variables_par_niveau = NULL;
1913:
1914: l_niveau_courant = (*s_etat_processus).l_liste_variables_par_niveau;
1915:
1916: // Si la variable en tête n'est pas une variable de niveau 0, le niveau
1.47 bertrand 1917: // 0, s'il existe est le niveau précédent la valeur courante dans la
1.38 bertrand 1918: // boucle.
1919:
1920: if ((*((struct_variable *) (*(*l_niveau_courant).liste).donnee)).niveau
1921: != 0)
1922: {
1923: l_niveau_courant = (*l_niveau_courant).precedent;
1924: }
1925:
1926: // Les variables de niveaux 0 et 1 sont accessibles en au plus trois
1927: // itérations (par construction).
1.28 bertrand 1928:
1.47 bertrand 1929: niveau_0_traite = d_faux;
1930: niveau_1_traite = d_faux;
1931:
1.38 bertrand 1932: for(i = 0; i <= 2; i++)
1933: {
1934: if ((*((struct_variable *) (*(*l_niveau_courant).liste)
1935: .donnee)).niveau == 0)
1936: {
1.47 bertrand 1937: if (niveau_0_traite == d_faux)
1938: {
1939: l_element_courant = (*l_niveau_courant).liste;
1.23 bertrand 1940:
1.47 bertrand 1941: while(l_element_courant != NULL)
1.38 bertrand 1942: {
1.47 bertrand 1943: if (ajout_variable(s_nouvel_etat_processus,
1944: (struct_variable *) (*l_element_courant).donnee)
1945: == d_erreur)
1946: {
1947: return;
1948: }
1949:
1950: l_element_courant = (*l_element_courant).suivant;
1.38 bertrand 1951: }
1952:
1.47 bertrand 1953: niveau_0_traite = d_vrai;
1.38 bertrand 1954: }
1955: }
1956: else if ((*((struct_variable *) (*(*l_niveau_courant).liste)
1957: .donnee)).niveau == 1)
1958: {
1.47 bertrand 1959: if (niveau_1_traite == d_faux)
1.38 bertrand 1960: {
1.47 bertrand 1961: l_element_courant = (*l_niveau_courant).liste;
1.38 bertrand 1962:
1.47 bertrand 1963: while(l_element_courant != NULL)
1.38 bertrand 1964: {
1.47 bertrand 1965: s_variable = (*((struct_variable *)
1966: (*l_element_courant).donnee));
1.38 bertrand 1967:
1.47 bertrand 1968: if ((s_variable.nom = strdup((*((struct_variable *)
1969: (*l_element_courant).donnee)).nom)) == NULL)
1970: {
1971: (*s_nouvel_etat_processus).erreur_systeme =
1972: d_es_allocation_memoire;
1973: return;
1974: }
1975:
1976: if ((s_variable.objet = copie_objet(s_nouvel_etat_processus,
1977: (*((struct_variable *) (*l_element_courant).donnee))
1978: .objet, 'P')) == NULL)
1979: {
1980: (*s_nouvel_etat_processus).erreur_systeme =
1981: d_es_allocation_memoire;
1982: return;
1983: }
1984:
1985: if (ajout_variable(s_nouvel_etat_processus, &s_variable)
1986: == d_erreur)
1987: {
1988: return;
1989: }
1.38 bertrand 1990:
1.47 bertrand 1991: l_element_courant = (*l_element_courant).suivant;
1.38 bertrand 1992: }
1993:
1.47 bertrand 1994: niveau_1_traite = d_vrai;
1.38 bertrand 1995: }
1996:
1997: // Les variables de niveau 0 ayant déjà été copiées, on
1998: // peut sortir de la boucle car toutes les variables sont
1999: // maintenant disponibles dans le fil d'exécution fils.
2000:
2001: break;
2002: }
2003:
2004: l_niveau_courant = (*l_niveau_courant).precedent;
2005: }
2006:
2007: return;
1.23 bertrand 2008: }
2009:
2010:
2011: /*
2012: ================================================================================
2013: Procédure d'initialisation de la table de correspondance des variables
2014: ================================================================================
2015: Entrée :
2016: --------------------------------------------------------------------------------
2017: Sortie :
2018: --------------------------------------------------------------------------------
2019: Effets de bord : néant
2020: ================================================================================
2021: */
2022:
2023: /*
2024: * Caractères autorisés dans les instructions
2025: *
2026: * 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
2027: * 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
2028: * _
2029: * 1 2 3 4 5 6 7 8 9 0
2030: */
2031:
2032: void
2033: initialisation_variables(struct_processus *s_etat_processus)
2034: {
2035: int decalage;
2036: int i;
2037: int longueur_tableau;
2038:
2039: unsigned char caractere;
2040:
2041: // Récupération de la longueur d'un unsigned char
2042:
2043: longueur_tableau = 1;
2044: decalage = 0;
2045: caractere = 1;
2046:
2047: while((1L << decalage) == (long) ((unsigned char) (caractere << decalage)))
2048: {
2049: decalage++;
2050: longueur_tableau *= 2;
2051: }
2052:
2053: if (((*s_etat_processus).pointeurs_caracteres_variables =
2054: malloc(longueur_tableau * sizeof(int))) == NULL)
2055: {
2056: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2057: return;
2058: }
2059:
2060: for(i = 0; i < longueur_tableau; i++)
2061: {
2062: (*s_etat_processus).pointeurs_caracteres_variables[i] = -1;
2063: }
2064:
2065: (*s_etat_processus).nombre_caracteres_variables = 0;
2066:
2067: #define DECLARATION_CARACTERE(c) \
2068: do { (*s_etat_processus).pointeurs_caracteres_variables[c] = \
2069: (*s_etat_processus).nombre_caracteres_variables++; } while(0)
2070:
2071: DECLARATION_CARACTERE('A');
2072: DECLARATION_CARACTERE('B');
2073: DECLARATION_CARACTERE('C');
2074: DECLARATION_CARACTERE('D');
2075: DECLARATION_CARACTERE('E');
2076: DECLARATION_CARACTERE('F');
2077: DECLARATION_CARACTERE('G');
2078: DECLARATION_CARACTERE('H');
2079: DECLARATION_CARACTERE('I');
2080: DECLARATION_CARACTERE('J');
2081: DECLARATION_CARACTERE('K');
2082: DECLARATION_CARACTERE('L');
2083: DECLARATION_CARACTERE('M');
2084: DECLARATION_CARACTERE('N');
2085: DECLARATION_CARACTERE('O');
2086: DECLARATION_CARACTERE('P');
2087: DECLARATION_CARACTERE('Q');
2088: DECLARATION_CARACTERE('R');
2089: DECLARATION_CARACTERE('S');
2090: DECLARATION_CARACTERE('T');
2091: DECLARATION_CARACTERE('U');
2092: DECLARATION_CARACTERE('V');
2093: DECLARATION_CARACTERE('W');
2094: DECLARATION_CARACTERE('X');
2095: DECLARATION_CARACTERE('Y');
2096: DECLARATION_CARACTERE('Z');
2097:
2098: DECLARATION_CARACTERE('a');
2099: DECLARATION_CARACTERE('b');
2100: DECLARATION_CARACTERE('c');
2101: DECLARATION_CARACTERE('d');
2102: DECLARATION_CARACTERE('e');
2103: DECLARATION_CARACTERE('f');
2104: DECLARATION_CARACTERE('g');
2105: DECLARATION_CARACTERE('h');
2106: DECLARATION_CARACTERE('i');
2107: DECLARATION_CARACTERE('j');
2108: DECLARATION_CARACTERE('k');
2109: DECLARATION_CARACTERE('l');
2110: DECLARATION_CARACTERE('m');
2111: DECLARATION_CARACTERE('n');
2112: DECLARATION_CARACTERE('o');
2113: DECLARATION_CARACTERE('p');
2114: DECLARATION_CARACTERE('q');
2115: DECLARATION_CARACTERE('r');
2116: DECLARATION_CARACTERE('s');
2117: DECLARATION_CARACTERE('t');
2118: DECLARATION_CARACTERE('u');
2119: DECLARATION_CARACTERE('v');
2120: DECLARATION_CARACTERE('w');
2121: DECLARATION_CARACTERE('x');
2122: DECLARATION_CARACTERE('y');
2123: DECLARATION_CARACTERE('z');
2124:
2125: DECLARATION_CARACTERE('_');
2126:
2127: DECLARATION_CARACTERE('1');
2128: DECLARATION_CARACTERE('2');
2129: DECLARATION_CARACTERE('3');
2130: DECLARATION_CARACTERE('4');
2131: DECLARATION_CARACTERE('5');
2132: DECLARATION_CARACTERE('6');
2133: DECLARATION_CARACTERE('7');
2134: DECLARATION_CARACTERE('8');
2135: DECLARATION_CARACTERE('9');
2136: DECLARATION_CARACTERE('0');
2137: #undef DECLARATION_CARACTERE
2138:
2139: return;
2140: }
1.25 bertrand 2141:
1.1 bertrand 2142: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>