Annotation of rpl/src/gestion_variables_statiques.c, revision 1.37
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.37 ! bertrand 28: Routine d'ajout d'un bouchon dans la liste des variables statiques
1.1 bertrand 29: ================================================================================
30: Entrée :
31: --------------------------------------------------------------------------------
32: Sortie :
33: --------------------------------------------------------------------------------
34: Effets de bords : néant
35: ================================================================================
36: */
37:
1.37 ! bertrand 38: // Routine ajoutant à la liste des variables statiques créées un 'bouchon'
! 39: // qui est un enregistrement dont la variable est NULL. Cela permet
! 40: // d'effacer les variables statiques créées dans une expression évaluées car,
! 41: // l'adresse de ces variables changeant à chaque évaluation, elles ne sont
! 42: // pas utilisables et constituent une fuite de mémoire
! 43:
1.1 bertrand 44: logical1
1.37 ! bertrand 45: ajout_bouchon_variable_statique(struct_processus *s_etat_processus)
1.1 bertrand 46: {
1.37 ! bertrand 47: struct_liste_variables_statiques *l_tete_liste;
! 48:
! 49: l_tete_liste = (*s_etat_processus).l_liste_variables_statiques;
! 50:
! 51: if (((*s_etat_processus).l_liste_variables_statiques =
! 52: malloc(sizeof(struct_liste_variables_statiques))) == NULL)
! 53: {
! 54: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 55: return(d_erreur);
! 56: }
! 57:
! 58: (*(*s_etat_processus).l_liste_variables_statiques).variable = NULL;
! 59: (*(*s_etat_processus).l_liste_variables_statiques).suivant = l_tete_liste;
! 60: (*(*s_etat_processus).l_liste_variables_statiques).precedent = NULL;
! 61: (*l_tete_liste).precedent = (*s_etat_processus).l_liste_variables_statiques;
! 62:
! 63: return(d_absence_erreur);
! 64: }
1.1 bertrand 65:
66:
1.37 ! bertrand 67: /*
! 68: ================================================================================
! 69: Routine de retrait des variables statiques
! 70: ================================================================================
! 71: Entrée :
! 72: --------------------------------------------------------------------------------
! 73: Sortie :
! 74: --------------------------------------------------------------------------------
! 75: Effets de bords : néant
! 76: ================================================================================
! 77: */
1.1 bertrand 78:
1.37 ! bertrand 79: // Cette routine libère toutes les variables statiques jusqu'au prochain
! 80: // bouchon ou jusqu'à la fin de la liste si aucun bouchon n'est rencontré.
! 81:
! 82: logical1
! 83: retrait_variables_statiques(struct_processus *s_etat_processus)
! 84: {
! 85: unsigned char registre_mode_execution;
1.1 bertrand 86:
1.37 ! bertrand 87: registre_mode_execution = (*s_etat_processus).mode_execution_programme;
1.1 bertrand 88:
1.37 ! bertrand 89: while((*s_etat_processus).l_liste_variables_statiques != NULL)
! 90: {
! 91: (*s_etat_processus).mode_execution_programme =
! 92: ((*(*(*s_etat_processus).l_liste_variables_statiques)
! 93: .variable).origine == 'P') ? 'Y' : 'N';
! 94:
! 95: if ((*(*s_etat_processus).l_liste_variables_statiques).variable == NULL)
! 96: {
! 97: // On vient de tomber sur un bouchon...
! 98: (*s_etat_processus).l_liste_variables_statiques =
! 99: (*(*s_etat_processus).l_liste_variables_statiques).suivant;
! 100: free((*(*s_etat_processus).l_liste_variables_statiques).precedent);
! 101: (*(*s_etat_processus).l_liste_variables_statiques).precedent = NULL;
! 102: break;
! 103: }
! 104:
! 105: if (retrait_variable_statique(s_etat_processus, (*(*(*s_etat_processus)
! 106: .l_liste_variables_statiques).variable).nom,
! 107: (*(*(*s_etat_processus).l_liste_variables_statiques).variable)
! 108: .variable_statique) == d_erreur)
1.1 bertrand 109: {
1.37 ! bertrand 110: (*s_etat_processus).mode_execution_programme =
! 111: registre_mode_execution;
1.1 bertrand 112: return(d_erreur);
113: }
1.37 ! bertrand 114: }
! 115:
! 116: (*s_etat_processus).mode_execution_programme = registre_mode_execution;
! 117: return(d_absence_erreur);
! 118: }
! 119:
! 120:
! 121: /*
! 122: ================================================================================
! 123: Routine de création d'une nouvelle variable statique
! 124: ================================================================================
! 125: Entrée :
! 126: --------------------------------------------------------------------------------
! 127: Sortie :
! 128: --------------------------------------------------------------------------------
! 129: Effets de bords : néant
! 130: ================================================================================
! 131: */
! 132:
! 133: logical1
! 134: creation_variable_statique(struct_processus *s_etat_processus,
! 135: struct_variable_statique *s_variable)
! 136: {
! 137: struct_arbre_variables *l_variable_courante;
! 138:
! 139: struct_liste_variables_statiques *l_nouvel_element;
1.1 bertrand 140:
1.37 ! bertrand 141: unsigned char *ptr;
! 142:
! 143: // Ajout de la variable en tête de la liste des variables statiques
! 144:
! 145: if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_statiques)))
! 146: == NULL)
! 147: {
! 148: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 149: return(d_erreur);
1.1 bertrand 150: }
151:
1.37 ! bertrand 152: if (((*l_nouvel_element).variable = malloc(sizeof(
! 153: struct_variable_statique))) == NULL)
! 154: {
! 155: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 156: return(d_erreur);
! 157: }
1.1 bertrand 158:
1.37 ! bertrand 159: (*(*l_nouvel_element).variable) = (*s_variable);
! 160: (*l_nouvel_element).suivant = (*s_etat_processus)
! 161: .l_liste_variables_statiques;
! 162: (*(*s_etat_processus).l_liste_variables_statiques).precedent
! 163: = l_nouvel_element;
! 164: (*l_nouvel_element).precedent = NULL;
! 165: (*s_etat_processus).l_liste_variables_statiques = l_nouvel_element;
! 166:
! 167: // Ajout de la variable à la feuille statique de l'arbre des variables
1.1 bertrand 168:
1.37 ! bertrand 169: BUG((*s_etat_processus).s_arbre_variables == NULL,
! 170: uprintf("(*s_etat_processus).s_arbre_variables=NULL\n"));
! 171:
! 172: l_variable_courante = (*s_etat_processus).s_arbre_variables;
! 173: ptr = (*s_variable).nom;
! 174:
! 175: while((*ptr) != d_code_fin_chaine)
1.1 bertrand 176: {
1.37 ! bertrand 177: BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
! 178: uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
! 179: *ptr));
! 180:
! 181: // La feuille doit préexister car la variable statique est toujours
! 182: // créée depuis une variable locale.
! 183:
! 184: BUG((*l_variable_courante).noeuds[(*s_etat_processus)
! 185: .pointeurs_caracteres_variables[*ptr]] == NULL,
! 186: uprintf("Variable=\"%s\", (*ptr)='%c', nullified folder\n"));
! 187:
! 188: l_variable_courante = (*l_variable_courante).noeuds
! 189: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
! 190: ptr++;
1.1 bertrand 191: }
1.37 ! bertrand 192:
! 193: if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_statiques)))
! 194: == NULL)
1.1 bertrand 195: {
1.37 ! bertrand 196: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 197: return(d_erreur);
1.1 bertrand 198: }
199:
1.37 ! bertrand 200: // Dans la feuille statique de l'arbre des variables, on ne balaie
! 201: // les variables que dans l'ordre. Le champ 'reference' est alors utilisé
! 202: // pour sauvegarder une référence vers la liste des variables statiques
! 203: // pour pouvoir purger l'élément en cas de besoin.
! 204:
! 205: (*l_nouvel_element).suivant = (*l_variable_courante).feuille_statique;
! 206: (*l_nouvel_element).precedent = NULL;
! 207: (*(*l_nouvel_element).suivant).precedent = l_nouvel_element;
! 208:
! 209: (*l_nouvel_element).reference =
! 210: (*s_etat_processus).l_liste_variables_statiques;
! 211: (*l_nouvel_element).variable = (*(*s_etat_processus)
! 212: .l_liste_variables_statiques).variable;
! 213: (*l_variable_courante).feuille_statique = l_nouvel_element;
! 214: return(d_absence_erreur);
1.1 bertrand 215: }
216:
217:
218: /*
219: ================================================================================
220: Procédure de retrait d'une variable statique de la base
221: ================================================================================
222: Entrée :
223: --------------------------------------------------------------------------------
224: Sortie :
225: --------------------------------------------------------------------------------
226: Effets de bord : néant
227: ================================================================================
228: */
229:
230: logical1
231: retrait_variable_statique(struct_processus *s_etat_processus,
232: unsigned char *nom_variable, union_position_variable position)
233: {
1.37 ! bertrand 234: struct_liste_variables_statiques *l_element_a_supprimer;
! 235: struct_liste_variables_statiques *l_element_liste_a_supprimer;
! 236:
! 237: logical1 erreur;
! 238:
! 239: if ((l_element_a_supprimer = recherche_variable_statique(s_etat_processus,
! 240: nom_variable, position, ((*s_etat_processus)
! 241: .mode_execution_programme == 'Y') ? 'P' : 'E')) != NULL)
! 242: {
! 243: // (*s_etat_processus).pointeur_variable_statique_courante
! 244: // pointe sur la variable à éliminer. Cette variable est celle qui
! 245: // est présente dans l'une des feuilles statiques de l'arbre des
! 246: // variables.
1.1 bertrand 247:
1.37 ! bertrand 248: l_element_liste_a_supprimer = (*l_element_a_supprimer).reference;
1.1 bertrand 249:
1.37 ! bertrand 250: // Suppression de la liste des variables statiques
1.1 bertrand 251:
1.37 ! bertrand 252: if ((*l_element_liste_a_supprimer).precedent != NULL)
! 253: {
! 254: (*(*l_element_liste_a_supprimer).precedent).suivant =
! 255: (*l_element_liste_a_supprimer).suivant;
! 256: }
! 257: else
1.1 bertrand 258: {
1.37 ! bertrand 259: (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
! 260: }
1.1 bertrand 261:
1.37 ! bertrand 262: if ((*l_element_liste_a_supprimer).suivant != NULL)
! 263: {
! 264: (*(*l_element_liste_a_supprimer).suivant).precedent =
! 265: (*l_element_liste_a_supprimer).precedent;
! 266: }
! 267: else
! 268: {
! 269: (*(*l_element_liste_a_supprimer).precedent).suivant = NULL;
1.1 bertrand 270: }
271:
1.37 ! bertrand 272: free(l_element_liste_a_supprimer);
1.1 bertrand 273:
1.37 ! bertrand 274: // Suppression depuis la feuille statique. Le champ 'precedent' ne sert
! 275: // pas car la liste est simplement chaînée.
1.1 bertrand 276:
1.37 ! bertrand 277: if ((*l_element_a_supprimer).precedent != NULL)
! 278: {
! 279: (*(*l_element_a_supprimer).precedent).suivant =
! 280: (*l_element_a_supprimer).suivant;
! 281: }
! 282: else
! 283: {
! 284: (*(*l_element_a_supprimer).suivant).precedent = NULL;
! 285: }
1.1 bertrand 286:
1.37 ! bertrand 287: if ((*l_element_a_supprimer).suivant != NULL)
! 288: {
! 289: (*(*l_element_a_supprimer).suivant).precedent =
! 290: (*l_element_a_supprimer).precedent;
! 291: }
! 292: else
1.1 bertrand 293: {
1.37 ! bertrand 294: (*(*l_element_a_supprimer).precedent).suivant = NULL;
1.1 bertrand 295: }
296:
1.37 ! bertrand 297: liberation(s_etat_processus, (*(*l_element_a_supprimer).variable)
! 298: .objet);
! 299: free((*(*l_element_a_supprimer).variable).nom);
! 300: free((*l_element_a_supprimer).variable);
! 301: free(l_element_a_supprimer);
! 302:
1.1 bertrand 303: erreur = d_absence_erreur;
304: }
305: else
306: {
307: erreur = d_erreur;
308: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
309: }
310:
311: return erreur;
312: }
313:
314:
315: /*
316: ================================================================================
317: Procédure de recherche d'une variable statique par son nom dans la base
318: ================================================================================
319: Entrée :
320: --------------------------------------------------------------------------------
321: Sortie :
322: --------------------------------------------------------------------------------
323: Effets de bord : néant
324: ================================================================================
325: */
326:
1.37 ! bertrand 327: struct_liste_variables_statiques *
1.1 bertrand 328: recherche_variable_statique(struct_processus *s_etat_processus,
329: unsigned char *nom_variable, union_position_variable position,
330: unsigned char origine)
331: {
1.37 ! bertrand 332: int pointeur;
1.1 bertrand 333:
1.37 ! bertrand 334: struct_arbre_variables *l_variable_courante;
! 335: struct_liste_variables_statiques *l_element_courant;
1.1 bertrand 336:
1.37 ! bertrand 337: unsigned char *ptr;
1.1 bertrand 338:
1.37 ! bertrand 339: l_variable_courante = (*s_etat_processus).s_arbre_variables;
! 340: ptr = nom_variable;
1.1 bertrand 341:
1.37 ! bertrand 342: while((*ptr) != d_code_fin_chaine)
1.1 bertrand 343: {
1.37 ! bertrand 344: pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
1.1 bertrand 345:
1.37 ! bertrand 346: if (pointeur < 0)
1.1 bertrand 347: {
1.37 ! bertrand 348: // Caractère hors de l'alphabet des variables
1.1 bertrand 349:
1.37 ! bertrand 350: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
! 351: return(NULL);
1.1 bertrand 352: }
1.37 ! bertrand 353:
! 354: if ((*l_variable_courante).noeuds[pointeur] == NULL)
1.1 bertrand 355: {
1.37 ! bertrand 356: // Le chemin de la variable candidate n'existe pas.
! 357: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
! 358: return(NULL);
1.1 bertrand 359: }
360:
1.37 ! bertrand 361: l_variable_courante = (*l_variable_courante).noeuds[pointeur];
! 362: ptr++;
1.1 bertrand 363: }
1.37 ! bertrand 364:
! 365: if ((*l_variable_courante).feuille_statique != NULL)
1.1 bertrand 366: {
1.37 ! bertrand 367: // Il existe au moins une variable statique du nom requis.
1.1 bertrand 368:
1.37 ! bertrand 369: l_element_courant = (*l_variable_courante).feuille_statique;
1.1 bertrand 370:
1.37 ! bertrand 371: while(l_element_courant != NULL)
1.1 bertrand 372: {
1.37 ! bertrand 373: if ((*(*l_element_courant).variable).origine == 'P')
1.1 bertrand 374: {
1.37 ! bertrand 375: if (((*(*l_element_courant).variable).variable_statique.adresse
! 376: == position.adresse) &&
! 377: ((*(*l_element_courant).variable).origine == origine))
1.1 bertrand 378: {
1.37 ! bertrand 379: (*s_etat_processus).pointeur_variable_statique_courante
! 380: = (*l_element_courant).variable;
! 381: return(l_element_courant);
1.1 bertrand 382: }
383: }
1.37 ! bertrand 384: else
1.1 bertrand 385: {
1.37 ! bertrand 386: if (((*(*l_element_courant).variable).variable_statique.pointeur
! 387: == position.pointeur) &&
! 388: ((*(*l_element_courant).variable).origine == origine))
1.1 bertrand 389: {
1.37 ! bertrand 390: (*s_etat_processus).pointeur_variable_statique_courante
! 391: = (*l_element_courant).variable;
! 392: return(l_element_courant);
1.1 bertrand 393: }
394: }
395: }
396: }
397:
1.37 ! bertrand 398: (*s_etat_processus).pointeur_variable_statique_courante = NULL;
! 399: return(NULL);
1.1 bertrand 400: }
401:
402: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>