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: Routine de retrait des variables statiques
29: ================================================================================
30: Entrée :
31: --------------------------------------------------------------------------------
32: Sortie :
33: --------------------------------------------------------------------------------
34: Effets de bords : néant
35: ================================================================================
36: */
37:
38: // Cette routine libère toutes les variables statiques de niveau non
39: // nul, donc attachées à une expression et non un programme.
40:
41: logical1
42: retrait_variables_statiques_locales(struct_processus *s_etat_processus)
43: {
44: struct_liste_variables_statiques *l_element_courant;
45: struct_liste_variables_statiques *l_element_suivant;
46:
47: unsigned char registre_mode_execution;
48:
49: registre_mode_execution = (*s_etat_processus).mode_execution_programme;
50: l_element_courant = (*s_etat_processus).l_liste_variables_statiques;
51:
52: while(l_element_courant != NULL)
53: {
54: l_element_suivant = (*l_element_courant).suivant;
55:
56: (*s_etat_processus).mode_execution_programme =
57: ((*(*l_element_courant).variable).origine == 'P') ? 'Y' : 'N';
58:
59: if ((*(*l_element_courant).variable).niveau > 0)
60: {
61: if (retrait_variable_statique(s_etat_processus,
62: (*(*l_element_courant).variable).nom,
63: (*(*l_element_courant).variable).variable_statique)
64: == d_erreur)
65: {
66: (*s_etat_processus).mode_execution_programme =
67: registre_mode_execution;
68: return(d_erreur);
69: }
70: }
71:
72: l_element_courant = l_element_suivant;
73: }
74:
75: (*s_etat_processus).mode_execution_programme = registre_mode_execution;
76: return(d_absence_erreur);
77: }
78:
79:
80: /*
81: ================================================================================
82: Routine de création d'une nouvelle variable statique
83: ================================================================================
84: Entrée :
85: --------------------------------------------------------------------------------
86: Sortie :
87: --------------------------------------------------------------------------------
88: Effets de bords : néant
89: ================================================================================
90: */
91:
92: logical1
93: creation_variable_statique(struct_processus *s_etat_processus,
94: struct_variable_statique *s_variable)
95: {
96: int i;
97:
98: struct_arbre_variables *l_variable_courante;
99:
100: struct_liste_variables_statiques *l_nouvel_element;
101:
102: unsigned char *ptr;
103:
104: // Ajout de la variable en tête de la liste des variables statiques
105:
106: if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_statiques)))
107: == NULL)
108: {
109: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
110: return(d_erreur);
111: }
112:
113: if (((*l_nouvel_element).variable = malloc(sizeof(
114: struct_variable_statique))) == NULL)
115: {
116: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
117: return(d_erreur);
118: }
119:
120: (*(*l_nouvel_element).variable) = (*s_variable);
121: (*l_nouvel_element).suivant = (*s_etat_processus)
122: .l_liste_variables_statiques;
123: (*l_nouvel_element).precedent = NULL;
124:
125: if ((*s_etat_processus).l_liste_variables_statiques != NULL)
126: {
127: (*(*s_etat_processus).l_liste_variables_statiques).precedent
128: = l_nouvel_element;
129: }
130:
131: (*s_etat_processus).l_liste_variables_statiques = l_nouvel_element;
132:
133: // Ajout de la variable à la feuille statique de l'arbre des variables
134:
135: if ((*s_etat_processus).s_arbre_variables == NULL)
136: {
137: if (((*s_etat_processus).s_arbre_variables =
138: allocation_noeud(s_etat_processus)) == NULL)
139: {
140: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
141: return(d_erreur);
142: }
143:
144: (*(*s_etat_processus).s_arbre_variables).feuille = NULL;
145: (*(*s_etat_processus).s_arbre_variables).feuille_statique = NULL;
146: (*(*s_etat_processus).s_arbre_variables).noeuds_utilises = 0;
147: (*(*s_etat_processus).s_arbre_variables).indice_tableau_pere = -1;
148: (*(*s_etat_processus).s_arbre_variables).noeud_pere = NULL;
149:
150: if (((*(*s_etat_processus).s_arbre_variables).noeuds =
151: allocation_tableau_noeuds(s_etat_processus)) == NULL)
152: {
153: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
154: return(d_erreur);
155: }
156:
157: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
158: {
159: (*(*s_etat_processus).s_arbre_variables).noeuds[i] = NULL;
160: }
161: }
162:
163: l_variable_courante = (*s_etat_processus).s_arbre_variables;
164: ptr = (*s_variable).nom;
165:
166: while((*ptr) != d_code_fin_chaine)
167: {
168: BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
169: uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
170: *ptr));
171:
172: if ((*l_variable_courante).noeuds[(*s_etat_processus)
173: .pointeurs_caracteres_variables[*ptr]] == NULL)
174: {
175: // Le noeud n'existe pas encore, on le crée et on le marque
176: // comme utilisé dans la structure parente.
177:
178: if (((*l_variable_courante).noeuds[(*s_etat_processus)
179: .pointeurs_caracteres_variables[*ptr]] =
180: allocation_noeud(s_etat_processus)) == NULL)
181: {
182: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
183: return(d_erreur);
184: }
185:
186: (*l_variable_courante).noeuds_utilises++;
187:
188: // La feuille est par défaut vide et aucun élément du tableau noeuds
189: // (les branches qui peuvent être issues de ce nouveau noeud)
190: // n'est encore utilisée.
191:
192: (*(*l_variable_courante).noeuds[(*s_etat_processus)
193: .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
194: (*(*l_variable_courante).noeuds[(*s_etat_processus)
195: .pointeurs_caracteres_variables[*ptr]]).feuille_statique
196: = NULL;
197: (*(*l_variable_courante).noeuds[(*s_etat_processus)
198: .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
199:
200: // Le champ noeud_pere de la structure créée pointe sur
201: // la structure parente et l'indice tableau_pere correspond à la
202: // position réelle dans le tableau noeuds[] de la structure parente
203: // du noeud courant. Cette valeur sera utilisée lors de la
204: // destruction du noeud pour annuler le pointeur contenu dans
205: // le tableau noeuds[] de la structure parente.
206:
207: (*(*l_variable_courante).noeuds[(*s_etat_processus)
208: .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
209: l_variable_courante;
210: (*(*l_variable_courante).noeuds[(*s_etat_processus)
211: .pointeurs_caracteres_variables[*ptr]])
212: .indice_tableau_pere = (*s_etat_processus)
213: .pointeurs_caracteres_variables[*ptr];
214:
215: // Allocation du tableau noeuds[] et initialisation à zéro de
216: // tous les pointeurs.
217:
218: if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
219: .pointeurs_caracteres_variables[*ptr]]).noeuds =
220: allocation_tableau_noeuds(s_etat_processus)) == NULL)
221: {
222: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
223: return(d_erreur);
224: }
225:
226: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
227: {
228: (*(*l_variable_courante).noeuds[(*s_etat_processus)
229: .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
230: = NULL;
231: }
232: }
233:
234: l_variable_courante = (*l_variable_courante).noeuds
235: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
236: ptr++;
237: }
238:
239: if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_statiques)))
240: == NULL)
241: {
242: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
243: return(d_erreur);
244: }
245:
246: // Dans la feuille statique de l'arbre des variables, on ne balaie
247: // les variables que dans l'ordre. Le champ 'reference' est alors utilisé
248: // pour sauvegarder une référence vers la liste des variables statiques
249: // pour pouvoir purger l'élément en cas de besoin.
250:
251: (*l_nouvel_element).suivant = (*l_variable_courante).feuille_statique;
252: (*l_nouvel_element).precedent = NULL;
253:
254: if ((*l_nouvel_element).suivant != NULL)
255: {
256: (*(*l_nouvel_element).suivant).precedent = l_nouvel_element;
257: }
258:
259: (*l_nouvel_element).reference =
260: (*s_etat_processus).l_liste_variables_statiques;
261: (*l_nouvel_element).variable = (*(*s_etat_processus)
262: .l_liste_variables_statiques).variable;
263: (*l_variable_courante).feuille_statique = l_nouvel_element;
264: (*l_nouvel_element).feuille = l_variable_courante;
265:
266: return(d_absence_erreur);
267: }
268:
269:
270: /*
271: ================================================================================
272: Procédure de retrait d'une variable statique de la base
273: ================================================================================
274: Entrée :
275: --------------------------------------------------------------------------------
276: Sortie :
277: --------------------------------------------------------------------------------
278: Effets de bord : néant
279: ================================================================================
280: */
281:
282: logical1
283: retrait_variable_statique(struct_processus *s_etat_processus,
284: unsigned char *nom_variable, union_position_variable position)
285: {
286: struct_liste_variables_statiques *l_element_a_supprimer;
287: struct_liste_variables_statiques *l_element_liste_a_supprimer;
288:
289: logical1 erreur;
290:
291: if ((l_element_a_supprimer = recherche_variable_statique(s_etat_processus,
292: nom_variable, position, ((*s_etat_processus)
293: .mode_execution_programme == 'Y') ? 'P' : 'E')) != NULL)
294: {
295: // (*s_etat_processus).pointeur_variable_statique_courante
296: // pointe sur la variable à éliminer. Cette variable est celle qui
297: // est présente dans l'une des feuilles statiques de l'arbre des
298: // variables.
299:
300: l_element_liste_a_supprimer = (*l_element_a_supprimer).reference;
301:
302: // Suppression de la liste des variables statiques
303:
304: if ((*l_element_liste_a_supprimer).precedent != NULL)
305: {
306: // L'élément à supprimer n'est pas le premier de la liste.
307:
308: (*(*l_element_liste_a_supprimer).precedent).suivant =
309: (*l_element_liste_a_supprimer).suivant;
310:
311: if ((*l_element_liste_a_supprimer).suivant != NULL)
312: {
313: // Il y a un élément suivant. On le chaîne.
314: (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
315: }
316: }
317: else
318: {
319: // L'élement est le premier de la liste. S'il y a un élément
320: // suivant, on le chaîne.
321:
322: if ((*l_element_liste_a_supprimer).suivant != NULL)
323: {
324: (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
325: }
326:
327: (*s_etat_processus).l_liste_variables_statiques =
328: (*l_element_liste_a_supprimer).suivant;
329: }
330:
331: free(l_element_liste_a_supprimer);
332:
333: // Suppression depuis la feuille statique. Le champ 'precedent' ne sert
334: // pas car la liste est simplement chaînée.
335:
336: if ((*l_element_a_supprimer).precedent != NULL)
337: {
338: // L'élément n'est pas le premier de la liste.
339:
340: (*(*l_element_a_supprimer).precedent).suivant =
341: (*l_element_a_supprimer).suivant;
342:
343: if ((*l_element_a_supprimer).suivant != NULL)
344: {
345: (*(*l_element_a_supprimer).suivant).precedent =
346: (*l_element_a_supprimer).precedent;
347: }
348: else
349: {
350: (*(*l_element_a_supprimer).precedent).suivant = NULL;
351: }
352: }
353: else
354: {
355: // L'élément est le premier de la liste.
356:
357: if ((*l_element_a_supprimer).suivant != NULL)
358: {
359: (*(*l_element_a_supprimer).suivant).precedent = NULL;
360: }
361:
362: (*(*l_element_a_supprimer).feuille).feuille_statique
363: = (*l_element_a_supprimer).suivant;
364: }
365:
366: liberation(s_etat_processus, (*(*l_element_a_supprimer).variable)
367: .objet);
368: free((*(*l_element_a_supprimer).variable).nom);
369: free((*l_element_a_supprimer).variable);
370: free(l_element_a_supprimer);
371:
372: erreur = d_absence_erreur;
373: }
374: else
375: {
376: erreur = d_erreur;
377: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
378: }
379:
380: return erreur;
381: }
382:
383:
384: /*
385: ================================================================================
386: Procédure de recherche d'une variable statique par son nom dans la base
387: ================================================================================
388: Entrée :
389: --------------------------------------------------------------------------------
390: Sortie :
391: --------------------------------------------------------------------------------
392: Effets de bord : néant
393: ================================================================================
394: */
395:
396: struct_liste_variables_statiques *
397: recherche_variable_statique(struct_processus *s_etat_processus,
398: unsigned char *nom_variable, union_position_variable position,
399: unsigned char origine)
400: {
401: int pointeur;
402:
403: struct_arbre_variables *l_variable_courante;
404: struct_liste_variables_statiques *l_element_courant;
405:
406: unsigned char *ptr;
407:
408: l_variable_courante = (*s_etat_processus).s_arbre_variables;
409: ptr = nom_variable;
410:
411: while((*ptr) != d_code_fin_chaine)
412: {
413: pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
414:
415: if (pointeur < 0)
416: {
417: // Caractère hors de l'alphabet des variables
418:
419: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
420: return(NULL);
421: }
422:
423: if ((*l_variable_courante).noeuds[pointeur] == NULL)
424: {
425: // Le chemin de la variable candidate n'existe pas.
426: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
427: return(NULL);
428: }
429:
430: l_variable_courante = (*l_variable_courante).noeuds[pointeur];
431: ptr++;
432: }
433:
434: if ((*l_variable_courante).feuille_statique != NULL)
435: {
436: // Il existe au moins une variable statique du nom requis.
437:
438: l_element_courant = (*l_variable_courante).feuille_statique;
439:
440: while(l_element_courant != NULL)
441: {
442: if ((*(*l_element_courant).variable).origine == 'P')
443: {
444: if (((*(*l_element_courant).variable).variable_statique.adresse
445: == position.adresse) &&
446: ((*(*l_element_courant).variable).origine == origine))
447: {
448: (*s_etat_processus).pointeur_variable_statique_courante
449: = (*l_element_courant).variable;
450: return(l_element_courant);
451: }
452: }
453: else
454: {
455: if (((*(*l_element_courant).variable).variable_statique.pointeur
456: == position.pointeur) &&
457: ((*(*l_element_courant).variable).origine == origine))
458: {
459: (*s_etat_processus).pointeur_variable_statique_courante
460: = (*l_element_courant).variable;
461: return(l_element_courant);
462: }
463: }
464:
465: l_element_courant = (*l_element_courant).suivant;
466: }
467: }
468:
469: (*s_etat_processus).pointeur_variable_statique_courante = NULL;
470: return(NULL);
471: }
472:
473: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>