Annotation of rpl/src/gestion_variables_statiques.c, revision 1.38
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:
1.38 ! bertrand 106: printf("<0>\n");
1.37 bertrand 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);
1.1 bertrand 112: }
113:
1.37 bertrand 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: }
1.1 bertrand 120:
1.37 bertrand 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;
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;
! 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: }
1.37 bertrand 163:
164: l_variable_courante = (*s_etat_processus).s_arbre_variables;
165: ptr = (*s_variable).nom;
166:
167: while((*ptr) != d_code_fin_chaine)
1.1 bertrand 168: {
1.37 bertrand 169: BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
170: uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
171: *ptr));
172:
1.38 ! bertrand 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++;
1.37 bertrand 188:
1.38 ! bertrand 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: }
1.37 bertrand 234:
235: l_variable_courante = (*l_variable_courante).noeuds
236: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
237: ptr++;
1.1 bertrand 238: }
1.37 bertrand 239:
240: if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_statiques)))
241: == NULL)
1.1 bertrand 242: {
1.37 bertrand 243: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
244: return(d_erreur);
1.1 bertrand 245: }
246:
1.37 bertrand 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;
1.38 ! bertrand 254:
! 255: if ((*l_nouvel_element).suivant != NULL)
! 256: {
! 257: (*(*l_nouvel_element).suivant).precedent = l_nouvel_element;
! 258: }
1.37 bertrand 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;
1.38 ! bertrand 265: (*l_nouvel_element).feuille = l_variable_courante;
! 266:
1.37 bertrand 267: return(d_absence_erreur);
1.1 bertrand 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: {
1.37 bertrand 287: struct_liste_variables_statiques *l_element_a_supprimer;
288: struct_liste_variables_statiques *l_element_liste_a_supprimer;
289:
290: logical1 erreur;
291:
1.38 ! bertrand 292: printf("<1>\n");
1.37 bertrand 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: {
1.38 ! bertrand 297: printf("<2>\n");
1.37 bertrand 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.
1.1 bertrand 302:
1.37 bertrand 303: l_element_liste_a_supprimer = (*l_element_a_supprimer).reference;
1.1 bertrand 304:
1.37 bertrand 305: // Suppression de la liste des variables statiques
1.1 bertrand 306:
1.37 bertrand 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
1.1 bertrand 313: {
1.38 ! bertrand 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;
1.37 bertrand 321: }
1.1 bertrand 322:
1.37 bertrand 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;
1.1 bertrand 331: }
332:
1.37 bertrand 333: free(l_element_liste_a_supprimer);
1.1 bertrand 334:
1.37 bertrand 335: // Suppression depuis la feuille statique. Le champ 'precedent' ne sert
336: // pas car la liste est simplement chaînée.
1.1 bertrand 337:
1.37 bertrand 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;
1.38 ! bertrand 346: (*(*l_element_a_supprimer).feuille).feuille_statique
! 347: = (*l_element_a_supprimer).suivant;
1.37 bertrand 348: }
1.1 bertrand 349:
1.37 bertrand 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
1.1 bertrand 356: {
1.37 bertrand 357: (*(*l_element_a_supprimer).precedent).suivant = NULL;
1.1 bertrand 358: }
359:
1.37 bertrand 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:
1.1 bertrand 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:
1.37 bertrand 390: struct_liste_variables_statiques *
1.1 bertrand 391: recherche_variable_statique(struct_processus *s_etat_processus,
392: unsigned char *nom_variable, union_position_variable position,
393: unsigned char origine)
394: {
1.37 bertrand 395: int pointeur;
1.1 bertrand 396:
1.37 bertrand 397: struct_arbre_variables *l_variable_courante;
398: struct_liste_variables_statiques *l_element_courant;
1.1 bertrand 399:
1.37 bertrand 400: unsigned char *ptr;
1.1 bertrand 401:
1.37 bertrand 402: l_variable_courante = (*s_etat_processus).s_arbre_variables;
403: ptr = nom_variable;
1.1 bertrand 404:
1.37 bertrand 405: while((*ptr) != d_code_fin_chaine)
1.1 bertrand 406: {
1.37 bertrand 407: pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
1.1 bertrand 408:
1.37 bertrand 409: if (pointeur < 0)
1.1 bertrand 410: {
1.37 bertrand 411: // Caractère hors de l'alphabet des variables
1.1 bertrand 412:
1.37 bertrand 413: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
414: return(NULL);
1.1 bertrand 415: }
1.37 bertrand 416:
417: if ((*l_variable_courante).noeuds[pointeur] == NULL)
1.1 bertrand 418: {
1.37 bertrand 419: // Le chemin de la variable candidate n'existe pas.
420: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
421: return(NULL);
1.1 bertrand 422: }
423:
1.37 bertrand 424: l_variable_courante = (*l_variable_courante).noeuds[pointeur];
425: ptr++;
1.1 bertrand 426: }
1.37 bertrand 427:
428: if ((*l_variable_courante).feuille_statique != NULL)
1.1 bertrand 429: {
1.37 bertrand 430: // Il existe au moins une variable statique du nom requis.
1.1 bertrand 431:
1.37 bertrand 432: l_element_courant = (*l_variable_courante).feuille_statique;
1.1 bertrand 433:
1.37 bertrand 434: while(l_element_courant != NULL)
1.1 bertrand 435: {
1.37 bertrand 436: if ((*(*l_element_courant).variable).origine == 'P')
1.1 bertrand 437: {
1.37 bertrand 438: if (((*(*l_element_courant).variable).variable_statique.adresse
439: == position.adresse) &&
440: ((*(*l_element_courant).variable).origine == origine))
1.1 bertrand 441: {
1.37 bertrand 442: (*s_etat_processus).pointeur_variable_statique_courante
1.38 ! bertrand 443: = (*l_element_courant).variable;
1.37 bertrand 444: return(l_element_courant);
1.1 bertrand 445: }
446: }
1.37 bertrand 447: else
1.1 bertrand 448: {
1.37 bertrand 449: if (((*(*l_element_courant).variable).variable_statique.pointeur
450: == position.pointeur) &&
451: ((*(*l_element_courant).variable).origine == origine))
1.1 bertrand 452: {
1.37 bertrand 453: (*s_etat_processus).pointeur_variable_statique_courante
1.38 ! bertrand 454: = (*l_element_courant).variable;
1.37 bertrand 455: return(l_element_courant);
1.1 bertrand 456: }
457: }
1.38 ! bertrand 458:
! 459: l_element_courant = (*l_element_courant).suivant;
1.1 bertrand 460: }
461: }
462:
1.37 bertrand 463: (*s_etat_processus).pointeur_variable_statique_courante = NULL;
464: return(NULL);
1.1 bertrand 465: }
466:
467: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>