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