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