Annotation of rpl/src/gestion_variables_statiques.c, revision 1.39
1.1 bertrand 1: /*
2: ================================================================================
1.36 bertrand 3: RPL/2 (R) version 4.1.11
1.30 bertrand 4: Copyright (C) 1989-2012 Dr. BERTRAND Joël
1.1 bertrand 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:
1.11 bertrand 23: #include "rpl-conv.h"
1.1 bertrand 24:
25:
26: /*
27: ================================================================================
1.38 bertrand 28: Routine de retrait des variables statiques
1.1 bertrand 29: ================================================================================
30: Entrée :
31: --------------------------------------------------------------------------------
32: Sortie :
33: --------------------------------------------------------------------------------
34: Effets de bords : néant
35: ================================================================================
36: */
37:
1.38 bertrand 38: // Cette routine libère toutes les variables statiques de niveau non
39: // nul, donc attachées à une expression et non un programme.
1.37 bertrand 40:
1.1 bertrand 41: logical1
1.38 bertrand 42: retrait_variables_statiques_locales(struct_processus *s_etat_processus)
1.1 bertrand 43: {
1.38 bertrand 44: struct_liste_variables_statiques *l_element_courant;
45: struct_liste_variables_statiques *l_element_suivant;
1.37 bertrand 46:
47: unsigned char registre_mode_execution;
1.1 bertrand 48:
1.37 bertrand 49: registre_mode_execution = (*s_etat_processus).mode_execution_programme;
1.38 bertrand 50: l_element_courant = (*s_etat_processus).l_liste_variables_statiques;
1.1 bertrand 51:
1.38 bertrand 52: while(l_element_courant != NULL)
1.37 bertrand 53: {
1.38 bertrand 54: l_element_suivant = (*l_element_courant).suivant;
55:
1.37 bertrand 56: (*s_etat_processus).mode_execution_programme =
1.38 bertrand 57: ((*(*l_element_courant).variable).origine == 'P') ? 'Y' : 'N';
1.37 bertrand 58:
1.38 bertrand 59: if ((*(*l_element_courant).variable).niveau > 0)
1.37 bertrand 60: {
1.38 bertrand 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: }
1.37 bertrand 70: }
71:
1.38 bertrand 72: l_element_courant = l_element_suivant;
1.37 bertrand 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: {
1.38 bertrand 96: int i;
97:
1.37 bertrand 98: struct_arbre_variables *l_variable_courante;
99:
100: struct_liste_variables_statiques *l_nouvel_element;
1.1 bertrand 101:
1.37 bertrand 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);
1.1 bertrand 111: }
112:
1.37 bertrand 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: }
1.1 bertrand 119:
1.37 bertrand 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;
1.38 bertrand 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:
1.37 bertrand 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
1.1 bertrand 134:
1.38 bertrand 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: }
1.37 bertrand 162:
163: l_variable_courante = (*s_etat_processus).s_arbre_variables;
164: ptr = (*s_variable).nom;
165:
166: while((*ptr) != d_code_fin_chaine)
1.1 bertrand 167: {
1.37 bertrand 168: BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
169: uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
170: *ptr));
171:
1.38 bertrand 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++;
1.37 bertrand 187:
1.38 bertrand 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: }
1.37 bertrand 233:
234: l_variable_courante = (*l_variable_courante).noeuds
235: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
236: ptr++;
1.1 bertrand 237: }
1.37 bertrand 238:
239: if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_statiques)))
240: == NULL)
1.1 bertrand 241: {
1.37 bertrand 242: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
243: return(d_erreur);
1.1 bertrand 244: }
245:
1.37 bertrand 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;
1.38 bertrand 253:
254: if ((*l_nouvel_element).suivant != NULL)
255: {
256: (*(*l_nouvel_element).suivant).precedent = l_nouvel_element;
257: }
1.37 bertrand 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;
1.38 bertrand 264: (*l_nouvel_element).feuille = l_variable_courante;
265:
1.37 bertrand 266: return(d_absence_erreur);
1.1 bertrand 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: {
1.37 bertrand 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.
1.1 bertrand 299:
1.37 bertrand 300: l_element_liste_a_supprimer = (*l_element_a_supprimer).reference;
1.1 bertrand 301:
1.37 bertrand 302: // Suppression de la liste des variables statiques
1.1 bertrand 303:
1.37 bertrand 304: if ((*l_element_liste_a_supprimer).precedent != NULL)
305: {
1.39 ! bertrand 306: // L'élément à supprimer n'est pas le premier de la liste.
! 307:
1.37 bertrand 308: (*(*l_element_liste_a_supprimer).precedent).suivant =
309: (*l_element_liste_a_supprimer).suivant;
1.39 ! bertrand 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: }
1.37 bertrand 316: }
317: else
1.1 bertrand 318: {
1.39 ! bertrand 319: // L'élement est le premier de la liste. S'il y a un élément
! 320: // suivant, on le chaîne.
! 321:
1.38 bertrand 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;
1.37 bertrand 329: }
1.1 bertrand 330:
1.37 bertrand 331: free(l_element_liste_a_supprimer);
1.1 bertrand 332:
1.37 bertrand 333: // Suppression depuis la feuille statique. Le champ 'precedent' ne sert
334: // pas car la liste est simplement chaînée.
1.1 bertrand 335:
1.37 bertrand 336: if ((*l_element_a_supprimer).precedent != NULL)
337: {
1.39 ! bertrand 338: // L'élément n'est pas le premier de la liste.
! 339:
1.37 bertrand 340: (*(*l_element_a_supprimer).precedent).suivant =
341: (*l_element_a_supprimer).suivant;
1.39 ! bertrand 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: }
1.37 bertrand 352: }
353: else
354: {
1.39 ! bertrand 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:
1.38 bertrand 362: (*(*l_element_a_supprimer).feuille).feuille_statique
363: = (*l_element_a_supprimer).suivant;
1.37 bertrand 364: }
1.1 bertrand 365:
1.37 bertrand 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:
1.1 bertrand 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:
1.37 bertrand 396: struct_liste_variables_statiques *
1.1 bertrand 397: recherche_variable_statique(struct_processus *s_etat_processus,
398: unsigned char *nom_variable, union_position_variable position,
399: unsigned char origine)
400: {
1.37 bertrand 401: int pointeur;
1.1 bertrand 402:
1.37 bertrand 403: struct_arbre_variables *l_variable_courante;
404: struct_liste_variables_statiques *l_element_courant;
1.1 bertrand 405:
1.37 bertrand 406: unsigned char *ptr;
1.1 bertrand 407:
1.37 bertrand 408: l_variable_courante = (*s_etat_processus).s_arbre_variables;
409: ptr = nom_variable;
1.1 bertrand 410:
1.37 bertrand 411: while((*ptr) != d_code_fin_chaine)
1.1 bertrand 412: {
1.37 bertrand 413: pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
1.1 bertrand 414:
1.37 bertrand 415: if (pointeur < 0)
1.1 bertrand 416: {
1.37 bertrand 417: // Caractère hors de l'alphabet des variables
1.1 bertrand 418:
1.37 bertrand 419: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
420: return(NULL);
1.1 bertrand 421: }
1.37 bertrand 422:
423: if ((*l_variable_courante).noeuds[pointeur] == NULL)
1.1 bertrand 424: {
1.37 bertrand 425: // Le chemin de la variable candidate n'existe pas.
426: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
427: return(NULL);
1.1 bertrand 428: }
429:
1.37 bertrand 430: l_variable_courante = (*l_variable_courante).noeuds[pointeur];
431: ptr++;
1.1 bertrand 432: }
1.37 bertrand 433:
434: if ((*l_variable_courante).feuille_statique != NULL)
1.1 bertrand 435: {
1.37 bertrand 436: // Il existe au moins une variable statique du nom requis.
1.1 bertrand 437:
1.37 bertrand 438: l_element_courant = (*l_variable_courante).feuille_statique;
1.1 bertrand 439:
1.37 bertrand 440: while(l_element_courant != NULL)
1.1 bertrand 441: {
1.37 bertrand 442: if ((*(*l_element_courant).variable).origine == 'P')
1.1 bertrand 443: {
1.37 bertrand 444: if (((*(*l_element_courant).variable).variable_statique.adresse
445: == position.adresse) &&
446: ((*(*l_element_courant).variable).origine == origine))
1.1 bertrand 447: {
1.37 bertrand 448: (*s_etat_processus).pointeur_variable_statique_courante
1.38 bertrand 449: = (*l_element_courant).variable;
1.37 bertrand 450: return(l_element_courant);
1.1 bertrand 451: }
452: }
1.37 bertrand 453: else
1.1 bertrand 454: {
1.37 bertrand 455: if (((*(*l_element_courant).variable).variable_statique.pointeur
456: == position.pointeur) &&
457: ((*(*l_element_courant).variable).origine == origine))
1.1 bertrand 458: {
1.37 bertrand 459: (*s_etat_processus).pointeur_variable_statique_courante
1.38 bertrand 460: = (*l_element_courant).variable;
1.37 bertrand 461: return(l_element_courant);
1.1 bertrand 462: }
463: }
1.38 bertrand 464:
465: l_element_courant = (*l_element_courant).suivant;
1.1 bertrand 466: }
467: }
468:
1.37 bertrand 469: (*s_etat_processus).pointeur_variable_statique_courante = NULL;
470: return(NULL);
1.1 bertrand 471: }
472:
473: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>