Annotation of rpl/src/gestion_variables.c, revision 1.25
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: ================================================================================
28: Routine de création d'une nouvelle variable
29: Entrée : autorisation_creation_variable_statique vaut 'V' ou 'S'.
30: Dans le cas 'V', la variable est volatile.
31: Dans le cas 'S', elle est statique.
32: Entrée : autorisation_creation_variable_partagee vaut 'P' ou 'S'.
33: Dans le cas 'P', la variable est privée.
34: Dans le cas 'S', elle est partagée.
35: --------------------------------------------------------------------------------
36: Sortie :
37: --------------------------------------------------------------------------------
38: Effets de bords : néant
39: ================================================================================
40: */
41:
1.25 ! bertrand 42: static logical1
! 43: ajout_variable(struct_processus *s_etat_processus, struct_variable *s_variable)
1.1 bertrand 44: {
1.25 ! bertrand 45: int i;
! 46:
! 47: struct_arbre_variables *l_variable_courante;
1.12 bertrand 48:
1.25 ! bertrand 49: struct_liste_variables *l_nouvelle_variable;
! 50: struct_liste_variables *l_variable_candidate;
1.1 bertrand 51:
1.25 ! bertrand 52: struct_liste_chainee *l_nouvel_element;
1.1 bertrand 53:
1.25 ! bertrand 54: unsigned char *ptr;
1.1 bertrand 55:
1.25 ! bertrand 56: if ((*s_etat_processus).s_arbre_variables == NULL)
1.1 bertrand 57: {
1.25 ! bertrand 58: if (((*s_etat_processus).s_arbre_variables =
! 59: malloc(sizeof(struct_arbre_variables))) == NULL)
! 60: {
! 61: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 62: return(d_erreur);
! 63: }
! 64:
! 65: (*(*s_etat_processus).s_arbre_variables).feuille = NULL;
! 66: (*(*s_etat_processus).s_arbre_variables).noeuds_utilises = 0;
1.1 bertrand 67:
1.25 ! bertrand 68: if (((*(*s_etat_processus).arbre_instructions).noeud =
! 69: malloc((*s_etat_processus).nombre_caracteres_variables
! 70: * sizeof(struct_arbre_variables))) == NULL)
1.1 bertrand 71: {
1.25 ! bertrand 72: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 73: return(d_erreur);
! 74: }
! 75:
! 76: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
! 77: {
! 78: (*(*s_etat_processus).s_arbre_variables).noeud[i] = NULL;
! 79: }
! 80: }
! 81:
! 82: l_variable_courante = (*s_etat_processus).s_arbre_variables;
! 83: ptr = (*s_variable).nom;
! 84:
! 85: while((*ptr) != d_code_fin_chaine)
! 86: {
! 87: BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
! 88: printf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
! 89: *ptr));
! 90:
! 91: if ((*l_variable_courante).noeud[(*s_etat_processus)
! 92: .pointeurs_caracteres_variables[*ptr]] == NULL)
! 93: {
! 94: // Le noeud n'existe pas encore, on le crée.
! 95:
! 96: if (((*l_variable_courante).noeud[(*s_etat_processus)
! 97: .pointeurs_caracteres_variables[*ptr]] =
! 98: malloc(sizeof(struct_arbre_variables))) == NULL)
! 99: {
! 100: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 101: return(d_erreur);
! 102: }
! 103:
! 104: (*(*l_variable_courante).noeud[(*s_etat_processus)
! 105: .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
! 106: (*(*l_variable_courante).noeud[(*s_etat_processus)
! 107: .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
! 108:
! 109: if (((*(*l_variable_courante).noeud[(*s_etat_processus)
! 110: .pointeurs_caracteres_variables[*ptr]]).noeud =
! 111: malloc((*s_etat_processus).nombre_caracteres_variables
! 112: * sizeof(struct_arbre_variables))) == NULL)
! 113: {
! 114: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 115: return(d_erreur);
! 116: }
! 117:
! 118: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
! 119: {
! 120: (*(*l_variable_courante).noeud[(*s_etat_processus)
! 121: .pointeurs_caracteres_variables[*ptr]]).noeud[i] = NULL;
! 122: }
! 123: }
! 124:
! 125: (*l_variable_courante).noeuds_utilises++;
! 126: l_variable_courante = (*l_variable_courante).noeud
! 127: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
! 128: ptr++;
! 129: }
! 130:
! 131: if ((*l_variable_courante).feuille == NULL)
! 132: {
! 133: // Aucune variable de même nom préexiste. On alloue le premier
! 134: // élément de la liste doublement chaînée contenant toutes les
! 135: // variables de même nom. Cette liste boucle en premier lieu sur
! 136: // elle-même.
! 137:
! 138: if (((*l_variable_courante).feuille = malloc(
! 139: sizeof(struct_liste_variables))) == NULL)
! 140: {
! 141: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 142: return(d_erreur);
! 143: }
! 144:
! 145: (*(*l_variable_courante).feuille).suivant =
! 146: (*l_variable_courante).feuille;
! 147: (*(*l_variable_courante).feuille).precedent =
! 148: (*l_variable_courante).feuille;
! 149:
! 150: // Allocation de la variable sur l'élément de la liste.
! 151:
! 152: if (((*(*l_variable_courante).feuille).variable =
! 153: malloc(sizeof(struct_variable))) == NULL)
! 154: {
! 155: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 156: return(d_erreur);
! 157: }
! 158:
! 159: (*((struct_variable *) (*(*l_variable_courante).feuille).variable)) =
! 160: (*s_variable);
! 161:
! 162: if (((*((struct_variable *) (*(*l_variable_courante).feuille).variable))
! 163: .nom = strdup((*s_variable).nom)) == NULL)
! 164: {
! 165: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 166: return(d_erreur);
! 167: }
! 168: }
! 169: else
! 170: {
! 171: if ((*s_variable).niveau > 1)
! 172: {
! 173: // Cas d'une variable locale
! 174:
! 175: // Si le niveau de la dernière variable de même nom est
! 176: // supérieur au niveau de la variable locale que l'on veut
! 177: // enregistrer dans la liste, cette liste est incohérente.
! 178:
! 179: BUG((*(*(*l_variable_courante).feuille).variable).niveau >=
! 180: (*s_variable).niveau,
! 181: printf("Variable=\"%s\"\n", (*s_variable).nom));
! 182:
! 183: // On ajoute la variable à la liste existante.
! 184:
! 185: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
! 186: == NULL)
! 187: {
! 188: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 189: return(d_erreur);
! 190: }
! 191:
! 192: (*l_nouvelle_variable).suivant = (*l_variable_courante).feuille;
! 193: (*l_nouvelle_variable).precedent = (*(*l_variable_courante).feuille)
! 194: .precedent;
! 195: (*(*(*l_variable_courante).feuille).precedent).suivant =
! 196: l_nouvelle_variable;
! 197: (*(*l_variable_courante).feuille).precedent =
! 198: l_nouvelle_variable;
! 199: (*l_variable_courante).feuille = l_nouvelle_variable;
! 200:
! 201: if (((*(*l_variable_courante).feuille).variable =
! 202: malloc(sizeof(struct_variable))) == NULL)
! 203: {
! 204: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 205: return(d_erreur);
! 206: }
! 207:
! 208: (*((struct_variable *) (*(*l_variable_courante).feuille).variable))
! 209: = (*s_variable);
! 210:
! 211: if (((*((struct_variable *) (*(*l_variable_courante).feuille)
! 212: .variable)).nom = strdup((*s_variable).nom)) == NULL)
! 213: {
! 214: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 215: return(d_erreur);
! 216: }
1.1 bertrand 217: }
218: else
219: {
1.25 ! bertrand 220: // Cas d'une variable globale (niveau 0 [définitions] ou 1
! 221: // [variables globales])
! 222:
! 223: l_variable_candidate = (*l_variable_courante).feuille;
! 224:
! 225: do
! 226: {
! 227: // S'il y a déjà une variable de même niveau, la pile
! 228: // est incohérente.
! 229:
! 230: BUG((*(*l_variable_candidate).variable).niveau ==
! 231: (*s_variable).niveau,
! 232: printf("Variable=\"%s\"\n", (*s_variable).nom));
! 233:
! 234: l_variable_candidate = (*l_variable_candidate).precedent;
! 235: } while((l_variable_candidate != (*l_variable_courante).feuille) &&
! 236: ((*(*l_variable_candidate).variable).niveau <= 1));
! 237:
! 238: if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
! 239: .niveau > 1)
! 240: {
! 241: // Ajout inconditionnel des variables de niveaux 0 et 1
! 242: }
! 243: else
1.1 bertrand 244: {
1.25 ! bertrand 245: l_variable_candidate = (*(*l_variable_courante).feuille)
! 246: .precedent;
! 247: }
! 248:
! 249: (*l_nouvelle_variable).suivant = l_variable_candidate;
! 250: (*l_nouvelle_variable).precedent = (*l_variable_candidate)
! 251: .precedent;
! 252: (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
! 253: (*l_variable_candidate).precedent = l_nouvelle_variable;
! 254:
! 255: if (((*l_nouvelle_variable).variable =
! 256: malloc(sizeof(struct_variable))) == NULL)
! 257: {
! 258: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 259: return(d_erreur);
! 260: }
! 261:
! 262: (*(*l_nouvelle_variable).variable) = (*s_variable);
! 263:
! 264: if (((*(*l_nouvelle_variable).variable).nom =
! 265: strdup((*s_variable).nom)) == NULL)
! 266: {
! 267: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 268: return(d_erreur);
1.1 bertrand 269: }
270: }
1.25 ! bertrand 271: }
! 272:
! 273: // Ajout de la variable nouvellement créée à la liste par niveaux.
! 274: // Le pointeur contenu dans la structure de description du processus indique
! 275: // toujours le plus haut niveau utilisé.
! 276:
! 277: if ((*s_etat_processus).l_liste_variables_par_niveau == NULL)
! 278: {
! 279: // Le niveau courant n'existe pas. Il est créé.
! 280:
! 281: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
! 282: == NULL)
! 283: {
! 284: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 285: return(d_erreur);
! 286: }
! 287:
! 288: (*l_nouvelle_variable).suivant = l_nouvelle_variable;
! 289: (*l_nouvelle_variable).precedent = l_nouvelle_variable;
! 290:
! 291: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
! 292: }
! 293: else if ((*s_variable).niveau > (*((struct_variable *)
! 294: (*(*(*s_etat_processus).l_liste_variables_par_niveau).liste)
! 295: .donnee)).niveau)
! 296: {
! 297: // Le niveau courant n'existe pas. Il est créé.
1.1 bertrand 298:
1.25 ! bertrand 299: if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
! 300: == NULL)
1.1 bertrand 301: {
302: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
303: return(d_erreur);
304: }
305:
1.25 ! bertrand 306: (*l_nouvelle_variable).suivant = (*s_etat_processus)
! 307: .l_liste_variables_par_niveau;
! 308: (*l_nouvelle_variable).precedent = (*(*s_etat_processus)
! 309: .l_liste_variables_par_niveau).precedent;
! 310: (*(*(*s_etat_processus).l_liste_variables_par_niveau).precedent)
! 311: .suivant = l_nouvelle_variable;
! 312: (*(*s_etat_processus).l_liste_variables_par_niveau).precedent =
! 313: l_nouvelle_variable;
! 314:
! 315: (*s_etat_processus).l_liste_variables_par_niveau = l_nouvelle_variable;
! 316: }
! 317: else
! 318: {
! 319: // Création d'une variable de niveau 0 ou 1
! 320:
! 321: l_variable_candidate = (*s_etat_processus).l_liste_variables_par_niveau;
! 322:
! 323: if ((*((struct_variable *) (*(*(*(*s_etat_processus)
! 324: .l_liste_variables_par_niveau).precedent).liste).donnee))
! 325: .niveau > 1)
! 326: {
! 327: // Ajout inconditionnel des variables de niveaux 0 et 1
! 328: }
! 329: else
! 330: {
! 331: l_variable_candidate = (*(*s_etat_processus)
! 332: .l_liste_variables_par_niveau).precedent;
! 333: }
! 334:
! 335: (*l_nouvelle_variable).suivant = l_variable_candidate;
! 336: (*l_nouvelle_variable).precedent = (*l_variable_candidate)
! 337: .precedent;
! 338: (*(*l_variable_candidate).precedent).suivant = l_nouvelle_variable;
! 339: (*l_variable_candidate).precedent = l_nouvelle_variable;
! 340: }
! 341:
! 342: // Ajout de la variable en tête de la liste
! 343:
! 344: if ((l_nouvel_element = malloc(sizeof(struct_liste_chainee))) == NULL)
! 345: {
! 346: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 347: return(d_erreur);
1.1 bertrand 348: }
349:
1.25 ! bertrand 350: (*l_nouvel_element).suivant = (*(*s_etat_processus)
! 351: .l_liste_variables_par_niveau).liste;
! 352: (*l_nouvel_element).donnee = (struct_objet *) s_variable;
! 353: (*l_nouvelle_variable).liste = l_nouvel_element;
! 354:
! 355: return(d_absence_erreur);
! 356: }
! 357:
! 358: logical1
! 359: creation_variable(struct_processus *s_etat_processus,
! 360: struct_variable *s_variable,
! 361: unsigned char autorisation_creation_variable_statique,
! 362: unsigned char autorisation_creation_variable_partagee)
! 363: {
1.1 bertrand 364: if ((*s_etat_processus).mode_execution_programme == 'Y')
365: {
366: (*s_variable).origine = 'P';
367: }
368: else
369: {
370: (*s_variable).origine = 'E';
371: }
372:
373: if ((*s_variable).niveau == 0)
374: {
375: // Un point d'entrée de définition est verrouillé.
376:
377: if ((*s_variable).origine == 'P')
378: {
379: (*s_variable).variable_statique.adresse = 0;
380: (*s_variable).variable_partagee.adresse = 0;
381: }
382: else
383: {
384: (*s_variable).variable_statique.pointeur = NULL;
385: (*s_variable).variable_partagee.pointeur = NULL;
386: }
387:
388: (*s_variable).variable_verrouillee = d_vrai;
389: }
390: else if ((*s_variable).niveau == 1)
391: {
392: // Une variable globale ne peut être statique.
393:
394: if ((*s_variable).origine == 'P')
395: {
396: (*s_variable).variable_statique.adresse = 0;
397: (*s_variable).variable_partagee.adresse = 0;
398: }
399: else
400: {
401: (*s_variable).variable_statique.pointeur = NULL;
402: (*s_variable).variable_partagee.pointeur = NULL;
403: }
404:
405: (*s_variable).variable_verrouillee = d_faux;
406: }
407: else
408: {
409: // 0 -> variable volatile
410: // adresse de création -> variable statique
411:
412: if (autorisation_creation_variable_statique == 'V')
413: {
414: if (autorisation_creation_variable_partagee == 'S')
415: {
416: // On force la création d'une variable partagée
417:
418: if ((*s_variable).origine == 'P')
419: {
420: (*s_variable).variable_statique.adresse = 0;
421: (*s_variable).variable_partagee.adresse =
422: (*s_etat_processus).position_courante;
423: }
424: else
425: {
426: (*s_variable).variable_statique.pointeur = NULL;
427: (*s_variable).variable_partagee.pointeur =
428: (*s_etat_processus).objet_courant;
429: }
430: }
431: else
432: {
433: // On force la création d'une variable volatile
434:
435: if ((*s_variable).origine == 'P')
436: {
437: (*s_variable).variable_statique.adresse = 0;
438: (*s_variable).variable_partagee.adresse = 0;
439: }
440: else
441: {
442: (*s_variable).variable_statique.pointeur = NULL;
443: (*s_variable).variable_partagee.pointeur = NULL;
444: }
445: }
446: }
447: else
448: {
449: // On force la création d'une variable statique.
450:
451: if ((*s_variable).origine == 'P')
452: {
453: (*s_variable).variable_statique.adresse =
454: (*s_etat_processus).position_courante;
455: (*s_variable).variable_partagee.adresse = 0;
456: }
457: else
458: {
459: (*s_variable).variable_statique.pointeur =
460: (*s_etat_processus).objet_courant;
461: (*s_variable).variable_partagee.pointeur = 0;
462: }
463: }
464:
465: (*s_variable).variable_verrouillee = d_faux;
466: }
467:
468: /*
1.25 ! bertrand 469: * Recherche de la feuille correspondante dans l'arbre des variables.
! 470: * Si cette feuille n'existe pas, elle est créée.
1.1 bertrand 471: */
472:
1.25 ! bertrand 473: if (ajout_variable(s_etat_processus, s_variable) == d_erreur)
! 474: {
! 475: return(d_erreur);
! 476: }
! 477:
! 478: return(d_absence_erreur);
! 479: }
! 480:
! 481:
! 482: /*
! 483: ================================================================================
! 484: Procédure de recherche d'une variable par son nom dans la base
! 485: ================================================================================
! 486: Entrée :
! 487: --------------------------------------------------------------------------------
! 488: Sortie :
! 489: --------------------------------------------------------------------------------
! 490: Effets de bord : néant
! 491: ================================================================================
! 492: */
! 493:
! 494: logical1
! 495: recherche_variable(struct_processus *s_etat_processus,
! 496: unsigned char *nom_variable)
! 497: {
! 498: int pointeur;
! 499:
! 500: struct_arbre_variables *l_variable_courante;
! 501: struct_liste_pile_systeme *l_element_courant;
! 502:
! 503: unsigned char *ptr;
! 504:
! 505: unsigned long niveau_appel;
1.1 bertrand 506:
1.25 ! bertrand 507: if ((*s_etat_processus).s_arbre_variables == NULL)
1.1 bertrand 508: {
1.25 ! bertrand 509: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
! 510: return d_faux;
1.1 bertrand 511: }
1.25 ! bertrand 512:
! 513: ptr = nom_variable;
! 514:
! 515: while((*ptr) != d_code_fin_chaine)
1.1 bertrand 516: {
1.25 ! bertrand 517: pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
! 518:
! 519: if (pointeur < 0)
! 520: {
! 521: // Caractère hors de l'alphabet des variables
! 522: return(d_erreur);
! 523: }
! 524:
! 525: if ((*l_variable_courante).noeud[pointeur] == NULL)
1.1 bertrand 526: {
1.25 ! bertrand 527: // Le chemin de la variable candidate n'existe pas.
! 528: return(d_erreur);
1.1 bertrand 529: }
530:
1.25 ! bertrand 531: l_variable_courante = (*l_variable_courante).noeud[pointeur];
! 532: ptr++;
! 533: }
! 534:
! 535: if ((*l_variable_courante).feuille != NULL)
! 536: {
! 537: // Il existe une pile de variables de même nom. Le sommet de la
! 538: // pile est la variable de niveau le plus haut.
! 539:
! 540: l_element_courant = (*s_etat_processus).l_base_pile_systeme;
! 541:
! 542: if (l_element_courant == NULL)
1.12 bertrand 543: {
1.25 ! bertrand 544: // Problème : la pile système est vide !
! 545: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
! 546: return(d_erreur);
1.12 bertrand 547: }
1.25 ! bertrand 548:
! 549: while((*l_element_courant).retour_definition != 'Y')
1.12 bertrand 550: {
1.25 ! bertrand 551: l_element_courant = (*l_element_courant).suivant;
1.12 bertrand 552:
1.25 ! bertrand 553: if (l_element_courant == NULL)
1.12 bertrand 554: {
1.25 ! bertrand 555: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
! 556: return(d_erreur);
1.12 bertrand 557: }
1.25 ! bertrand 558: }
! 559:
! 560: niveau_appel = (*l_element_courant).niveau_courant;
1.12 bertrand 561:
1.25 ! bertrand 562: if (niveau_appel < (*(*(*l_variable_courante).feuille).variable).niveau)
! 563: {
! 564: // Une variable locale est accessible puisque créée dans la
! 565: // fonction courante.
! 566:
! 567: (*s_etat_processus).pointeur_variable_courante =
! 568: (*(*l_variable_courante).feuille).variable;
! 569: (*s_etat_processus).pointeur_feuille_courante =
! 570: (*l_variable_courante).feuille;
! 571: return(d_absence_erreur);
! 572: }
! 573: else
! 574: {
! 575: // Aucune variable locale n'est accessible depuis la fonction.
! 576: // Dans ce cas, on prend la variable de niveau le plus bas
! 577: // si ce niveau est inférieur ou égal à 1 (variable globale
! 578: // ou fonction définie par l'utilisateur). Si le niveau de la
! 579: // plus ancienne variable est strictement supérieur à 1, el
! 580: // s'agit d'une variable locale inaccessible.
! 581:
! 582: if ((*(*(*(*l_variable_courante).feuille).precedent).variable)
! 583: .niveau <= 1)
! 584: {
! 585: (*s_etat_processus).pointeur_variable_courante =
! 586: (*(*(*l_variable_courante).feuille).precedent).variable;
! 587: (*s_etat_processus).pointeur_feuille_courante =
! 588: (*l_variable_courante).feuille;
! 589: return(d_absence_erreur);
1.12 bertrand 590: }
591: }
1.1 bertrand 592: }
593:
1.25 ! bertrand 594: return(d_erreur);
1.1 bertrand 595: }
596:
597:
598: /*
599: ================================================================================
600: Procédure de retrait d'une variable de la base
601: ================================================================================
602: Entrée : type 'G' ou 'L' selon que l'on retire une variable locale (incluant
603: les globales) ou strictement globale.
604: --------------------------------------------------------------------------------
605: Sortie :
606: --------------------------------------------------------------------------------
607: Effets de bord : néant
608: ================================================================================
609: */
610:
611: logical1
612: retrait_variable(struct_processus *s_etat_processus,
613: unsigned char *nom_variable, unsigned char type)
614: {
615: logical1 erreur;
616:
617: if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
618: {
1.25 ! bertrand 619: // Une variable correspondant au nom recherché est accessible.
! 620:
1.1 bertrand 621: if (type == 'G')
622: {
1.25 ! bertrand 623: if ((*(*s_etat_processus).pointeur_variable_courante).niveau > 1)
! 624: {
! 625: // La variable obtenue est une variable locale. il faut
! 626: // s'assurer qu'il existe une variable de niveau 1 de même
! 627: // nom sur la feuille.
! 628: }
! 629:
1.1 bertrand 630: if ((*s_etat_processus).position_variable_courante > 0)
631: {
632: while(strcmp((*s_etat_processus).s_liste_variables
633: [(*s_etat_processus).position_variable_courante]
634: .nom, nom_variable) == 0)
635: {
636: (*s_etat_processus).position_variable_courante--;
637:
638: if ((*s_etat_processus).position_variable_courante >=
639: (*s_etat_processus).nombre_variables)
640: {
641: erreur = d_erreur;
642: (*s_etat_processus).erreur_execution =
643: d_ex_variable_non_definie;
644: return erreur;
645: }
646: }
647:
648: (*s_etat_processus).position_variable_courante++;
649: }
650:
651: if ((*s_etat_processus).s_liste_variables
652: [(*s_etat_processus).position_variable_courante]
653: .niveau != 1)
654: {
655: erreur = d_erreur;
656: (*s_etat_processus).erreur_execution =
657: d_ex_variable_non_definie;
658: return erreur;
659: }
660:
661: if ((*s_etat_processus).s_liste_variables
662: [(*s_etat_processus).position_variable_courante]
663: .variable_verrouillee == d_vrai)
664: {
665: erreur = d_erreur;
666: (*s_etat_processus).erreur_execution =
667: d_ex_variable_verrouillee;
668: return erreur;
669: }
670: }
671:
672: if ((*s_etat_processus).nombre_variables <
673: ((*s_etat_processus).nombre_variables_allouees / 2))
674: {
675: (*s_etat_processus).nombre_variables_allouees /= 2;
676:
677: // (*s_etat_processus).nombre_variables est forcément
678: // supérieur à 1 (la décrémentation est postérieure). Ce test
679: // est vrai lorsque le nombre de variables allouées est
680: // strictement supérieur à 2.
681:
682: if ((s_nouvelle_base =
683: realloc((*s_etat_processus).s_liste_variables,
684: (*s_etat_processus).nombre_variables_allouees *
685: sizeof(struct_variable))) == NULL)
686: {
687: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
688: return(d_erreur);
689: }
690:
691: (*s_etat_processus).s_liste_variables = s_nouvelle_base;
692: }
693:
694: position_supprimee = (*s_etat_processus).position_variable_courante;
695:
696: liberation(s_etat_processus, (*s_etat_processus).s_liste_variables
697: [position_supprimee].objet);
698: free((*s_etat_processus).s_liste_variables[position_supprimee].nom);
699:
700: (*s_etat_processus).nombre_variables--;
701:
702: for(position_courante = position_supprimee;
703: position_courante < (*s_etat_processus).nombre_variables;
704: position_courante++)
705: {
706: (*s_etat_processus).s_liste_variables[position_courante] =
707: (*s_etat_processus).s_liste_variables
708: [position_courante + 1];
709: }
710:
711: erreur = d_absence_erreur;
712: }
713: else
714: {
1.25 ! bertrand 715: // Aucune variable n'est accessible depuis le point courant du
! 716: // programme.
! 717:
1.1 bertrand 718: erreur = d_erreur;
719: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
720: }
721:
1.25 ! bertrand 722: return(erreur);
1.1 bertrand 723: }
724:
725:
726: /*
727: ================================================================================
728: Procédure de retrait des variables de niveau strictement supérieur au
729: niveau courant
730: ================================================================================
731: Entrée :
732: --------------------------------------------------------------------------------
733: Sortie :
734: --------------------------------------------------------------------------------
735: Effets de bord : néant
736: ================================================================================
737: */
738:
739: logical1
740: retrait_variable_par_niveau(struct_processus *s_etat_processus)
741: {
742: unsigned long i;
743: unsigned long j;
744:
745: struct_variable *tampon;
746:
747: for(j = 0, i = 0; i < (*s_etat_processus).nombre_variables; i++)
748: {
749: if ((*s_etat_processus).s_liste_variables[i].niveau <=
750: (*s_etat_processus).niveau_courant)
751: {
752: (*s_etat_processus).s_liste_variables[j++] =
753: (*s_etat_processus).s_liste_variables[i];
754: }
755: else
756: {
757: if ((*s_etat_processus).s_liste_variables[i].origine == 'P')
758: {
759: if ((*s_etat_processus).s_liste_variables[i]
760: .variable_statique.adresse != 0)
761: {
762: /*
763: * Gestion des variables statiques
764: */
765:
766: if (recherche_variable_statique(s_etat_processus,
767: (*s_etat_processus).s_liste_variables[i]
768: .nom, (*s_etat_processus).s_liste_variables
769: [i].variable_statique, ((*s_etat_processus)
770: .mode_execution_programme
771: == 'Y') ? 'P' : 'E') == d_vrai)
772: {
773: (*s_etat_processus).s_liste_variables_statiques
774: [(*s_etat_processus)
775: .position_variable_statique_courante]
776: .objet = (*s_etat_processus)
777: .s_liste_variables[i].objet;
778: }
779: else
780: {
781: (*s_etat_processus).erreur_systeme =
782: d_es_variable_introuvable;
783: }
784:
785: (*s_etat_processus).s_liste_variables[i].objet = NULL;
786: }
787: }
788: else
789: {
790: if ((*s_etat_processus).s_liste_variables[i]
791: .variable_statique.pointeur != NULL)
792: {
793: /*
794: * Gestion des variables statiques
795: */
796:
797: if (recherche_variable_statique(s_etat_processus,
798: (*s_etat_processus).s_liste_variables[i]
799: .nom, (*s_etat_processus).s_liste_variables[i]
800: .variable_statique, ((*s_etat_processus)
801: .mode_execution_programme
802: == 'Y') ? 'P' : 'E') == d_vrai)
803: {
804: (*s_etat_processus).s_liste_variables_statiques
805: [(*s_etat_processus)
806: .position_variable_statique_courante]
807: .objet = (*s_etat_processus)
808: .s_liste_variables[i].objet;
809: }
810: else
811: {
812: (*s_etat_processus).erreur_systeme =
813: d_es_variable_introuvable;
1.22 bertrand 814: return(d_erreur);
1.1 bertrand 815: }
816:
817: (*s_etat_processus).s_liste_variables[i].objet = NULL;
818: }
819: }
820:
821: free((*s_etat_processus).s_liste_variables[i].nom);
822: liberation(s_etat_processus,
823: (*s_etat_processus).s_liste_variables[i].objet);
824: }
825: }
826:
827: (*s_etat_processus).nombre_variables = j;
828:
829: if ((*s_etat_processus).nombre_variables <
830: ((*s_etat_processus).nombre_variables_allouees / 2))
831: {
832: (*s_etat_processus).nombre_variables_allouees /= 2;
833:
834: if ((tampon = realloc((*s_etat_processus).s_liste_variables,
835: (*s_etat_processus).nombre_variables_allouees *
836: sizeof(struct_variable))) == NULL)
837: {
838: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
839: return(d_erreur);
840: }
841:
842: (*s_etat_processus).s_liste_variables = tampon;
843: }
844:
845: return(d_absence_erreur);
846: }
847:
1.23 bertrand 848:
849: /*
850: ================================================================================
1.24 bertrand 851: Procédure de retrait des toutes les variables locales et globales
852: ================================================================================
853: Entrée : drapeau indiquant s'il faut retirer les définitions (variables
854: de niveau 0)
855: --------------------------------------------------------------------------------
856: Sortie :
857: --------------------------------------------------------------------------------
858: Effets de bord : néant
859: ================================================================================
860: */
861:
862: void
863: liberation_arbre_variables(struct_processus *s_etat_processus,
864: struct_arbre_variables *arbre, logical1 retrait_definitions)
865: {
866: int i;
867:
868: struct_liste_chainee *l_element_courant;
869: struct_liste_chainee *l_element_suivant;
870:
871: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
872: {
873: if ((*arbre).noeud[i] != NULL)
874: {
875: l_element_courant = (*arbre).l_variables;
876:
877: while(l_element_courant != NULL)
878: {
879: l_element_suivant = (*l_element_courant).suivant;
880:
881: if (retrait_definitions == d_vrai)
882: {
883: liberation(s_etat_processus, (*((struct_variable *)
884: (*l_element_courant).donnee)).objet);
885: free((*((struct_variable *) (*l_element_courant)
886: .donnee)).nom);
887: free((struct_variable *) (*l_element_courant).donnee);
888: }
889: else
890: {
891: if ((*((struct_variable *) (*l_element_courant).donnee))
892: .niveau >= 1)
893: {
894: liberation(s_etat_processus, (*((struct_variable *)
895: (*l_element_courant).donnee)).objet);
896: free((*((struct_variable *) (*l_element_courant)
897: .donnee)).nom);
898: free((struct_variable *) (*l_element_courant).donnee);
899: }
900: }
901:
902: free(l_element_courant);
903: l_element_courant = l_element_suivant;
904: }
905:
906: liberation_arbre_variables(s_etat_processus, (*arbre).noeud[i]);
907: }
908: }
909:
910: free((*arbre).noeud);
911: free(arbre);
912:
913: return;
914: }
915:
916: /*
917: ================================================================================
1.23 bertrand 918: Procédure de copie de l'arbre des variables
919: ================================================================================
920: Entrée :
921: --------------------------------------------------------------------------------
922: Sortie :
923: --------------------------------------------------------------------------------
924: Effets de bord : néant
925: ================================================================================
926: */
927:
928: struct_arbre_variables *
929: copie_arbre_variables(struct_processus *s_etat_processus)
930: {
931: // Les définitions sont partagées entre tous les threads et ne sont pas
932: // copiées.
933:
934: return(d_absence_erreur);
935: }
936:
937:
938: /*
939: ================================================================================
940: Procédure d'initialisation de la table de correspondance des variables
941: ================================================================================
942: Entrée :
943: --------------------------------------------------------------------------------
944: Sortie :
945: --------------------------------------------------------------------------------
946: Effets de bord : néant
947: ================================================================================
948: */
949:
950: /*
951: * Caractères autorisés dans les instructions
952: *
953: * 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
954: * 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
955: * _
956: * 1 2 3 4 5 6 7 8 9 0
957: */
958:
959: void
960: initialisation_variables(struct_processus *s_etat_processus)
961: {
962: int decalage;
963: int i;
964: int longueur_tableau;
965:
966: unsigned char caractere;
967:
968: // Récupération de la longueur d'un unsigned char
969:
970: longueur_tableau = 1;
971: decalage = 0;
972: caractere = 1;
973:
974: while((1L << decalage) == (long) ((unsigned char) (caractere << decalage)))
975: {
976: decalage++;
977: longueur_tableau *= 2;
978: }
979:
980: if (((*s_etat_processus).pointeurs_caracteres_variables =
981: malloc(longueur_tableau * sizeof(int))) == NULL)
982: {
983: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
984: return;
985: }
986:
987: for(i = 0; i < longueur_tableau; i++)
988: {
989: (*s_etat_processus).pointeurs_caracteres_variables[i] = -1;
990: }
991:
992: (*s_etat_processus).nombre_caracteres_variables = 0;
993:
994: #define DECLARATION_CARACTERE(c) \
995: do { (*s_etat_processus).pointeurs_caracteres_variables[c] = \
996: (*s_etat_processus).nombre_caracteres_variables++; } while(0)
997:
998: DECLARATION_CARACTERE('A');
999: DECLARATION_CARACTERE('B');
1000: DECLARATION_CARACTERE('C');
1001: DECLARATION_CARACTERE('D');
1002: DECLARATION_CARACTERE('E');
1003: DECLARATION_CARACTERE('F');
1004: DECLARATION_CARACTERE('G');
1005: DECLARATION_CARACTERE('H');
1006: DECLARATION_CARACTERE('I');
1007: DECLARATION_CARACTERE('J');
1008: DECLARATION_CARACTERE('K');
1009: DECLARATION_CARACTERE('L');
1010: DECLARATION_CARACTERE('M');
1011: DECLARATION_CARACTERE('N');
1012: DECLARATION_CARACTERE('O');
1013: DECLARATION_CARACTERE('P');
1014: DECLARATION_CARACTERE('Q');
1015: DECLARATION_CARACTERE('R');
1016: DECLARATION_CARACTERE('S');
1017: DECLARATION_CARACTERE('T');
1018: DECLARATION_CARACTERE('U');
1019: DECLARATION_CARACTERE('V');
1020: DECLARATION_CARACTERE('W');
1021: DECLARATION_CARACTERE('X');
1022: DECLARATION_CARACTERE('Y');
1023: DECLARATION_CARACTERE('Z');
1024:
1025: DECLARATION_CARACTERE('a');
1026: DECLARATION_CARACTERE('b');
1027: DECLARATION_CARACTERE('c');
1028: DECLARATION_CARACTERE('d');
1029: DECLARATION_CARACTERE('e');
1030: DECLARATION_CARACTERE('f');
1031: DECLARATION_CARACTERE('g');
1032: DECLARATION_CARACTERE('h');
1033: DECLARATION_CARACTERE('i');
1034: DECLARATION_CARACTERE('j');
1035: DECLARATION_CARACTERE('k');
1036: DECLARATION_CARACTERE('l');
1037: DECLARATION_CARACTERE('m');
1038: DECLARATION_CARACTERE('n');
1039: DECLARATION_CARACTERE('o');
1040: DECLARATION_CARACTERE('p');
1041: DECLARATION_CARACTERE('q');
1042: DECLARATION_CARACTERE('r');
1043: DECLARATION_CARACTERE('s');
1044: DECLARATION_CARACTERE('t');
1045: DECLARATION_CARACTERE('u');
1046: DECLARATION_CARACTERE('v');
1047: DECLARATION_CARACTERE('w');
1048: DECLARATION_CARACTERE('x');
1049: DECLARATION_CARACTERE('y');
1050: DECLARATION_CARACTERE('z');
1051:
1052: DECLARATION_CARACTERE('_');
1053:
1054: DECLARATION_CARACTERE('1');
1055: DECLARATION_CARACTERE('2');
1056: DECLARATION_CARACTERE('3');
1057: DECLARATION_CARACTERE('4');
1058: DECLARATION_CARACTERE('5');
1059: DECLARATION_CARACTERE('6');
1060: DECLARATION_CARACTERE('7');
1061: DECLARATION_CARACTERE('8');
1062: DECLARATION_CARACTERE('9');
1063: DECLARATION_CARACTERE('0');
1064: #undef DECLARATION_CARACTERE
1065:
1066: return;
1067: }
1.25 ! bertrand 1068:
1.1 bertrand 1069: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>