File:  [local] / rpl / src / gestion_variables.c
Revision 1.26: download - view: text, annotated - select for diffs - revision graph
Thu Apr 21 16:00:55 2011 UTC (13 years ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Merge entre la branche 4_0 et HEAD.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.0.prerelease.0
    4:   Copyright (C) 1989-2011 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: static logical1
   43: ajout_variable(struct_processus *s_etat_processus, struct_variable *s_variable)
   44: {
   45:     int                         i;
   46: 
   47:     struct_arbre_variables      *l_variable_courante;
   48: 
   49:     struct_liste_variables      *l_nouvelle_variable;
   50:     struct_liste_variables      *l_variable_candidate;
   51: 
   52:     struct_liste_chainee        *l_nouvel_element;
   53: 
   54:     unsigned char               *ptr;
   55: 
   56:     if ((*s_etat_processus).s_arbre_variables == NULL)
   57:     {
   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;
   67: 
   68:         if (((*(*s_etat_processus).arbre_instructions).noeud =
   69:                 malloc((*s_etat_processus).nombre_caracteres_variables
   70:                 * sizeof(struct_arbre_variables))) == NULL)
   71:         {
   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:             }
  217:         }
  218:         else
  219:         {
  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
  244:             {
  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);
  269:             }
  270:         }
  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éé.
  298: 
  299:         if ((l_nouvelle_variable = malloc(sizeof(struct_liste_variables)))
  300:                 == NULL)
  301:         {
  302:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  303:             return(d_erreur);
  304:         }
  305: 
  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);
  348:     }
  349: 
  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: {
  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:     /*
  469:      * Recherche de la feuille correspondante dans l'arbre des variables.
  470:      * Si cette feuille n'existe pas, elle est créée.
  471:      */
  472: 
  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;
  506: 
  507:     if ((*s_etat_processus).s_arbre_variables == NULL)
  508:     {
  509:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  510:         return d_faux;
  511:     }
  512: 
  513:     ptr = nom_variable;
  514: 
  515:     while((*ptr) != d_code_fin_chaine)
  516:     {
  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)
  526:         {
  527:             // Le chemin de la variable candidate n'existe pas.
  528:             return(d_erreur);
  529:         }
  530: 
  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)
  543:         {
  544:             // Problème : la pile système est vide !
  545:             (*s_etat_processus).erreur_systeme = d_es_pile_vide;
  546:             return(d_erreur);
  547:         }
  548: 
  549:         while((*l_element_courant).retour_definition != 'Y')
  550:         {
  551:             l_element_courant = (*l_element_courant).suivant;
  552: 
  553:             if (l_element_courant == NULL)
  554:             {
  555:                 (*s_etat_processus).erreur_systeme = d_es_pile_vide;
  556:                 return(d_erreur);
  557:             }
  558:         }
  559: 
  560:         niveau_appel = (*l_element_courant).niveau_courant;
  561: 
  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);
  590:             }
  591:         }
  592:     }
  593: 
  594:     return(d_erreur);
  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:     {
  619:         // Une variable correspondant au nom recherché est accessible.
  620: 
  621:         if (type == 'G')
  622:         {
  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: 
  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:     {
  715:         // Aucune variable n'est accessible depuis le point courant du
  716:         // programme.
  717: 
  718:         erreur = d_erreur;
  719:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  720:     }
  721: 
  722:     return(erreur);
  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;
  814:                         return(d_erreur);
  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: 
  848: 
  849: /*
  850: ================================================================================
  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: ================================================================================
  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: }
 1068: 
 1069: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>