1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.0.prerelease.0
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: Routine de création d'une nouvelle variable
29: Entrée : autorisation_creation_variable_statique vaut 'V' ou 'S'.
30: Dans le cas 'V', la variable est volatile.
31: Dans le cas 'S', elle est statique.
32: Entrée : autorisation_creation_variable_partagee vaut 'P' ou 'S'.
33: Dans le cas 'P', la variable est privée.
34: Dans le cas 'S', elle est partagée.
35: --------------------------------------------------------------------------------
36: Sortie :
37: --------------------------------------------------------------------------------
38: Effets de bords : néant
39: ================================================================================
40: */
41:
42: static logical1
43: ajout_variable(struct_processus *s_etat_processus, struct_variable *s_variable)
44: {
45: int i;
46:
47: struct_arbre_variables *l_variable_courante;
48:
49: struct_liste_variables *l_nouvelle_variable;
50: struct_liste_variables *l_variable_candidate;
51:
52: struct_liste_chainee *l_nouvel_element;
53:
54: unsigned char *ptr;
55:
56: if ((*s_etat_processus).s_arbre_variables == NULL)
57: {
58: if (((*s_etat_processus).s_arbre_variables =
59: malloc(sizeof(struct_arbre_variables))) == NULL)
60: {
61: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
62: return(d_erreur);
63: }
64:
65: (*(*s_etat_processus).s_arbre_variables).feuille = NULL;
66: (*(*s_etat_processus).s_arbre_variables).noeuds_utilises = 0;
67:
68: if (((*(*s_etat_processus).arbre_instructions).noeud =
69: malloc((*s_etat_processus).nombre_caracteres_variables
70: * sizeof(struct_arbre_variables))) == NULL)
71: {
72: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
73: return(d_erreur);
74: }
75:
76: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
77: {
78: (*(*s_etat_processus).s_arbre_variables).noeud[i] = NULL;
79: }
80: }
81:
82: l_variable_courante = (*s_etat_processus).s_arbre_variables;
83: ptr = (*s_variable).nom;
84:
85: while((*ptr) != d_code_fin_chaine)
86: {
87: BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
88: printf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
89: *ptr));
90:
91: if ((*l_variable_courante).noeud[(*s_etat_processus)
92: .pointeurs_caracteres_variables[*ptr]] == NULL)
93: {
94: // Le noeud n'existe pas encore, on le crée.
95:
96: if (((*l_variable_courante).noeud[(*s_etat_processus)
97: .pointeurs_caracteres_variables[*ptr]] =
98: malloc(sizeof(struct_arbre_variables))) == NULL)
99: {
100: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
101: return(d_erreur);
102: }
103:
104: (*(*l_variable_courante).noeud[(*s_etat_processus)
105: .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
106: (*(*l_variable_courante).noeud[(*s_etat_processus)
107: .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
108:
109: if (((*(*l_variable_courante).noeud[(*s_etat_processus)
110: .pointeurs_caracteres_variables[*ptr]]).noeud =
111: malloc((*s_etat_processus).nombre_caracteres_variables
112: * sizeof(struct_arbre_variables))) == NULL)
113: {
114: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
115: return(d_erreur);
116: }
117:
118: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
119: {
120: (*(*l_variable_courante).noeud[(*s_etat_processus)
121: .pointeurs_caracteres_variables[*ptr]]).noeud[i] = NULL;
122: }
123: }
124:
125: (*l_variable_courante).noeuds_utilises++;
126: l_variable_courante = (*l_variable_courante).noeud
127: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
128: ptr++;
129: }
130:
131: if ((*l_variable_courante).feuille == NULL)
132: {
133: // Aucune variable de même nom préexiste. On alloue le premier
134: // élément de la liste doublement chaînée contenant toutes les
135: // variables de même nom. Cette liste boucle en premier lieu sur
136: // elle-même.
137:
138: if (((*l_variable_courante).feuille = malloc(
139: sizeof(struct_liste_variables))) == NULL)
140: {
141: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
142: return(d_erreur);
143: }
144:
145: (*(*l_variable_courante).feuille).suivant =
146: (*l_variable_courante).feuille;
147: (*(*l_variable_courante).feuille).precedent =
148: (*l_variable_courante).feuille;
149:
150: // Allocation de la variable sur l'élément de la liste.
151:
152: if (((*(*l_variable_courante).feuille).variable =
153: malloc(sizeof(struct_variable))) == NULL)
154: {
155: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
156: return(d_erreur);
157: }
158:
159: (*((struct_variable *) (*(*l_variable_courante).feuille).variable)) =
160: (*s_variable);
161:
162: if (((*((struct_variable *) (*(*l_variable_courante).feuille).variable))
163: .nom = strdup((*s_variable).nom)) == NULL)
164: {
165: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
166: return(d_erreur);
167: }
168: }
169: else
170: {
171: if ((*s_variable).niveau > 1)
172: {
173: // Cas d'une variable locale
174:
175: // Si le niveau de la dernière variable de même nom est
176: // supérieur au niveau de la variable locale que l'on veut
177: // enregistrer dans la liste, cette liste est incohérente.
178:
179: BUG((*(*(*l_variable_courante).feuille).variable).niveau >=
180: (*s_variable).niveau,
181: printf("Variable=\"%s\"\n", (*s_variable).nom));
182:
183: // On ajoute la variable à la liste existante.
184:
185: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
186: == NULL)
187: {
188: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
189: return(d_erreur);
190: }
191:
192: (*l_nouvelle_variable).suivant = (*l_variable_courante).feuille;
193: (*l_nouvelle_variable).precedent = (*(*l_variable_courante).feuille)
194: .precedent;
195: (*(*(*l_variable_courante).feuille).precedent).suivant =
196: l_nouvelle_variable;
197: (*(*l_variable_courante).feuille).precedent =
198: l_nouvelle_variable;
199: (*l_variable_courante).feuille = l_nouvelle_variable;
200:
201: if (((*(*l_variable_courante).feuille).variable =
202: malloc(sizeof(struct_variable))) == NULL)
203: {
204: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
205: return(d_erreur);
206: }
207:
208: (*((struct_variable *) (*(*l_variable_courante).feuille).variable))
209: = (*s_variable);
210:
211: if (((*((struct_variable *) (*(*l_variable_courante).feuille)
212: .variable)).nom = strdup((*s_variable).nom)) == NULL)
213: {
214: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
215: return(d_erreur);
216: }
217: }
218: else
219: {
220: // Cas d'une variable globale (niveau 0 [définitions] ou 1
221: // [variables globales])
222:
223: l_variable_candidate = (*l_variable_courante).feuille;
224:
225: do
226: {
227: // S'il y a déjà une variable de même niveau, la pile
228: // est incohérente.
229:
230: BUG((*(*l_variable_candidate).variable).niveau ==
231: (*s_variable).niveau,
232: printf("Variable=\"%s\"\n", (*s_variable).nom));
233:
234: l_variable_candidate = (*l_variable_candidate).precedent;
235: } while((l_variable_candidate != (*l_variable_courante).feuille) &&
236: ((*(*l_variable_candidate).variable).niveau <= 1));
237:
238: if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
239: .niveau > 1)
240: {
241: // Ajout inconditionnel des variables de niveaux 0 et 1
242: }
243: else
244: {
245: l_variable_candidate = (*(*l_variable_courante).feuille)
246: .precedent;
247: }
248:
249: (*l_nouvelle_variable).suivant = l_variable_candidate;
250: (*l_nouvelle_variable).precedent = (*l_variable_candidate)
251: .precedent;
252: (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
253: (*l_variable_candidate).precedent = l_nouvelle_variable;
254:
255: if (((*l_nouvelle_variable).variable =
256: malloc(sizeof(struct_variable))) == NULL)
257: {
258: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
259: return(d_erreur);
260: }
261:
262: (*(*l_nouvelle_variable).variable) = (*s_variable);
263:
264: if (((*(*l_nouvelle_variable).variable).nom =
265: strdup((*s_variable).nom)) == NULL)
266: {
267: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
268: return(d_erreur);
269: }
270: }
271: }
272:
273: // Ajout de la variable nouvellement créée à la liste par niveaux.
274: // Le pointeur contenu dans la structure de description du processus indique
275: // toujours le plus haut niveau utilisé.
276:
277: if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
278: {
279: // Le niveau courant n'existe pas. Il est créé.
280:
281: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
282: == NULL)
283: {
284: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
285: return(d_erreur);
286: }
287:
288: (*l_nouvelle_variable).suivant = l_nouvelle_variable;
289: (*l_nouvelle_variable).precedent = l_nouvelle_variable;
290:
291: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
292: }
293: else if ((*s_variable).niveau > (*((struct_variable *)
294: (*(*(*s_etat_processus).l_liste_variables_par_niveau).liste)
295: .donnee)).niveau)
296: {
297: // Le niveau courant n'existe pas. Il est créé.
298:
299: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
300: == NULL)
301: {
302: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
303: return(d_erreur);
304: }
305:
306: (*l_nouvelle_variable).suivant = (*s_etat_processus)
307: .l_liste_variables_par_niveau;
308: (*l_nouvelle_variable).precedent = (*(*s_etat_processus)
309: .l_liste_variables_par_niveau).precedent;
310: (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent)
311: .suivant = l_nouvelle_variable;
312: (*(*s_etat_processus).l_liste_variables_par_niveau).precedent =
313: l_nouvelle_variable;
314:
315: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
316: }
317: else
318: {
319: // Création d'une variable de niveau 0 ou 1
320:
321: l_variable_candidate = (*s_etat_processus).l_liste_variables_par_niveau;
322:
323: if ((*((struct_variable *) (*(*(*(*s_etat_processus)
324: .l_liste_variables_par_niveau).precedent).liste).donnee))
325: .niveau > 1)
326: {
327: // Ajout inconditionnel des variables de niveaux 0 et 1
328: }
329: else
330: {
331: l_variable_candidate = (*(*s_etat_processus)
332: .l_liste_variables_par_niveau).precedent;
333: }
334:
335: (*l_nouvelle_variable).suivant = l_variable_candidate;
336: (*l_nouvelle_variable).precedent = (*l_variable_candidate)
337: .precedent;
338: (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
339: (*l_variable_candidate).precedent = l_nouvelle_variable;
340: }
341:
342: // Ajout de la variable en tête de la liste
343:
344: if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
345: {
346: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
347: return(d_erreur);
348: }
349:
350: (*l_nouvel_element).suivant = (*(*s_etat_processus)
351: .l_liste_variables_par_niveau).liste;
352: (*l_nouvel_element).donnee = (struct_objet *) s_variable;
353: (*l_nouvelle_variable).liste = l_nouvel_element;
354:
355: return(d_absence_erreur);
356: }
357:
358: logical1
359: creation_variable(struct_processus *s_etat_processus,
360: struct_variable *s_variable,
361: unsigned char autorisation_creation_variable_statique,
362: unsigned char autorisation_creation_variable_partagee)
363: {
364: if ((*s_etat_processus).mode_execution_programme == 'Y')
365: {
366: (*s_variable).origine = 'P';
367: }
368: else
369: {
370: (*s_variable).origine = 'E';
371: }
372:
373: if ((*s_variable).niveau == 0)
374: {
375: // Un point d'entrée de définition est verrouillé.
376:
377: if ((*s_variable).origine == 'P')
378: {
379: (*s_variable).variable_statique.adresse = 0;
380: (*s_variable).variable_partagee.adresse = 0;
381: }
382: else
383: {
384: (*s_variable).variable_statique.pointeur = NULL;
385: (*s_variable).variable_partagee.pointeur = NULL;
386: }
387:
388: (*s_variable).variable_verrouillee = d_vrai;
389: }
390: else if ((*s_variable).niveau == 1)
391: {
392: // Une variable globale ne peut être statique.
393:
394: if ((*s_variable).origine == 'P')
395: {
396: (*s_variable).variable_statique.adresse = 0;
397: (*s_variable).variable_partagee.adresse = 0;
398: }
399: else
400: {
401: (*s_variable).variable_statique.pointeur = NULL;
402: (*s_variable).variable_partagee.pointeur = NULL;
403: }
404:
405: (*s_variable).variable_verrouillee = d_faux;
406: }
407: else
408: {
409: // 0 -> variable volatile
410: // adresse de création -> variable statique
411:
412: if (autorisation_creation_variable_statique == 'V')
413: {
414: if (autorisation_creation_variable_partagee == 'S')
415: {
416: // On force la création d'une variable partagée
417:
418: if ((*s_variable).origine == 'P')
419: {
420: (*s_variable).variable_statique.adresse = 0;
421: (*s_variable).variable_partagee.adresse =
422: (*s_etat_processus).position_courante;
423: }
424: else
425: {
426: (*s_variable).variable_statique.pointeur = NULL;
427: (*s_variable).variable_partagee.pointeur =
428: (*s_etat_processus).objet_courant;
429: }
430: }
431: else
432: {
433: // On force la création d'une variable volatile
434:
435: if ((*s_variable).origine == 'P')
436: {
437: (*s_variable).variable_statique.adresse = 0;
438: (*s_variable).variable_partagee.adresse = 0;
439: }
440: else
441: {
442: (*s_variable).variable_statique.pointeur = NULL;
443: (*s_variable).variable_partagee.pointeur = NULL;
444: }
445: }
446: }
447: else
448: {
449: // On force la création d'une variable statique.
450:
451: if ((*s_variable).origine == 'P')
452: {
453: (*s_variable).variable_statique.adresse =
454: (*s_etat_processus).position_courante;
455: (*s_variable).variable_partagee.adresse = 0;
456: }
457: else
458: {
459: (*s_variable).variable_statique.pointeur =
460: (*s_etat_processus).objet_courant;
461: (*s_variable).variable_partagee.pointeur = 0;
462: }
463: }
464:
465: (*s_variable).variable_verrouillee = d_faux;
466: }
467:
468: /*
469: * Recherche de la feuille correspondante dans l'arbre des variables.
470: * Si cette feuille n'existe pas, elle est créée.
471: */
472:
473: if (ajout_variable(s_etat_processus, s_variable) == d_erreur)
474: {
475: return(d_erreur);
476: }
477:
478: return(d_absence_erreur);
479: }
480:
481:
482: /*
483: ================================================================================
484: Procédure de recherche d'une variable par son nom dans la base
485: ================================================================================
486: Entrée :
487: --------------------------------------------------------------------------------
488: Sortie :
489: --------------------------------------------------------------------------------
490: Effets de bord : néant
491: ================================================================================
492: */
493:
494: logical1
495: recherche_variable(struct_processus *s_etat_processus,
496: unsigned char *nom_variable)
497: {
498: int pointeur;
499:
500: struct_arbre_variables *l_variable_courante;
501: struct_liste_pile_systeme *l_element_courant;
502:
503: unsigned char *ptr;
504:
505: unsigned long niveau_appel;
506:
507: if ((*s_etat_processus).s_arbre_variables == NULL)
508: {
509: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
510: return d_faux;
511: }
512:
513: ptr = nom_variable;
514:
515: while((*ptr) != d_code_fin_chaine)
516: {
517: pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
518:
519: if (pointeur < 0)
520: {
521: // Caractère hors de l'alphabet des variables
522: return(d_erreur);
523: }
524:
525: if ((*l_variable_courante).noeud[pointeur] == NULL)
526: {
527: // Le chemin de la variable candidate n'existe pas.
528: return(d_erreur);
529: }
530:
531: l_variable_courante = (*l_variable_courante).noeud[pointeur];
532: ptr++;
533: }
534:
535: if ((*l_variable_courante).feuille != NULL)
536: {
537: // Il existe une pile de variables de même nom. Le sommet de la
538: // pile est la variable de niveau le plus haut.
539:
540: l_element_courant = (*s_etat_processus).l_base_pile_systeme;
541:
542: if (l_element_courant == NULL)
543: {
544: // Problème : la pile système est vide !
545: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
546: return(d_erreur);
547: }
548:
549: while((*l_element_courant).retour_definition != 'Y')
550: {
551: l_element_courant = (*l_element_courant).suivant;
552:
553: if (l_element_courant == NULL)
554: {
555: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
556: return(d_erreur);
557: }
558: }
559:
560: niveau_appel = (*l_element_courant).niveau_courant;
561:
562: if (niveau_appel < (*(*(*l_variable_courante).feuille).variable).niveau)
563: {
564: // Une variable locale est accessible puisque créée dans la
565: // fonction courante.
566:
567: (*s_etat_processus).pointeur_variable_courante =
568: (*(*l_variable_courante).feuille).variable;
569: (*s_etat_processus).pointeur_feuille_courante =
570: (*l_variable_courante).feuille;
571: return(d_absence_erreur);
572: }
573: else
574: {
575: // Aucune variable locale n'est accessible depuis la fonction.
576: // Dans ce cas, on prend la variable de niveau le plus bas
577: // si ce niveau est inférieur ou égal à 1 (variable globale
578: // ou fonction définie par l'utilisateur). Si le niveau de la
579: // plus ancienne variable est strictement supérieur à 1, il
580: // s'agit d'une variable locale inaccessible.
581:
582: if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
583: .niveau <= 1)
584: {
585: (*s_etat_processus).pointeur_variable_courante =
586: (*(*(*l_variable_courante).feuille).precedent).variable;
587: (*s_etat_processus).pointeur_feuille_courante =
588: (*l_variable_courante).feuille;
589:
590: // S'il existe une variable de niveau 0 et une seconde de
591: // niveau 1, la variable de niveau 0 (fonction) est masquée
592: // par celle de niveau 1.
593:
594: if (((*(*(*l_variable_courante).feuille).variable).niveau == 0)
595: && ((*(*(*(*l_variable_courante).feuille).precedent)
596: .variable).niveau == 1))
597: {
598: (*s_etat_processus).pointeur_variable_courante =
599: (*(*(*l_variable_courante).feuille).precedent)
600: .variable;
601: (*s_etat_processus).pointeur_feuille_courante =
602: (*l_variable_courante).feuille;
603: }
604:
605: return(d_absence_erreur);
606: }
607: }
608: }
609:
610: return(d_erreur);
611: }
612:
613:
614: /*
615: ================================================================================
616: Procédure de retrait d'une variable de la base
617: ================================================================================
618: Entrée : type 'G' ou 'L' selon que l'on retire une variable locale (incluant
619: les globales) ou strictement globale.
620: --------------------------------------------------------------------------------
621: Sortie :
622: --------------------------------------------------------------------------------
623: Effets de bord : néant
624: ================================================================================
625: */
626:
627: logical1
628: retrait_variable(struct_processus *s_etat_processus,
629: unsigned char *nom_variable, unsigned char type)
630: {
631: logical1 erreur;
632:
633: if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
634: {
635: // Une variable correspondant au nom recherché est accessible.
636:
637: if (type == 'G')
638: {
639: if ((*(*s_etat_processus).pointeur_variable_courante).niveau > 1)
640: {
641: // La variable obtenue est une variable locale. il faut
642: // s'assurer qu'il existe une variable de niveau 1 de même
643: // nom sur la feuille.
644:
645: if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
646: .precedent).variable).niveau <= 1)
647: {
648: (*s_etat_processus).pointeur_feuille_courante =
649: (*(*s_etat_processus).pointeur_feuille_courante)
650: .precedent;
651: (*s_etat_processus).pointeur_variable_courante =
652: (*(*s_etat_processus).pointeur_feuille_courante)
653: .variable;
654:
655: // Si la variable retournée est de niveau 0, on regarde
656: // un peu plus loin si une variable de niveau 1 existe.
657:
658: if (((*(*(*s_etat_processus).pointeur_feuille_courante)
659: .variable).niveau == 0) &&
660: ((*(*(*(*s_etat_processus)
661: .pointeur_feuille_courante).precedent).variable)
662: .niveau == 1))
663: {
664: (*s_etat_processus).pointeur_feuille_courante =
665: (*(*s_etat_processus).pointeur_feuille_courante)
666: .precedent;
667: (*s_etat_processus).pointeur_variable_courante =
668: (*(*s_etat_processus).pointeur_feuille_courante)
669: .variable;
670: }
671: }
672: else
673: {
674: // Aucune variable globale (niveau 1) n'existe.
675:
676: erreur = d_erreur;
677: (*s_etat_processus).erreur_execution =
678: d_ex_variable_non_definie;
679: return(erreur);
680: }
681: }
682:
683: if ((*(*s_etat_processus).pointeur_variable_courante)
684: .variable_verrouillee == d_vrai)
685: {
686: erreur = d_erreur;
687: (*s_etat_processus).erreur_execution =
688: d_ex_variable_verrouillee;
689: return erreur;
690: }
691: }
692:
693: // Suppression de la variable de la liste.
694: // Deux cas peuvent survenir :
695: // 1/ les pointeurs sur la variable et la variable suivante
696: // sont identiques et on supprime la variable ainsi que la feuille
697: // associée ;
698: // 2/ ces deux pointeurs sont différents et se contente de retirer
699: // la structure décrivant la variable.
700:
701: position_supprimee = (*s_etat_processus).position_variable_courante;
702:
703: liberation(s_etat_processus, (*s_etat_processus).s_liste_variables
704: [position_supprimee].objet);
705: free((*s_etat_processus).s_liste_variables[position_supprimee].nom);
706:
707: (*s_etat_processus).nombre_variables--;
708:
709: for(position_courante = position_supprimee;
710: position_courante < (*s_etat_processus).nombre_variables;
711: position_courante++)
712: {
713: (*s_etat_processus).s_liste_variables[position_courante] =
714: (*s_etat_processus).s_liste_variables
715: [position_courante + 1];
716: }
717:
718: erreur = d_absence_erreur;
719: }
720: else
721: {
722: // Aucune variable n'est accessible depuis le point courant du
723: // programme.
724:
725: erreur = d_erreur;
726: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
727: }
728:
729: return(erreur);
730: }
731:
732:
733: /*
734: ================================================================================
735: Procédure de retrait des variables de niveau strictement supérieur au
736: niveau courant
737: ================================================================================
738: Entrée :
739: --------------------------------------------------------------------------------
740: Sortie :
741: --------------------------------------------------------------------------------
742: Effets de bord : néant
743: ================================================================================
744: */
745:
746: logical1
747: retrait_variable_par_niveau(struct_processus *s_etat_processus)
748: {
749: unsigned long i;
750: unsigned long j;
751:
752: struct_variable *tampon;
753:
754: for(j = 0, i = 0; i < (*s_etat_processus).nombre_variables; i++)
755: {
756: if ((*s_etat_processus).s_liste_variables[i].niveau <=
757: (*s_etat_processus).niveau_courant)
758: {
759: (*s_etat_processus).s_liste_variables[j++] =
760: (*s_etat_processus).s_liste_variables[i];
761: }
762: else
763: {
764: if ((*s_etat_processus).s_liste_variables[i].origine == 'P')
765: {
766: if ((*s_etat_processus).s_liste_variables[i]
767: .variable_statique.adresse != 0)
768: {
769: /*
770: * Gestion des variables statiques
771: */
772:
773: if (recherche_variable_statique(s_etat_processus,
774: (*s_etat_processus).s_liste_variables[i]
775: .nom, (*s_etat_processus).s_liste_variables
776: [i].variable_statique, ((*s_etat_processus)
777: .mode_execution_programme
778: == 'Y') ? 'P' : 'E') == d_vrai)
779: {
780: (*s_etat_processus).s_liste_variables_statiques
781: [(*s_etat_processus)
782: .position_variable_statique_courante]
783: .objet = (*s_etat_processus)
784: .s_liste_variables[i].objet;
785: }
786: else
787: {
788: (*s_etat_processus).erreur_systeme =
789: d_es_variable_introuvable;
790: }
791:
792: (*s_etat_processus).s_liste_variables[i].objet = NULL;
793: }
794: }
795: else
796: {
797: if ((*s_etat_processus).s_liste_variables[i]
798: .variable_statique.pointeur != NULL)
799: {
800: /*
801: * Gestion des variables statiques
802: */
803:
804: if (recherche_variable_statique(s_etat_processus,
805: (*s_etat_processus).s_liste_variables[i]
806: .nom, (*s_etat_processus).s_liste_variables[i]
807: .variable_statique, ((*s_etat_processus)
808: .mode_execution_programme
809: == 'Y') ? 'P' : 'E') == d_vrai)
810: {
811: (*s_etat_processus).s_liste_variables_statiques
812: [(*s_etat_processus)
813: .position_variable_statique_courante]
814: .objet = (*s_etat_processus)
815: .s_liste_variables[i].objet;
816: }
817: else
818: {
819: (*s_etat_processus).erreur_systeme =
820: d_es_variable_introuvable;
821: return(d_erreur);
822: }
823:
824: (*s_etat_processus).s_liste_variables[i].objet = NULL;
825: }
826: }
827:
828: free((*s_etat_processus).s_liste_variables[i].nom);
829: liberation(s_etat_processus,
830: (*s_etat_processus).s_liste_variables[i].objet);
831: }
832: }
833:
834: (*s_etat_processus).nombre_variables = j;
835:
836: if ((*s_etat_processus).nombre_variables <
837: ((*s_etat_processus).nombre_variables_allouees / 2))
838: {
839: (*s_etat_processus).nombre_variables_allouees /= 2;
840:
841: if ((tampon = realloc((*s_etat_processus).s_liste_variables,
842: (*s_etat_processus).nombre_variables_allouees *
843: sizeof(struct_variable))) == NULL)
844: {
845: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
846: return(d_erreur);
847: }
848:
849: (*s_etat_processus).s_liste_variables = tampon;
850: }
851:
852: return(d_absence_erreur);
853: }
854:
855:
856: /*
857: ================================================================================
858: Procédure de retrait des toutes les variables locales et globales
859: ================================================================================
860: Entrée : drapeau indiquant s'il faut retirer les définitions (variables
861: de niveau 0)
862: --------------------------------------------------------------------------------
863: Sortie :
864: --------------------------------------------------------------------------------
865: Effets de bord : néant
866: ================================================================================
867: */
868:
869: void
870: liberation_arbre_variables(struct_processus *s_etat_processus,
871: struct_arbre_variables *arbre, logical1 retrait_definitions)
872: {
873: int i;
874:
875: struct_liste_chainee *l_element_courant;
876: struct_liste_chainee *l_element_suivant;
877:
878: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
879: {
880: if ((*arbre).noeud[i] != NULL)
881: {
882: l_element_courant = (*arbre).l_variables;
883:
884: while(l_element_courant != NULL)
885: {
886: l_element_suivant = (*l_element_courant).suivant;
887:
888: if (retrait_definitions == d_vrai)
889: {
890: liberation(s_etat_processus, (*((struct_variable *)
891: (*l_element_courant).donnee)).objet);
892: free((*((struct_variable *) (*l_element_courant)
893: .donnee)).nom);
894: free((struct_variable *) (*l_element_courant).donnee);
895: }
896: else
897: {
898: if ((*((struct_variable *) (*l_element_courant).donnee))
899: .niveau >= 1)
900: {
901: liberation(s_etat_processus, (*((struct_variable *)
902: (*l_element_courant).donnee)).objet);
903: free((*((struct_variable *) (*l_element_courant)
904: .donnee)).nom);
905: free((struct_variable *) (*l_element_courant).donnee);
906: }
907: }
908:
909: free(l_element_courant);
910: l_element_courant = l_element_suivant;
911: }
912:
913: liberation_arbre_variables(s_etat_processus, (*arbre).noeud[i]);
914: }
915: }
916:
917: free((*arbre).noeud);
918: free(arbre);
919:
920: return;
921: }
922:
923: /*
924: ================================================================================
925: Procédure de copie de l'arbre des variables
926: ================================================================================
927: Entrée :
928: --------------------------------------------------------------------------------
929: Sortie :
930: --------------------------------------------------------------------------------
931: Effets de bord : néant
932: ================================================================================
933: */
934:
935: struct_arbre_variables *
936: copie_arbre_variables(struct_processus *s_etat_processus)
937: {
938: // Les définitions sont partagées entre tous les threads et ne sont pas
939: // copiées.
940:
941: return(d_absence_erreur);
942: }
943:
944:
945: /*
946: ================================================================================
947: Procédure d'initialisation de la table de correspondance des variables
948: ================================================================================
949: Entrée :
950: --------------------------------------------------------------------------------
951: Sortie :
952: --------------------------------------------------------------------------------
953: Effets de bord : néant
954: ================================================================================
955: */
956:
957: /*
958: * Caractères autorisés dans les instructions
959: *
960: * 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
961: * 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
962: * _
963: * 1 2 3 4 5 6 7 8 9 0
964: */
965:
966: void
967: initialisation_variables(struct_processus *s_etat_processus)
968: {
969: int decalage;
970: int i;
971: int longueur_tableau;
972:
973: unsigned char caractere;
974:
975: // Récupération de la longueur d'un unsigned char
976:
977: longueur_tableau = 1;
978: decalage = 0;
979: caractere = 1;
980:
981: while((1L << decalage) == (long) ((unsigned char) (caractere << decalage)))
982: {
983: decalage++;
984: longueur_tableau *= 2;
985: }
986:
987: if (((*s_etat_processus).pointeurs_caracteres_variables =
988: malloc(longueur_tableau * sizeof(int))) == NULL)
989: {
990: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
991: return;
992: }
993:
994: for(i = 0; i < longueur_tableau; i++)
995: {
996: (*s_etat_processus).pointeurs_caracteres_variables[i] = -1;
997: }
998:
999: (*s_etat_processus).nombre_caracteres_variables = 0;
1000:
1001: #define DECLARATION_CARACTERE(c) \
1002: do { (*s_etat_processus).pointeurs_caracteres_variables[c] = \
1003: (*s_etat_processus).nombre_caracteres_variables++; } while(0)
1004:
1005: DECLARATION_CARACTERE('A');
1006: DECLARATION_CARACTERE('B');
1007: DECLARATION_CARACTERE('C');
1008: DECLARATION_CARACTERE('D');
1009: DECLARATION_CARACTERE('E');
1010: DECLARATION_CARACTERE('F');
1011: DECLARATION_CARACTERE('G');
1012: DECLARATION_CARACTERE('H');
1013: DECLARATION_CARACTERE('I');
1014: DECLARATION_CARACTERE('J');
1015: DECLARATION_CARACTERE('K');
1016: DECLARATION_CARACTERE('L');
1017: DECLARATION_CARACTERE('M');
1018: DECLARATION_CARACTERE('N');
1019: DECLARATION_CARACTERE('O');
1020: DECLARATION_CARACTERE('P');
1021: DECLARATION_CARACTERE('Q');
1022: DECLARATION_CARACTERE('R');
1023: DECLARATION_CARACTERE('S');
1024: DECLARATION_CARACTERE('T');
1025: DECLARATION_CARACTERE('U');
1026: DECLARATION_CARACTERE('V');
1027: DECLARATION_CARACTERE('W');
1028: DECLARATION_CARACTERE('X');
1029: DECLARATION_CARACTERE('Y');
1030: DECLARATION_CARACTERE('Z');
1031:
1032: DECLARATION_CARACTERE('a');
1033: DECLARATION_CARACTERE('b');
1034: DECLARATION_CARACTERE('c');
1035: DECLARATION_CARACTERE('d');
1036: DECLARATION_CARACTERE('e');
1037: DECLARATION_CARACTERE('f');
1038: DECLARATION_CARACTERE('g');
1039: DECLARATION_CARACTERE('h');
1040: DECLARATION_CARACTERE('i');
1041: DECLARATION_CARACTERE('j');
1042: DECLARATION_CARACTERE('k');
1043: DECLARATION_CARACTERE('l');
1044: DECLARATION_CARACTERE('m');
1045: DECLARATION_CARACTERE('n');
1046: DECLARATION_CARACTERE('o');
1047: DECLARATION_CARACTERE('p');
1048: DECLARATION_CARACTERE('q');
1049: DECLARATION_CARACTERE('r');
1050: DECLARATION_CARACTERE('s');
1051: DECLARATION_CARACTERE('t');
1052: DECLARATION_CARACTERE('u');
1053: DECLARATION_CARACTERE('v');
1054: DECLARATION_CARACTERE('w');
1055: DECLARATION_CARACTERE('x');
1056: DECLARATION_CARACTERE('y');
1057: DECLARATION_CARACTERE('z');
1058:
1059: DECLARATION_CARACTERE('_');
1060:
1061: DECLARATION_CARACTERE('1');
1062: DECLARATION_CARACTERE('2');
1063: DECLARATION_CARACTERE('3');
1064: DECLARATION_CARACTERE('4');
1065: DECLARATION_CARACTERE('5');
1066: DECLARATION_CARACTERE('6');
1067: DECLARATION_CARACTERE('7');
1068: DECLARATION_CARACTERE('8');
1069: DECLARATION_CARACTERE('9');
1070: DECLARATION_CARACTERE('0');
1071: #undef DECLARATION_CARACTERE
1072:
1073: return;
1074: }
1075:
1076: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>