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