File:
[local] /
rpl /
src /
gestion_variables.c
Revision
1.60:
download - view:
text,
annotated -
select for diffs -
revision graph
Fri Oct 5 13:12:39 2012 UTC (12 years, 7 months ago) by
bertrand
Branches:
MAIN
CVS tags:
HEAD
Seconde série de patches pour intégrer les variables statiques à l'arbre
des variables. Cela compile sans warning mais n'a pas été testé. Au passage, la
condition de dépassement des puissances entières d'un argument réel ou complexe
a été corrigée.
1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.11
4: Copyright (C) 1989-2012 Dr. BERTRAND Joël
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:
23: #include "rpl-conv.h"
24:
25:
26: /*
27: ================================================================================
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:
49: printf("=========================================================="
50: "======================\n");
51: printf(" Liste des variables par niveaux\n");
52: printf("=========================================================="
53: "======================\n");
54:
55: if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
56: {
57: printf("=========================================================="
58: "======================\n");
59: return;
60: }
61:
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: {
74: printf("%s (%p->%p, %d) ", ((struct_variable *) e->donnee)->nom,
75: e, e->donnee, ((struct_variable *) e->donnee)->niveau);
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: {
99: printf("%s (%p->%p, %d) ", ((struct_variable *) e->donnee)->nom,
100: e, e->donnee, ((struct_variable *) e->donnee)->niveau);
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:
111: printf("=========================================================="
112: "======================\n");
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:
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:
153: if ((*arbre).feuille != NULL)
154: {
155: printf("Feuille %p [%d]\n", (*arbre).feuille, (*arbre).noeuds_utilises);
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:
191: printf("----------------------------------------------------------"
192: "----------------------\n");
193:
194: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
195: {
196: if ((*arbre).noeuds[i] != NULL)
197: {
198:
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: {
212: printf("=========================================================="
213: "======================\n");
214: printf(" Liste des variables sur le tas\n");
215: printf("=========================================================="
216: "======================\n");
217:
218: liste_variables_tas(s_etat_processus,
219: (*s_etat_processus).s_arbre_variables);
220:
221: printf("=========================================================="
222: "======================\n");
223:
224: return;
225: }
226:
227:
228: /*
229: ================================================================================
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: ================================================================================
385: Routine de création d'une nouvelle variable
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.
393: --------------------------------------------------------------------------------
394: Sortie :
395: --------------------------------------------------------------------------------
396: Effets de bords : néant
397: ================================================================================
398: */
399:
400: static logical1
401: ajout_variable(struct_processus *s_etat_processus, struct_variable *s_variable)
402: {
403: int i;
404:
405: logical1 niveau_acceptable;
406:
407: struct_liste_variables *l_nouvelle_variable;
408: struct_liste_variables *l_variable_candidate;
409:
410: struct_arbre_variables *l_variable_courante;
411: struct_arbre_variables *l_variable_precedente;
412:
413: struct_liste_chainee *l_nouvel_element;
414:
415: unsigned char *ptr;
416:
417: void *pointeur_variable_cree;
418:
419: if ((*s_etat_processus).s_arbre_variables == NULL)
420: {
421: if (((*s_etat_processus).s_arbre_variables =
422: allocation_noeud(s_etat_processus)) == NULL)
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).feuille_statique = NULL;
430: (*(*s_etat_processus).s_arbre_variables).noeuds_utilises = 0;
431: (*(*s_etat_processus).s_arbre_variables).indice_tableau_pere = -1;
432: (*(*s_etat_processus).s_arbre_variables).noeud_pere = NULL;
433:
434: if (((*(*s_etat_processus).s_arbre_variables).noeuds =
435: allocation_tableau_noeuds(s_etat_processus)) == NULL)
436: {
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: {
443: (*(*s_etat_processus).s_arbre_variables).noeuds[i] = NULL;
444: }
445: }
446:
447: l_variable_precedente = NULL;
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,
454: uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
455: *ptr));
456:
457: if ((*l_variable_courante).noeuds[(*s_etat_processus)
458: .pointeurs_caracteres_variables[*ptr]] == NULL)
459: {
460: // Le noeud n'existe pas encore, on le crée et on le marque
461: // comme utilisé dans la structure parente.
462:
463: if (((*l_variable_courante).noeuds[(*s_etat_processus)
464: .pointeurs_caracteres_variables[*ptr]] =
465: allocation_noeud(s_etat_processus)) == NULL)
466: {
467: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
468: return(d_erreur);
469: }
470:
471: (*l_variable_courante).noeuds_utilises++;
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:
477: (*(*l_variable_courante).noeuds[(*s_etat_processus)
478: .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
479: (*(*l_variable_courante).noeuds[(*s_etat_processus)
480: .pointeurs_caracteres_variables[*ptr]]).feuille_statique
481: = NULL;
482: (*(*l_variable_courante).noeuds[(*s_etat_processus)
483: .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
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:
492: (*(*l_variable_courante).noeuds[(*s_etat_processus)
493: .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
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.
502:
503: if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
504: .pointeurs_caracteres_variables[*ptr]]).noeuds =
505: allocation_tableau_noeuds(s_etat_processus)) == NULL)
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: {
513: (*(*l_variable_courante).noeuds[(*s_etat_processus)
514: .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
515: = NULL;
516: }
517: }
518:
519: l_variable_precedente = l_variable_courante;
520: l_variable_courante = (*l_variable_courante).noeuds
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:
532: if (((*l_variable_courante).feuille = allocation_feuille(
533: s_etat_processus)) == NULL)
534: {
535: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
536: return(d_erreur);
537: }
538:
539: (*l_variable_courante).noeuds_utilises++;
540:
541: (*(*l_variable_courante).feuille).suivant =
542: (*l_variable_courante).feuille;
543: (*(*l_variable_courante).feuille).precedent =
544: (*l_variable_courante).feuille;
545: (*(*l_variable_courante).feuille).noeud_pere = l_variable_precedente;
546: (*(*l_variable_courante).feuille).noeud = l_variable_courante;
547:
548: // Allocation de la variable sur l'élément de la liste.
549:
550: if (((*(*l_variable_courante).feuille).variable =
551: allocation_variable(s_etat_processus)) == NULL)
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);
559: pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
560: }
561: else
562: {
563: if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
564: == NULL)
565: {
566: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
567: return(d_erreur);
568: }
569:
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,
580: uprintf("Variable=\"%s\"\n", (*s_variable).nom));
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;
587: (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
588: (*l_nouvelle_variable).noeud = l_variable_courante;
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 =
596: allocation_variable(s_etat_processus)) == NULL)
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);
604: pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
605: }
606: else
607: {
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,
620: uprintf("Variable=\"%s\"\n", (*s_variable).nom));
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:
626: BUG((*s_variable).niveau == 0,
627: uprintf("Attempt to create a level-0 variable!\n"));
628:
629: if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
630: .niveau > 1)
631: {
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.
636: }
637: else
638: {
639: // Le niveau de la variable précédente dans la boucle est
640: // inférieur ou égal à 1.
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;
648: (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
649: (*l_nouvelle_variable).noeud = l_variable_courante;
650: (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
651: (*l_variable_candidate).precedent = l_nouvelle_variable;
652:
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:
664: if (((*l_nouvelle_variable).variable =
665: allocation_variable(s_etat_processus)) == NULL)
666: {
667: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
668: return(d_erreur);
669: }
670:
671: (*(*l_nouvelle_variable).variable) = (*s_variable);
672: pointeur_variable_cree = (*l_nouvelle_variable).variable;
673: }
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:
684: if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
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;
693: (*l_nouvelle_variable).noeud_pere = NULL;
694: (*l_nouvelle_variable).liste = NULL;
695:
696: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
697:
698: // Ajout de la variable en tête de la liste
699:
700: if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
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;
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éé.
717:
718: if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
719: == NULL)
720: {
721: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
722: return(d_erreur);
723: }
724:
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;
729: (*l_nouvelle_variable).noeud_pere = NULL;
730: (*l_nouvelle_variable).liste = NULL;
731: (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent)
732: .suivant = l_nouvelle_variable;
733: (*(*s_etat_processus).l_liste_variables_par_niveau)
734: .precedent = l_nouvelle_variable;
735:
736: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
737:
738: // Ajout de la variable en tête de la liste
739:
740: if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
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;
751: }
752: else if ((*s_variable).niveau <= 1)
753: {
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;
760:
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)
779: {
780: if ((l_nouvelle_variable = allocation_feuille(s_etat_processus))
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;
809: }
810:
811: // Ajout de la variable en tête de la liste l_variable_candidate.
812:
813: if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
814: {
815: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
816: return(d_erreur);
817: }
818:
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;
822: }
823: else
824: {
825: // Ajout de la variable en tête de la liste
826:
827: if ((l_nouvel_element = allocation_maillon(s_etat_processus)) == NULL)
828: {
829: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
830: return(d_erreur);
831: }
832:
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;
838: }
839:
840: return(d_absence_erreur);
841: }
842:
843:
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: {
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: /*
955: * Recherche de la feuille correspondante dans l'arbre des variables.
956: * Si cette feuille n'existe pas, elle est créée.
957: */
958:
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;
992:
993: if ((*s_etat_processus).s_arbre_variables == NULL)
994: {
995: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
996: return(d_faux);
997: }
998:
999: l_variable_courante = (*s_etat_processus).s_arbre_variables;
1000: ptr = nom_variable;
1001:
1002: while((*ptr) != d_code_fin_chaine)
1003: {
1004: pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
1005:
1006: if (pointeur < 0)
1007: {
1008: // Caractère hors de l'alphabet des variables
1009:
1010: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1011: return(d_faux);
1012: }
1013:
1014: if ((*l_variable_courante).noeuds[pointeur] == NULL)
1015: {
1016: // Le chemin de la variable candidate n'existe pas.
1017: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1018: return(d_faux);
1019: }
1020:
1021: l_variable_courante = (*l_variable_courante).noeuds[pointeur];
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)
1033: {
1034: // Problème : la pile système est vide !
1035: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
1036: return(d_faux);
1037: }
1038:
1039: while((*l_element_courant).retour_definition != 'Y')
1040: {
1041: l_element_courant = (*l_element_courant).suivant;
1042:
1043: if (l_element_courant == NULL)
1044: {
1045: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
1046: return(d_faux);
1047: }
1048: }
1049:
1050: niveau_appel = (*l_element_courant).niveau_courant;
1051:
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;
1061: return(d_vrai);
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
1069: // plus ancienne variable est strictement supérieur à 1, il
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 =
1078: (*(*l_variable_courante).feuille).precedent;
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:
1084: if (((*(*(*(*l_variable_courante).feuille).precedent)
1085: .variable).niveau == 0) && ((*(*(*(*
1086: (*l_variable_courante).feuille).precedent).precedent)
1087: .variable).niveau == 1))
1088: {
1089: (*s_etat_processus).pointeur_variable_courante =
1090: (*(*(*(*l_variable_courante).feuille).precedent)
1091: .precedent).variable;
1092: (*s_etat_processus).pointeur_feuille_courante =
1093: (*(*(*l_variable_courante).feuille).precedent)
1094: .precedent;
1095: }
1096:
1097: return(d_vrai);
1098: }
1099: }
1100: }
1101:
1102: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1103: return(d_faux);
1104: }
1105:
1106:
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: {
1121: // La variable est une définition.
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:
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: {
1194: logical1 erreur;
1195: logical1 variable_supprimee;
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;
1207:
1208: (*s_etat_processus).niveau_supprime = d_faux;
1209:
1210: if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
1211: {
1212: // Une variable correspondant au nom recherché est accessible.
1213:
1214: if (type == 'G')
1215: {
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:
1222: if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
1223: .precedent).variable).niveau <= 1)
1224: {
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))
1240: {
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;
1247: }
1248: }
1249: else
1250: {
1251: // Aucune variable globale (niveau 1) n'existe.
1252:
1253: erreur = d_erreur;
1254: (*s_etat_processus).erreur_execution =
1255: d_ex_variable_non_definie;
1256: return(erreur);
1257: }
1258: }
1259:
1260: if ((*(*s_etat_processus).pointeur_variable_courante)
1261: .variable_verrouillee == d_vrai)
1262: {
1263: erreur = d_erreur;
1264: (*s_etat_processus).erreur_execution =
1265: d_ex_variable_verrouillee;
1266: return(erreur);
1267: }
1268: }
1269:
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.
1277:
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;
1290: s_arbre_courant = (*variable_a_supprimer).noeud;
1291: BUG((*s_arbre_courant).noeuds_utilises == 0,
1292: uprintf("Freed node !\n"));
1293: (*s_arbre_courant).noeuds_utilises--;
1294:
1295: (*((*(*variable_a_supprimer).noeud_pere).noeuds
1296: [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
1297: .feuille = NULL;
1298:
1299: while(((*s_arbre_courant).noeuds_utilises == 0) &&
1300: ((*s_arbre_courant).feuille_statique == NULL))
1301: {
1302: s_arbre_a_supprimer = s_arbre_courant;
1303: s_arbre_courant = (*s_arbre_courant).noeud_pere;
1304:
1305: if (s_arbre_courant == NULL)
1306: {
1307: liberation_tableau_noeuds(s_etat_processus,
1308: (*s_arbre_a_supprimer).noeuds);
1309: liberation_noeud(s_etat_processus, s_arbre_a_supprimer);
1310:
1311: (*s_etat_processus).s_arbre_variables = NULL;
1312: break;
1313: }
1314:
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:
1325: liberation_tableau_noeuds(s_etat_processus,
1326: (*s_arbre_a_supprimer).noeuds);
1327: liberation_noeud(s_etat_processus, s_arbre_a_supprimer);
1328:
1329: BUG((*s_arbre_courant).noeuds_utilises == 0,
1330: uprintf("Freed node !\n"));
1331: (*s_arbre_courant).noeuds_utilises--;
1332: }
1333: }
1334: else
1335: {
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;
1348:
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;
1368: }
1369:
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;
1375: variable_supprimee = d_faux;
1376:
1377: if (variables_par_niveau != NULL)
1378: {
1379: do
1380: {
1381: l_element_courant = (*variables_par_niveau).liste;
1382:
1383: if (l_element_courant != NULL)
1384: {
1385: if ((*((struct_variable *) (*l_element_courant).donnee))
1386: .niveau == niveau)
1387: {
1388: // On parcourt le bon niveau.
1389:
1390: l_element_precedent = NULL;
1391:
1392: while(l_element_courant != NULL)
1393: {
1394: // Tant que l_element_courant est non nul, il reste
1395: // des variables à explorer dans le niveau courant.
1396:
1397: if ((*l_element_courant).donnee ==
1398: (void *) (*variable_a_supprimer).variable)
1399: {
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:
1413: liberation_maillon(s_etat_processus,
1414: l_element_courant);
1415:
1416: if ((*variables_par_niveau).liste == NULL)
1417: {
1418: (*s_etat_processus).niveau_supprime =
1419: d_vrai;
1420:
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;
1441: liberation_feuille(s_etat_processus,
1442: variables_par_niveau);
1443: }
1444:
1445: variable_supprimee = d_vrai;
1446: break;
1447: }
1448:
1449: l_element_precedent = l_element_courant;
1450: l_element_courant = (*l_element_courant).suivant;
1451: }
1452: }
1453: }
1454:
1455: if (variable_supprimee == d_vrai)
1456: {
1457: break;
1458: }
1459:
1460: variables_par_niveau = (*variables_par_niveau).suivant;
1461:
1462: } while(variables_par_niveau != (*s_etat_processus)
1463: .l_liste_variables_par_niveau);
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);
1470: liberation_variable(s_etat_processus, (*variable_a_supprimer).variable);
1471: liberation_feuille(s_etat_processus, variable_a_supprimer);
1472:
1473: erreur = d_absence_erreur;
1474: }
1475: else
1476: {
1477: // Aucune variable n'est accessible depuis le point courant du
1478: // programme.
1479:
1480: erreur = d_erreur;
1481: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1482: }
1483:
1484: return(erreur);
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_variables_par_niveau(struct_processus *s_etat_processus)
1503: {
1504: struct_liste_variables *l_element_a_supprimer;
1505:
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.
1509:
1510: while((*s_etat_processus).l_liste_variables_par_niveau != NULL)
1511: {
1512: if ((*(*s_etat_processus).l_liste_variables_par_niveau).liste == NULL)
1513: {
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.
1517: }
1518: else
1519: {
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)
1525: {
1526: // On a retiré de l'arbre des variables toutes les
1527: // variables de niveau strictement supérieur au niveau
1528: // courant.
1529:
1530: break;
1531: }
1532:
1533: while((*(*s_etat_processus).l_liste_variables_par_niveau).liste
1534: != NULL)
1535: {
1536: // Nécessaire car le pointeur sur la tête de la pile
1537: // peut être modifié par retrait_variable().
1538: // Sauvegarde des variables statiques.
1539:
1540: if ((*((struct_variable *) (*(*(*s_etat_processus)
1541: .l_liste_variables_par_niveau).liste).donnee)).origine
1542: == 'P')
1543: {
1544: if ((*((struct_variable *) (*(*(*s_etat_processus)
1545: .l_liste_variables_par_niveau).liste).donnee))
1546: .variable_statique.adresse != 0)
1547: {
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') != NULL)
1557: {
1558: (*(*s_etat_processus)
1559: .pointeur_variable_statique_courante)
1560: .objet = (*((struct_variable *)
1561: (*(*(*s_etat_processus)
1562: .l_liste_variables_par_niveau).liste)
1563: .donnee)).objet;
1564: }
1565: else
1566: {
1567: (*s_etat_processus).erreur_systeme =
1568: d_es_variable_introuvable;
1569: }
1570:
1571: (*((struct_variable *) (*(*(*s_etat_processus)
1572: .l_liste_variables_par_niveau).liste).donnee))
1573: .objet = NULL;
1574: }
1575: }
1576: else
1577: {
1578: if ((*((struct_variable *) (*(*(*s_etat_processus)
1579: .l_liste_variables_par_niveau).liste).donnee))
1580: .variable_statique.pointeur != NULL)
1581: {
1582: /*
1583: * Gestion des variables statiques
1584: */
1585:
1586: if (recherche_variable_statique(s_etat_processus,
1587: (*((struct_variable *) (*(*(*s_etat_processus)
1588: .l_liste_variables_par_niveau).liste).donnee))
1589: .nom, (*((struct_variable *)
1590: (*(*(*s_etat_processus)
1591: .l_liste_variables_par_niveau).liste).donnee))
1592: .variable_statique, ((*s_etat_processus)
1593: .mode_execution_programme
1594: == 'Y') ? 'P' : 'E') != NULL)
1595: {
1596: (*(*s_etat_processus)
1597: .pointeur_variable_statique_courante)
1598: .objet = (*((struct_variable *)
1599: (*(*(*s_etat_processus)
1600: .l_liste_variables_par_niveau).liste)
1601: .donnee)).objet;
1602: }
1603: else
1604: {
1605: (*s_etat_processus).erreur_systeme =
1606: d_es_variable_introuvable;
1607: return(d_erreur);
1608: }
1609:
1610: (*((struct_variable *) (*(*(*s_etat_processus)
1611: .l_liste_variables_par_niveau).liste).donnee))
1612: .objet = NULL;
1613: }
1614: }
1615:
1616: if (retrait_variable(s_etat_processus,
1617: (*((struct_variable *) (*(*(*s_etat_processus)
1618: .l_liste_variables_par_niveau).liste).donnee)).nom,
1619: 'L') == d_erreur)
1620: {
1621: return(d_erreur);
1622: }
1623:
1624: if ((*((struct_variable *) (*(*(*s_etat_processus)
1625: .l_liste_variables_par_niveau).liste).donnee)).niveau
1626: <= (*s_etat_processus).niveau_courant)
1627: {
1628: // On a retiré de l'arbre des variables toutes les
1629: // variables de niveau strictement supérieur au niveau
1630: // courant.
1631:
1632: return(d_absence_erreur);
1633: }
1634: }
1635: }
1636:
1637: // On retire l'élément de la liste doublement chaînée et circulaire.
1638:
1639: (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent).suivant
1640: = (*(*s_etat_processus).l_liste_variables_par_niveau).suivant;
1641: (*(*(*s_etat_processus).l_liste_variables_par_niveau).suivant).precedent
1642: = (*(*s_etat_processus).l_liste_variables_par_niveau).precedent;
1643:
1644: l_element_a_supprimer = (*s_etat_processus)
1645: .l_liste_variables_par_niveau;
1646: (*s_etat_processus).l_liste_variables_par_niveau =
1647: (*l_element_a_supprimer).suivant;
1648: liberation_feuille(s_etat_processus, l_element_a_supprimer);
1649: }
1650:
1651: return(d_absence_erreur);
1652: }
1653:
1654:
1655: /*
1656: ================================================================================
1657: Procédure de retrait des toutes les variables locales et globales
1658: ================================================================================
1659: Entrée : drapeau indiquant s'il faut retirer les définitions (variables
1660: de niveau 0)
1661: --------------------------------------------------------------------------------
1662: Sortie :
1663: --------------------------------------------------------------------------------
1664: Effets de bord : néant
1665: ================================================================================
1666: */
1667:
1668: void
1669: liberation_arbre_variables(struct_processus *s_etat_processus,
1670: struct_arbre_variables *arbre, logical1 retrait_definitions)
1671: {
1672: int i;
1673:
1674: struct_liste_chainee *l_element_courant_liste;
1675: struct_liste_chainee *l_element_suivant_liste;
1676:
1677: struct_liste_variables *l_element_courant;
1678: struct_liste_variables *l_element_suivant;
1679:
1680: struct_liste_variables_statiques *l_element_statique_courant;
1681: struct_liste_variables_statiques *l_element_statique_suivant;
1682:
1683: // Libération de l'arbre des variables. Le contenu des variables n'est
1684: // pas détruit par cette opération, il sera détruit lors de la libération
1685: // de la liste des variables par niveau.
1686:
1687: if (arbre == NULL)
1688: {
1689: return;
1690: }
1691:
1692: l_element_courant = (*arbre).feuille;
1693:
1694: if (l_element_courant != NULL)
1695: {
1696: do
1697: {
1698: l_element_suivant = (*l_element_courant).suivant;
1699: liberation_feuille(s_etat_processus, l_element_courant);
1700: l_element_courant = l_element_suivant;
1701: } while(l_element_courant != (*arbre).feuille);
1702:
1703: (*arbre).feuille = NULL;
1704: }
1705:
1706: l_element_statique_courant = (*arbre).feuille_statique;
1707:
1708: while(l_element_statique_courant != NULL)
1709: {
1710: l_element_statique_suivant = (*l_element_statique_courant).suivant;
1711:
1712: free((*(*l_element_statique_courant).variable).nom);
1713: liberation(s_etat_processus, (*(*l_element_statique_courant)
1714: .variable).objet);
1715:
1716: l_element_statique_courant = l_element_statique_suivant;
1717: }
1718:
1719: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1720: {
1721: if ((*arbre).noeuds[i] != NULL)
1722: {
1723: liberation_arbre_variables(s_etat_processus, (*arbre).noeuds[i],
1724: retrait_definitions);
1725: (*arbre).noeuds[i] = NULL;
1726: }
1727: }
1728:
1729: // Suppression de la liste des variables par niveau.
1730:
1731: if (arbre == (*s_etat_processus).s_arbre_variables)
1732: {
1733: l_element_courant = (*s_etat_processus).l_liste_variables_par_niveau;
1734:
1735: if (l_element_courant != NULL)
1736: {
1737: do
1738: {
1739: l_element_courant_liste = (*l_element_courant).liste;
1740:
1741: while(l_element_courant_liste != NULL)
1742: {
1743: if ((retrait_definitions == d_vrai) ||
1744: ((*((struct_variable *) (*l_element_courant_liste)
1745: .donnee)).niveau >= 1))
1746: {
1747: liberation(s_etat_processus, (*((struct_variable *)
1748: (*l_element_courant_liste).donnee)).objet);
1749: free((*((struct_variable *) (*l_element_courant_liste)
1750: .donnee)).nom);
1751: }
1752:
1753: l_element_suivant_liste =
1754: (*l_element_courant_liste).suivant;
1755: liberation_variable(s_etat_processus, (struct_variable *)
1756: (*l_element_courant_liste).donnee);
1757: liberation_maillon(s_etat_processus,
1758: l_element_courant_liste);
1759: l_element_courant_liste = l_element_suivant_liste;
1760: }
1761:
1762: l_element_suivant = (*l_element_courant).suivant;
1763: liberation_feuille(s_etat_processus, l_element_courant);
1764: l_element_courant = l_element_suivant;
1765: } while(l_element_courant != (*s_etat_processus)
1766: .l_liste_variables_par_niveau);
1767: }
1768: }
1769:
1770: liberation_tableau_noeuds(s_etat_processus, (*arbre).noeuds);
1771: liberation_noeud(s_etat_processus, arbre);
1772: arbre = NULL;
1773:
1774: return;
1775: }
1776:
1777:
1778: /*
1779: ================================================================================
1780: Procédure renvoyant les variables dans un tableau
1781: ================================================================================
1782: Entrée :
1783: --------------------------------------------------------------------------------
1784: Sortie :
1785: --------------------------------------------------------------------------------
1786: Effets de bord : néant
1787: ================================================================================
1788: */
1789:
1790: int
1791: nombre_variables(struct_processus *s_etat_processus,
1792: struct_arbre_variables *l_element_courant)
1793: {
1794: int i;
1795: int n;
1796:
1797: struct_liste_variables *l_variable;
1798: struct_liste_variables_statiques *l_variable_statique;
1799:
1800: n = 0;
1801:
1802: if ((*l_element_courant).feuille != NULL)
1803: {
1804: l_variable = (*l_element_courant).feuille;
1805:
1806: do
1807: {
1808: n++;
1809: l_variable = (*l_variable).suivant;
1810: } while(l_variable != (*l_element_courant).feuille);
1811: }
1812:
1813: if ((*l_element_courant).feuille_statique != NULL)
1814: {
1815: l_variable_statique = (*l_element_courant).feuille_statique;
1816:
1817: do
1818: {
1819: // Si le pointeur est nul, la variable est accessible et a été
1820: // copiée dans l'arbre des variables.
1821:
1822: if ((*(*l_variable_statique).variable).objet != NULL)
1823: {
1824: n++;
1825: }
1826:
1827: l_variable_statique = (*l_variable_statique).suivant;
1828: } while(l_variable_statique != NULL);
1829: }
1830:
1831: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1832: {
1833: if ((*l_element_courant).noeuds[i] != NULL)
1834: {
1835: n += nombre_variables(s_etat_processus,
1836: (*l_element_courant).noeuds[i]);
1837: }
1838: }
1839:
1840: return(n);
1841: }
1842:
1843:
1844: int
1845: liste_variables(struct_processus *s_etat_processus,
1846: struct_tableau_variables *tableau, int position,
1847: struct_arbre_variables *l_element_courant)
1848: {
1849: int i;
1850:
1851: struct_liste_variables *l_variable;
1852: struct_liste_variables_statiques *l_variable_statique;
1853:
1854: if ((*l_element_courant).feuille != NULL)
1855: {
1856: l_variable = (*l_element_courant).feuille;
1857:
1858: do
1859: {
1860: tableau[position].origine = (*(*l_variable).variable).origine;
1861: tableau[position].nom = (*(*l_variable).variable).nom;
1862: tableau[position].niveau = (*(*l_variable).variable).niveau;
1863: tableau[position].objet = (*(*l_variable).variable).objet;
1864: tableau[position].variable_verrouillee =
1865: (*(*l_variable).variable).variable_verrouillee;
1866: tableau[position].variable_statique =
1867: (*(*l_variable).variable).variable_statique;
1868: tableau[position].variable_partagee =
1869: (*(*l_variable).variable).variable_partagee;
1870: tableau[position].variable_masquee = d_faux;
1871:
1872: position++;
1873: l_variable = (*l_variable).suivant;
1874: } while(l_variable != (*l_element_courant).feuille);
1875: }
1876:
1877: if ((*l_element_courant).feuille_statique != NULL)
1878: {
1879: l_variable_statique = (*l_element_courant).feuille_statique;
1880:
1881: do
1882: {
1883: if ((*(*l_variable_statique).variable).objet != NULL)
1884: {
1885: tableau[position].origine = 'E';
1886: tableau[position].nom = (*(*l_variable_statique).variable).nom;
1887: tableau[position].niveau =
1888: (*(*l_variable_statique).variable).niveau;
1889: tableau[position].objet =
1890: (*(*l_variable_statique).variable).objet;
1891: tableau[position].variable_verrouillee = d_faux;
1892: tableau[position].variable_statique =
1893: (*(*l_variable_statique).variable).variable_statique;
1894: tableau[position].variable_partagee.pointeur = NULL;
1895: tableau[position].variable_masquee = d_vrai;
1896:
1897: position++;
1898: }
1899:
1900: l_variable_statique = (*l_variable_statique).suivant;
1901: } while(l_variable_statique != NULL);
1902: }
1903:
1904: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1905: {
1906: if ((*l_element_courant).noeuds[i] != NULL)
1907: {
1908: position = liste_variables(s_etat_processus,
1909: tableau, position, (*l_element_courant).noeuds[i]);
1910: }
1911: }
1912:
1913: return(position);
1914: }
1915:
1916:
1917: /*
1918: ================================================================================
1919: Procédure de copie de l'arbre des variables
1920: ================================================================================
1921: Entrée :
1922: --------------------------------------------------------------------------------
1923: Sortie :
1924: --------------------------------------------------------------------------------
1925: Effets de bord : néant
1926: ================================================================================
1927: */
1928:
1929: void
1930: copie_arbre_variables(struct_processus *s_etat_processus, struct_processus
1931: *s_nouvel_etat_processus)
1932: {
1933: // Les définitions sont partagées entre tous les threads et ne sont pas
1934: // copiées.
1935: //
1936: // NB : on ne copie que les variables de niveaux 0 et 1, les autres
1937: // variables locales étant masquées par le processus de création de thread
1938: // ou de processus, elles seront inaccessibles de tous les points
1939: // du fil d'exécution fils.
1940:
1941: // Pour copier ces variables, on récupère les variables depuis la liste par
1942: // niveaux (niveaux 0 et 1) et on ajoute les variables dans la nouvelle
1943: // structure. Les variables de niveau 0 étant non modifiables, elles
1944: // ne sont pas dupliquées.
1945:
1946: int i;
1947:
1948: logical1 niveau_0_traite;
1949: logical1 niveau_1_traite;
1950:
1951: struct_arbre_variables *l_variable_courante;
1952:
1953: struct_liste_chainee *l_element_courant;
1954:
1955: struct_liste_variables *l_niveau_courant;
1956: struct_liste_variables_statiques *l_element_statique_courant;
1957:
1958: struct_variable s_variable;
1959:
1960: unsigned char *ptr;
1961:
1962: (*s_nouvel_etat_processus).s_arbre_variables = NULL;
1963: (*s_nouvel_etat_processus).l_liste_variables_par_niveau = NULL;
1964:
1965: l_niveau_courant = (*s_etat_processus).l_liste_variables_par_niveau;
1966:
1967: // Si la variable en tête n'est pas une variable de niveau 0, le niveau
1968: // 0, s'il existe est le niveau précédent la valeur courante dans la
1969: // boucle.
1970:
1971: if ((*((struct_variable *) (*(*l_niveau_courant).liste).donnee)).niveau
1972: != 0)
1973: {
1974: l_niveau_courant = (*l_niveau_courant).precedent;
1975: }
1976:
1977: // Les variables de niveaux 0 et 1 sont accessibles en au plus trois
1978: // itérations (par construction).
1979:
1980: niveau_0_traite = d_faux;
1981: niveau_1_traite = d_faux;
1982:
1983: for(i = 0; i <= 2; i++)
1984: {
1985: if ((*((struct_variable *) (*(*l_niveau_courant).liste)
1986: .donnee)).niveau == 0)
1987: {
1988: if (niveau_0_traite == d_faux)
1989: {
1990: l_element_courant = (*l_niveau_courant).liste;
1991:
1992: while(l_element_courant != NULL)
1993: {
1994: if (ajout_variable(s_nouvel_etat_processus,
1995: (struct_variable *) (*l_element_courant).donnee)
1996: == d_erreur)
1997: {
1998: return;
1999: }
2000:
2001: l_element_courant = (*l_element_courant).suivant;
2002: }
2003:
2004: niveau_0_traite = d_vrai;
2005: }
2006: }
2007: else if ((*((struct_variable *) (*(*l_niveau_courant).liste)
2008: .donnee)).niveau == 1)
2009: {
2010: if (niveau_1_traite == d_faux)
2011: {
2012: l_element_courant = (*l_niveau_courant).liste;
2013:
2014: while(l_element_courant != NULL)
2015: {
2016: s_variable = (*((struct_variable *)
2017: (*l_element_courant).donnee));
2018:
2019: if ((s_variable.nom = strdup((*((struct_variable *)
2020: (*l_element_courant).donnee)).nom)) == NULL)
2021: {
2022: (*s_nouvel_etat_processus).erreur_systeme =
2023: d_es_allocation_memoire;
2024: return;
2025: }
2026:
2027: if ((s_variable.objet = copie_objet(s_nouvel_etat_processus,
2028: (*((struct_variable *) (*l_element_courant).donnee))
2029: .objet, 'P')) == NULL)
2030: {
2031: (*s_nouvel_etat_processus).erreur_systeme =
2032: d_es_allocation_memoire;
2033: return;
2034: }
2035:
2036: if (ajout_variable(s_nouvel_etat_processus, &s_variable)
2037: == d_erreur)
2038: {
2039: return;
2040: }
2041:
2042: l_element_courant = (*l_element_courant).suivant;
2043: }
2044:
2045: niveau_1_traite = d_vrai;
2046: }
2047:
2048: // Les variables de niveau 0 ayant déjà été copiées, on
2049: // peut sortir de la boucle car toutes les variables sont
2050: // maintenant disponibles dans le fil d'exécution fils.
2051:
2052: break;
2053: }
2054:
2055: l_niveau_courant = (*l_niveau_courant).precedent;
2056: }
2057:
2058: // Copie des variables statiques
2059:
2060: l_element_statique_courant = (*s_etat_processus)
2061: .l_liste_variables_statiques;
2062:
2063: while(l_element_statique_courant != NULL)
2064: {
2065: // Création des branches de l'arbre si nécessaire.
2066:
2067: if ((*s_nouvel_etat_processus).s_arbre_variables == NULL)
2068: {
2069: if (((*s_nouvel_etat_processus).s_arbre_variables =
2070: allocation_noeud(s_nouvel_etat_processus)) == NULL)
2071: {
2072: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2073: return;
2074: }
2075:
2076: (*(*s_nouvel_etat_processus).s_arbre_variables).feuille = NULL;
2077: (*(*s_nouvel_etat_processus).s_arbre_variables).feuille_statique
2078: = NULL;
2079: (*(*s_nouvel_etat_processus).s_arbre_variables).noeuds_utilises = 0;
2080: (*(*s_nouvel_etat_processus).s_arbre_variables).indice_tableau_pere
2081: = -1;
2082: (*(*s_nouvel_etat_processus).s_arbre_variables).noeud_pere = NULL;
2083:
2084: if (((*(*s_nouvel_etat_processus).s_arbre_variables).noeuds =
2085: allocation_tableau_noeuds(s_nouvel_etat_processus)) == NULL)
2086: {
2087: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2088: return;
2089: }
2090:
2091: for(i = 0; i < (*s_nouvel_etat_processus)
2092: .nombre_caracteres_variables; i++)
2093: {
2094: (*(*s_nouvel_etat_processus).s_arbre_variables).noeuds[i]
2095: = NULL;
2096: }
2097: }
2098:
2099: l_variable_courante = (*s_nouvel_etat_processus).s_arbre_variables;
2100: ptr = (*(*l_element_statique_courant).variable).nom;
2101:
2102: while((*ptr) != d_code_fin_chaine)
2103: {
2104: BUG((*s_nouvel_etat_processus).pointeurs_caracteres_variables
2105: [*ptr] < 0, uprintf("Variable=\"%s\", (*ptr)='%c'\n",
2106: (*(*l_element_statique_courant).variable).nom, *ptr));
2107:
2108: if ((*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2109: .pointeurs_caracteres_variables[*ptr]] == NULL)
2110: {
2111: // Le noeud n'existe pas encore, on le crée et on le marque
2112: // comme utilisé dans la structure parente.
2113:
2114: if (((*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2115: .pointeurs_caracteres_variables[*ptr]] =
2116: allocation_noeud(s_nouvel_etat_processus)) == NULL)
2117: {
2118: (*s_etat_processus).erreur_systeme =
2119: d_es_allocation_memoire;
2120: return;
2121: }
2122:
2123: (*l_variable_courante).noeuds_utilises++;
2124:
2125: // La feuille est par défaut vide et aucun élément du tableau
2126: // noeuds (les branches qui peuvent être issues de ce nouveau
2127: // noeud) n'est encore utilisée.
2128:
2129: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2130: .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
2131: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2132: .pointeurs_caracteres_variables[*ptr]]).feuille_statique
2133: = NULL;
2134: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2135: .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises
2136: = 0;
2137:
2138: // Le champ noeud_pere de la structure créée pointe sur
2139: // la structure parente et l'indice tableau_pere correspond à la
2140: // position réelle dans le tableau noeuds[] de la structure
2141: // parente du noeud courant. Cette valeur sera utilisée lors de
2142: // la destruction du noeud pour annuler le pointeur contenu dans
2143: // le tableau noeuds[] de la structure parente.
2144:
2145: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2146: .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
2147: l_variable_courante;
2148: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2149: .pointeurs_caracteres_variables[*ptr]])
2150: .indice_tableau_pere = (*s_nouvel_etat_processus)
2151: .pointeurs_caracteres_variables[*ptr];
2152:
2153: // Allocation du tableau noeuds[] et initialisation à zéro de
2154: // tous les pointeurs.
2155:
2156: if (((*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2157: .pointeurs_caracteres_variables[*ptr]]).noeuds =
2158: allocation_tableau_noeuds(s_nouvel_etat_processus))
2159: == NULL)
2160: {
2161: (*s_etat_processus).erreur_systeme
2162: = d_es_allocation_memoire;
2163: return;
2164: }
2165:
2166: for(i = 0; i < (*s_nouvel_etat_processus)
2167: .nombre_caracteres_variables; i++)
2168: {
2169: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2170: .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
2171: = NULL;
2172: }
2173: }
2174:
2175: l_variable_courante = (*l_variable_courante).noeuds
2176: [(*s_nouvel_etat_processus).pointeurs_caracteres_variables
2177: [*ptr]];
2178:
2179: ptr++;
2180: }
2181:
2182: if (creation_variable_statique(s_nouvel_etat_processus,
2183: (*l_element_statique_courant).variable) == d_erreur)
2184: {
2185: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2186: return;
2187: }
2188:
2189: l_element_statique_courant = (*l_element_statique_courant).suivant;
2190: }
2191:
2192: return;
2193: }
2194:
2195:
2196: /*
2197: ================================================================================
2198: Procédure d'initialisation de la table de correspondance des variables
2199: ================================================================================
2200: Entrée :
2201: --------------------------------------------------------------------------------
2202: Sortie :
2203: --------------------------------------------------------------------------------
2204: Effets de bord : néant
2205: ================================================================================
2206: */
2207:
2208: /*
2209: * Caractères autorisés dans les instructions
2210: *
2211: * 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
2212: * 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
2213: * _
2214: * 1 2 3 4 5 6 7 8 9 0
2215: */
2216:
2217: void
2218: initialisation_variables(struct_processus *s_etat_processus)
2219: {
2220: int decalage;
2221: int i;
2222: int longueur_tableau;
2223:
2224: unsigned char caractere;
2225:
2226: // Récupération de la longueur d'un unsigned char
2227:
2228: longueur_tableau = 1;
2229: decalage = 0;
2230: caractere = 1;
2231:
2232: while((1L << decalage) == (long) ((unsigned char) (caractere << decalage)))
2233: {
2234: decalage++;
2235: longueur_tableau *= 2;
2236: }
2237:
2238: if (((*s_etat_processus).pointeurs_caracteres_variables =
2239: malloc(longueur_tableau * sizeof(int))) == NULL)
2240: {
2241: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2242: return;
2243: }
2244:
2245: for(i = 0; i < longueur_tableau; i++)
2246: {
2247: (*s_etat_processus).pointeurs_caracteres_variables[i] = -1;
2248: }
2249:
2250: (*s_etat_processus).nombre_caracteres_variables = 0;
2251:
2252: #define DECLARATION_CARACTERE(c) \
2253: do { (*s_etat_processus).pointeurs_caracteres_variables[c] = \
2254: (*s_etat_processus).nombre_caracteres_variables++; } while(0)
2255:
2256: DECLARATION_CARACTERE('A');
2257: DECLARATION_CARACTERE('B');
2258: DECLARATION_CARACTERE('C');
2259: DECLARATION_CARACTERE('D');
2260: DECLARATION_CARACTERE('E');
2261: DECLARATION_CARACTERE('F');
2262: DECLARATION_CARACTERE('G');
2263: DECLARATION_CARACTERE('H');
2264: DECLARATION_CARACTERE('I');
2265: DECLARATION_CARACTERE('J');
2266: DECLARATION_CARACTERE('K');
2267: DECLARATION_CARACTERE('L');
2268: DECLARATION_CARACTERE('M');
2269: DECLARATION_CARACTERE('N');
2270: DECLARATION_CARACTERE('O');
2271: DECLARATION_CARACTERE('P');
2272: DECLARATION_CARACTERE('Q');
2273: DECLARATION_CARACTERE('R');
2274: DECLARATION_CARACTERE('S');
2275: DECLARATION_CARACTERE('T');
2276: DECLARATION_CARACTERE('U');
2277: DECLARATION_CARACTERE('V');
2278: DECLARATION_CARACTERE('W');
2279: DECLARATION_CARACTERE('X');
2280: DECLARATION_CARACTERE('Y');
2281: DECLARATION_CARACTERE('Z');
2282:
2283: DECLARATION_CARACTERE('a');
2284: DECLARATION_CARACTERE('b');
2285: DECLARATION_CARACTERE('c');
2286: DECLARATION_CARACTERE('d');
2287: DECLARATION_CARACTERE('e');
2288: DECLARATION_CARACTERE('f');
2289: DECLARATION_CARACTERE('g');
2290: DECLARATION_CARACTERE('h');
2291: DECLARATION_CARACTERE('i');
2292: DECLARATION_CARACTERE('j');
2293: DECLARATION_CARACTERE('k');
2294: DECLARATION_CARACTERE('l');
2295: DECLARATION_CARACTERE('m');
2296: DECLARATION_CARACTERE('n');
2297: DECLARATION_CARACTERE('o');
2298: DECLARATION_CARACTERE('p');
2299: DECLARATION_CARACTERE('q');
2300: DECLARATION_CARACTERE('r');
2301: DECLARATION_CARACTERE('s');
2302: DECLARATION_CARACTERE('t');
2303: DECLARATION_CARACTERE('u');
2304: DECLARATION_CARACTERE('v');
2305: DECLARATION_CARACTERE('w');
2306: DECLARATION_CARACTERE('x');
2307: DECLARATION_CARACTERE('y');
2308: DECLARATION_CARACTERE('z');
2309:
2310: DECLARATION_CARACTERE('_');
2311:
2312: DECLARATION_CARACTERE('1');
2313: DECLARATION_CARACTERE('2');
2314: DECLARATION_CARACTERE('3');
2315: DECLARATION_CARACTERE('4');
2316: DECLARATION_CARACTERE('5');
2317: DECLARATION_CARACTERE('6');
2318: DECLARATION_CARACTERE('7');
2319: DECLARATION_CARACTERE('8');
2320: DECLARATION_CARACTERE('9');
2321: DECLARATION_CARACTERE('0');
2322: #undef DECLARATION_CARACTERE
2323:
2324: return;
2325: }
2326:
2327: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>