Annotation of rpl/src/gestion_variables.c, revision 1.33
1.1 bertrand 1: /*
2: ================================================================================
1.21 bertrand 3: RPL/2 (R) version 4.1.0.prerelease.0
1.19 bertrand 4: Copyright (C) 1989-2011 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.14 bertrand 23: #include "rpl-conv.h"
1.1 bertrand 24:
25:
26: /*
27: ================================================================================
1.33 ! bertrand 28: Fonction de debug
! 29: ================================================================================
! 30: Entrée :
! 31: --------------------------------------------------------------------------------
! 32: Sortie :
! 33: --------------------------------------------------------------------------------
! 34: Effets de bords : néant
! 35: ================================================================================
! 36: */
! 37:
! 38: static void
! 39: liste_variables_par_niveaux(struct_processus *s_etat_processus)
! 40: {
! 41: int c;
! 42:
! 43: logical1 fin;
! 44:
! 45: struct_liste_variables *l;
! 46:
! 47: struct_liste_chainee *e;
! 48:
! 49: printf("===========================================================\n");
! 50: printf(" Liste des variables par niveaux\n");
! 51: printf("===========================================================\n");
! 52:
! 53: printf("Backward\n");
! 54: l = (*s_etat_processus).l_liste_variables_par_niveau;
! 55: c = 0;
! 56: fin = d_faux;
! 57:
! 58: do
! 59: {
! 60: l = l->precedent;
! 61: e = l->liste;
! 62:
! 63: while(e != NULL)
! 64: {
! 65: printf("%s (%p, %d) ", ((struct_variable *) e->donnee)->nom,
! 66: e->donnee, ((struct_variable *) e->donnee)->niveau);
! 67: e = e->suivant;
! 68: c++;
! 69: if (c > 100)
! 70: {
! 71: fin = d_vrai;
! 72: break;
! 73: }
! 74: }
! 75:
! 76: printf("\n");
! 77:
! 78: } while(l != (*s_etat_processus).l_liste_variables_par_niveau);
! 79:
! 80: printf("Forward\n");
! 81: l = (*s_etat_processus).l_liste_variables_par_niveau;
! 82: c = 0;
! 83:
! 84: do
! 85: {
! 86: e = l->liste;
! 87:
! 88: while(e != NULL)
! 89: {
! 90: printf("%s (%p, %d) ", ((struct_variable *) e->donnee)->nom,
! 91: e->donnee, ((struct_variable *) e->donnee)->niveau);
! 92: e = e->suivant;
! 93: c++;
! 94: if (c > 100) exit(0);
! 95: }
! 96:
! 97: printf("\n");
! 98:
! 99: l = l->suivant;
! 100: } while(l != (*s_etat_processus).l_liste_variables_par_niveau);
! 101:
! 102: printf("===========================================================\n");
! 103:
! 104: if (fin == d_vrai) exit(0);
! 105:
! 106: return;
! 107: }
! 108:
! 109: static void
! 110: liste_variables_tas(struct_processus *s_etat_processus,
! 111: struct_arbre_variables *arbre)
! 112: {
! 113: int c;
! 114: int i;
! 115:
! 116: logical1 fin;
! 117:
! 118: struct_liste_variables *l;
! 119:
! 120: fin = d_faux;
! 121:
! 122: if ((*arbre).feuille != NULL)
! 123: {
! 124: printf("Feuille %p\n", (*arbre).feuille);
! 125:
! 126: printf(" Backward\n");
! 127:
! 128: l = (*arbre).feuille;
! 129: c = 0;
! 130: fin = d_faux;
! 131:
! 132: do
! 133: {
! 134: l = l->precedent;
! 135: c++;
! 136: if (c > 100)
! 137: {
! 138: fin = d_vrai;
! 139: break;
! 140: }
! 141: printf(" %s (%p, %d)\n", l->variable->nom, l->variable,
! 142: l->variable->niveau);
! 143: } while((*arbre).feuille != l);
! 144:
! 145: printf(" Forward\n");
! 146:
! 147: l = (*arbre).feuille;
! 148: c = 0;
! 149:
! 150: do
! 151: {
! 152: c++;
! 153: if (c > 100) exit(0);
! 154: printf(" %s (%p, %d)\n", l->variable->nom, l->variable,
! 155: l->variable->niveau);
! 156: l = l->suivant;
! 157: } while((*arbre).feuille != l);
! 158: }
! 159:
! 160: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
! 161: {
! 162: if ((*arbre).noeuds[i] != NULL)
! 163: {
! 164: liste_variables_tas(s_etat_processus, (*arbre).noeuds[i]);
! 165: }
! 166: }
! 167:
! 168: if (fin == d_vrai) exit(0);
! 169:
! 170: return;
! 171: }
! 172:
! 173:
! 174: static void
! 175: liste_variables_par_feuilles(struct_processus *s_etat_processus)
! 176: {
! 177: printf("===========================================================\n");
! 178: printf(" Liste des variables sur le tas\n");
! 179: printf("===========================================================\n");
! 180:
! 181: liste_variables_tas(s_etat_processus,
! 182: (*s_etat_processus).s_arbre_variables);
! 183:
! 184: printf("===========================================================\n");
! 185:
! 186: return;
! 187: }
! 188:
! 189:
! 190: /*
! 191: ================================================================================
1.1 bertrand 192: Routine de création d'une nouvelle variable
1.33 ! bertrand 193: ================================================================================
! 194: Entrée : autorisation_creation_variable_statique vaut 'v' ou 's'.
! 195: dans le cas 'v', la variable est volatile.
! 196: dans le cas 's', elle est statique.
! 197: Entrée : autorisation_creation_variable_partagee vaut 'p' ou 's'.
! 198: dans le cas 'p', la variable est privée.
! 199: dans le cas 's', elle est partagée.
1.1 bertrand 200: --------------------------------------------------------------------------------
201: Sortie :
202: --------------------------------------------------------------------------------
203: Effets de bords : néant
204: ================================================================================
205: */
206:
1.25 bertrand 207: static logical1
208: ajout_variable(struct_processus *s_etat_processus, struct_variable *s_variable)
1.1 bertrand 209: {
1.25 bertrand 210: int i;
211:
1.33 ! bertrand 212: logical1 niveau_acceptable;
! 213:
1.25 bertrand 214: struct_liste_variables *l_nouvelle_variable;
215: struct_liste_variables *l_variable_candidate;
1.33 ! bertrand 216:
1.28 bertrand 217: struct_arbre_variables *l_variable_courante;
218: struct_arbre_variables *l_variable_precedente;
1.1 bertrand 219:
1.25 bertrand 220: struct_liste_chainee *l_nouvel_element;
1.1 bertrand 221:
1.25 bertrand 222: unsigned char *ptr;
1.1 bertrand 223:
1.31 bertrand 224: void *pointeur_variable_cree;
225:
1.25 bertrand 226: if ((*s_etat_processus).s_arbre_variables == NULL)
1.1 bertrand 227: {
1.25 bertrand 228: if (((*s_etat_processus).s_arbre_variables =
229: malloc(sizeof(struct_arbre_variables))) == NULL)
230: {
231: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
232: return(d_erreur);
233: }
234:
235: (*(*s_etat_processus).s_arbre_variables).feuille = NULL;
236: (*(*s_etat_processus).s_arbre_variables).noeuds_utilises = 0;
1.31 bertrand 237: (*(*s_etat_processus).s_arbre_variables).indice_tableau_pere = -1;
1.28 bertrand 238: (*(*s_etat_processus).s_arbre_variables).noeud_pere = NULL;
1.1 bertrand 239:
1.30 bertrand 240: if (((*(*s_etat_processus).s_arbre_variables).noeuds =
1.25 bertrand 241: malloc((*s_etat_processus).nombre_caracteres_variables
242: * sizeof(struct_arbre_variables))) == NULL)
1.1 bertrand 243: {
1.25 bertrand 244: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
245: return(d_erreur);
246: }
247:
248: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
249: {
1.28 bertrand 250: (*(*s_etat_processus).s_arbre_variables).noeuds[i] = NULL;
1.25 bertrand 251: }
252: }
253:
1.28 bertrand 254: l_variable_precedente = NULL;
1.25 bertrand 255: l_variable_courante = (*s_etat_processus).s_arbre_variables;
256: ptr = (*s_variable).nom;
257:
258: while((*ptr) != d_code_fin_chaine)
259: {
260: BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
261: printf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
262: *ptr));
263:
1.28 bertrand 264: if ((*l_variable_courante).noeuds[(*s_etat_processus)
1.25 bertrand 265: .pointeurs_caracteres_variables[*ptr]] == NULL)
266: {
1.31 bertrand 267: // Le noeud n'existe pas encore, on le crée et on le marque
268: // comme utilisé dans la structure parente.
1.25 bertrand 269:
1.28 bertrand 270: if (((*l_variable_courante).noeuds[(*s_etat_processus)
1.25 bertrand 271: .pointeurs_caracteres_variables[*ptr]] =
272: malloc(sizeof(struct_arbre_variables))) == NULL)
273: {
274: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
275: return(d_erreur);
276: }
277:
1.28 bertrand 278: (*l_variable_courante).noeuds_utilises++;
1.31 bertrand 279:
280: // La feuille est par défaut vide et aucun élément du tableau noeuds
281: // (les branches qui peuvent être issues de ce nouveau noeud)
282: // n'est encore utilisée.
283:
1.28 bertrand 284: (*(*l_variable_courante).noeuds[(*s_etat_processus)
1.25 bertrand 285: .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
1.28 bertrand 286: (*(*l_variable_courante).noeuds[(*s_etat_processus)
1.25 bertrand 287: .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
1.31 bertrand 288:
289: // Le champ noeud_pere de la structure créée pointe sur
290: // la structure parente et l'indice tableau_pere correspond à la
291: // position réelle dans le tableau noeuds[] de la structure parente
292: // du noeud courant. Cette valeur sera utilisée lors de la
293: // destruction du noeud pour annuler le pointeur contenu dans
294: // le tableau noeuds[] de la structure parente.
295:
1.28 bertrand 296: (*(*l_variable_courante).noeuds[(*s_etat_processus)
297: .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
1.31 bertrand 298: l_variable_courante;
299: (*(*l_variable_courante).noeuds[(*s_etat_processus)
300: .pointeurs_caracteres_variables[*ptr]])
301: .indice_tableau_pere = (*s_etat_processus)
302: .pointeurs_caracteres_variables[*ptr];
303:
304: // Allocation du tableau noeuds[] et initialisation à zéro de
305: // tous les pointeurs.
1.25 bertrand 306:
1.28 bertrand 307: if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
308: .pointeurs_caracteres_variables[*ptr]]).noeuds =
1.25 bertrand 309: malloc((*s_etat_processus).nombre_caracteres_variables
310: * sizeof(struct_arbre_variables))) == NULL)
311: {
312: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
313: return(d_erreur);
314: }
315:
316: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
317: {
1.28 bertrand 318: (*(*l_variable_courante).noeuds[(*s_etat_processus)
319: .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
320: = NULL;
1.25 bertrand 321: }
322: }
323:
1.28 bertrand 324: l_variable_precedente = l_variable_courante;
325: l_variable_courante = (*l_variable_courante).noeuds
1.25 bertrand 326: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
327: ptr++;
328: }
329:
330: if ((*l_variable_courante).feuille == NULL)
331: {
332: // Aucune variable de même nom préexiste. On alloue le premier
333: // élément de la liste doublement chaînée contenant toutes les
334: // variables de même nom. Cette liste boucle en premier lieu sur
335: // elle-même.
336:
337: if (((*l_variable_courante).feuille = malloc(
338: sizeof(struct_liste_variables))) == NULL)
339: {
340: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
341: return(d_erreur);
342: }
343:
344: (*(*l_variable_courante).feuille).suivant =
345: (*l_variable_courante).feuille;
346: (*(*l_variable_courante).feuille).precedent =
347: (*l_variable_courante).feuille;
1.28 bertrand 348: (*(*l_variable_courante).feuille).noeud_pere = l_variable_precedente;
1.32 bertrand 349: (*(*l_variable_courante).feuille).noeud = l_variable_courante;
1.25 bertrand 350:
351: // Allocation de la variable sur l'élément de la liste.
352:
353: if (((*(*l_variable_courante).feuille).variable =
354: malloc(sizeof(struct_variable))) == NULL)
355: {
356: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
357: return(d_erreur);
358: }
359:
360: (*((struct_variable *) (*(*l_variable_courante).feuille).variable)) =
361: (*s_variable);
1.31 bertrand 362: pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
1.25 bertrand 363: }
364: else
365: {
1.28 bertrand 366: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
367: == NULL)
368: {
369: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
370: return(d_erreur);
371: }
372:
1.25 bertrand 373: if ((*s_variable).niveau > 1)
374: {
375: // Cas d'une variable locale
376:
377: // Si le niveau de la dernière variable de même nom est
378: // supérieur au niveau de la variable locale que l'on veut
379: // enregistrer dans la liste, cette liste est incohérente.
380:
381: BUG((*(*(*l_variable_courante).feuille).variable).niveau >=
382: (*s_variable).niveau,
383: printf("Variable=\"%s\"\n", (*s_variable).nom));
384:
385: // On ajoute la variable à la liste existante.
386:
387: (*l_nouvelle_variable).suivant = (*l_variable_courante).feuille;
388: (*l_nouvelle_variable).precedent = (*(*l_variable_courante).feuille)
389: .precedent;
1.28 bertrand 390: (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
1.33 ! bertrand 391: (*l_nouvelle_variable).noeud = l_variable_courante;
1.25 bertrand 392: (*(*(*l_variable_courante).feuille).precedent).suivant =
393: l_nouvelle_variable;
394: (*(*l_variable_courante).feuille).precedent =
395: l_nouvelle_variable;
396: (*l_variable_courante).feuille = l_nouvelle_variable;
397:
398: if (((*(*l_variable_courante).feuille).variable =
399: malloc(sizeof(struct_variable))) == NULL)
400: {
401: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
402: return(d_erreur);
403: }
404:
405: (*((struct_variable *) (*(*l_variable_courante).feuille).variable))
406: = (*s_variable);
1.31 bertrand 407: pointeur_variable_cree = (*(*l_variable_courante).feuille).variable;
1.1 bertrand 408: }
409: else
410: {
1.25 bertrand 411: // Cas d'une variable globale (niveau 0 [définitions] ou 1
412: // [variables globales])
413:
414: l_variable_candidate = (*l_variable_courante).feuille;
415:
416: do
417: {
418: // S'il y a déjà une variable de même niveau, la pile
419: // est incohérente.
420:
421: BUG((*(*l_variable_candidate).variable).niveau ==
422: (*s_variable).niveau,
423: printf("Variable=\"%s\"\n", (*s_variable).nom));
424:
425: l_variable_candidate = (*l_variable_candidate).precedent;
426: } while((l_variable_candidate != (*l_variable_courante).feuille) &&
427: ((*(*l_variable_candidate).variable).niveau <= 1));
428:
429: if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
430: .niveau > 1)
431: {
432: // Ajout inconditionnel des variables de niveaux 0 et 1
433: }
434: else
1.1 bertrand 435: {
1.25 bertrand 436: l_variable_candidate = (*(*l_variable_courante).feuille)
437: .precedent;
438: }
439:
440: (*l_nouvelle_variable).suivant = l_variable_candidate;
441: (*l_nouvelle_variable).precedent = (*l_variable_candidate)
442: .precedent;
1.28 bertrand 443: (*l_nouvelle_variable).noeud_pere = l_variable_precedente;
1.33 ! bertrand 444: (*l_nouvelle_variable).noeud = l_variable_courante;
1.25 bertrand 445: (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
446: (*l_variable_candidate).precedent = l_nouvelle_variable;
447:
448: if (((*l_nouvelle_variable).variable =
449: malloc(sizeof(struct_variable))) == NULL)
450: {
451: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
452: return(d_erreur);
453: }
454:
455: (*(*l_nouvelle_variable).variable) = (*s_variable);
1.31 bertrand 456: pointeur_variable_cree = (*l_nouvelle_variable).variable;
1.1 bertrand 457: }
1.25 bertrand 458: }
459:
460: // Ajout de la variable nouvellement créée à la liste par niveaux.
461: // Le pointeur contenu dans la structure de description du processus indique
462: // toujours le plus haut niveau utilisé.
463:
464: if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
465: {
466: // Le niveau courant n'existe pas. Il est créé.
467:
468: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
469: == NULL)
470: {
471: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
472: return(d_erreur);
473: }
474:
475: (*l_nouvelle_variable).suivant = l_nouvelle_variable;
476: (*l_nouvelle_variable).precedent = l_nouvelle_variable;
1.28 bertrand 477: (*l_nouvelle_variable).noeud_pere = NULL;
1.31 bertrand 478: (*l_nouvelle_variable).liste = NULL;
1.25 bertrand 479:
480: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
1.33 ! bertrand 481:
! 482: // Ajout de la variable en tête de la liste
! 483:
! 484: if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
! 485: {
! 486: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 487: return(d_erreur);
! 488: }
! 489:
! 490: (*l_nouvel_element).suivant = (*(*s_etat_processus)
! 491: .l_liste_variables_par_niveau).liste;
! 492: (*l_nouvel_element).donnee = pointeur_variable_cree;
! 493: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
! 494: l_nouvel_element;
1.25 bertrand 495: }
496: else if ((*s_variable).niveau > (*((struct_variable *)
497: (*(*(*s_etat_processus).l_liste_variables_par_niveau).liste)
498: .donnee)).niveau)
499: {
500: // Le niveau courant n'existe pas. Il est créé.
1.1 bertrand 501:
1.25 bertrand 502: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
503: == NULL)
1.1 bertrand 504: {
505: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
506: return(d_erreur);
507: }
508:
1.25 bertrand 509: (*l_nouvelle_variable).suivant = (*s_etat_processus)
510: .l_liste_variables_par_niveau;
511: (*l_nouvelle_variable).precedent = (*(*s_etat_processus)
512: .l_liste_variables_par_niveau).precedent;
1.28 bertrand 513: (*l_nouvelle_variable).noeud_pere = NULL;
1.31 bertrand 514: (*l_nouvelle_variable).liste = NULL;
1.25 bertrand 515: (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent)
516: .suivant = l_nouvelle_variable;
1.33 ! bertrand 517: (*(*s_etat_processus).l_liste_variables_par_niveau)
! 518: .precedent = l_nouvelle_variable;
1.25 bertrand 519:
520: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
1.33 ! bertrand 521:
! 522: // Ajout de la variable en tête de la liste
! 523:
! 524: if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
! 525: {
! 526: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 527: return(d_erreur);
! 528: }
! 529:
! 530: (*l_nouvel_element).suivant = (*(*s_etat_processus)
! 531: .l_liste_variables_par_niveau).liste;
! 532: (*l_nouvel_element).donnee = pointeur_variable_cree;
! 533: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
! 534: l_nouvel_element;
1.25 bertrand 535: }
1.31 bertrand 536: else if ((*s_variable).niveau <= 1)
1.25 bertrand 537: {
1.33 ! bertrand 538: // Création d'une variable de niveau 0 ou 1. Il convient de
! 539: // chercher dans la liste si un niveau 0 ou 1 préexiste. Pour cela, on
! 540: // regarde la position courante et les deux précédentes.
! 541:
! 542: l_variable_candidate = (*s_etat_processus).l_liste_variables_par_niveau;
! 543: niveau_acceptable = d_faux;
1.25 bertrand 544:
1.33 ! bertrand 545: for(i = 0; i <= 2; i++)
! 546: {
! 547: if ((*l_variable_candidate).liste == NULL)
! 548: {
! 549: continue;
! 550: }
! 551:
! 552: if ((*((struct_variable *) (*(*l_variable_candidate)
! 553: .liste).donnee)).niveau == (*s_variable).niveau)
! 554: {
! 555: niveau_acceptable = d_vrai;
! 556: break;
! 557: }
! 558:
! 559: l_variable_candidate = (*l_variable_candidate).precedent;
! 560: }
! 561:
! 562: if (niveau_acceptable == d_faux)
1.28 bertrand 563: {
1.33 ! bertrand 564: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
! 565: == NULL)
! 566: {
! 567: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 568: return(d_erreur);
! 569: }
! 570:
! 571: l_variable_candidate =
! 572: (*(*s_etat_processus).l_liste_variables_par_niveau)
! 573: .precedent;
! 574:
! 575: // On ne peut créer qu'une variable de niveau supérieur ou égal à
! 576: // 1 lors de l'exécution normale d'un programme. Les variables
! 577: // de niveau 0 sont créées à l'initialisation et relèvent du
! 578: // cas précédent car il n'existe lors de leur création aucun
! 579: // niveau non nul.
! 580:
! 581: BUG((*s_variable).niveau == 0,
! 582: uprintf("Attempt to create a level-0 variable!\n"));
! 583:
! 584: (*l_nouvelle_variable).suivant = l_variable_candidate;
! 585: (*l_nouvelle_variable).precedent = (*l_variable_candidate)
! 586: .precedent;
! 587: (*l_nouvelle_variable).noeud_pere = NULL;
! 588: (*l_nouvelle_variable).liste = NULL;
! 589: (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
! 590: (*l_variable_candidate).precedent = l_nouvelle_variable;
! 591:
! 592: l_variable_candidate = l_nouvelle_variable;
1.28 bertrand 593: }
594:
1.33 ! bertrand 595: // Ajout de la variable en tête de la liste l_variable_candidate.
1.25 bertrand 596:
1.33 ! bertrand 597: if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
1.25 bertrand 598: {
1.33 ! bertrand 599: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 600: return(d_erreur);
1.25 bertrand 601: }
602:
1.33 ! bertrand 603: (*l_nouvel_element).suivant = (*l_variable_candidate).liste;
! 604: (*l_nouvel_element).donnee = pointeur_variable_cree;
! 605: (*l_variable_candidate).liste = l_nouvel_element;
1.25 bertrand 606: }
1.33 ! bertrand 607: else
! 608: {
! 609: // Ajout de la variable en tête de la liste
1.25 bertrand 610:
1.33 ! bertrand 611: if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
! 612: {
! 613: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 614: return(d_erreur);
! 615: }
1.25 bertrand 616:
1.33 ! bertrand 617: (*l_nouvel_element).suivant = (*(*s_etat_processus)
! 618: .l_liste_variables_par_niveau).liste;
! 619: (*l_nouvel_element).donnee = pointeur_variable_cree;
! 620: (*(*s_etat_processus).l_liste_variables_par_niveau).liste =
! 621: l_nouvel_element;
1.1 bertrand 622: }
623:
1.25 bertrand 624: return(d_absence_erreur);
625: }
626:
1.31 bertrand 627:
1.25 bertrand 628: logical1
629: creation_variable(struct_processus *s_etat_processus,
630: struct_variable *s_variable,
631: unsigned char autorisation_creation_variable_statique,
632: unsigned char autorisation_creation_variable_partagee)
633: {
1.1 bertrand 634: if ((*s_etat_processus).mode_execution_programme == 'Y')
635: {
636: (*s_variable).origine = 'P';
637: }
638: else
639: {
640: (*s_variable).origine = 'E';
641: }
642:
643: if ((*s_variable).niveau == 0)
644: {
645: // Un point d'entrée de définition est verrouillé.
646:
647: if ((*s_variable).origine == 'P')
648: {
649: (*s_variable).variable_statique.adresse = 0;
650: (*s_variable).variable_partagee.adresse = 0;
651: }
652: else
653: {
654: (*s_variable).variable_statique.pointeur = NULL;
655: (*s_variable).variable_partagee.pointeur = NULL;
656: }
657:
658: (*s_variable).variable_verrouillee = d_vrai;
659: }
660: else if ((*s_variable).niveau == 1)
661: {
662: // Une variable globale ne peut être statique.
663:
664: if ((*s_variable).origine == 'P')
665: {
666: (*s_variable).variable_statique.adresse = 0;
667: (*s_variable).variable_partagee.adresse = 0;
668: }
669: else
670: {
671: (*s_variable).variable_statique.pointeur = NULL;
672: (*s_variable).variable_partagee.pointeur = NULL;
673: }
674:
675: (*s_variable).variable_verrouillee = d_faux;
676: }
677: else
678: {
679: // 0 -> variable volatile
680: // adresse de création -> variable statique
681:
682: if (autorisation_creation_variable_statique == 'V')
683: {
684: if (autorisation_creation_variable_partagee == 'S')
685: {
686: // On force la création d'une variable partagée
687:
688: if ((*s_variable).origine == 'P')
689: {
690: (*s_variable).variable_statique.adresse = 0;
691: (*s_variable).variable_partagee.adresse =
692: (*s_etat_processus).position_courante;
693: }
694: else
695: {
696: (*s_variable).variable_statique.pointeur = NULL;
697: (*s_variable).variable_partagee.pointeur =
698: (*s_etat_processus).objet_courant;
699: }
700: }
701: else
702: {
703: // On force la création d'une variable volatile
704:
705: if ((*s_variable).origine == 'P')
706: {
707: (*s_variable).variable_statique.adresse = 0;
708: (*s_variable).variable_partagee.adresse = 0;
709: }
710: else
711: {
712: (*s_variable).variable_statique.pointeur = NULL;
713: (*s_variable).variable_partagee.pointeur = NULL;
714: }
715: }
716: }
717: else
718: {
719: // On force la création d'une variable statique.
720:
721: if ((*s_variable).origine == 'P')
722: {
723: (*s_variable).variable_statique.adresse =
724: (*s_etat_processus).position_courante;
725: (*s_variable).variable_partagee.adresse = 0;
726: }
727: else
728: {
729: (*s_variable).variable_statique.pointeur =
730: (*s_etat_processus).objet_courant;
731: (*s_variable).variable_partagee.pointeur = 0;
732: }
733: }
734:
735: (*s_variable).variable_verrouillee = d_faux;
736: }
737:
738: /*
1.25 bertrand 739: * Recherche de la feuille correspondante dans l'arbre des variables.
740: * Si cette feuille n'existe pas, elle est créée.
1.1 bertrand 741: */
742:
1.25 bertrand 743: if (ajout_variable(s_etat_processus, s_variable) == d_erreur)
744: {
745: return(d_erreur);
746: }
747:
748: return(d_absence_erreur);
749: }
750:
751:
752: /*
753: ================================================================================
754: Procédure de recherche d'une variable par son nom dans la base
755: ================================================================================
756: Entrée :
757: --------------------------------------------------------------------------------
758: Sortie :
759: --------------------------------------------------------------------------------
760: Effets de bord : néant
761: ================================================================================
762: */
763:
764: logical1
765: recherche_variable(struct_processus *s_etat_processus,
766: unsigned char *nom_variable)
767: {
768: int pointeur;
769:
770: struct_arbre_variables *l_variable_courante;
771: struct_liste_pile_systeme *l_element_courant;
772:
773: unsigned char *ptr;
774:
775: unsigned long niveau_appel;
1.1 bertrand 776:
1.25 bertrand 777: if ((*s_etat_processus).s_arbre_variables == NULL)
1.1 bertrand 778: {
1.25 bertrand 779: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1.30 bertrand 780: return(d_faux);
1.1 bertrand 781: }
1.25 bertrand 782:
1.28 bertrand 783: l_variable_courante = (*s_etat_processus).s_arbre_variables;
1.25 bertrand 784: ptr = nom_variable;
785:
786: while((*ptr) != d_code_fin_chaine)
1.1 bertrand 787: {
1.25 bertrand 788: pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
789:
790: if (pointeur < 0)
791: {
792: // Caractère hors de l'alphabet des variables
1.30 bertrand 793:
794: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
795: return(d_faux);
1.25 bertrand 796: }
797:
1.28 bertrand 798: if ((*l_variable_courante).noeuds[pointeur] == NULL)
1.1 bertrand 799: {
1.25 bertrand 800: // Le chemin de la variable candidate n'existe pas.
1.30 bertrand 801: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
802: return(d_faux);
1.1 bertrand 803: }
804:
1.28 bertrand 805: l_variable_courante = (*l_variable_courante).noeuds[pointeur];
1.25 bertrand 806: ptr++;
807: }
808:
809: if ((*l_variable_courante).feuille != NULL)
810: {
811: // Il existe une pile de variables de même nom. Le sommet de la
812: // pile est la variable de niveau le plus haut.
813:
814: l_element_courant = (*s_etat_processus).l_base_pile_systeme;
815:
816: if (l_element_courant == NULL)
1.12 bertrand 817: {
1.25 bertrand 818: // Problème : la pile système est vide !
819: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
1.30 bertrand 820: return(d_faux);
1.12 bertrand 821: }
1.25 bertrand 822:
823: while((*l_element_courant).retour_definition != 'Y')
1.12 bertrand 824: {
1.25 bertrand 825: l_element_courant = (*l_element_courant).suivant;
1.12 bertrand 826:
1.25 bertrand 827: if (l_element_courant == NULL)
1.12 bertrand 828: {
1.25 bertrand 829: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
1.30 bertrand 830: return(d_faux);
1.12 bertrand 831: }
1.25 bertrand 832: }
833:
834: niveau_appel = (*l_element_courant).niveau_courant;
1.12 bertrand 835:
1.25 bertrand 836: if (niveau_appel < (*(*(*l_variable_courante).feuille).variable).niveau)
837: {
838: // Une variable locale est accessible puisque créée dans la
839: // fonction courante.
840:
841: (*s_etat_processus).pointeur_variable_courante =
842: (*(*l_variable_courante).feuille).variable;
843: (*s_etat_processus).pointeur_feuille_courante =
844: (*l_variable_courante).feuille;
1.30 bertrand 845: return(d_vrai);
1.25 bertrand 846: }
847: else
848: {
849: // Aucune variable locale n'est accessible depuis la fonction.
850: // Dans ce cas, on prend la variable de niveau le plus bas
851: // si ce niveau est inférieur ou égal à 1 (variable globale
852: // ou fonction définie par l'utilisateur). Si le niveau de la
1.27 bertrand 853: // plus ancienne variable est strictement supérieur à 1, il
1.25 bertrand 854: // s'agit d'une variable locale inaccessible.
855:
856: if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
857: .niveau <= 1)
858: {
859: (*s_etat_processus).pointeur_variable_courante =
860: (*(*(*l_variable_courante).feuille).precedent).variable;
861: (*s_etat_processus).pointeur_feuille_courante =
1.33 ! bertrand 862: (*(*l_variable_courante).feuille).precedent;
1.27 bertrand 863:
864: // S'il existe une variable de niveau 0 et une seconde de
865: // niveau 1, la variable de niveau 0 (fonction) est masquée
866: // par celle de niveau 1.
867:
1.33 ! bertrand 868: if (((*(*(*(*l_variable_courante).feuille).precedent)
! 869: .variable).niveau == 0) && ((*(*(*(*
! 870: (*l_variable_courante).feuille).precedent).precedent)
1.27 bertrand 871: .variable).niveau == 1))
872: {
873: (*s_etat_processus).pointeur_variable_courante =
1.33 ! bertrand 874: (*(*(*(*l_variable_courante).feuille).precedent)
! 875: .precedent).variable;
! 876: (*s_etat_processus).pointeur_feuille_courante =
1.27 bertrand 877: (*(*(*l_variable_courante).feuille).precedent)
1.33 ! bertrand 878: .precedent;
1.27 bertrand 879: }
880:
1.30 bertrand 881: return(d_vrai);
1.12 bertrand 882: }
883: }
1.1 bertrand 884: }
885:
1.30 bertrand 886: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
887: return(d_faux);
1.1 bertrand 888: }
889:
890:
1.29 bertrand 891: logical1
892: recherche_variable_globale(struct_processus *s_etat_processus,
893: unsigned char *nom)
894: {
895: logical1 presence_variable;
896:
897: presence_variable = recherche_variable(s_etat_processus, nom);
898:
899: if (presence_variable == d_vrai)
900: {
901: switch((*(*s_etat_processus).pointeur_variable_courante).niveau)
902: {
903: case 0:
904: {
1.33 ! bertrand 905: // La variable est une définition.
1.29 bertrand 906: presence_variable = d_faux;
907: break;
908: }
909:
910: case 1:
911: {
912: break;
913: }
914:
915: default:
916: {
917: if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
918: .precedent).variable).niveau == 1)
919: {
920: (*s_etat_processus).pointeur_feuille_courante =
921: (*(*s_etat_processus).pointeur_feuille_courante)
922: .precedent;
923: (*s_etat_processus).pointeur_variable_courante =
924: (*(*s_etat_processus).pointeur_feuille_courante)
925: .variable;
926: }
927: else if ((*(*(*(*(*s_etat_processus).pointeur_feuille_courante)
928: .precedent).precedent).variable).niveau == 1)
929: {
930: (*s_etat_processus).pointeur_feuille_courante =
931: (*(*(*s_etat_processus).pointeur_feuille_courante)
932: .precedent).precedent;
933: (*s_etat_processus).pointeur_variable_courante =
934: (*(*s_etat_processus).pointeur_feuille_courante)
935: .variable;
936: }
937: else
938: {
939: presence_variable = d_faux;
940: }
941:
942: break;
943: }
944: }
945: }
946:
947: if (presence_variable == d_vrai)
948: {
949: if ((*(*s_etat_processus).pointeur_variable_courante).objet == NULL)
950: {
951: // La variable n'est pas globale, elle est partagée.
952: presence_variable = d_faux;
953: (*s_etat_processus).erreur_execution = d_ex_variable_partagee;
954: }
955: }
956:
957: return(presence_variable);
958: }
959:
960:
1.1 bertrand 961: /*
962: ================================================================================
963: Procédure de retrait d'une variable de la base
964: ================================================================================
965: Entrée : type 'G' ou 'L' selon que l'on retire une variable locale (incluant
966: les globales) ou strictement globale.
967: --------------------------------------------------------------------------------
968: Sortie :
969: --------------------------------------------------------------------------------
970: Effets de bord : néant
971: ================================================================================
972: */
973:
974: logical1
975: retrait_variable(struct_processus *s_etat_processus,
976: unsigned char *nom_variable, unsigned char type)
977: {
1.28 bertrand 978: logical1 erreur;
979:
980: struct_arbre_variables *s_arbre_a_supprimer;
981: struct_arbre_variables *s_arbre_courant;
1.32 bertrand 982: struct_arbre_variables *noeud_courant;
1.28 bertrand 983:
984: struct_liste_chainee *l_element_courant;
985: struct_liste_chainee *l_element_precedent;
986:
987: struct_liste_variables *variable_a_supprimer;
988: struct_liste_variables *variables_par_niveau;
989:
990: unsigned long niveau;
1.1 bertrand 991:
992: if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
993: {
1.25 bertrand 994: // Une variable correspondant au nom recherché est accessible.
995:
1.1 bertrand 996: if (type == 'G')
997: {
1.25 bertrand 998: if ((*(*s_etat_processus).pointeur_variable_courante).niveau > 1)
999: {
1000: // La variable obtenue est une variable locale. il faut
1001: // s'assurer qu'il existe une variable de niveau 1 de même
1002: // nom sur la feuille.
1003:
1.27 bertrand 1004: if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
1005: .precedent).variable).niveau <= 1)
1.1 bertrand 1006: {
1.27 bertrand 1007: (*s_etat_processus).pointeur_feuille_courante =
1008: (*(*s_etat_processus).pointeur_feuille_courante)
1009: .precedent;
1010: (*s_etat_processus).pointeur_variable_courante =
1011: (*(*s_etat_processus).pointeur_feuille_courante)
1012: .variable;
1013:
1014: // Si la variable retournée est de niveau 0, on regarde
1015: // un peu plus loin si une variable de niveau 1 existe.
1016:
1017: if (((*(*(*s_etat_processus).pointeur_feuille_courante)
1018: .variable).niveau == 0) &&
1019: ((*(*(*(*s_etat_processus)
1020: .pointeur_feuille_courante).precedent).variable)
1021: .niveau == 1))
1.1 bertrand 1022: {
1.27 bertrand 1023: (*s_etat_processus).pointeur_feuille_courante =
1024: (*(*s_etat_processus).pointeur_feuille_courante)
1025: .precedent;
1026: (*s_etat_processus).pointeur_variable_courante =
1027: (*(*s_etat_processus).pointeur_feuille_courante)
1028: .variable;
1.1 bertrand 1029: }
1030: }
1.27 bertrand 1031: else
1032: {
1033: // Aucune variable globale (niveau 1) n'existe.
1.1 bertrand 1034:
1.27 bertrand 1035: erreur = d_erreur;
1036: (*s_etat_processus).erreur_execution =
1037: d_ex_variable_non_definie;
1038: return(erreur);
1039: }
1.1 bertrand 1040: }
1041:
1.27 bertrand 1042: if ((*(*s_etat_processus).pointeur_variable_courante)
1.1 bertrand 1043: .variable_verrouillee == d_vrai)
1044: {
1045: erreur = d_erreur;
1046: (*s_etat_processus).erreur_execution =
1047: d_ex_variable_verrouillee;
1.28 bertrand 1048: return(erreur);
1.1 bertrand 1049: }
1050: }
1051:
1.27 bertrand 1052: // Suppression de la variable de la liste.
1053: // Deux cas peuvent survenir :
1054: // 1/ les pointeurs sur la variable et la variable suivante
1055: // sont identiques et on supprime la variable ainsi que la feuille
1056: // associée ;
1057: // 2/ ces deux pointeurs sont différents et se contente de retirer
1058: // la structure décrivant la variable.
1.1 bertrand 1059:
1.28 bertrand 1060: if ((*s_etat_processus).pointeur_feuille_courante ==
1061: (*(*s_etat_processus).pointeur_feuille_courante).suivant)
1062: {
1063: // Cas 1 :
1064: // On retire la variable du noeud en décrémentant le nombre
1065: // de feuilles de ce noeud. Si le nombre de feuilles du noeud
1066: // est nul, on retire les noeuds récursivement jusqu'à obtenir
1067: // un nombre non nul de feuilles utilisées (ou la racine des
1068: // variables).
1069:
1070: variable_a_supprimer = (*s_etat_processus)
1071: .pointeur_feuille_courante;
1072: s_arbre_courant = (*variable_a_supprimer).noeud_pere;
1.32 bertrand 1073: noeud_courant = (*variable_a_supprimer).noeud;
1.33 ! bertrand 1074: (*s_arbre_courant).noeuds[(*noeud_courant).indice_tableau_pere]
! 1075: = NULL;
1.28 bertrand 1076:
1077: BUG((*s_arbre_courant).noeuds_utilises == 0,
1078: uprintf("Freed node !\n"));
1079: (*s_arbre_courant).noeuds_utilises--;
1.1 bertrand 1080:
1.28 bertrand 1081: while((*s_arbre_courant).noeuds_utilises == 0)
1082: {
1083: s_arbre_a_supprimer = s_arbre_courant;
1084: s_arbre_courant = (*s_arbre_courant).noeud_pere;
1.1 bertrand 1085:
1.28 bertrand 1086: if (s_arbre_courant == NULL)
1087: {
1.31 bertrand 1088: free((*s_arbre_a_supprimer).noeuds);
1089: free(s_arbre_a_supprimer);
1.28 bertrand 1090: break;
1091: }
1092:
1.31 bertrand 1093: // s_arbre_a_supprimer contient la structure de feuille qui
1094: // vient d'être libérée. Il s'agit maintenant
1095: // d'annuler le pointeur dans le tableau noeuds de la structure
1096: // pointée par noeud_pere, soit s_arbre_courant.
1097:
1098: BUG((*s_arbre_a_supprimer).indice_tableau_pere < 0,
1099: uprintf("Invalid pointer !\n"));
1100: (*s_arbre_courant).noeuds[(*s_arbre_a_supprimer)
1101: .indice_tableau_pere] = NULL;
1102:
1103: free((*s_arbre_a_supprimer).noeuds);
1104: free(s_arbre_a_supprimer);
1105:
1.28 bertrand 1106: BUG((*s_arbre_courant).noeuds_utilises == 0,
1107: uprintf("Freed node !\n"));
1108: (*s_arbre_courant).noeuds_utilises--;
1109: }
1110: }
1111: else
1.1 bertrand 1112: {
1.28 bertrand 1113: // Cas 2 :
1114: // On retire la variable de la liste.
1115:
1116: variable_a_supprimer = (*s_etat_processus)
1117: .pointeur_feuille_courante;
1118:
1119: (*(*(*s_etat_processus).pointeur_feuille_courante).precedent)
1120: .suivant = (*(*s_etat_processus).pointeur_feuille_courante)
1121: .suivant;
1122: (*(*(*s_etat_processus).pointeur_feuille_courante).suivant)
1123: .precedent = (*(*s_etat_processus)
1124: .pointeur_feuille_courante).precedent;
1.32 bertrand 1125:
1.33 ! bertrand 1126: // Mise à jour du pointeur dans l'arbre des variables. Cette
! 1127: // mise à jour n'est nécessaire que dans le cas où la variable
! 1128: // supprimée est en tête de la liste.
! 1129:
! 1130: if (variable_a_supprimer == (*((*(*variable_a_supprimer).noeud_pere)
! 1131: .noeuds[(*(*variable_a_supprimer).noeud)
! 1132: .indice_tableau_pere])).feuille)
! 1133: {
! 1134: (*((*(*variable_a_supprimer).noeud_pere).noeuds
! 1135: [(*(*variable_a_supprimer).noeud).indice_tableau_pere]))
! 1136: .feuille = (*(*((*(*variable_a_supprimer).noeud_pere)
! 1137: .noeuds[(*(*variable_a_supprimer).noeud)
! 1138: .indice_tableau_pere])).feuille).suivant;
! 1139: }
! 1140:
! 1141: (*s_etat_processus).pointeur_feuille_courante =
! 1142: (*(*s_etat_processus).pointeur_feuille_courante).suivant;
! 1143: (*s_etat_processus).pointeur_variable_courante =
! 1144: (*(*s_etat_processus).pointeur_feuille_courante).variable;
! 1145:
1.32 bertrand 1146: noeud_courant = NULL;
1.1 bertrand 1147: }
1148:
1.28 bertrand 1149: // Dans tous les cas, on retire la variable de la liste des variables
1150: // par niveau.
1151:
1152: niveau = (*(*variable_a_supprimer).variable).niveau;
1153: variables_par_niveau = (*s_etat_processus).l_liste_variables_par_niveau;
1154:
1.31 bertrand 1155: if (variables_par_niveau != NULL)
1.28 bertrand 1156: {
1.31 bertrand 1157: do
1158: {
1159: l_element_courant = (*variables_par_niveau).liste;
1.28 bertrand 1160:
1.31 bertrand 1161: if (l_element_courant != NULL)
1.28 bertrand 1162: {
1.31 bertrand 1163: if ((*((struct_variable *) (*l_element_courant).donnee))
1164: .niveau == niveau)
1165: {
1166: // On parcourt le bon niveau.
1.28 bertrand 1167:
1.31 bertrand 1168: l_element_precedent = NULL;
1.28 bertrand 1169:
1.31 bertrand 1170: while(l_element_courant != NULL)
1.28 bertrand 1171: {
1.31 bertrand 1172: // Tant que l_element_courant est non nul, il reste
1173: // des variables à explorer dans le niveau courant.
1.28 bertrand 1174:
1.31 bertrand 1175: if ((*l_element_courant).donnee ==
1176: (void *) (*variable_a_supprimer).variable)
1.28 bertrand 1177: {
1.31 bertrand 1178: // On a trouvé la variable à supprimer.
1179:
1180: if (l_element_precedent == NULL)
1181: {
1182: (*variables_par_niveau).liste =
1183: (*l_element_courant).suivant;
1184: }
1185: else
1186: {
1187: (*l_element_precedent).suivant =
1188: (*l_element_courant).suivant;
1189: }
1190:
1191: free(l_element_courant);
1192: break;
1.28 bertrand 1193: }
1.31 bertrand 1194:
1195: l_element_precedent = l_element_courant;
1196: l_element_courant = (*l_element_courant).suivant;
1.28 bertrand 1197: }
1198: }
1199: }
1200:
1.31 bertrand 1201: variables_par_niveau = (*variables_par_niveau).suivant;
1202:
1203: } while(variables_par_niveau != (*s_etat_processus)
1204: .l_liste_variables_par_niveau);
1.28 bertrand 1205: }
1206:
1207: // Puis on libère le contenu de la variable.
1208:
1209: free((*(*variable_a_supprimer).variable).nom);
1210: liberation(s_etat_processus, (*(*variable_a_supprimer).variable).objet);
1.32 bertrand 1211: free((*variable_a_supprimer).variable);
1.33 ! bertrand 1212: free(variable_a_supprimer);
1.28 bertrand 1213:
1.1 bertrand 1214: erreur = d_absence_erreur;
1.32 bertrand 1215:
1216: if (noeud_courant != NULL)
1217: {
1218: free((*noeud_courant).noeuds);
1219: free(noeud_courant);
1220: }
1.1 bertrand 1221: }
1222: else
1223: {
1.25 bertrand 1224: // Aucune variable n'est accessible depuis le point courant du
1225: // programme.
1226:
1.1 bertrand 1227: erreur = d_erreur;
1228: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
1229: }
1230:
1.25 bertrand 1231: return(erreur);
1.1 bertrand 1232: }
1233:
1234:
1235: /*
1236: ================================================================================
1237: Procédure de retrait des variables de niveau strictement supérieur au
1238: niveau courant
1239: ================================================================================
1240: Entrée :
1241: --------------------------------------------------------------------------------
1242: Sortie :
1243: --------------------------------------------------------------------------------
1244: Effets de bord : néant
1245: ================================================================================
1246: */
1247:
1248: logical1
1249: retrait_variable_par_niveau(struct_processus *s_etat_processus)
1250: {
1.31 bertrand 1251: struct_liste_variables *l_element_a_supprimer;
1252:
1.28 bertrand 1253: // Utilisation du champ (*s_etat_processus).liste_variables_par_niveau.
1254: // La tête de la pile contient toujours les variables de plus haut niveau
1255: // créées.
1.1 bertrand 1256:
1.28 bertrand 1257: while((*s_etat_processus).l_liste_variables_par_niveau != NULL)
1.1 bertrand 1258: {
1.28 bertrand 1259: if ((*(*s_etat_processus).l_liste_variables_par_niveau).liste == NULL)
1.1 bertrand 1260: {
1.28 bertrand 1261: // Si le niveau ne contient aucune variable, on le détruit.
1262: // Le pointeur sur la chaîne est déjà nul et il ne reste rien à
1263: // faire.
1.1 bertrand 1264: }
1265: else
1266: {
1.28 bertrand 1267: // Le niveau contient des variables.
1268:
1269: if ((*((struct_variable *) (*(*(*s_etat_processus)
1270: .l_liste_variables_par_niveau).liste).donnee)).niveau
1271: <= (*s_etat_processus).niveau_courant)
1.1 bertrand 1272: {
1.28 bertrand 1273: // On a retiré de l'arbre des variables toutes les
1274: // variables de niveau strictement supérieur au niveau
1275: // courant.
1.1 bertrand 1276:
1.28 bertrand 1277: break;
1.1 bertrand 1278: }
1.28 bertrand 1279:
1280: while((*(*s_etat_processus).l_liste_variables_par_niveau).liste
1281: != NULL)
1.1 bertrand 1282: {
1.28 bertrand 1283: // Sauvegarde des variables statiques.
1284:
1285: if ((*((struct_variable *) (*(*(*s_etat_processus)
1286: .l_liste_variables_par_niveau).liste).donnee)).origine
1287: == 'P')
1.1 bertrand 1288: {
1.28 bertrand 1289: if ((*((struct_variable *) (*(*(*s_etat_processus)
1290: .l_liste_variables_par_niveau).liste).donnee))
1291: .variable_statique.adresse != 0)
1.1 bertrand 1292: {
1.28 bertrand 1293: if (recherche_variable_statique(s_etat_processus,
1294: (*((struct_variable *) (*(*(*s_etat_processus)
1295: .l_liste_variables_par_niveau).liste).donnee))
1296: .nom, (*((struct_variable *)
1297: (*(*(*s_etat_processus)
1298: .l_liste_variables_par_niveau).liste).donnee))
1299: .variable_statique, ((*s_etat_processus)
1300: .mode_execution_programme
1301: == 'Y') ? 'P' : 'E') == d_vrai)
1302: {
1303: (*s_etat_processus).s_liste_variables_statiques
1304: [(*s_etat_processus)
1305: .position_variable_statique_courante]
1306: .objet = (*((struct_variable *)
1307: (*(*(*s_etat_processus)
1308: .l_liste_variables_par_niveau).liste)
1309: .donnee)).objet;
1310: }
1311: else
1312: {
1313: (*s_etat_processus).erreur_systeme =
1314: d_es_variable_introuvable;
1315: }
1316:
1317: (*((struct_variable *) (*(*(*s_etat_processus)
1318: .l_liste_variables_par_niveau).liste).donnee))
1319: .objet = NULL;
1.1 bertrand 1320: }
1.28 bertrand 1321: }
1322: else
1323: {
1324: if ((*((struct_variable *) (*(*(*s_etat_processus)
1325: .l_liste_variables_par_niveau).liste).donnee))
1326: .variable_statique.pointeur != NULL)
1.1 bertrand 1327: {
1.28 bertrand 1328: /*
1329: * Gestion des variables statiques
1330: */
1331:
1332: if (recherche_variable_statique(s_etat_processus,
1333: (*((struct_variable *) (*(*(*s_etat_processus)
1334: .l_liste_variables_par_niveau).liste).donnee))
1335: .nom, (*((struct_variable *)
1336: (*(*(*s_etat_processus)
1337: .l_liste_variables_par_niveau).liste).donnee))
1338: .variable_statique, ((*s_etat_processus)
1339: .mode_execution_programme
1340: == 'Y') ? 'P' : 'E') == d_vrai)
1341: {
1342: (*s_etat_processus).s_liste_variables_statiques
1343: [(*s_etat_processus)
1344: .position_variable_statique_courante]
1345: .objet = (*((struct_variable *)
1346: (*(*(*s_etat_processus)
1347: .l_liste_variables_par_niveau).liste)
1348: .donnee)).objet;
1349: }
1350: else
1351: {
1352: (*s_etat_processus).erreur_systeme =
1353: d_es_variable_introuvable;
1354: return(d_erreur);
1355: }
1356:
1357: (*((struct_variable *) (*(*(*s_etat_processus)
1358: .l_liste_variables_par_niveau).liste).donnee))
1359: .objet = NULL;
1.1 bertrand 1360: }
1.28 bertrand 1361: }
1.1 bertrand 1362:
1.28 bertrand 1363: if (retrait_variable(s_etat_processus,
1364: (*((struct_variable *) (*(*(*s_etat_processus)
1365: .l_liste_variables_par_niveau).liste).donnee)).nom,
1366: 'L') == d_erreur)
1367: {
1368: return(d_erreur);
1.1 bertrand 1369: }
1370: }
1371: }
1372:
1.31 bertrand 1373: // On retire l'élément de la liste doublement chaînée et circulaire.
1374:
1375: (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent).suivant
1376: = (*(*s_etat_processus).l_liste_variables_par_niveau).suivant;
1377: (*(*(*s_etat_processus).l_liste_variables_par_niveau).suivant).precedent
1378: = (*(*s_etat_processus).l_liste_variables_par_niveau).precedent;
1379:
1380: l_element_a_supprimer = (*s_etat_processus)
1381: .l_liste_variables_par_niveau;
1382: (*s_etat_processus).l_liste_variables_par_niveau =
1383: (*l_element_a_supprimer).suivant;
1384: free(l_element_a_supprimer);
1.1 bertrand 1385: }
1386:
1387: return(d_absence_erreur);
1388: }
1389:
1.23 bertrand 1390:
1391: /*
1392: ================================================================================
1.24 bertrand 1393: Procédure de retrait des toutes les variables locales et globales
1394: ================================================================================
1395: Entrée : drapeau indiquant s'il faut retirer les définitions (variables
1396: de niveau 0)
1397: --------------------------------------------------------------------------------
1398: Sortie :
1399: --------------------------------------------------------------------------------
1400: Effets de bord : néant
1401: ================================================================================
1402: */
1403:
1404: void
1405: liberation_arbre_variables(struct_processus *s_etat_processus,
1406: struct_arbre_variables *arbre, logical1 retrait_definitions)
1407: {
1408: int i;
1409:
1.28 bertrand 1410: struct_liste_chainee *l_element_courant_liste;
1411: struct_liste_chainee *l_element_suivant_liste;
1412:
1413: struct_liste_variables *l_element_courant;
1414: struct_liste_variables *l_element_suivant;
1415:
1416: // Libération de l'arbre des variables. Le contenu des variables n'est
1417: // pas détruit par cette opération, il sera détruit lors de la libération
1418: // de la liste des variables par niveau.
1.24 bertrand 1419:
1.31 bertrand 1420: l_element_courant = (*arbre).feuille;
1421:
1422: if (l_element_courant != NULL)
1423: {
1424: do
1425: {
1426: l_element_suivant = (*l_element_courant).suivant;
1427: free(l_element_courant);
1428: l_element_courant = l_element_suivant;
1429: } while(l_element_courant != (*arbre).feuille);
1430: }
1431:
1.24 bertrand 1432: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1433: {
1.28 bertrand 1434: if ((*arbre).noeuds[i] != NULL)
1.24 bertrand 1435: {
1.28 bertrand 1436: liberation_arbre_variables(s_etat_processus, (*arbre).noeuds[i],
1437: retrait_definitions);
1438: }
1439: }
1440:
1441: // Suppression de la liste des variables par niveau.
1442:
1443: if (arbre == (*s_etat_processus).s_arbre_variables)
1444: {
1445: l_element_courant = (*s_etat_processus).l_liste_variables_par_niveau;
1446:
1.31 bertrand 1447: if (l_element_courant != NULL)
1.28 bertrand 1448: {
1.31 bertrand 1449: do
1450: {
1451: l_element_courant_liste = (*l_element_courant).liste;
1.24 bertrand 1452:
1.31 bertrand 1453: while(l_element_courant_liste != NULL)
1.24 bertrand 1454: {
1.31 bertrand 1455: if ((retrait_definitions == d_vrai) ||
1456: ((*((struct_variable *) (*l_element_courant_liste)
1457: .donnee)).niveau >= 1))
1458: {
1459: liberation(s_etat_processus, (*((struct_variable *)
1460: (*l_element_courant_liste).donnee)).objet);
1461: free((*((struct_variable *) (*l_element_courant_liste)
1462: .donnee)).nom);
1463: free((*l_element_courant_liste).donnee);
1464: }
1465:
1466: l_element_suivant_liste =
1467: (*l_element_courant_liste).suivant;
1468: free(l_element_courant_liste);
1469: l_element_courant_liste = l_element_suivant_liste;
1.24 bertrand 1470: }
1471:
1.31 bertrand 1472: l_element_suivant = (*l_element_courant).suivant;
1473: free(l_element_courant);
1474: l_element_courant = l_element_suivant;
1475: } while(l_element_courant != (*s_etat_processus)
1476: .l_liste_variables_par_niveau);
1.24 bertrand 1477: }
1478: }
1479:
1.28 bertrand 1480: free((*arbre).noeuds);
1.24 bertrand 1481: free(arbre);
1482:
1483: return;
1484: }
1485:
1.28 bertrand 1486:
1.24 bertrand 1487: /*
1488: ================================================================================
1.33 ! bertrand 1489: Procédure renvoyant les variables dans un tableau
! 1490: ================================================================================
! 1491: Entrée :
! 1492: --------------------------------------------------------------------------------
! 1493: Sortie :
! 1494: --------------------------------------------------------------------------------
! 1495: Effets de bord : néant
! 1496: ================================================================================
! 1497: */
! 1498:
! 1499: int
! 1500: nombre_variables(struct_processus *s_etat_processus,
! 1501: struct_arbre_variables *l_element_courant)
! 1502: {
! 1503: int i;
! 1504: int n;
! 1505:
! 1506: struct_liste_variables *l_variable;
! 1507:
! 1508: n = 0;
! 1509:
! 1510: if ((*l_element_courant).feuille != NULL)
! 1511: {
! 1512: l_variable = (*l_element_courant).feuille;
! 1513:
! 1514: do
! 1515: {
! 1516: n++;
! 1517: l_variable = (*l_variable).suivant;
! 1518: } while(l_variable != (*l_element_courant).feuille);
! 1519: }
! 1520:
! 1521: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
! 1522: {
! 1523: if ((*l_element_courant).noeuds[i] != NULL)
! 1524: {
! 1525: n += nombre_variables(s_etat_processus,
! 1526: (*l_element_courant).noeuds[i]);
! 1527: }
! 1528: }
! 1529:
! 1530: return(n);
! 1531: }
! 1532:
! 1533: int
! 1534: liste_variables(struct_processus *s_etat_processus,
! 1535: struct_tableau_variables *tableau, int position,
! 1536: struct_arbre_variables *l_element_courant)
! 1537: {
! 1538: int i;
! 1539:
! 1540: struct_liste_variables *l_variable;
! 1541:
! 1542: if ((*l_element_courant).feuille != NULL)
! 1543: {
! 1544: l_variable = (*l_element_courant).feuille;
! 1545:
! 1546: do
! 1547: {
! 1548: tableau[position].origine = (*(*l_variable).variable).origine;
! 1549: tableau[position].nom = (*(*l_variable).variable).nom;
! 1550: tableau[position].niveau = (*(*l_variable).variable).niveau;
! 1551: tableau[position].objet = (*(*l_variable).variable).objet;
! 1552: tableau[position].variable_verrouillee =
! 1553: (*(*l_variable).variable).variable_verrouillee;
! 1554: tableau[position].variable_statique =
! 1555: (*(*l_variable).variable).variable_statique;
! 1556: tableau[position].variable_partagee =
! 1557: (*(*l_variable).variable).variable_partagee;
! 1558:
! 1559: position++;
! 1560: l_variable = (*l_variable).suivant;
! 1561: } while(l_variable != (*l_element_courant).feuille);
! 1562: }
! 1563:
! 1564: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
! 1565: {
! 1566: if ((*l_element_courant).noeuds[i] != NULL)
! 1567: {
! 1568: position = liste_variables(s_etat_processus,
! 1569: tableau, position, (*l_element_courant).noeuds[i]);
! 1570: }
! 1571: }
! 1572:
! 1573: return(position);
! 1574: }
! 1575:
! 1576: /*
! 1577: ================================================================================
1.23 bertrand 1578: Procédure de copie de l'arbre des variables
1579: ================================================================================
1580: Entrée :
1581: --------------------------------------------------------------------------------
1582: Sortie :
1583: --------------------------------------------------------------------------------
1584: Effets de bord : néant
1585: ================================================================================
1586: */
1587:
1588: struct_arbre_variables *
1589: copie_arbre_variables(struct_processus *s_etat_processus)
1590: {
1591: // Les définitions sont partagées entre tous les threads et ne sont pas
1592: // copiées.
1.28 bertrand 1593: //
1594: // NB : on ne copie que les variables de niveaux 0 et 1, les autres
1595: // variables locales étant masquées par le processus de création de thread
1596: // ou de processus, elles sont inaccessibles.
1597:
1598: BUG(1, uprintf("Oops !\n"));
1.23 bertrand 1599:
1600: return(d_absence_erreur);
1601: }
1602:
1603:
1604: /*
1605: ================================================================================
1606: Procédure d'initialisation de la table de correspondance des variables
1607: ================================================================================
1608: Entrée :
1609: --------------------------------------------------------------------------------
1610: Sortie :
1611: --------------------------------------------------------------------------------
1612: Effets de bord : néant
1613: ================================================================================
1614: */
1615:
1616: /*
1617: * Caractères autorisés dans les instructions
1618: *
1619: * A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
1620: * a b c d e f g h i j k l m n o p q r s t u v w x y z
1621: * _
1622: * 1 2 3 4 5 6 7 8 9 0
1623: */
1624:
1625: void
1626: initialisation_variables(struct_processus *s_etat_processus)
1627: {
1628: int decalage;
1629: int i;
1630: int longueur_tableau;
1631:
1632: unsigned char caractere;
1633:
1634: // Récupération de la longueur d'un unsigned char
1635:
1636: longueur_tableau = 1;
1637: decalage = 0;
1638: caractere = 1;
1639:
1640: while((1L << decalage) == (long) ((unsigned char) (caractere << decalage)))
1641: {
1642: decalage++;
1643: longueur_tableau *= 2;
1644: }
1645:
1646: if (((*s_etat_processus).pointeurs_caracteres_variables =
1647: malloc(longueur_tableau * sizeof(int))) == NULL)
1648: {
1649: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1650: return;
1651: }
1652:
1653: for(i = 0; i < longueur_tableau; i++)
1654: {
1655: (*s_etat_processus).pointeurs_caracteres_variables[i] = -1;
1656: }
1657:
1658: (*s_etat_processus).nombre_caracteres_variables = 0;
1659:
1660: #define DECLARATION_CARACTERE(c) \
1661: do { (*s_etat_processus).pointeurs_caracteres_variables[c] = \
1662: (*s_etat_processus).nombre_caracteres_variables++; } while(0)
1663:
1664: DECLARATION_CARACTERE('A');
1665: DECLARATION_CARACTERE('B');
1666: DECLARATION_CARACTERE('C');
1667: DECLARATION_CARACTERE('D');
1668: DECLARATION_CARACTERE('E');
1669: DECLARATION_CARACTERE('F');
1670: DECLARATION_CARACTERE('G');
1671: DECLARATION_CARACTERE('H');
1672: DECLARATION_CARACTERE('I');
1673: DECLARATION_CARACTERE('J');
1674: DECLARATION_CARACTERE('K');
1675: DECLARATION_CARACTERE('L');
1676: DECLARATION_CARACTERE('M');
1677: DECLARATION_CARACTERE('N');
1678: DECLARATION_CARACTERE('O');
1679: DECLARATION_CARACTERE('P');
1680: DECLARATION_CARACTERE('Q');
1681: DECLARATION_CARACTERE('R');
1682: DECLARATION_CARACTERE('S');
1683: DECLARATION_CARACTERE('T');
1684: DECLARATION_CARACTERE('U');
1685: DECLARATION_CARACTERE('V');
1686: DECLARATION_CARACTERE('W');
1687: DECLARATION_CARACTERE('X');
1688: DECLARATION_CARACTERE('Y');
1689: DECLARATION_CARACTERE('Z');
1690:
1691: DECLARATION_CARACTERE('a');
1692: DECLARATION_CARACTERE('b');
1693: DECLARATION_CARACTERE('c');
1694: DECLARATION_CARACTERE('d');
1695: DECLARATION_CARACTERE('e');
1696: DECLARATION_CARACTERE('f');
1697: DECLARATION_CARACTERE('g');
1698: DECLARATION_CARACTERE('h');
1699: DECLARATION_CARACTERE('i');
1700: DECLARATION_CARACTERE('j');
1701: DECLARATION_CARACTERE('k');
1702: DECLARATION_CARACTERE('l');
1703: DECLARATION_CARACTERE('m');
1704: DECLARATION_CARACTERE('n');
1705: DECLARATION_CARACTERE('o');
1706: DECLARATION_CARACTERE('p');
1707: DECLARATION_CARACTERE('q');
1708: DECLARATION_CARACTERE('r');
1709: DECLARATION_CARACTERE('s');
1710: DECLARATION_CARACTERE('t');
1711: DECLARATION_CARACTERE('u');
1712: DECLARATION_CARACTERE('v');
1713: DECLARATION_CARACTERE('w');
1714: DECLARATION_CARACTERE('x');
1715: DECLARATION_CARACTERE('y');
1716: DECLARATION_CARACTERE('z');
1717:
1718: DECLARATION_CARACTERE('_');
1719:
1720: DECLARATION_CARACTERE('1');
1721: DECLARATION_CARACTERE('2');
1722: DECLARATION_CARACTERE('3');
1723: DECLARATION_CARACTERE('4');
1724: DECLARATION_CARACTERE('5');
1725: DECLARATION_CARACTERE('6');
1726: DECLARATION_CARACTERE('7');
1727: DECLARATION_CARACTERE('8');
1728: DECLARATION_CARACTERE('9');
1729: DECLARATION_CARACTERE('0');
1730: #undef DECLARATION_CARACTERE
1731:
1732: return;
1733: }
1.25 bertrand 1734:
1.1 bertrand 1735: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>