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: 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: 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: free((*l_element_statique_courant).variable);
1716: free(l_element_statique_courant);
1717:
1718: l_element_statique_courant = l_element_statique_suivant;
1719: }
1720:
1721: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1722: {
1723: if ((*arbre).noeuds[i] != NULL)
1724: {
1725: liberation_arbre_variables(s_etat_processus, (*arbre).noeuds[i],
1726: retrait_definitions);
1727: (*arbre).noeuds[i] = NULL;
1728: }
1729: }
1730:
1731: // Suppression de la liste des variables par niveau.
1732:
1733: if (arbre == (*s_etat_processus).s_arbre_variables)
1734: {
1735: l_element_courant = (*s_etat_processus).l_liste_variables_par_niveau;
1736:
1737: if (l_element_courant != NULL)
1738: {
1739: do
1740: {
1741: l_element_courant_liste = (*l_element_courant).liste;
1742:
1743: while(l_element_courant_liste != NULL)
1744: {
1745: if ((retrait_definitions == d_vrai) ||
1746: ((*((struct_variable *) (*l_element_courant_liste)
1747: .donnee)).niveau >= 1))
1748: {
1749: liberation(s_etat_processus, (*((struct_variable *)
1750: (*l_element_courant_liste).donnee)).objet);
1751: free((*((struct_variable *) (*l_element_courant_liste)
1752: .donnee)).nom);
1753: }
1754:
1755: l_element_suivant_liste =
1756: (*l_element_courant_liste).suivant;
1757: liberation_variable(s_etat_processus, (struct_variable *)
1758: (*l_element_courant_liste).donnee);
1759: liberation_maillon(s_etat_processus,
1760: l_element_courant_liste);
1761: l_element_courant_liste = l_element_suivant_liste;
1762: }
1763:
1764: l_element_suivant = (*l_element_courant).suivant;
1765: liberation_feuille(s_etat_processus, l_element_courant);
1766: l_element_courant = l_element_suivant;
1767: } while(l_element_courant != (*s_etat_processus)
1768: .l_liste_variables_par_niveau);
1769: }
1770: }
1771:
1772: liberation_tableau_noeuds(s_etat_processus, (*arbre).noeuds);
1773: liberation_noeud(s_etat_processus, arbre);
1774: arbre = NULL;
1775:
1776: return;
1777: }
1778:
1779:
1780: /*
1781: ================================================================================
1782: Procédure renvoyant les variables dans un tableau
1783: ================================================================================
1784: Entrée :
1785: --------------------------------------------------------------------------------
1786: Sortie :
1787: --------------------------------------------------------------------------------
1788: Effets de bord : néant
1789: ================================================================================
1790: */
1791:
1792: int
1793: nombre_variables(struct_processus *s_etat_processus,
1794: struct_arbre_variables *l_element_courant)
1795: {
1796: int i;
1797: int n;
1798:
1799: struct_liste_variables *l_variable;
1800: struct_liste_variables_statiques *l_variable_statique;
1801:
1802: n = 0;
1803:
1804: if ((*l_element_courant).feuille != NULL)
1805: {
1806: l_variable = (*l_element_courant).feuille;
1807:
1808: do
1809: {
1810: n++;
1811: l_variable = (*l_variable).suivant;
1812: } while(l_variable != (*l_element_courant).feuille);
1813: }
1814:
1815: if ((*l_element_courant).feuille_statique != NULL)
1816: {
1817: l_variable_statique = (*l_element_courant).feuille_statique;
1818:
1819: do
1820: {
1821: // Si le pointeur est nul, la variable est accessible et a été
1822: // copiée dans l'arbre des variables.
1823:
1824: if ((*(*l_variable_statique).variable).objet != NULL)
1825: {
1826: n++;
1827: }
1828:
1829: l_variable_statique = (*l_variable_statique).suivant;
1830: } while(l_variable_statique != NULL);
1831: }
1832:
1833: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1834: {
1835: if ((*l_element_courant).noeuds[i] != NULL)
1836: {
1837: n += nombre_variables(s_etat_processus,
1838: (*l_element_courant).noeuds[i]);
1839: }
1840: }
1841:
1842: return(n);
1843: }
1844:
1845:
1846: int
1847: liste_variables(struct_processus *s_etat_processus,
1848: struct_tableau_variables *tableau, int position,
1849: struct_arbre_variables *l_element_courant)
1850: {
1851: int i;
1852:
1853: struct_liste_variables *l_variable;
1854: struct_liste_variables_statiques *l_variable_statique;
1855:
1856: if ((*l_element_courant).feuille != NULL)
1857: {
1858: l_variable = (*l_element_courant).feuille;
1859:
1860: do
1861: {
1862: tableau[position].origine = (*(*l_variable).variable).origine;
1863: tableau[position].nom = (*(*l_variable).variable).nom;
1864: tableau[position].niveau = (*(*l_variable).variable).niveau;
1865: tableau[position].objet = (*(*l_variable).variable).objet;
1866: tableau[position].variable_verrouillee =
1867: (*(*l_variable).variable).variable_verrouillee;
1868: tableau[position].variable_statique =
1869: (*(*l_variable).variable).variable_statique;
1870: tableau[position].variable_partagee =
1871: (*(*l_variable).variable).variable_partagee;
1872: tableau[position].variable_masquee = d_faux;
1873:
1874: position++;
1875: l_variable = (*l_variable).suivant;
1876: } while(l_variable != (*l_element_courant).feuille);
1877: }
1878:
1879: if ((*l_element_courant).feuille_statique != NULL)
1880: {
1881: l_variable_statique = (*l_element_courant).feuille_statique;
1882:
1883: do
1884: {
1885: if ((*(*l_variable_statique).variable).objet != NULL)
1886: {
1887: tableau[position].origine = 'E';
1888: tableau[position].nom = (*(*l_variable_statique).variable).nom;
1889: tableau[position].niveau =
1890: (*(*l_variable_statique).variable).niveau;
1891: tableau[position].objet =
1892: (*(*l_variable_statique).variable).objet;
1893: tableau[position].variable_verrouillee = d_faux;
1894: tableau[position].variable_statique =
1895: (*(*l_variable_statique).variable).variable_statique;
1896: tableau[position].variable_partagee.pointeur = NULL;
1897: tableau[position].variable_masquee = d_vrai;
1898:
1899: position++;
1900: }
1901:
1902: l_variable_statique = (*l_variable_statique).suivant;
1903: } while(l_variable_statique != NULL);
1904: }
1905:
1906: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1907: {
1908: if ((*l_element_courant).noeuds[i] != NULL)
1909: {
1910: position = liste_variables(s_etat_processus,
1911: tableau, position, (*l_element_courant).noeuds[i]);
1912: }
1913: }
1914:
1915: return(position);
1916: }
1917:
1918:
1919: /*
1920: ================================================================================
1921: Procédure de copie de l'arbre des variables
1922: ================================================================================
1923: Entrée :
1924: --------------------------------------------------------------------------------
1925: Sortie :
1926: --------------------------------------------------------------------------------
1927: Effets de bord : néant
1928: ================================================================================
1929: */
1930:
1931: void
1932: copie_arbre_variables(struct_processus *s_etat_processus, struct_processus
1933: *s_nouvel_etat_processus)
1934: {
1935: // Les définitions sont partagées entre tous les threads et ne sont pas
1936: // copiées.
1937: //
1938: // NB : on ne copie que les variables de niveaux 0 et 1, les autres
1939: // variables locales étant masquées par le processus de création de thread
1940: // ou de processus, elles seront inaccessibles de tous les points
1941: // du fil d'exécution fils.
1942:
1943: // Pour copier ces variables, on récupère les variables depuis la liste par
1944: // niveaux (niveaux 0 et 1) et on ajoute les variables dans la nouvelle
1945: // structure. Les variables de niveau 0 étant non modifiables, elles
1946: // ne sont pas dupliquées.
1947:
1948: int i;
1949:
1950: logical1 niveau_0_traite;
1951: logical1 niveau_1_traite;
1952:
1953: struct_arbre_variables *l_variable_courante;
1954:
1955: struct_liste_chainee *l_element_courant;
1956:
1957: struct_liste_variables *l_niveau_courant;
1958: struct_liste_variables_statiques *l_element_statique_courant;
1959:
1960: struct_variable s_variable;
1961: struct_variable_statique s_variable_statique;
1962:
1963: unsigned char *ptr;
1964:
1965: (*s_nouvel_etat_processus).s_arbre_variables = NULL;
1966: (*s_nouvel_etat_processus).l_liste_variables_par_niveau = NULL;
1967:
1968: l_niveau_courant = (*s_etat_processus).l_liste_variables_par_niveau;
1969:
1970: // Si la variable en tête n'est pas une variable de niveau 0, le niveau
1971: // 0, s'il existe est le niveau précédent la valeur courante dans la
1972: // boucle.
1973:
1974: if ((*((struct_variable *) (*(*l_niveau_courant).liste).donnee)).niveau
1975: != 0)
1976: {
1977: l_niveau_courant = (*l_niveau_courant).precedent;
1978: }
1979:
1980: // Les variables de niveaux 0 et 1 sont accessibles en au plus trois
1981: // itérations (par construction).
1982:
1983: niveau_0_traite = d_faux;
1984: niveau_1_traite = d_faux;
1985:
1986: for(i = 0; i <= 2; i++)
1987: {
1988: if ((*((struct_variable *) (*(*l_niveau_courant).liste)
1989: .donnee)).niveau == 0)
1990: {
1991: if (niveau_0_traite == d_faux)
1992: {
1993: l_element_courant = (*l_niveau_courant).liste;
1994:
1995: while(l_element_courant != NULL)
1996: {
1997: if (ajout_variable(s_nouvel_etat_processus,
1998: (struct_variable *) (*l_element_courant).donnee)
1999: == d_erreur)
2000: {
2001: return;
2002: }
2003:
2004: l_element_courant = (*l_element_courant).suivant;
2005: }
2006:
2007: niveau_0_traite = d_vrai;
2008: }
2009: }
2010: else if ((*((struct_variable *) (*(*l_niveau_courant).liste)
2011: .donnee)).niveau == 1)
2012: {
2013: if (niveau_1_traite == d_faux)
2014: {
2015: l_element_courant = (*l_niveau_courant).liste;
2016:
2017: while(l_element_courant != NULL)
2018: {
2019: s_variable = (*((struct_variable *)
2020: (*l_element_courant).donnee));
2021:
2022: if ((s_variable.nom = strdup((*((struct_variable *)
2023: (*l_element_courant).donnee)).nom)) == NULL)
2024: {
2025: (*s_nouvel_etat_processus).erreur_systeme =
2026: d_es_allocation_memoire;
2027: return;
2028: }
2029:
2030: if ((s_variable.objet = copie_objet(s_nouvel_etat_processus,
2031: (*((struct_variable *) (*l_element_courant).donnee))
2032: .objet, 'P')) == NULL)
2033: {
2034: (*s_nouvel_etat_processus).erreur_systeme =
2035: d_es_allocation_memoire;
2036: return;
2037: }
2038:
2039: if (ajout_variable(s_nouvel_etat_processus, &s_variable)
2040: == d_erreur)
2041: {
2042: return;
2043: }
2044:
2045: l_element_courant = (*l_element_courant).suivant;
2046: }
2047:
2048: niveau_1_traite = d_vrai;
2049: }
2050:
2051: // Les variables de niveau 0 ayant déjà été copiées, on
2052: // peut sortir de la boucle car toutes les variables sont
2053: // maintenant disponibles dans le fil d'exécution fils.
2054:
2055: break;
2056: }
2057:
2058: l_niveau_courant = (*l_niveau_courant).precedent;
2059: }
2060:
2061: // Copie des variables statiques
2062:
2063: l_element_statique_courant = (*s_etat_processus)
2064: .l_liste_variables_statiques;
2065:
2066: while(l_element_statique_courant != NULL)
2067: {
2068: // Création des branches de l'arbre si nécessaire.
2069:
2070: if ((*s_nouvel_etat_processus).s_arbre_variables == NULL)
2071: {
2072: if (((*s_nouvel_etat_processus).s_arbre_variables =
2073: allocation_noeud(s_nouvel_etat_processus)) == NULL)
2074: {
2075: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2076: return;
2077: }
2078:
2079: (*(*s_nouvel_etat_processus).s_arbre_variables).feuille = NULL;
2080: (*(*s_nouvel_etat_processus).s_arbre_variables).feuille_statique
2081: = NULL;
2082: (*(*s_nouvel_etat_processus).s_arbre_variables).noeuds_utilises = 0;
2083: (*(*s_nouvel_etat_processus).s_arbre_variables).indice_tableau_pere
2084: = -1;
2085: (*(*s_nouvel_etat_processus).s_arbre_variables).noeud_pere = NULL;
2086:
2087: if (((*(*s_nouvel_etat_processus).s_arbre_variables).noeuds =
2088: allocation_tableau_noeuds(s_nouvel_etat_processus)) == NULL)
2089: {
2090: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2091: return;
2092: }
2093:
2094: for(i = 0; i < (*s_nouvel_etat_processus)
2095: .nombre_caracteres_variables; i++)
2096: {
2097: (*(*s_nouvel_etat_processus).s_arbre_variables).noeuds[i]
2098: = NULL;
2099: }
2100: }
2101:
2102: l_variable_courante = (*s_nouvel_etat_processus).s_arbre_variables;
2103: ptr = (*(*l_element_statique_courant).variable).nom;
2104:
2105: while((*ptr) != d_code_fin_chaine)
2106: {
2107: BUG((*s_nouvel_etat_processus).pointeurs_caracteres_variables
2108: [*ptr] < 0, uprintf("Variable=\"%s\", (*ptr)='%c'\n",
2109: (*(*l_element_statique_courant).variable).nom, *ptr));
2110:
2111: if ((*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2112: .pointeurs_caracteres_variables[*ptr]] == NULL)
2113: {
2114: // Le noeud n'existe pas encore, on le crée et on le marque
2115: // comme utilisé dans la structure parente.
2116:
2117: if (((*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2118: .pointeurs_caracteres_variables[*ptr]] =
2119: allocation_noeud(s_nouvel_etat_processus)) == NULL)
2120: {
2121: (*s_etat_processus).erreur_systeme =
2122: d_es_allocation_memoire;
2123: return;
2124: }
2125:
2126: (*l_variable_courante).noeuds_utilises++;
2127:
2128: // La feuille est par défaut vide et aucun élément du tableau
2129: // noeuds (les branches qui peuvent être issues de ce nouveau
2130: // noeud) n'est encore utilisée.
2131:
2132: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2133: .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
2134: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2135: .pointeurs_caracteres_variables[*ptr]]).feuille_statique
2136: = NULL;
2137: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2138: .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises
2139: = 0;
2140:
2141: // Le champ noeud_pere de la structure créée pointe sur
2142: // la structure parente et l'indice tableau_pere correspond à la
2143: // position réelle dans le tableau noeuds[] de la structure
2144: // parente du noeud courant. Cette valeur sera utilisée lors de
2145: // la destruction du noeud pour annuler le pointeur contenu dans
2146: // le tableau noeuds[] de la structure parente.
2147:
2148: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2149: .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
2150: l_variable_courante;
2151: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2152: .pointeurs_caracteres_variables[*ptr]])
2153: .indice_tableau_pere = (*s_nouvel_etat_processus)
2154: .pointeurs_caracteres_variables[*ptr];
2155:
2156: // Allocation du tableau noeuds[] et initialisation à zéro de
2157: // tous les pointeurs.
2158:
2159: if (((*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2160: .pointeurs_caracteres_variables[*ptr]]).noeuds =
2161: allocation_tableau_noeuds(s_nouvel_etat_processus))
2162: == NULL)
2163: {
2164: (*s_etat_processus).erreur_systeme
2165: = d_es_allocation_memoire;
2166: return;
2167: }
2168:
2169: for(i = 0; i < (*s_nouvel_etat_processus)
2170: .nombre_caracteres_variables; i++)
2171: {
2172: (*(*l_variable_courante).noeuds[(*s_nouvel_etat_processus)
2173: .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
2174: = NULL;
2175: }
2176: }
2177:
2178: l_variable_courante = (*l_variable_courante).noeuds
2179: [(*s_nouvel_etat_processus).pointeurs_caracteres_variables
2180: [*ptr]];
2181:
2182: ptr++;
2183: }
2184:
2185: // Il faut copier la variable pour la dissocier de la variable
2186: // restant dans le thread parent.
2187:
2188: s_variable_statique = (*(*l_element_statique_courant).variable);
2189:
2190: if (copie_objet(s_etat_processus, s_variable_statique.objet, 'P')
2191: == NULL)
2192: {
2193: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2194: return;
2195: }
2196:
2197: if ((s_variable_statique.nom = malloc((strlen(
2198: (*(*l_element_statique_courant).variable).nom) + 1) *
2199: sizeof(unsigned char))) == NULL)
2200: {
2201: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2202: return;
2203: }
2204:
2205: strcpy(s_variable_statique.nom, (*(*l_element_statique_courant)
2206: .variable).nom);
2207:
2208: if (creation_variable_statique(s_nouvel_etat_processus,
2209: &s_variable_statique) == d_erreur)
2210: {
2211: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2212: return;
2213: }
2214:
2215: l_element_statique_courant = (*l_element_statique_courant).suivant;
2216: }
2217:
2218: return;
2219: }
2220:
2221:
2222: /*
2223: ================================================================================
2224: Procédure d'initialisation de la table de correspondance des variables
2225: ================================================================================
2226: Entrée :
2227: --------------------------------------------------------------------------------
2228: Sortie :
2229: --------------------------------------------------------------------------------
2230: Effets de bord : néant
2231: ================================================================================
2232: */
2233:
2234: /*
2235: * Caractères autorisés dans les instructions
2236: *
2237: * 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
2238: * 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
2239: * _
2240: * 1 2 3 4 5 6 7 8 9 0
2241: */
2242:
2243: void
2244: initialisation_variables(struct_processus *s_etat_processus)
2245: {
2246: int decalage;
2247: int i;
2248: int longueur_tableau;
2249:
2250: unsigned char caractere;
2251:
2252: // Récupération de la longueur d'un unsigned char
2253:
2254: longueur_tableau = 1;
2255: decalage = 0;
2256: caractere = 1;
2257:
2258: while((1L << decalage) == (long) ((unsigned char) (caractere << decalage)))
2259: {
2260: decalage++;
2261: longueur_tableau *= 2;
2262: }
2263:
2264: if (((*s_etat_processus).pointeurs_caracteres_variables =
2265: malloc(longueur_tableau * sizeof(int))) == NULL)
2266: {
2267: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2268: return;
2269: }
2270:
2271: for(i = 0; i < longueur_tableau; i++)
2272: {
2273: (*s_etat_processus).pointeurs_caracteres_variables[i] = -1;
2274: }
2275:
2276: (*s_etat_processus).nombre_caracteres_variables = 0;
2277:
2278: #define DECLARATION_CARACTERE(c) \
2279: do { (*s_etat_processus).pointeurs_caracteres_variables[c] = \
2280: (*s_etat_processus).nombre_caracteres_variables++; } while(0)
2281:
2282: DECLARATION_CARACTERE('A');
2283: DECLARATION_CARACTERE('B');
2284: DECLARATION_CARACTERE('C');
2285: DECLARATION_CARACTERE('D');
2286: DECLARATION_CARACTERE('E');
2287: DECLARATION_CARACTERE('F');
2288: DECLARATION_CARACTERE('G');
2289: DECLARATION_CARACTERE('H');
2290: DECLARATION_CARACTERE('I');
2291: DECLARATION_CARACTERE('J');
2292: DECLARATION_CARACTERE('K');
2293: DECLARATION_CARACTERE('L');
2294: DECLARATION_CARACTERE('M');
2295: DECLARATION_CARACTERE('N');
2296: DECLARATION_CARACTERE('O');
2297: DECLARATION_CARACTERE('P');
2298: DECLARATION_CARACTERE('Q');
2299: DECLARATION_CARACTERE('R');
2300: DECLARATION_CARACTERE('S');
2301: DECLARATION_CARACTERE('T');
2302: DECLARATION_CARACTERE('U');
2303: DECLARATION_CARACTERE('V');
2304: DECLARATION_CARACTERE('W');
2305: DECLARATION_CARACTERE('X');
2306: DECLARATION_CARACTERE('Y');
2307: DECLARATION_CARACTERE('Z');
2308:
2309: DECLARATION_CARACTERE('a');
2310: DECLARATION_CARACTERE('b');
2311: DECLARATION_CARACTERE('c');
2312: DECLARATION_CARACTERE('d');
2313: DECLARATION_CARACTERE('e');
2314: DECLARATION_CARACTERE('f');
2315: DECLARATION_CARACTERE('g');
2316: DECLARATION_CARACTERE('h');
2317: DECLARATION_CARACTERE('i');
2318: DECLARATION_CARACTERE('j');
2319: DECLARATION_CARACTERE('k');
2320: DECLARATION_CARACTERE('l');
2321: DECLARATION_CARACTERE('m');
2322: DECLARATION_CARACTERE('n');
2323: DECLARATION_CARACTERE('o');
2324: DECLARATION_CARACTERE('p');
2325: DECLARATION_CARACTERE('q');
2326: DECLARATION_CARACTERE('r');
2327: DECLARATION_CARACTERE('s');
2328: DECLARATION_CARACTERE('t');
2329: DECLARATION_CARACTERE('u');
2330: DECLARATION_CARACTERE('v');
2331: DECLARATION_CARACTERE('w');
2332: DECLARATION_CARACTERE('x');
2333: DECLARATION_CARACTERE('y');
2334: DECLARATION_CARACTERE('z');
2335:
2336: DECLARATION_CARACTERE('_');
2337:
2338: DECLARATION_CARACTERE('1');
2339: DECLARATION_CARACTERE('2');
2340: DECLARATION_CARACTERE('3');
2341: DECLARATION_CARACTERE('4');
2342: DECLARATION_CARACTERE('5');
2343: DECLARATION_CARACTERE('6');
2344: DECLARATION_CARACTERE('7');
2345: DECLARATION_CARACTERE('8');
2346: DECLARATION_CARACTERE('9');
2347: DECLARATION_CARACTERE('0');
2348: #undef DECLARATION_CARACTERE
2349:
2350: return;
2351: }
2352:
2353: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>