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