1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.0.prerelease.1
4: Copyright (C) 1989-2011 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("===========================================================\n");
50: printf(" Liste des variables par niveaux\n");
51: printf("===========================================================\n");
52:
53: if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
54: {
55: printf("===========================================================\n");
56: return;
57: }
58:
59: printf("Backward\n");
60: l = (*s_etat_processus).l_liste_variables_par_niveau;
61: c = 0;
62: fin = d_faux;
63:
64: do
65: {
66: l = l->precedent;
67: e = l->liste;
68:
69: while(e != NULL)
70: {
71: printf("%s (%p, %d) ", ((struct_variable *) e->donnee)->nom,
72: e->donnee, ((struct_variable *) e->donnee)->niveau);
73: e = e->suivant;
74: c++;
75: if (c > 100)
76: {
77: fin = d_vrai;
78: break;
79: }
80: }
81:
82: printf("\n");
83:
84: } while(l != (*s_etat_processus).l_liste_variables_par_niveau);
85:
86: printf("Forward\n");
87: l = (*s_etat_processus).l_liste_variables_par_niveau;
88: c = 0;
89:
90: do
91: {
92: e = l->liste;
93:
94: while(e != NULL)
95: {
96: printf("%s (%p, %d) ", ((struct_variable *) e->donnee)->nom,
97: e->donnee, ((struct_variable *) e->donnee)->niveau);
98: e = e->suivant;
99: c++;
100: if (c > 100) exit(0);
101: }
102:
103: printf("\n");
104:
105: l = l->suivant;
106: } while(l != (*s_etat_processus).l_liste_variables_par_niveau);
107:
108: printf("===========================================================\n");
109:
110: if (fin == d_vrai) exit(0);
111:
112: return;
113: }
114:
115: static void
116: liste_variables_tas(struct_processus *s_etat_processus,
117: struct_arbre_variables *arbre)
118: {
119: int c;
120: int i;
121:
122: logical1 fin;
123:
124: struct_liste_variables *l;
125:
126: fin = d_faux;
127:
128: if (arbre == NULL)
129: {
130: return;
131: }
132:
133: printf(">>> Position : %d\n",
134: (*arbre).indice_tableau_pere);
135: printf(">>> Nombre de noeuds utilisés : %u\n",
136: (*arbre).noeuds_utilises);
137: printf(">>> Noeuds fils : ");
138:
139: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
140: {
141: if ((*arbre).noeuds[i] != NULL)
142: {
143: printf("%d ", i);
144: }
145: }
146:
147: printf("\b\n");
148:
149: if ((*arbre).feuille != NULL)
150: {
151: printf("Feuille %p [%d]\n", (*arbre).feuille, (*arbre).noeuds_utilises);
152:
153: printf(" Backward\n");
154:
155: l = (*arbre).feuille;
156: c = 0;
157: fin = d_faux;
158:
159: do
160: {
161: l = l->precedent;
162: c++;
163: if (c > 100)
164: {
165: fin = d_vrai;
166: break;
167: }
168: printf(" %s (%p, %d)\n", l->variable->nom, l->variable,
169: l->variable->niveau);
170: } while((*arbre).feuille != l);
171:
172: printf(" Forward\n");
173:
174: l = (*arbre).feuille;
175: c = 0;
176:
177: do
178: {
179: c++;
180: if (c > 100) exit(0);
181: printf(" %s (%p, %d)\n", l->variable->nom, l->variable,
182: l->variable->niveau);
183: l = l->suivant;
184: } while((*arbre).feuille != l);
185: }
186:
187: printf("-----------------------------------------------------------\n");
188:
189: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
190: {
191: if ((*arbre).noeuds[i] != NULL)
192: {
193:
194: liste_variables_tas(s_etat_processus, (*arbre).noeuds[i]);
195: }
196: }
197:
198: if (fin == d_vrai) exit(0);
199:
200: return;
201: }
202:
203:
204: static void
205: liste_variables_par_feuilles(struct_processus *s_etat_processus)
206: {
207: printf("===========================================================\n");
208: printf(" Liste des variables sur le tas\n");
209: printf("===========================================================\n");
210:
211: liste_variables_tas(s_etat_processus,
212: (*s_etat_processus).s_arbre_variables);
213:
214: printf("===========================================================\n");
215:
216: return;
217: }
218:
219:
220: /*
221: ================================================================================
222: Routine de création d'une nouvelle variable
223: ================================================================================
224: Entrée : autorisation_creation_variable_statique vaut 'v' ou 's'.
225: dans le cas 'v', la variable est volatile.
226: dans le cas 's', elle est statique.
227: Entrée : autorisation_creation_variable_partagee vaut 'p' ou 's'.
228: dans le cas 'p', la variable est privée.
229: dans le cas 's', elle est partagée.
230: --------------------------------------------------------------------------------
231: Sortie :
232: --------------------------------------------------------------------------------
233: Effets de bords : néant
234: ================================================================================
235: */
236:
237: static logical1
238: ajout_variable(struct_processus *s_etat_processus, struct_variable *s_variable)
239: {
240: int i;
241:
242: logical1 niveau_acceptable;
243:
244: struct_liste_variables *l_nouvelle_variable;
245: struct_liste_variables *l_variable_candidate;
246:
247: struct_arbre_variables *l_variable_courante;
248: struct_arbre_variables *l_variable_precedente;
249:
250: struct_liste_chainee *l_nouvel_element;
251:
252: unsigned char *ptr;
253:
254: void *pointeur_variable_cree;
255:
256: if ((*s_etat_processus).s_arbre_variables == NULL)
257: {
258: if (((*s_etat_processus).s_arbre_variables =
259: malloc(sizeof(struct_arbre_variables))) == NULL)
260: {
261: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
262: return(d_erreur);
263: }
264:
265: (*(*s_etat_processus).s_arbre_variables).feuille = NULL;
266: (*(*s_etat_processus).s_arbre_variables).noeuds_utilises = 0;
267: (*(*s_etat_processus).s_arbre_variables).indice_tableau_pere = -1;
268: (*(*s_etat_processus).s_arbre_variables).noeud_pere = NULL;
269:
270: if (((*(*s_etat_processus).s_arbre_variables).noeuds =
271: malloc((*s_etat_processus).nombre_caracteres_variables
272: * sizeof(struct_arbre_variables))) == NULL)
273: {
274: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
275: return(d_erreur);
276: }
277:
278: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
279: {
280: (*(*s_etat_processus).s_arbre_variables).noeuds[i] = NULL;
281: }
282: }
283:
284: l_variable_precedente = NULL;
285: l_variable_courante = (*s_etat_processus).s_arbre_variables;
286: ptr = (*s_variable).nom;
287:
288: while((*ptr) != d_code_fin_chaine)
289: {
290: BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
291: printf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
292: *ptr));
293:
294: if ((*l_variable_courante).noeuds[(*s_etat_processus)
295: .pointeurs_caracteres_variables[*ptr]] == NULL)
296: {
297: // Le noeud n'existe pas encore, on le crée et on le marque
298: // comme utilisé dans la structure parente.
299:
300: if (((*l_variable_courante).noeuds[(*s_etat_processus)
301: .pointeurs_caracteres_variables[*ptr]] =
302: malloc(sizeof(struct_arbre_variables))) == NULL)
303: {
304: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
305: return(d_erreur);
306: }
307:
308: (*l_variable_courante).noeuds_utilises++;
309:
310: // La feuille est par défaut vide et aucun élément du tableau noeuds
311: // (les branches qui peuvent être issues de ce nouveau noeud)
312: // n'est encore utilisée.
313:
314: (*(*l_variable_courante).noeuds[(*s_etat_processus)
315: .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
316: (*(*l_variable_courante).noeuds[(*s_etat_processus)
317: .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
318:
319: // Le champ noeud_pere de la structure créée pointe sur
320: // la structure parente et l'indice tableau_pere correspond à la
321: // position réelle dans le tableau noeuds[] de la structure parente
322: // du noeud courant. Cette valeur sera utilisée lors de la
323: // destruction du noeud pour annuler le pointeur contenu dans
324: // le tableau noeuds[] de la structure parente.
325:
326: (*(*l_variable_courante).noeuds[(*s_etat_processus)
327: .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
328: l_variable_courante;
329: (*(*l_variable_courante).noeuds[(*s_etat_processus)
330: .pointeurs_caracteres_variables[*ptr]])
331: .indice_tableau_pere = (*s_etat_processus)
332: .pointeurs_caracteres_variables[*ptr];
333:
334: // Allocation du tableau noeuds[] et initialisation à zéro de
335: // tous les pointeurs.
336:
337: if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
338: .pointeurs_caracteres_variables[*ptr]]).noeuds =
339: malloc((*s_etat_processus).nombre_caracteres_variables
340: * sizeof(struct_arbre_variables))) == NULL)
341: {
342: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
343: return(d_erreur);
344: }
345:
346: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
347: {
348: (*(*l_variable_courante).noeuds[(*s_etat_processus)
349: .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
350: = NULL;
351: }
352: }
353:
354: l_variable_precedente = l_variable_courante;
355: l_variable_courante = (*l_variable_courante).noeuds
356: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
357: ptr++;
358: }
359:
360: if ((*l_variable_courante).feuille == NULL)
361: {
362: // Aucune variable de même nom préexiste. On alloue le premier
363: // élément de la liste doublement chaînée contenant toutes les
364: // variables de même nom. Cette liste boucle en premier lieu sur
365: // elle-même.
366:
367: if (((*l_variable_courante).feuille = malloc(
368: sizeof(struct_liste_variables))) == NULL)
369: {
370: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
371: return(d_erreur);
372: }
373:
374: (*l_variable_courante).noeuds_utilises++;
375:
376: (*(*l_variable_courante).feuille).suivant =
377: (*l_variable_courante).feuille;
378: (*(*l_variable_courante).feuille).precedent =
379: (*l_variable_courante).feuille;
380: (*(*l_variable_courante).feuille).noeud_pere = l_variable_precedente;
381: (*(*l_variable_courante).feuille).noeud = l_variable_courante;
382:
383: // Allocation de la variable sur l'élément de la liste.
384:
385: if (((*(*l_variable_courante).feuille).variable =
386: malloc(sizeof(struct_variable))) == NULL)
387: {
388: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
389: return(d_erreur);
390: }
391:
392: (*((struct_variable *) (*(*l_variable_courante).feuille).variable)) =
393: (*s_variable);
394: pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
395: }
396: else
397: {
398: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
399: == NULL)
400: {
401: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
402: return(d_erreur);
403: }
404:
405: if ((*s_variable).niveau > 1)
406: {
407: // Cas d'une variable locale
408:
409: // Si le niveau de la dernière variable de même nom est
410: // supérieur au niveau de la variable locale que l'on veut
411: // enregistrer dans la liste, cette liste est incohérente.
412:
413: BUG((*(*(*l_variable_courante).feuille).variable).niveau >=
414: (*s_variable).niveau,
415: printf("Variable=\"%s\"\n", (*s_variable).nom));
416:
417: // On ajoute la variable à la liste existante.
418:
419: (*l_nouvelle_variable).suivant = (*l_variable_courante).feuille;
420: (*l_nouvelle_variable).precedent = (*(*l_variable_courante).feuille)
421: .precedent;
422: (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
423: (*l_nouvelle_variable).noeud = l_variable_courante;
424: (*(*(*l_variable_courante).feuille).precedent).suivant =
425: l_nouvelle_variable;
426: (*(*l_variable_courante).feuille).precedent =
427: l_nouvelle_variable;
428: (*l_variable_courante).feuille = l_nouvelle_variable;
429:
430: if (((*(*l_variable_courante).feuille).variable =
431: malloc(sizeof(struct_variable))) == NULL)
432: {
433: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
434: return(d_erreur);
435: }
436:
437: (*((struct_variable *) (*(*l_variable_courante).feuille).variable))
438: = (*s_variable);
439: pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
440: }
441: else
442: {
443: // Cas d'une variable globale (niveau 0 [définitions] ou 1
444: // [variables globales])
445:
446: l_variable_candidate = (*l_variable_courante).feuille;
447:
448: do
449: {
450: // S'il y a déjà une variable de même niveau, la pile
451: // est incohérente.
452:
453: BUG((*(*l_variable_candidate).variable).niveau ==
454: (*s_variable).niveau,
455: printf("Variable=\"%s\"\n", (*s_variable).nom));
456:
457: l_variable_candidate = (*l_variable_candidate).precedent;
458: } while((l_variable_candidate != (*l_variable_courante).feuille) &&
459: ((*(*l_variable_candidate).variable).niveau <= 1));
460:
461: BUG((*s_variable).niveau == 0,
462: uprintf("Attempt to create a level-0 variable!\n"));
463:
464: if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
465: .niveau > 1)
466: {
467: // La variable précédente est de niveau strictement supérieur
468: // à 1. Il ne peut donc y avoir aucune variable de niveau
469: // inférieur ou égal à 1 puisque la boucle est triée.
470: // On insère donc directement la variable en queue.
471: }
472: else
473: {
474: // Le niveau de la variable précédente dans la boucle est
475: // inférieur ou égal à 1.
476: l_variable_candidate = (*(*l_variable_courante).feuille)
477: .precedent;
478: }
479:
480: (*l_nouvelle_variable).suivant = l_variable_candidate;
481: (*l_nouvelle_variable).precedent = (*l_variable_candidate)
482: .precedent;
483: (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
484: (*l_nouvelle_variable).noeud = l_variable_courante;
485: (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
486: (*l_variable_candidate).precedent = l_nouvelle_variable;
487:
488: // Si la variable suivant la variable que l'on vient d'insérer
489: // dans la boucle est de niveau 0, la variable insérée est par
490: // construction de niveau 1 et il convient de modifier le
491: // pointeur de feuille pointant sur l'élément de plus haut niveau
492: // de la boucle.
493:
494: if ((*(*(*l_nouvelle_variable).precedent).variable).niveau == 0)
495: {
496: (*(*l_nouvelle_variable).noeud).feuille = l_nouvelle_variable;
497: }
498:
499: if (((*l_nouvelle_variable).variable =
500: malloc(sizeof(struct_variable))) == NULL)
501: {
502: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
503: return(d_erreur);
504: }
505:
506: (*(*l_nouvelle_variable).variable) = (*s_variable);
507: pointeur_variable_cree = (*l_nouvelle_variable).variable;
508: }
509: }
510:
511: // Ajout de la variable nouvellement créée à la liste par niveaux.
512: // Le pointeur contenu dans la structure de description du processus indique
513: // toujours le plus haut niveau utilisé.
514:
515: if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
516: {
517: // Le niveau courant n'existe pas. Il est créé.
518:
519: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
520: == NULL)
521: {
522: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
523: return(d_erreur);
524: }
525:
526: (*l_nouvelle_variable).suivant = l_nouvelle_variable;
527: (*l_nouvelle_variable).precedent = l_nouvelle_variable;
528: (*l_nouvelle_variable).noeud_pere = NULL;
529: (*l_nouvelle_variable).liste = NULL;
530:
531: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
532:
533: // Ajout de la variable en tête de la liste
534:
535: if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
536: {
537: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
538: return(d_erreur);
539: }
540:
541: (*l_nouvel_element).suivant = (*(*s_etat_processus)
542: .l_liste_variables_par_niveau).liste;
543: (*l_nouvel_element).donnee = pointeur_variable_cree;
544: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
545: l_nouvel_element;
546: }
547: else if ((*s_variable).niveau > (*((struct_variable *)
548: (*(*(*s_etat_processus).l_liste_variables_par_niveau).liste)
549: .donnee)).niveau)
550: {
551: // Le niveau courant n'existe pas. Il est créé.
552:
553: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
554: == NULL)
555: {
556: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
557: return(d_erreur);
558: }
559:
560: (*l_nouvelle_variable).suivant = (*s_etat_processus)
561: .l_liste_variables_par_niveau;
562: (*l_nouvelle_variable).precedent = (*(*s_etat_processus)
563: .l_liste_variables_par_niveau).precedent;
564: (*l_nouvelle_variable).noeud_pere = NULL;
565: (*l_nouvelle_variable).liste = NULL;
566: (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent)
567: .suivant = l_nouvelle_variable;
568: (*(*s_etat_processus).l_liste_variables_par_niveau)
569: .precedent = l_nouvelle_variable;
570:
571: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
572:
573: // Ajout de la variable en tête de la liste
574:
575: if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
576: {
577: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
578: return(d_erreur);
579: }
580:
581: (*l_nouvel_element).suivant = (*(*s_etat_processus)
582: .l_liste_variables_par_niveau).liste;
583: (*l_nouvel_element).donnee = pointeur_variable_cree;
584: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
585: l_nouvel_element;
586: }
587: else if ((*s_variable).niveau <= 1)
588: {
589: // Création d'une variable de niveau 0 ou 1. Il convient de
590: // chercher dans la liste si un niveau 0 ou 1 préexiste. Pour cela, on
591: // regarde la position courante et les deux précédentes.
592:
593: l_variable_candidate = (*s_etat_processus).l_liste_variables_par_niveau;
594: niveau_acceptable = d_faux;
595:
596: for(i = 0; i <= 2; i++)
597: {
598: if ((*l_variable_candidate).liste == NULL)
599: {
600: continue;
601: }
602:
603: if ((*((struct_variable *) (*(*l_variable_candidate)
604: .liste).donnee)).niveau == (*s_variable).niveau)
605: {
606: niveau_acceptable = d_vrai;
607: break;
608: }
609:
610: l_variable_candidate = (*l_variable_candidate).precedent;
611: }
612:
613: if (niveau_acceptable == d_faux)
614: {
615: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
616: == NULL)
617: {
618: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
619: return(d_erreur);
620: }
621:
622: l_variable_candidate =
623: (*(*s_etat_processus).l_liste_variables_par_niveau)
624: .precedent;
625:
626: // On ne peut créer qu'une variable de niveau supérieur ou égal à
627: // 1 lors de l'exécution normale d'un programme. Les variables
628: // de niveau 0 sont créées à l'initialisation et relèvent du
629: // cas précédent car il n'existe lors de leur création aucun
630: // niveau non nul.
631:
632: BUG((*s_variable).niveau == 0,
633: uprintf("Attempt to create a level-0 variable!\n"));
634:
635: (*l_nouvelle_variable).suivant = l_variable_candidate;
636: (*l_nouvelle_variable).precedent = (*l_variable_candidate)
637: .precedent;
638: (*l_nouvelle_variable).noeud_pere = NULL;
639: (*l_nouvelle_variable).liste = NULL;
640: (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
641: (*l_variable_candidate).precedent = l_nouvelle_variable;
642:
643: l_variable_candidate = l_nouvelle_variable;
644: }
645:
646: // Ajout de la variable en tête de la liste l_variable_candidate.
647:
648: if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
649: {
650: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
651: return(d_erreur);
652: }
653:
654: (*l_nouvel_element).suivant = (*l_variable_candidate).liste;
655: (*l_nouvel_element).donnee = pointeur_variable_cree;
656: (*l_variable_candidate).liste = l_nouvel_element;
657: }
658: else
659: {
660: // Ajout de la variable en tête de la liste
661:
662: if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
663: {
664: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
665: return(d_erreur);
666: }
667:
668: (*l_nouvel_element).suivant = (*(*s_etat_processus)
669: .l_liste_variables_par_niveau).liste;
670: (*l_nouvel_element).donnee = pointeur_variable_cree;
671: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
672: l_nouvel_element;
673: }
674:
675: return(d_absence_erreur);
676: }
677:
678:
679: logical1
680: creation_variable(struct_processus *s_etat_processus,
681: struct_variable *s_variable,
682: unsigned char autorisation_creation_variable_statique,
683: unsigned char autorisation_creation_variable_partagee)
684: {
685: if ((*s_etat_processus).mode_execution_programme == 'Y')
686: {
687: (*s_variable).origine = 'P';
688: }
689: else
690: {
691: (*s_variable).origine = 'E';
692: }
693:
694: if ((*s_variable).niveau == 0)
695: {
696: // Un point d'entrée de définition est verrouillé.
697:
698: if ((*s_variable).origine == 'P')
699: {
700: (*s_variable).variable_statique.adresse = 0;
701: (*s_variable).variable_partagee.adresse = 0;
702: }
703: else
704: {
705: (*s_variable).variable_statique.pointeur = NULL;
706: (*s_variable).variable_partagee.pointeur = NULL;
707: }
708:
709: (*s_variable).variable_verrouillee = d_vrai;
710: }
711: else if ((*s_variable).niveau == 1)
712: {
713: // Une variable globale ne peut être statique.
714:
715: if ((*s_variable).origine == 'P')
716: {
717: (*s_variable).variable_statique.adresse = 0;
718: (*s_variable).variable_partagee.adresse = 0;
719: }
720: else
721: {
722: (*s_variable).variable_statique.pointeur = NULL;
723: (*s_variable).variable_partagee.pointeur = NULL;
724: }
725:
726: (*s_variable).variable_verrouillee = d_faux;
727: }
728: else
729: {
730: // 0 -> variable volatile
731: // adresse de création -> variable statique
732:
733: if (autorisation_creation_variable_statique == 'V')
734: {
735: if (autorisation_creation_variable_partagee == 'S')
736: {
737: // On force la création d'une variable partagée
738:
739: if ((*s_variable).origine == 'P')
740: {
741: (*s_variable).variable_statique.adresse = 0;
742: (*s_variable).variable_partagee.adresse =
743: (*s_etat_processus).position_courante;
744: }
745: else
746: {
747: (*s_variable).variable_statique.pointeur = NULL;
748: (*s_variable).variable_partagee.pointeur =
749: (*s_etat_processus).objet_courant;
750: }
751: }
752: else
753: {
754: // On force la création d'une variable volatile
755:
756: if ((*s_variable).origine == 'P')
757: {
758: (*s_variable).variable_statique.adresse = 0;
759: (*s_variable).variable_partagee.adresse = 0;
760: }
761: else
762: {
763: (*s_variable).variable_statique.pointeur = NULL;
764: (*s_variable).variable_partagee.pointeur = NULL;
765: }
766: }
767: }
768: else
769: {
770: // On force la création d'une variable statique.
771:
772: if ((*s_variable).origine == 'P')
773: {
774: (*s_variable).variable_statique.adresse =
775: (*s_etat_processus).position_courante;
776: (*s_variable).variable_partagee.adresse = 0;
777: }
778: else
779: {
780: (*s_variable).variable_statique.pointeur =
781: (*s_etat_processus).objet_courant;
782: (*s_variable).variable_partagee.pointeur = 0;
783: }
784: }
785:
786: (*s_variable).variable_verrouillee = d_faux;
787: }
788:
789: /*
790: * Recherche de la feuille correspondante dans l'arbre des variables.
791: * Si cette feuille n'existe pas, elle est créée.
792: */
793:
794: if (ajout_variable(s_etat_processus, s_variable) == d_erreur)
795: {
796: return(d_erreur);
797: }
798:
799: return(d_absence_erreur);
800: }
801:
802:
803: /*
804: ================================================================================
805: Procédure de recherche d'une variable par son nom dans la base
806: ================================================================================
807: Entrée :
808: --------------------------------------------------------------------------------
809: Sortie :
810: --------------------------------------------------------------------------------
811: Effets de bord : néant
812: ================================================================================
813: */
814:
815: logical1
816: recherche_variable(struct_processus *s_etat_processus,
817: unsigned char *nom_variable)
818: {
819: int pointeur;
820:
821: struct_arbre_variables *l_variable_courante;
822: struct_liste_pile_systeme *l_element_courant;
823:
824: unsigned char *ptr;
825:
826: unsigned long niveau_appel;
827:
828: if ((*s_etat_processus).s_arbre_variables == NULL)
829: {
830: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
831: return(d_faux);
832: }
833:
834: l_variable_courante = (*s_etat_processus).s_arbre_variables;
835: ptr = nom_variable;
836:
837: while((*ptr) != d_code_fin_chaine)
838: {
839: pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
840:
841: if (pointeur < 0)
842: {
843: // Caractère hors de l'alphabet des variables
844:
845: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
846: return(d_faux);
847: }
848:
849: if ((*l_variable_courante).noeuds[pointeur] == NULL)
850: {
851: // Le chemin de la variable candidate n'existe pas.
852: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
853: return(d_faux);
854: }
855:
856: l_variable_courante = (*l_variable_courante).noeuds[pointeur];
857: ptr++;
858: }
859:
860: if ((*l_variable_courante).feuille != NULL)
861: {
862: // Il existe une pile de variables de même nom. Le sommet de la
863: // pile est la variable de niveau le plus haut.
864:
865: l_element_courant = (*s_etat_processus).l_base_pile_systeme;
866:
867: if (l_element_courant == NULL)
868: {
869: // Problème : la pile système est vide !
870: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
871: return(d_faux);
872: }
873:
874: while((*l_element_courant).retour_definition != 'Y')
875: {
876: l_element_courant = (*l_element_courant).suivant;
877:
878: if (l_element_courant == NULL)
879: {
880: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
881: return(d_faux);
882: }
883: }
884:
885: niveau_appel = (*l_element_courant).niveau_courant;
886:
887: if (niveau_appel < (*(*(*l_variable_courante).feuille).variable).niveau)
888: {
889: // Une variable locale est accessible puisque créée dans la
890: // fonction courante.
891:
892: (*s_etat_processus).pointeur_variable_courante =
893: (*(*l_variable_courante).feuille).variable;
894: (*s_etat_processus).pointeur_feuille_courante =
895: (*l_variable_courante).feuille;
896: return(d_vrai);
897: }
898: else
899: {
900: // Aucune variable locale n'est accessible depuis la fonction.
901: // Dans ce cas, on prend la variable de niveau le plus bas
902: // si ce niveau est inférieur ou égal à 1 (variable globale
903: // ou fonction définie par l'utilisateur). Si le niveau de la
904: // plus ancienne variable est strictement supérieur à 1, il
905: // s'agit d'une variable locale inaccessible.
906:
907: if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
908: .niveau <= 1)
909: {
910: (*s_etat_processus).pointeur_variable_courante =
911: (*(*(*l_variable_courante).feuille).precedent).variable;
912: (*s_etat_processus).pointeur_feuille_courante =
913: (*(*l_variable_courante).feuille).precedent;
914:
915: // S'il existe une variable de niveau 0 et une seconde de
916: // niveau 1, la variable de niveau 0 (fonction) est masquée
917: // par celle de niveau 1.
918:
919: if (((*(*(*(*l_variable_courante).feuille).precedent)
920: .variable).niveau == 0) && ((*(*(*(*
921: (*l_variable_courante).feuille).precedent).precedent)
922: .variable).niveau == 1))
923: {
924: (*s_etat_processus).pointeur_variable_courante =
925: (*(*(*(*l_variable_courante).feuille).precedent)
926: .precedent).variable;
927: (*s_etat_processus).pointeur_feuille_courante =
928: (*(*(*l_variable_courante).feuille).precedent)
929: .precedent;
930: }
931:
932: return(d_vrai);
933: }
934: }
935: }
936:
937: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
938: return(d_faux);
939: }
940:
941:
942: logical1
943: recherche_variable_globale(struct_processus *s_etat_processus,
944: unsigned char *nom)
945: {
946: logical1 presence_variable;
947:
948: presence_variable = recherche_variable(s_etat_processus, nom);
949:
950: if (presence_variable == d_vrai)
951: {
952: switch((*(*s_etat_processus).pointeur_variable_courante).niveau)
953: {
954: case 0:
955: {
956: // La variable est une définition.
957: presence_variable = d_faux;
958: break;
959: }
960:
961: case 1:
962: {
963: break;
964: }
965:
966: default:
967: {
968: if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
969: .precedent).variable).niveau == 1)
970: {
971: (*s_etat_processus).pointeur_feuille_courante =
972: (*(*s_etat_processus).pointeur_feuille_courante)
973: .precedent;
974: (*s_etat_processus).pointeur_variable_courante =
975: (*(*s_etat_processus).pointeur_feuille_courante)
976: .variable;
977: }
978: else if ((*(*(*(*(*s_etat_processus).pointeur_feuille_courante)
979: .precedent).precedent).variable).niveau == 1)
980: {
981: (*s_etat_processus).pointeur_feuille_courante =
982: (*(*(*s_etat_processus).pointeur_feuille_courante)
983: .precedent).precedent;
984: (*s_etat_processus).pointeur_variable_courante =
985: (*(*s_etat_processus).pointeur_feuille_courante)
986: .variable;
987: }
988: else
989: {
990: presence_variable = d_faux;
991: }
992:
993: break;
994: }
995: }
996: }
997:
998: if (presence_variable == d_vrai)
999: {
1000: if ((*(*s_etat_processus).pointeur_variable_courante).objet == NULL)
1001: {
1002: // La variable n'est pas globale, elle est partagée.
1003: presence_variable = d_faux;
1004: (*s_etat_processus).erreur_execution = d_ex_variable_partagee;
1005: }
1006: }
1007:
1008: return(presence_variable);
1009: }
1010:
1011:
1012: /*
1013: ================================================================================
1014: Procédure de retrait d'une variable de la base
1015: ================================================================================
1016: Entrée : type 'G' ou 'L' selon que l'on retire une variable locale (incluant
1017: les globales) ou strictement globale.
1018: --------------------------------------------------------------------------------
1019: Sortie :
1020: --------------------------------------------------------------------------------
1021: Effets de bord : néant
1022: ================================================================================
1023: */
1024:
1025: logical1
1026: retrait_variable(struct_processus *s_etat_processus,
1027: unsigned char *nom_variable, unsigned char type)
1028: {
1029: logical1 erreur;
1030: logical1 variable_supprimee;
1031:
1032: struct_arbre_variables *s_arbre_a_supprimer;
1033: struct_arbre_variables *s_arbre_courant;
1034:
1035: struct_liste_chainee *l_element_courant;
1036: struct_liste_chainee *l_element_precedent;
1037:
1038: struct_liste_variables *variable_a_supprimer;
1039: struct_liste_variables *variables_par_niveau;
1040:
1041: unsigned long niveau;
1042:
1043: (*s_etat_processus).niveau_supprime = d_faux;
1044:
1045: if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
1046: {
1047: // Une variable correspondant au nom recherché est accessible.
1048:
1049: if (type == 'G')
1050: {
1051: if ((*(*s_etat_processus).pointeur_variable_courante).niveau > 1)
1052: {
1053: // La variable obtenue est une variable locale. il faut
1054: // s'assurer qu'il existe une variable de niveau 1 de même
1055: // nom sur la feuille.
1056:
1057: if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
1058: .precedent).variable).niveau <= 1)
1059: {
1060: (*s_etat_processus).pointeur_feuille_courante =
1061: (*(*s_etat_processus).pointeur_feuille_courante)
1062: .precedent;
1063: (*s_etat_processus).pointeur_variable_courante =
1064: (*(*s_etat_processus).pointeur_feuille_courante)
1065: .variable;
1066:
1067: // Si la variable retournée est de niveau 0, on regarde
1068: // un peu plus loin si une variable de niveau 1 existe.
1069:
1070: if (((*(*(*s_etat_processus).pointeur_feuille_courante)
1071: .variable).niveau == 0) &&
1072: ((*(*(*(*s_etat_processus)
1073: .pointeur_feuille_courante).precedent).variable)
1074: .niveau == 1))
1075: {
1076: (*s_etat_processus).pointeur_feuille_courante =
1077: (*(*s_etat_processus).pointeur_feuille_courante)
1078: .precedent;
1079: (*s_etat_processus).pointeur_variable_courante =
1080: (*(*s_etat_processus).pointeur_feuille_courante)
1081: .variable;
1082: }
1083: }
1084: else
1085: {
1086: // Aucune variable globale (niveau 1) n'existe.
1087:
1088: erreur = d_erreur;
1089: (*s_etat_processus).erreur_execution =
1090: d_ex_variable_non_definie;
1091: return(erreur);
1092: }
1093: }
1094:
1095: if ((*(*s_etat_processus).pointeur_variable_courante)
1096: .variable_verrouillee == d_vrai)
1097: {
1098: erreur = d_erreur;
1099: (*s_etat_processus).erreur_execution =
1100: d_ex_variable_verrouillee;
1101: return(erreur);
1102: }
1103: }
1104:
1105: // Suppression de la variable de la liste.
1106: // Deux cas peuvent survenir :
1107: // 1/ les pointeurs sur la variable et la variable suivante
1108: // sont identiques et on supprime la variable ainsi que la feuille
1109: // associée ;
1110: // 2/ ces deux pointeurs sont différents et se contente de retirer
1111: // la structure décrivant la variable.
1112:
1113: if ((*s_etat_processus).pointeur_feuille_courante ==
1114: (*(*s_etat_processus).pointeur_feuille_courante).suivant)
1115: {
1116: // Cas 1 :
1117: // On retire la variable du noeud en décrémentant le nombre
1118: // de feuilles de ce noeud. Si le nombre de feuilles du noeud
1119: // est nul, on retire les noeuds récursivement jusqu'à obtenir
1120: // un nombre non nul de feuilles utilisées (ou la racine des
1121: // variables).
1122:
1123: variable_a_supprimer = (*s_etat_processus)
1124: .pointeur_feuille_courante;
1125: //s_arbre_courant = (*variable_a_supprimer).noeud_pere;
1126: s_arbre_courant = (*variable_a_supprimer).noeud;
1127: BUG((*s_arbre_courant).noeuds_utilises == 0,
1128: uprintf("Freed node !\n"));
1129: (*s_arbre_courant).noeuds_utilises--;
1130:
1131: (*((*(*variable_a_supprimer).noeud_pere).noeuds
1132: [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
1133: .feuille = NULL;
1134:
1135: while((*s_arbre_courant).noeuds_utilises == 0)
1136: {
1137: s_arbre_a_supprimer = s_arbre_courant;
1138: s_arbre_courant = (*s_arbre_courant).noeud_pere;
1139:
1140: if (s_arbre_courant == NULL)
1141: {
1142: free((*s_arbre_a_supprimer).noeuds);
1143: free(s_arbre_a_supprimer);
1144:
1145: (*s_etat_processus).s_arbre_variables = NULL;
1146: break;
1147: }
1148:
1149: // s_arbre_a_supprimer contient la structure de feuille qui
1150: // vient d'être libérée. Il s'agit maintenant
1151: // d'annuler le pointeur dans le tableau noeuds de la structure
1152: // pointée par noeud_pere, soit s_arbre_courant.
1153:
1154: BUG((*s_arbre_a_supprimer).indice_tableau_pere < 0,
1155: uprintf("Invalid pointer !\n"));
1156: (*s_arbre_courant).noeuds[(*s_arbre_a_supprimer)
1157: .indice_tableau_pere] = NULL;
1158:
1159: free((*s_arbre_a_supprimer).noeuds);
1160: free(s_arbre_a_supprimer);
1161:
1162: BUG((*s_arbre_courant).noeuds_utilises == 0,
1163: uprintf("Freed node !\n"));
1164: (*s_arbre_courant).noeuds_utilises--;
1165: }
1166: }
1167: else
1168: {
1169: // Cas 2 :
1170: // On retire la variable de la liste.
1171:
1172: variable_a_supprimer = (*s_etat_processus)
1173: .pointeur_feuille_courante;
1174:
1175: (*(*(*s_etat_processus).pointeur_feuille_courante).precedent)
1176: .suivant = (*(*s_etat_processus).pointeur_feuille_courante)
1177: .suivant;
1178: (*(*(*s_etat_processus).pointeur_feuille_courante).suivant)
1179: .precedent = (*(*s_etat_processus)
1180: .pointeur_feuille_courante).precedent;
1181:
1182: // Mise à jour du pointeur dans l'arbre des variables. Cette
1183: // mise à jour n'est nécessaire que dans le cas où la variable
1184: // supprimée est en tête de la liste.
1185:
1186: if (variable_a_supprimer == (*((*(*variable_a_supprimer).noeud_pere)
1187: .noeuds[(*(*variable_a_supprimer).noeud)
1188: .indice_tableau_pere])).feuille)
1189: {
1190: (*((*(*variable_a_supprimer).noeud_pere).noeuds
1191: [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
1192: .feuille = (*(*((*(*variable_a_supprimer).noeud_pere)
1193: .noeuds[(*(*variable_a_supprimer).noeud)
1194: .indice_tableau_pere])).feuille).suivant;
1195: }
1196:
1197: (*s_etat_processus).pointeur_feuille_courante =
1198: (*(*s_etat_processus).pointeur_feuille_courante).suivant;
1199: (*s_etat_processus).pointeur_variable_courante =
1200: (*(*s_etat_processus).pointeur_feuille_courante).variable;
1201: }
1202:
1203: // Dans tous les cas, on retire la variable de la liste des variables
1204: // par niveau.
1205:
1206: niveau = (*(*variable_a_supprimer).variable).niveau;
1207: variables_par_niveau = (*s_etat_processus).l_liste_variables_par_niveau;
1208: variable_supprimee = d_faux;
1209:
1210: if (variables_par_niveau != NULL)
1211: {
1212: do
1213: {
1214: l_element_courant = (*variables_par_niveau).liste;
1215:
1216: if (l_element_courant != NULL)
1217: {
1218: if ((*((struct_variable *) (*l_element_courant).donnee))
1219: .niveau == niveau)
1220: {
1221: // On parcourt le bon niveau.
1222:
1223: l_element_precedent = NULL;
1224:
1225: while(l_element_courant != NULL)
1226: {
1227: // Tant que l_element_courant est non nul, il reste
1228: // des variables à explorer dans le niveau courant.
1229:
1230: if ((*l_element_courant).donnee ==
1231: (void *) (*variable_a_supprimer).variable)
1232: {
1233: // On a trouvé la variable à supprimer.
1234:
1235: if (l_element_precedent == NULL)
1236: {
1237: (*variables_par_niveau).liste =
1238: (*l_element_courant).suivant;
1239: }
1240: else
1241: {
1242: (*l_element_precedent).suivant =
1243: (*l_element_courant).suivant;
1244: }
1245:
1246: free(l_element_courant);
1247:
1248: if ((*variables_par_niveau).liste == NULL)
1249: {
1250: (*s_etat_processus).niveau_supprime =
1251: d_vrai;
1252:
1253: if ((*s_etat_processus)
1254: .l_liste_variables_par_niveau
1255: == variables_par_niveau)
1256: {
1257: // On retire l'élément de la liste
1258: // pointé par
1259: // l_liste_variable_par_niveau
1260:
1261: (*s_etat_processus)
1262: .l_liste_variables_par_niveau =
1263: (*variables_par_niveau).suivant;
1264: }
1265:
1266: (*(*variables_par_niveau).precedent)
1267: .suivant =
1268: (*variables_par_niveau).suivant;
1269: (*(*variables_par_niveau).suivant)
1270: .precedent =
1271: (*variables_par_niveau)
1272: .precedent;
1273: free(variables_par_niveau);
1274: }
1275:
1276: variable_supprimee = d_vrai;
1277: break;
1278: }
1279:
1280: l_element_precedent = l_element_courant;
1281: l_element_courant = (*l_element_courant).suivant;
1282: }
1283: }
1284: }
1285:
1286: if (variable_supprimee == d_vrai)
1287: {
1288: break;
1289: }
1290:
1291: variables_par_niveau = (*variables_par_niveau).suivant;
1292:
1293: } while(variables_par_niveau != (*s_etat_processus)
1294: .l_liste_variables_par_niveau);
1295: }
1296:
1297: // Puis on libère le contenu de la variable.
1298:
1299: free((*(*variable_a_supprimer).variable).nom);
1300: liberation(s_etat_processus, (*(*variable_a_supprimer).variable).objet);
1301: free((*variable_a_supprimer).variable);
1302: free(variable_a_supprimer);
1303:
1304: erreur = d_absence_erreur;
1305: }
1306: else
1307: {
1308: // Aucune variable n'est accessible depuis le point courant du
1309: // programme.
1310:
1311: erreur = d_erreur;
1312: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1313: }
1314:
1315: return(erreur);
1316: }
1317:
1318:
1319: /*
1320: ================================================================================
1321: Procédure de retrait des variables de niveau strictement supérieur au
1322: niveau courant
1323: ================================================================================
1324: Entrée :
1325: --------------------------------------------------------------------------------
1326: Sortie :
1327: --------------------------------------------------------------------------------
1328: Effets de bord : néant
1329: ================================================================================
1330: */
1331:
1332: logical1
1333: retrait_variable_par_niveau(struct_processus *s_etat_processus)
1334: {
1335: struct_liste_variables *l_element_a_supprimer;
1336:
1337: // Utilisation du champ (*s_etat_processus).liste_variables_par_niveau.
1338: // La tête de la pile contient toujours les variables de plus haut niveau
1339: // créées.
1340:
1341: while((*s_etat_processus).l_liste_variables_par_niveau != NULL)
1342: {
1343: if ((*(*s_etat_processus).l_liste_variables_par_niveau).liste == NULL)
1344: {
1345: // Si le niveau ne contient aucune variable, on le détruit.
1346: // Le pointeur sur la chaîne est déjà nul et il ne reste rien à
1347: // faire.
1348: }
1349: else
1350: {
1351: // Le niveau contient des variables.
1352:
1353: if ((*((struct_variable *) (*(*(*s_etat_processus)
1354: .l_liste_variables_par_niveau).liste).donnee)).niveau
1355: <= (*s_etat_processus).niveau_courant)
1356: {
1357: // On a retiré de l'arbre des variables toutes les
1358: // variables de niveau strictement supérieur au niveau
1359: // courant.
1360:
1361: break;
1362: }
1363:
1364: while((*(*s_etat_processus).l_liste_variables_par_niveau).liste
1365: != NULL)
1366: {
1367: // Nécessaire car le pointeur sur la tête de la pile
1368: // peut être modifié par retrait_variable().
1369: // Sauvegarde des variables statiques.
1370:
1371: if ((*((struct_variable *) (*(*(*s_etat_processus)
1372: .l_liste_variables_par_niveau).liste).donnee)).origine
1373: == 'P')
1374: {
1375: if ((*((struct_variable *) (*(*(*s_etat_processus)
1376: .l_liste_variables_par_niveau).liste).donnee))
1377: .variable_statique.adresse != 0)
1378: {
1379: if (recherche_variable_statique(s_etat_processus,
1380: (*((struct_variable *) (*(*(*s_etat_processus)
1381: .l_liste_variables_par_niveau).liste).donnee))
1382: .nom, (*((struct_variable *)
1383: (*(*(*s_etat_processus)
1384: .l_liste_variables_par_niveau).liste).donnee))
1385: .variable_statique, ((*s_etat_processus)
1386: .mode_execution_programme
1387: == 'Y') ? 'P' : 'E') == d_vrai)
1388: {
1389: (*s_etat_processus).s_liste_variables_statiques
1390: [(*s_etat_processus)
1391: .position_variable_statique_courante]
1392: .objet = (*((struct_variable *)
1393: (*(*(*s_etat_processus)
1394: .l_liste_variables_par_niveau).liste)
1395: .donnee)).objet;
1396: }
1397: else
1398: {
1399: (*s_etat_processus).erreur_systeme =
1400: d_es_variable_introuvable;
1401: }
1402:
1403: (*((struct_variable *) (*(*(*s_etat_processus)
1404: .l_liste_variables_par_niveau).liste).donnee))
1405: .objet = NULL;
1406: }
1407: }
1408: else
1409: {
1410: if ((*((struct_variable *) (*(*(*s_etat_processus)
1411: .l_liste_variables_par_niveau).liste).donnee))
1412: .variable_statique.pointeur != NULL)
1413: {
1414: /*
1415: * Gestion des variables statiques
1416: */
1417:
1418: if (recherche_variable_statique(s_etat_processus,
1419: (*((struct_variable *) (*(*(*s_etat_processus)
1420: .l_liste_variables_par_niveau).liste).donnee))
1421: .nom, (*((struct_variable *)
1422: (*(*(*s_etat_processus)
1423: .l_liste_variables_par_niveau).liste).donnee))
1424: .variable_statique, ((*s_etat_processus)
1425: .mode_execution_programme
1426: == 'Y') ? 'P' : 'E') == d_vrai)
1427: {
1428: (*s_etat_processus).s_liste_variables_statiques
1429: [(*s_etat_processus)
1430: .position_variable_statique_courante]
1431: .objet = (*((struct_variable *)
1432: (*(*(*s_etat_processus)
1433: .l_liste_variables_par_niveau).liste)
1434: .donnee)).objet;
1435: }
1436: else
1437: {
1438: (*s_etat_processus).erreur_systeme =
1439: d_es_variable_introuvable;
1440: return(d_erreur);
1441: }
1442:
1443: (*((struct_variable *) (*(*(*s_etat_processus)
1444: .l_liste_variables_par_niveau).liste).donnee))
1445: .objet = NULL;
1446: }
1447: }
1448:
1449: if (retrait_variable(s_etat_processus,
1450: (*((struct_variable *) (*(*(*s_etat_processus)
1451: .l_liste_variables_par_niveau).liste).donnee)).nom,
1452: 'L') == d_erreur)
1453: {
1454: return(d_erreur);
1455: }
1456:
1457: if ((*((struct_variable *) (*(*(*s_etat_processus)
1458: .l_liste_variables_par_niveau).liste).donnee)).niveau
1459: <= (*s_etat_processus).niveau_courant)
1460: {
1461: // On a retiré de l'arbre des variables toutes les
1462: // variables de niveau strictement supérieur au niveau
1463: // courant.
1464:
1465: return(d_absence_erreur);
1466: }
1467: }
1468: }
1469:
1470: // On retire l'élément de la liste doublement chaînée et circulaire.
1471:
1472: (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent).suivant
1473: = (*(*s_etat_processus).l_liste_variables_par_niveau).suivant;
1474: (*(*(*s_etat_processus).l_liste_variables_par_niveau).suivant).precedent
1475: = (*(*s_etat_processus).l_liste_variables_par_niveau).precedent;
1476:
1477: l_element_a_supprimer = (*s_etat_processus)
1478: .l_liste_variables_par_niveau;
1479: (*s_etat_processus).l_liste_variables_par_niveau =
1480: (*l_element_a_supprimer).suivant;
1481: free(l_element_a_supprimer);
1482: }
1483:
1484: return(d_absence_erreur);
1485: }
1486:
1487:
1488: /*
1489: ================================================================================
1490: Procédure de retrait des toutes les variables locales et globales
1491: ================================================================================
1492: Entrée : drapeau indiquant s'il faut retirer les définitions (variables
1493: de niveau 0)
1494: --------------------------------------------------------------------------------
1495: Sortie :
1496: --------------------------------------------------------------------------------
1497: Effets de bord : néant
1498: ================================================================================
1499: */
1500:
1501: void
1502: liberation_arbre_variables(struct_processus *s_etat_processus,
1503: struct_arbre_variables *arbre, logical1 retrait_definitions)
1504: {
1505: int i;
1506:
1507: struct_liste_chainee *l_element_courant_liste;
1508: struct_liste_chainee *l_element_suivant_liste;
1509:
1510: struct_liste_variables *l_element_courant;
1511: struct_liste_variables *l_element_suivant;
1512:
1513: // Libération de l'arbre des variables. Le contenu des variables n'est
1514: // pas détruit par cette opération, il sera détruit lors de la libération
1515: // de la liste des variables par niveau.
1516:
1517: if (arbre == NULL)
1518: {
1519: return;
1520: }
1521:
1522: l_element_courant = (*arbre).feuille;
1523:
1524: if (l_element_courant != NULL)
1525: {
1526: do
1527: {
1528: l_element_suivant = (*l_element_courant).suivant;
1529: free(l_element_courant);
1530: l_element_courant = l_element_suivant;
1531: } while(l_element_courant != (*arbre).feuille);
1532: }
1533:
1534: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1535: {
1536: if ((*arbre).noeuds[i] != NULL)
1537: {
1538: liberation_arbre_variables(s_etat_processus, (*arbre).noeuds[i],
1539: retrait_definitions);
1540: }
1541: }
1542:
1543: // Suppression de la liste des variables par niveau.
1544:
1545: if (arbre == (*s_etat_processus).s_arbre_variables)
1546: {
1547: l_element_courant = (*s_etat_processus).l_liste_variables_par_niveau;
1548:
1549: if (l_element_courant != NULL)
1550: {
1551: do
1552: {
1553: l_element_courant_liste = (*l_element_courant).liste;
1554:
1555: while(l_element_courant_liste != NULL)
1556: {
1557: if ((retrait_definitions == d_vrai) ||
1558: ((*((struct_variable *) (*l_element_courant_liste)
1559: .donnee)).niveau >= 1))
1560: {
1561: liberation(s_etat_processus, (*((struct_variable *)
1562: (*l_element_courant_liste).donnee)).objet);
1563: free((*((struct_variable *) (*l_element_courant_liste)
1564: .donnee)).nom);
1565: free((*l_element_courant_liste).donnee);
1566: }
1567:
1568: l_element_suivant_liste =
1569: (*l_element_courant_liste).suivant;
1570: free(l_element_courant_liste);
1571: l_element_courant_liste = l_element_suivant_liste;
1572: }
1573:
1574: l_element_suivant = (*l_element_courant).suivant;
1575: free(l_element_courant);
1576: l_element_courant = l_element_suivant;
1577: } while(l_element_courant != (*s_etat_processus)
1578: .l_liste_variables_par_niveau);
1579: }
1580: }
1581:
1582: free((*arbre).noeuds);
1583: free(arbre);
1584:
1585: return;
1586: }
1587:
1588:
1589: /*
1590: ================================================================================
1591: Procédure renvoyant les variables dans un tableau
1592: ================================================================================
1593: Entrée :
1594: --------------------------------------------------------------------------------
1595: Sortie :
1596: --------------------------------------------------------------------------------
1597: Effets de bord : néant
1598: ================================================================================
1599: */
1600:
1601: int
1602: nombre_variables(struct_processus *s_etat_processus,
1603: struct_arbre_variables *l_element_courant)
1604: {
1605: int i;
1606: int n;
1607:
1608: struct_liste_variables *l_variable;
1609:
1610: n = 0;
1611:
1612: if ((*l_element_courant).feuille != NULL)
1613: {
1614: l_variable = (*l_element_courant).feuille;
1615:
1616: do
1617: {
1618: n++;
1619: l_variable = (*l_variable).suivant;
1620: } while(l_variable != (*l_element_courant).feuille);
1621: }
1622:
1623: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1624: {
1625: if ((*l_element_courant).noeuds[i] != NULL)
1626: {
1627: n += nombre_variables(s_etat_processus,
1628: (*l_element_courant).noeuds[i]);
1629: }
1630: }
1631:
1632: return(n);
1633: }
1634:
1635: int
1636: liste_variables(struct_processus *s_etat_processus,
1637: struct_tableau_variables *tableau, int position,
1638: struct_arbre_variables *l_element_courant)
1639: {
1640: int i;
1641:
1642: struct_liste_variables *l_variable;
1643:
1644: if ((*l_element_courant).feuille != NULL)
1645: {
1646: l_variable = (*l_element_courant).feuille;
1647:
1648: do
1649: {
1650: tableau[position].origine = (*(*l_variable).variable).origine;
1651: tableau[position].nom = (*(*l_variable).variable).nom;
1652: tableau[position].niveau = (*(*l_variable).variable).niveau;
1653: tableau[position].objet = (*(*l_variable).variable).objet;
1654: tableau[position].variable_verrouillee =
1655: (*(*l_variable).variable).variable_verrouillee;
1656: tableau[position].variable_statique =
1657: (*(*l_variable).variable).variable_statique;
1658: tableau[position].variable_partagee =
1659: (*(*l_variable).variable).variable_partagee;
1660:
1661: position++;
1662: l_variable = (*l_variable).suivant;
1663: } while(l_variable != (*l_element_courant).feuille);
1664: }
1665:
1666: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1667: {
1668: if ((*l_element_courant).noeuds[i] != NULL)
1669: {
1670: position = liste_variables(s_etat_processus,
1671: tableau, position, (*l_element_courant).noeuds[i]);
1672: }
1673: }
1674:
1675: return(position);
1676: }
1677:
1678: /*
1679: ================================================================================
1680: Procédure de copie de l'arbre des variables
1681: ================================================================================
1682: Entrée :
1683: --------------------------------------------------------------------------------
1684: Sortie :
1685: --------------------------------------------------------------------------------
1686: Effets de bord : néant
1687: ================================================================================
1688: */
1689:
1690: struct_arbre_variables *
1691: copie_arbre_variables(struct_processus *s_etat_processus)
1692: {
1693: // Les définitions sont partagées entre tous les threads et ne sont pas
1694: // copiées.
1695: //
1696: // NB : on ne copie que les variables de niveaux 0 et 1, les autres
1697: // variables locales étant masquées par le processus de création de thread
1698: // ou de processus, elles sont inaccessibles.
1699:
1700: BUG(1, uprintf("Oops !\n"));
1701:
1702: return(d_absence_erreur);
1703: }
1704:
1705:
1706: /*
1707: ================================================================================
1708: Procédure d'initialisation de la table de correspondance des variables
1709: ================================================================================
1710: Entrée :
1711: --------------------------------------------------------------------------------
1712: Sortie :
1713: --------------------------------------------------------------------------------
1714: Effets de bord : néant
1715: ================================================================================
1716: */
1717:
1718: /*
1719: * Caractères autorisés dans les instructions
1720: *
1721: * 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
1722: * 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
1723: * _
1724: * 1 2 3 4 5 6 7 8 9 0
1725: */
1726:
1727: void
1728: initialisation_variables(struct_processus *s_etat_processus)
1729: {
1730: int decalage;
1731: int i;
1732: int longueur_tableau;
1733:
1734: unsigned char caractere;
1735:
1736: // Récupération de la longueur d'un unsigned char
1737:
1738: longueur_tableau = 1;
1739: decalage = 0;
1740: caractere = 1;
1741:
1742: while((1L << decalage) == (long) ((unsigned char) (caractere << decalage)))
1743: {
1744: decalage++;
1745: longueur_tableau *= 2;
1746: }
1747:
1748: if (((*s_etat_processus).pointeurs_caracteres_variables =
1749: malloc(longueur_tableau * sizeof(int))) == NULL)
1750: {
1751: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1752: return;
1753: }
1754:
1755: for(i = 0; i < longueur_tableau; i++)
1756: {
1757: (*s_etat_processus).pointeurs_caracteres_variables[i] = -1;
1758: }
1759:
1760: (*s_etat_processus).nombre_caracteres_variables = 0;
1761:
1762: #define DECLARATION_CARACTERE(c) \
1763: do { (*s_etat_processus).pointeurs_caracteres_variables[c] = \
1764: (*s_etat_processus).nombre_caracteres_variables++; } while(0)
1765:
1766: DECLARATION_CARACTERE('A');
1767: DECLARATION_CARACTERE('B');
1768: DECLARATION_CARACTERE('C');
1769: DECLARATION_CARACTERE('D');
1770: DECLARATION_CARACTERE('E');
1771: DECLARATION_CARACTERE('F');
1772: DECLARATION_CARACTERE('G');
1773: DECLARATION_CARACTERE('H');
1774: DECLARATION_CARACTERE('I');
1775: DECLARATION_CARACTERE('J');
1776: DECLARATION_CARACTERE('K');
1777: DECLARATION_CARACTERE('L');
1778: DECLARATION_CARACTERE('M');
1779: DECLARATION_CARACTERE('N');
1780: DECLARATION_CARACTERE('O');
1781: DECLARATION_CARACTERE('P');
1782: DECLARATION_CARACTERE('Q');
1783: DECLARATION_CARACTERE('R');
1784: DECLARATION_CARACTERE('S');
1785: DECLARATION_CARACTERE('T');
1786: DECLARATION_CARACTERE('U');
1787: DECLARATION_CARACTERE('V');
1788: DECLARATION_CARACTERE('W');
1789: DECLARATION_CARACTERE('X');
1790: DECLARATION_CARACTERE('Y');
1791: DECLARATION_CARACTERE('Z');
1792:
1793: DECLARATION_CARACTERE('a');
1794: DECLARATION_CARACTERE('b');
1795: DECLARATION_CARACTERE('c');
1796: DECLARATION_CARACTERE('d');
1797: DECLARATION_CARACTERE('e');
1798: DECLARATION_CARACTERE('f');
1799: DECLARATION_CARACTERE('g');
1800: DECLARATION_CARACTERE('h');
1801: DECLARATION_CARACTERE('i');
1802: DECLARATION_CARACTERE('j');
1803: DECLARATION_CARACTERE('k');
1804: DECLARATION_CARACTERE('l');
1805: DECLARATION_CARACTERE('m');
1806: DECLARATION_CARACTERE('n');
1807: DECLARATION_CARACTERE('o');
1808: DECLARATION_CARACTERE('p');
1809: DECLARATION_CARACTERE('q');
1810: DECLARATION_CARACTERE('r');
1811: DECLARATION_CARACTERE('s');
1812: DECLARATION_CARACTERE('t');
1813: DECLARATION_CARACTERE('u');
1814: DECLARATION_CARACTERE('v');
1815: DECLARATION_CARACTERE('w');
1816: DECLARATION_CARACTERE('x');
1817: DECLARATION_CARACTERE('y');
1818: DECLARATION_CARACTERE('z');
1819:
1820: DECLARATION_CARACTERE('_');
1821:
1822: DECLARATION_CARACTERE('1');
1823: DECLARATION_CARACTERE('2');
1824: DECLARATION_CARACTERE('3');
1825: DECLARATION_CARACTERE('4');
1826: DECLARATION_CARACTERE('5');
1827: DECLARATION_CARACTERE('6');
1828: DECLARATION_CARACTERE('7');
1829: DECLARATION_CARACTERE('8');
1830: DECLARATION_CARACTERE('9');
1831: DECLARATION_CARACTERE('0');
1832: #undef DECLARATION_CARACTERE
1833:
1834: return;
1835: }
1836:
1837: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>