Annotation of rpl/src/gestion_variables.c, revision 1.1
1.1 ! bertrand 1: /*
! 2: ================================================================================
! 3: RPL/2 (R) version 4.0.9
! 4: Copyright (C) 1989-2010 Dr. BERTRAND Joël
! 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:
! 23: #include "rpl.conv.h"
! 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:
! 42: logical1
! 43: creation_variable(struct_processus *s_etat_processus,
! 44: struct_variable *s_variable,
! 45: unsigned char autorisation_creation_variable_statique,
! 46: unsigned char autorisation_creation_variable_partagee)
! 47: {
! 48: long i;
! 49:
! 50: struct_variable *s_nouvelle_base;
! 51:
! 52: (*s_etat_processus).nombre_variables++;
! 53:
! 54: if ((*s_etat_processus).nombre_variables > (*s_etat_processus)
! 55: .nombre_variables_allouees)
! 56: {
! 57: // La nouvelle variable ne tient pas dans la table courante. Il
! 58: // faut donc en augmenter la taille.
! 59:
! 60: if ((*s_etat_processus).nombre_variables_allouees == 0)
! 61: {
! 62: (*s_etat_processus).nombre_variables_allouees =
! 63: (*s_etat_processus).nombre_variables;
! 64: }
! 65: else
! 66: {
! 67: while((*s_etat_processus).nombre_variables >
! 68: (*s_etat_processus).nombre_variables_allouees)
! 69: {
! 70: (*s_etat_processus).nombre_variables_allouees *= 2;
! 71: }
! 72: }
! 73:
! 74: if ((s_nouvelle_base = realloc((*s_etat_processus).s_liste_variables,
! 75: (*s_etat_processus).nombre_variables_allouees *
! 76: sizeof(struct_variable))) == NULL)
! 77: {
! 78: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 79: (*s_etat_processus).nombre_variables--;
! 80: return(d_erreur);
! 81: }
! 82:
! 83: (*s_etat_processus).s_liste_variables = s_nouvelle_base;
! 84: }
! 85:
! 86: if ((*s_etat_processus).mode_execution_programme == 'Y')
! 87: {
! 88: (*s_variable).origine = 'P';
! 89: }
! 90: else
! 91: {
! 92: (*s_variable).origine = 'E';
! 93: }
! 94:
! 95: if ((*s_variable).niveau == 0)
! 96: {
! 97: // Un point d'entrée de définition est verrouillé.
! 98:
! 99: if ((*s_variable).origine == 'P')
! 100: {
! 101: (*s_variable).variable_statique.adresse = 0;
! 102: (*s_variable).variable_partagee.adresse = 0;
! 103: }
! 104: else
! 105: {
! 106: (*s_variable).variable_statique.pointeur = NULL;
! 107: (*s_variable).variable_partagee.pointeur = NULL;
! 108: }
! 109:
! 110: (*s_variable).variable_verrouillee = d_vrai;
! 111: }
! 112: else if ((*s_variable).niveau == 1)
! 113: {
! 114: // Une variable globale ne peut être statique.
! 115:
! 116: if ((*s_variable).origine == 'P')
! 117: {
! 118: (*s_variable).variable_statique.adresse = 0;
! 119: (*s_variable).variable_partagee.adresse = 0;
! 120: }
! 121: else
! 122: {
! 123: (*s_variable).variable_statique.pointeur = NULL;
! 124: (*s_variable).variable_partagee.pointeur = NULL;
! 125: }
! 126:
! 127: (*s_variable).variable_verrouillee = d_faux;
! 128: }
! 129: else
! 130: {
! 131: // 0 -> variable volatile
! 132: // adresse de création -> variable statique
! 133:
! 134: if (autorisation_creation_variable_statique == 'V')
! 135: {
! 136: if (autorisation_creation_variable_partagee == 'S')
! 137: {
! 138: // On force la création d'une variable partagée
! 139:
! 140: if ((*s_variable).origine == 'P')
! 141: {
! 142: (*s_variable).variable_statique.adresse = 0;
! 143: (*s_variable).variable_partagee.adresse =
! 144: (*s_etat_processus).position_courante;
! 145: }
! 146: else
! 147: {
! 148: (*s_variable).variable_statique.pointeur = NULL;
! 149: (*s_variable).variable_partagee.pointeur =
! 150: (*s_etat_processus).objet_courant;
! 151: }
! 152: }
! 153: else
! 154: {
! 155: // On force la création d'une variable volatile
! 156:
! 157: if ((*s_variable).origine == 'P')
! 158: {
! 159: (*s_variable).variable_statique.adresse = 0;
! 160: (*s_variable).variable_partagee.adresse = 0;
! 161: }
! 162: else
! 163: {
! 164: (*s_variable).variable_statique.pointeur = NULL;
! 165: (*s_variable).variable_partagee.pointeur = NULL;
! 166: }
! 167: }
! 168: }
! 169: else
! 170: {
! 171: // On force la création d'une variable statique.
! 172:
! 173: if ((*s_variable).origine == 'P')
! 174: {
! 175: (*s_variable).variable_statique.adresse =
! 176: (*s_etat_processus).position_courante;
! 177: (*s_variable).variable_partagee.adresse = 0;
! 178: }
! 179: else
! 180: {
! 181: (*s_variable).variable_statique.pointeur =
! 182: (*s_etat_processus).objet_courant;
! 183: (*s_variable).variable_partagee.pointeur = 0;
! 184: }
! 185: }
! 186:
! 187: (*s_variable).variable_verrouillee = d_faux;
! 188: }
! 189:
! 190: /*
! 191: * Positionnement de la variable au bon endroit
! 192: */
! 193:
! 194: // Nous avons (*s_etat_processus).nombre_variables - 1 variables dans la
! 195: // table qui sera balayée de la fin vers le début.
! 196:
! 197: if ((*s_etat_processus).nombre_variables == 1)
! 198: {
! 199: (*s_etat_processus).s_liste_variables[0] = (*s_variable);
! 200: }
! 201: else
! 202: {
! 203: for(i = (*s_etat_processus).nombre_variables - 2; i >= 0; i--)
! 204: {
! 205: if (strcmp((*s_variable).nom,
! 206: (*s_etat_processus).s_liste_variables[i].nom) < 0)
! 207: {
! 208: (*s_etat_processus).s_liste_variables[i + 1] =
! 209: (*s_etat_processus).s_liste_variables[i];
! 210: }
! 211: else
! 212: {
! 213: break;
! 214: }
! 215: }
! 216:
! 217: (*s_etat_processus).s_liste_variables[i + 1] = (*s_variable);
! 218: }
! 219:
! 220: return(d_absence_erreur);
! 221: }
! 222:
! 223:
! 224: /*
! 225: ================================================================================
! 226: Procédure de retrait d'une variable de la base
! 227: ================================================================================
! 228: Entrée : type 'G' ou 'L' selon que l'on retire une variable locale (incluant
! 229: les globales) ou strictement globale.
! 230: --------------------------------------------------------------------------------
! 231: Sortie :
! 232: --------------------------------------------------------------------------------
! 233: Effets de bord : néant
! 234: ================================================================================
! 235: */
! 236:
! 237: logical1
! 238: retrait_variable(struct_processus *s_etat_processus,
! 239: unsigned char *nom_variable, unsigned char type)
! 240: {
! 241: struct_variable *s_nouvelle_base;
! 242:
! 243: logical1 erreur;
! 244:
! 245: unsigned long position_courante;
! 246: unsigned long position_supprimee;
! 247:
! 248: if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
! 249: {
! 250: if (type == 'G')
! 251: {
! 252: if ((*s_etat_processus).position_variable_courante > 0)
! 253: {
! 254: while(strcmp((*s_etat_processus).s_liste_variables
! 255: [(*s_etat_processus).position_variable_courante]
! 256: .nom, nom_variable) == 0)
! 257: {
! 258: (*s_etat_processus).position_variable_courante--;
! 259:
! 260: if ((*s_etat_processus).position_variable_courante >=
! 261: (*s_etat_processus).nombre_variables)
! 262: {
! 263: erreur = d_erreur;
! 264: (*s_etat_processus).erreur_execution =
! 265: d_ex_variable_non_definie;
! 266: return erreur;
! 267: }
! 268: }
! 269:
! 270: (*s_etat_processus).position_variable_courante++;
! 271: }
! 272:
! 273: if ((*s_etat_processus).s_liste_variables
! 274: [(*s_etat_processus).position_variable_courante]
! 275: .niveau != 1)
! 276: {
! 277: erreur = d_erreur;
! 278: (*s_etat_processus).erreur_execution =
! 279: d_ex_variable_non_definie;
! 280: return erreur;
! 281: }
! 282:
! 283: if ((*s_etat_processus).s_liste_variables
! 284: [(*s_etat_processus).position_variable_courante]
! 285: .variable_verrouillee == d_vrai)
! 286: {
! 287: erreur = d_erreur;
! 288: (*s_etat_processus).erreur_execution =
! 289: d_ex_variable_verrouillee;
! 290: return erreur;
! 291: }
! 292: }
! 293:
! 294: if ((*s_etat_processus).nombre_variables <
! 295: ((*s_etat_processus).nombre_variables_allouees / 2))
! 296: {
! 297: (*s_etat_processus).nombre_variables_allouees /= 2;
! 298:
! 299: // (*s_etat_processus).nombre_variables est forcément
! 300: // supérieur à 1 (la décrémentation est postérieure). Ce test
! 301: // est vrai lorsque le nombre de variables allouées est
! 302: // strictement supérieur à 2.
! 303:
! 304: if ((s_nouvelle_base =
! 305: realloc((*s_etat_processus).s_liste_variables,
! 306: (*s_etat_processus).nombre_variables_allouees *
! 307: sizeof(struct_variable))) == NULL)
! 308: {
! 309: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 310: return(d_erreur);
! 311: }
! 312:
! 313: (*s_etat_processus).s_liste_variables = s_nouvelle_base;
! 314: }
! 315:
! 316: position_supprimee = (*s_etat_processus).position_variable_courante;
! 317:
! 318: liberation(s_etat_processus, (*s_etat_processus).s_liste_variables
! 319: [position_supprimee].objet);
! 320: free((*s_etat_processus).s_liste_variables[position_supprimee].nom);
! 321:
! 322: (*s_etat_processus).nombre_variables--;
! 323:
! 324: for(position_courante = position_supprimee;
! 325: position_courante < (*s_etat_processus).nombre_variables;
! 326: position_courante++)
! 327: {
! 328: (*s_etat_processus).s_liste_variables[position_courante] =
! 329: (*s_etat_processus).s_liste_variables
! 330: [position_courante + 1];
! 331: }
! 332:
! 333: erreur = d_absence_erreur;
! 334: }
! 335: else
! 336: {
! 337: erreur = d_erreur;
! 338: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
! 339: }
! 340:
! 341: return erreur;
! 342: }
! 343:
! 344:
! 345: /*
! 346: ================================================================================
! 347: Procédure de recherche d'une variable par son nom dans la base
! 348: ================================================================================
! 349: Entrée :
! 350: --------------------------------------------------------------------------------
! 351: Sortie :
! 352: --------------------------------------------------------------------------------
! 353: Effets de bord : néant
! 354: ================================================================================
! 355: */
! 356:
! 357: logical1
! 358: recherche_variable(struct_processus *s_etat_processus,
! 359: unsigned char *nom_variable)
! 360: {
! 361: logical1 existence_variable;
! 362:
! 363: long difference;
! 364: long difference_inferieure;
! 365: long difference_superieure;
! 366:
! 367: struct_liste_pile_systeme *l_element_courant;
! 368:
! 369: unsigned long borne_inferieure;
! 370: unsigned long borne_superieure;
! 371: unsigned long moyenne;
! 372: unsigned long niveau_appel;
! 373: unsigned long nombre_iterations_maximal;
! 374: unsigned long ordre_iteration;
! 375:
! 376: if ((*s_etat_processus).nombre_variables == 0)
! 377: {
! 378: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
! 379: return d_faux;
! 380: }
! 381:
! 382: ordre_iteration = 0;
! 383: nombre_iterations_maximal = ((unsigned long)
! 384: (log((*s_etat_processus).nombre_variables) / log(2))) + 2;
! 385:
! 386: borne_inferieure = 0;
! 387: borne_superieure = (*s_etat_processus).nombre_variables - 1;
! 388:
! 389: do
! 390: {
! 391: moyenne = (borne_inferieure + borne_superieure) / 2;
! 392: ordre_iteration++;
! 393:
! 394: if (((borne_inferieure + borne_superieure) % 2) == 0)
! 395: {
! 396: difference = strcmp(nom_variable,
! 397: ((*s_etat_processus).s_liste_variables)[moyenne].nom);
! 398:
! 399: if (difference != 0)
! 400: {
! 401: if (difference > 0)
! 402: {
! 403: borne_inferieure = moyenne;
! 404: }
! 405: else
! 406: {
! 407: borne_superieure = moyenne;
! 408: }
! 409: }
! 410: }
! 411: else
! 412: {
! 413: difference_inferieure = strcmp(nom_variable,
! 414: ((*s_etat_processus).s_liste_variables)[moyenne].nom);
! 415: difference_superieure = strcmp(nom_variable,
! 416: ((*s_etat_processus).s_liste_variables)[moyenne + 1].nom);
! 417:
! 418: if (difference_inferieure == 0)
! 419: {
! 420: difference = 0;
! 421: }
! 422: else if (difference_superieure == 0)
! 423: {
! 424: difference = 0;
! 425: moyenne++;
! 426: }
! 427: else
! 428: {
! 429: difference = difference_inferieure;
! 430:
! 431: if (difference > 0)
! 432: {
! 433: borne_inferieure = moyenne;
! 434: }
! 435: else
! 436: {
! 437: borne_superieure = moyenne;
! 438: }
! 439: }
! 440: }
! 441: } while((difference != 0) &&
! 442: (ordre_iteration <= nombre_iterations_maximal));
! 443:
! 444: if (ordre_iteration > nombre_iterations_maximal)
! 445: {
! 446: existence_variable = d_faux;
! 447: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
! 448: }
! 449: else
! 450: {
! 451: if ((moyenne + 1) < (*s_etat_processus).nombre_variables)
! 452: {
! 453: while(strcmp(((*s_etat_processus).s_liste_variables)
! 454: [moyenne + 1].nom, nom_variable) == 0)
! 455: {
! 456: moyenne++;
! 457:
! 458: if ((moyenne + 1) >= (*s_etat_processus).nombre_variables)
! 459: {
! 460: break;
! 461: }
! 462: }
! 463: }
! 464:
! 465: (*s_etat_processus).position_variable_courante = moyenne;
! 466:
! 467: if ((*s_etat_processus).s_liste_variables[(*s_etat_processus)
! 468: .position_variable_courante].niveau > 1)
! 469: {
! 470: // La variable trouvée est une variable locale.
! 471: // On vérifie qu'elle est accessible à la définition
! 472: // courante.
! 473:
! 474: niveau_appel = (*s_etat_processus).niveau_courant;
! 475: l_element_courant = (*s_etat_processus).l_base_pile_systeme;
! 476:
! 477: if (l_element_courant == NULL)
! 478: {
! 479: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
! 480: existence_variable = d_faux;
! 481:
! 482: return existence_variable;
! 483: }
! 484:
! 485: while((*l_element_courant).retour_definition != 'Y')
! 486: {
! 487: l_element_courant = (*l_element_courant).suivant;
! 488:
! 489: if (l_element_courant == NULL)
! 490: {
! 491: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
! 492: existence_variable = d_faux;
! 493:
! 494: return existence_variable;
! 495: }
! 496: }
! 497:
! 498: niveau_appel = (*l_element_courant).niveau_courant;
! 499:
! 500: if (niveau_appel < (*s_etat_processus).s_liste_variables
! 501: [(*s_etat_processus).position_variable_courante].niveau)
! 502: {
! 503: existence_variable = d_vrai;
! 504: }
! 505: else
! 506: {
! 507: existence_variable = d_faux;
! 508:
! 509: // La variable locale n'est pas accessible. On regarde si par
! 510: // hasard il existe une variable globale.
! 511:
! 512: while((*s_etat_processus).position_variable_courante != 0)
! 513: {
! 514: if (strcmp(((*s_etat_processus).s_liste_variables)
! 515: [(*s_etat_processus).position_variable_courante - 1] .nom, nom_variable) == 0)
! 516: {
! 517: (*s_etat_processus).position_variable_courante--;
! 518: }
! 519: else
! 520: {
! 521: if ((*s_etat_processus).s_liste_variables
! 522: [(*s_etat_processus).position_variable_courante]
! 523: .niveau <= 1)
! 524: {
! 525: existence_variable = d_vrai;
! 526: }
! 527:
! 528: break;
! 529: }
! 530: }
! 531:
! 532: if ((strcmp(((*s_etat_processus).s_liste_variables)
! 533: [(*s_etat_processus).position_variable_courante].nom,
! 534: nom_variable) == 0) && ((*s_etat_processus)
! 535: .s_liste_variables[(*s_etat_processus)
! 536: .position_variable_courante].niveau <= 1))
! 537: {
! 538: existence_variable = d_vrai;
! 539: }
! 540: }
! 541: }
! 542: else
! 543: {
! 544: // La variable trouvée est soit un pointeur sur une définition
! 545: // (niveau 0), soit une variable globale (niveau 1).
! 546:
! 547: existence_variable = d_vrai;
! 548: }
! 549: }
! 550:
! 551: return existence_variable;
! 552: }
! 553:
! 554:
! 555: /*
! 556: ================================================================================
! 557: Procédure de retrait des variables de niveau strictement supérieur au
! 558: niveau courant
! 559: ================================================================================
! 560: Entrée :
! 561: --------------------------------------------------------------------------------
! 562: Sortie :
! 563: --------------------------------------------------------------------------------
! 564: Effets de bord : néant
! 565: ================================================================================
! 566: */
! 567:
! 568: logical1
! 569: retrait_variable_par_niveau(struct_processus *s_etat_processus)
! 570: {
! 571: unsigned long i;
! 572: unsigned long j;
! 573:
! 574: struct_variable *tampon;
! 575:
! 576: for(j = 0, i = 0; i < (*s_etat_processus).nombre_variables; i++)
! 577: {
! 578: if ((*s_etat_processus).s_liste_variables[i].niveau <=
! 579: (*s_etat_processus).niveau_courant)
! 580: {
! 581: (*s_etat_processus).s_liste_variables[j++] =
! 582: (*s_etat_processus).s_liste_variables[i];
! 583: }
! 584: else
! 585: {
! 586: if ((*s_etat_processus).s_liste_variables[i].origine == 'P')
! 587: {
! 588: if ((*s_etat_processus).s_liste_variables[i]
! 589: .variable_statique.adresse != 0)
! 590: {
! 591: /*
! 592: * Gestion des variables statiques
! 593: */
! 594:
! 595: if (recherche_variable_statique(s_etat_processus,
! 596: (*s_etat_processus).s_liste_variables[i]
! 597: .nom, (*s_etat_processus).s_liste_variables
! 598: [i].variable_statique, ((*s_etat_processus)
! 599: .mode_execution_programme
! 600: == 'Y') ? 'P' : 'E') == d_vrai)
! 601: {
! 602: (*s_etat_processus).s_liste_variables_statiques
! 603: [(*s_etat_processus)
! 604: .position_variable_statique_courante]
! 605: .objet = (*s_etat_processus)
! 606: .s_liste_variables[i].objet;
! 607: }
! 608: else
! 609: {
! 610: (*s_etat_processus).erreur_systeme =
! 611: d_es_variable_introuvable;
! 612: }
! 613:
! 614: (*s_etat_processus).s_liste_variables[i].objet = NULL;
! 615: }
! 616: }
! 617: else
! 618: {
! 619: if ((*s_etat_processus).s_liste_variables[i]
! 620: .variable_statique.pointeur != NULL)
! 621: {
! 622: /*
! 623: * Gestion des variables statiques
! 624: */
! 625:
! 626: if (recherche_variable_statique(s_etat_processus,
! 627: (*s_etat_processus).s_liste_variables[i]
! 628: .nom, (*s_etat_processus).s_liste_variables[i]
! 629: .variable_statique, ((*s_etat_processus)
! 630: .mode_execution_programme
! 631: == 'Y') ? 'P' : 'E') == d_vrai)
! 632: {
! 633: (*s_etat_processus).s_liste_variables_statiques
! 634: [(*s_etat_processus)
! 635: .position_variable_statique_courante]
! 636: .objet = (*s_etat_processus)
! 637: .s_liste_variables[i].objet;
! 638: }
! 639: else
! 640: {
! 641: (*s_etat_processus).erreur_systeme =
! 642: d_es_variable_introuvable;
! 643: }
! 644:
! 645: (*s_etat_processus).s_liste_variables[i].objet = NULL;
! 646: }
! 647: }
! 648:
! 649: free((*s_etat_processus).s_liste_variables[i].nom);
! 650: liberation(s_etat_processus,
! 651: (*s_etat_processus).s_liste_variables[i].objet);
! 652: }
! 653: }
! 654:
! 655: (*s_etat_processus).nombre_variables = j;
! 656:
! 657: if ((*s_etat_processus).nombre_variables <
! 658: ((*s_etat_processus).nombre_variables_allouees / 2))
! 659: {
! 660: (*s_etat_processus).nombre_variables_allouees /= 2;
! 661:
! 662: if ((tampon = realloc((*s_etat_processus).s_liste_variables,
! 663: (*s_etat_processus).nombre_variables_allouees *
! 664: sizeof(struct_variable))) == NULL)
! 665: {
! 666: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 667: return(d_erreur);
! 668: }
! 669:
! 670: (*s_etat_processus).s_liste_variables = tampon;
! 671: }
! 672:
! 673: return(d_absence_erreur);
! 674: }
! 675:
! 676: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>