File:  [local] / rpl / src / gestion_variables.c
Revision 1.27: download - view: text, annotated - select for diffs - revision graph
Wed Jun 1 18:17:35 2011 UTC (12 years, 11 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Suite des modifications...

    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, il
  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: 
  590:                 // S'il existe une variable de niveau 0 et une seconde de
  591:                 // niveau 1, la variable de niveau 0 (fonction) est masquée
  592:                 // par celle de niveau 1.
  593: 
  594:                 if (((*(*(*l_variable_courante).feuille).variable).niveau == 0)
  595:                         && ((*(*(*(*l_variable_courante).feuille).precedent)
  596:                         .variable).niveau == 1))
  597:                 {
  598:                     (*s_etat_processus).pointeur_variable_courante =
  599:                             (*(*(*l_variable_courante).feuille).precedent)
  600:                             .variable;
  601:                     (*s_etat_processus).pointeur_feuille_courante =
  602:                             (*l_variable_courante).feuille;
  603:                 }
  604: 
  605:                 return(d_absence_erreur);
  606:             }
  607:         }
  608:     }
  609: 
  610:     return(d_erreur);
  611: }
  612: 
  613: 
  614: /*
  615: ================================================================================
  616:   Procédure de retrait d'une variable de la base
  617: ================================================================================
  618:   Entrée : type 'G' ou 'L' selon que l'on retire une variable locale (incluant
  619:            les globales) ou strictement globale.
  620: --------------------------------------------------------------------------------
  621:   Sortie :
  622: --------------------------------------------------------------------------------
  623:   Effets de bord : néant
  624: ================================================================================
  625: */
  626: 
  627: logical1
  628: retrait_variable(struct_processus *s_etat_processus,
  629:         unsigned char *nom_variable, unsigned char type)
  630: {
  631:     logical1            erreur;
  632: 
  633:     if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
  634:     {
  635:         // Une variable correspondant au nom recherché est accessible.
  636: 
  637:         if (type == 'G')
  638:         {
  639:             if ((*(*s_etat_processus).pointeur_variable_courante).niveau > 1)
  640:             {
  641:                 // La variable obtenue est une variable locale. il faut
  642:                 // s'assurer qu'il existe une variable de niveau 1 de même
  643:                 // nom sur la feuille.
  644: 
  645:                 if ((*(*(*(*s_etat_processus).pointeur_feuille_courante)
  646:                         .precedent).variable).niveau <= 1)
  647:                 {
  648:                     (*s_etat_processus).pointeur_feuille_courante =
  649:                             (*(*s_etat_processus).pointeur_feuille_courante)
  650:                             .precedent;
  651:                     (*s_etat_processus).pointeur_variable_courante =
  652:                             (*(*s_etat_processus).pointeur_feuille_courante)
  653:                             .variable;
  654: 
  655:                     // Si la variable retournée est de niveau 0, on regarde
  656:                     // un peu plus loin si une variable de niveau 1 existe.
  657: 
  658:                     if (((*(*(*s_etat_processus).pointeur_feuille_courante)
  659:                             .variable).niveau == 0) &&
  660:                             ((*(*(*(*s_etat_processus)
  661:                             .pointeur_feuille_courante).precedent).variable)
  662:                             .niveau == 1))
  663:                     {
  664:                         (*s_etat_processus).pointeur_feuille_courante =
  665:                                 (*(*s_etat_processus).pointeur_feuille_courante)
  666:                                 .precedent;
  667:                         (*s_etat_processus).pointeur_variable_courante =
  668:                                 (*(*s_etat_processus).pointeur_feuille_courante)
  669:                                 .variable;
  670:                     }
  671:                 }
  672:                 else
  673:                 {
  674:                     // Aucune variable globale (niveau 1) n'existe.
  675: 
  676:                     erreur = d_erreur;
  677:                     (*s_etat_processus).erreur_execution =
  678:                             d_ex_variable_non_definie;
  679:                     return(erreur);
  680:                 }
  681:             }
  682: 
  683:             if ((*(*s_etat_processus).pointeur_variable_courante)
  684:                     .variable_verrouillee == d_vrai)
  685:             {
  686:                 erreur = d_erreur;
  687:                 (*s_etat_processus).erreur_execution =
  688:                         d_ex_variable_verrouillee;
  689:                 return erreur;
  690:             }
  691:         }
  692: 
  693:         // Suppression de la variable de la liste.
  694:         // Deux cas peuvent survenir :
  695:         // 1/ les pointeurs sur la variable et la variable suivante
  696:         // sont identiques et on supprime la variable ainsi que la feuille
  697:         // associée ;
  698:         // 2/ ces deux pointeurs sont différents et se contente de retirer
  699:         // la structure décrivant la variable.
  700: 
  701:         position_supprimee = (*s_etat_processus).position_variable_courante;
  702: 
  703:         liberation(s_etat_processus, (*s_etat_processus).s_liste_variables
  704:                 [position_supprimee].objet);
  705:         free((*s_etat_processus).s_liste_variables[position_supprimee].nom);
  706: 
  707:         (*s_etat_processus).nombre_variables--;
  708: 
  709:         for(position_courante = position_supprimee;
  710:                 position_courante < (*s_etat_processus).nombre_variables;
  711:                 position_courante++)
  712:         {
  713:             (*s_etat_processus).s_liste_variables[position_courante] =
  714:                     (*s_etat_processus).s_liste_variables
  715:                     [position_courante + 1];
  716:         }
  717: 
  718:         erreur = d_absence_erreur;
  719:     }
  720:     else
  721:     {
  722:         // Aucune variable n'est accessible depuis le point courant du
  723:         // programme.
  724: 
  725:         erreur = d_erreur;
  726:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  727:     }
  728: 
  729:     return(erreur);
  730: }
  731: 
  732: 
  733: /*
  734: ================================================================================
  735:   Procédure de retrait des variables de niveau strictement supérieur au
  736:   niveau courant
  737: ================================================================================
  738:   Entrée :
  739: --------------------------------------------------------------------------------
  740:   Sortie :
  741: --------------------------------------------------------------------------------
  742:   Effets de bord : néant
  743: ================================================================================
  744: */
  745: 
  746: logical1
  747: retrait_variable_par_niveau(struct_processus *s_etat_processus)
  748: {
  749:     unsigned long                   i;
  750:     unsigned long                   j;
  751: 
  752:     struct_variable                 *tampon;
  753: 
  754:     for(j = 0, i = 0; i < (*s_etat_processus).nombre_variables; i++)
  755:     {
  756:         if ((*s_etat_processus).s_liste_variables[i].niveau <=
  757:                 (*s_etat_processus).niveau_courant)
  758:         {
  759:             (*s_etat_processus).s_liste_variables[j++] =
  760:                     (*s_etat_processus).s_liste_variables[i];
  761:         }
  762:         else
  763:         {
  764:             if ((*s_etat_processus).s_liste_variables[i].origine == 'P')
  765:             {
  766:                 if ((*s_etat_processus).s_liste_variables[i]
  767:                         .variable_statique.adresse != 0)
  768:                 {
  769:                     /*
  770:                      * Gestion des variables statiques
  771:                      */
  772: 
  773:                     if (recherche_variable_statique(s_etat_processus,
  774:                             (*s_etat_processus).s_liste_variables[i]
  775:                             .nom, (*s_etat_processus).s_liste_variables
  776:                             [i].variable_statique, ((*s_etat_processus)
  777:                             .mode_execution_programme
  778:                              == 'Y') ? 'P' : 'E') == d_vrai)
  779:                     {
  780:                         (*s_etat_processus).s_liste_variables_statiques
  781:                                 [(*s_etat_processus)
  782:                                 .position_variable_statique_courante]
  783:                                 .objet = (*s_etat_processus)
  784:                                 .s_liste_variables[i].objet;
  785:                     }
  786:                     else
  787:                     {
  788:                         (*s_etat_processus).erreur_systeme =
  789:                                 d_es_variable_introuvable;
  790:                     }
  791: 
  792:                     (*s_etat_processus).s_liste_variables[i].objet = NULL;
  793:                 }
  794:             }
  795:             else
  796:             {
  797:                 if ((*s_etat_processus).s_liste_variables[i]
  798:                         .variable_statique.pointeur != NULL)
  799:                 {
  800:                     /*
  801:                      * Gestion des variables statiques
  802:                      */
  803: 
  804:                     if (recherche_variable_statique(s_etat_processus,
  805:                             (*s_etat_processus).s_liste_variables[i]
  806:                             .nom, (*s_etat_processus).s_liste_variables[i]
  807:                             .variable_statique, ((*s_etat_processus)
  808:                             .mode_execution_programme
  809:                              == 'Y') ? 'P' : 'E') == d_vrai)
  810:                     {
  811:                         (*s_etat_processus).s_liste_variables_statiques
  812:                                 [(*s_etat_processus)
  813:                                 .position_variable_statique_courante]
  814:                                 .objet = (*s_etat_processus)
  815:                                 .s_liste_variables[i].objet;
  816:                     }
  817:                     else
  818:                     {
  819:                         (*s_etat_processus).erreur_systeme =
  820:                                 d_es_variable_introuvable;
  821:                         return(d_erreur);
  822:                     }
  823: 
  824:                     (*s_etat_processus).s_liste_variables[i].objet = NULL;
  825:                 }
  826:             }
  827: 
  828:             free((*s_etat_processus).s_liste_variables[i].nom);
  829:             liberation(s_etat_processus,
  830:                     (*s_etat_processus).s_liste_variables[i].objet);
  831:         }
  832:     }
  833: 
  834:     (*s_etat_processus).nombre_variables = j;
  835: 
  836:     if ((*s_etat_processus).nombre_variables <
  837:             ((*s_etat_processus).nombre_variables_allouees / 2))
  838:     {
  839:         (*s_etat_processus).nombre_variables_allouees /= 2;
  840: 
  841:         if ((tampon = realloc((*s_etat_processus).s_liste_variables,
  842:                 (*s_etat_processus).nombre_variables_allouees *
  843:                 sizeof(struct_variable))) == NULL)
  844:         {
  845:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  846:             return(d_erreur);
  847:         }
  848: 
  849:         (*s_etat_processus).s_liste_variables = tampon;
  850:     }
  851: 
  852:     return(d_absence_erreur);
  853: }
  854: 
  855: 
  856: /*
  857: ================================================================================
  858:   Procédure de retrait des toutes les variables locales et globales
  859: ================================================================================
  860:   Entrée : drapeau indiquant s'il faut retirer les définitions (variables
  861:            de niveau 0)
  862: --------------------------------------------------------------------------------
  863:   Sortie :
  864: --------------------------------------------------------------------------------
  865:   Effets de bord : néant
  866: ================================================================================
  867: */
  868: 
  869: void
  870: liberation_arbre_variables(struct_processus *s_etat_processus,
  871:         struct_arbre_variables *arbre, logical1 retrait_definitions)
  872: {
  873:     int                     i;
  874: 
  875:     struct_liste_chainee    *l_element_courant;
  876:     struct_liste_chainee    *l_element_suivant;
  877: 
  878:     for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
  879:     {
  880:         if ((*arbre).noeud[i] != NULL)
  881:         {
  882:             l_element_courant = (*arbre).l_variables;
  883: 
  884:             while(l_element_courant != NULL)
  885:             {
  886:                 l_element_suivant = (*l_element_courant).suivant;
  887: 
  888:                 if (retrait_definitions == d_vrai)
  889:                 {
  890:                     liberation(s_etat_processus, (*((struct_variable *)
  891:                             (*l_element_courant).donnee)).objet);
  892:                     free((*((struct_variable *) (*l_element_courant)
  893:                             .donnee)).nom);
  894:                     free((struct_variable *) (*l_element_courant).donnee);
  895:                 }
  896:                 else
  897:                 {
  898:                     if ((*((struct_variable *) (*l_element_courant).donnee))
  899:                             .niveau >= 1)
  900:                     {
  901:                         liberation(s_etat_processus, (*((struct_variable *)
  902:                                 (*l_element_courant).donnee)).objet);
  903:                         free((*((struct_variable *) (*l_element_courant)
  904:                                 .donnee)).nom);
  905:                         free((struct_variable *) (*l_element_courant).donnee);
  906:                     }
  907:                 }
  908: 
  909:                 free(l_element_courant);
  910:                 l_element_courant = l_element_suivant;
  911:             }
  912: 
  913:             liberation_arbre_variables(s_etat_processus, (*arbre).noeud[i]);
  914:         }
  915:     }
  916: 
  917:     free((*arbre).noeud);
  918:     free(arbre);
  919: 
  920:     return;
  921: }
  922: 
  923: /*
  924: ================================================================================
  925:   Procédure de copie de l'arbre des variables
  926: ================================================================================
  927:   Entrée :
  928: --------------------------------------------------------------------------------
  929:   Sortie :
  930: --------------------------------------------------------------------------------
  931:   Effets de bord : néant
  932: ================================================================================
  933: */
  934: 
  935: struct_arbre_variables *
  936: copie_arbre_variables(struct_processus *s_etat_processus)
  937: {
  938:     // Les définitions sont partagées entre tous les threads et ne sont pas
  939:     // copiées.
  940: 
  941:     return(d_absence_erreur);
  942: }
  943: 
  944: 
  945: /*
  946: ================================================================================
  947:   Procédure d'initialisation de la table de correspondance des variables
  948: ================================================================================
  949:   Entrée :
  950: --------------------------------------------------------------------------------
  951:   Sortie :
  952: --------------------------------------------------------------------------------
  953:   Effets de bord : néant
  954: ================================================================================
  955: */
  956: 
  957: /*
  958:  * Caractères autorisés dans les instructions
  959:  *
  960:  * 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
  961:  * 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
  962:  * _
  963:  * 1 2 3 4 5 6 7 8 9 0
  964:  */
  965: 
  966: void
  967: initialisation_variables(struct_processus *s_etat_processus)
  968: {
  969:     int             decalage;
  970:     int             i;
  971:     int             longueur_tableau;
  972: 
  973:     unsigned char   caractere;
  974: 
  975:     // Récupération de la longueur d'un unsigned char
  976: 
  977:     longueur_tableau = 1;
  978:     decalage = 0;
  979:     caractere = 1;
  980: 
  981:     while((1L << decalage) == (long) ((unsigned char) (caractere << decalage)))
  982:     {
  983:         decalage++;
  984:         longueur_tableau *= 2;
  985:     }
  986: 
  987:     if (((*s_etat_processus).pointeurs_caracteres_variables =
  988:             malloc(longueur_tableau * sizeof(int))) == NULL)
  989:     {
  990:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  991:         return;
  992:     }
  993: 
  994:     for(i = 0; i < longueur_tableau; i++)
  995:     {
  996:         (*s_etat_processus).pointeurs_caracteres_variables[i] = -1;
  997:     }
  998: 
  999:     (*s_etat_processus).nombre_caracteres_variables = 0;
 1000: 
 1001: #define DECLARATION_CARACTERE(c) \
 1002:         do { (*s_etat_processus).pointeurs_caracteres_variables[c] = \
 1003:         (*s_etat_processus).nombre_caracteres_variables++; } while(0)
 1004: 
 1005:     DECLARATION_CARACTERE('A');
 1006:     DECLARATION_CARACTERE('B');
 1007:     DECLARATION_CARACTERE('C');
 1008:     DECLARATION_CARACTERE('D');
 1009:     DECLARATION_CARACTERE('E');
 1010:     DECLARATION_CARACTERE('F');
 1011:     DECLARATION_CARACTERE('G');
 1012:     DECLARATION_CARACTERE('H');
 1013:     DECLARATION_CARACTERE('I');
 1014:     DECLARATION_CARACTERE('J');
 1015:     DECLARATION_CARACTERE('K');
 1016:     DECLARATION_CARACTERE('L');
 1017:     DECLARATION_CARACTERE('M');
 1018:     DECLARATION_CARACTERE('N');
 1019:     DECLARATION_CARACTERE('O');
 1020:     DECLARATION_CARACTERE('P');
 1021:     DECLARATION_CARACTERE('Q');
 1022:     DECLARATION_CARACTERE('R');
 1023:     DECLARATION_CARACTERE('S');
 1024:     DECLARATION_CARACTERE('T');
 1025:     DECLARATION_CARACTERE('U');
 1026:     DECLARATION_CARACTERE('V');
 1027:     DECLARATION_CARACTERE('W');
 1028:     DECLARATION_CARACTERE('X');
 1029:     DECLARATION_CARACTERE('Y');
 1030:     DECLARATION_CARACTERE('Z');
 1031: 
 1032:     DECLARATION_CARACTERE('a');
 1033:     DECLARATION_CARACTERE('b');
 1034:     DECLARATION_CARACTERE('c');
 1035:     DECLARATION_CARACTERE('d');
 1036:     DECLARATION_CARACTERE('e');
 1037:     DECLARATION_CARACTERE('f');
 1038:     DECLARATION_CARACTERE('g');
 1039:     DECLARATION_CARACTERE('h');
 1040:     DECLARATION_CARACTERE('i');
 1041:     DECLARATION_CARACTERE('j');
 1042:     DECLARATION_CARACTERE('k');
 1043:     DECLARATION_CARACTERE('l');
 1044:     DECLARATION_CARACTERE('m');
 1045:     DECLARATION_CARACTERE('n');
 1046:     DECLARATION_CARACTERE('o');
 1047:     DECLARATION_CARACTERE('p');
 1048:     DECLARATION_CARACTERE('q');
 1049:     DECLARATION_CARACTERE('r');
 1050:     DECLARATION_CARACTERE('s');
 1051:     DECLARATION_CARACTERE('t');
 1052:     DECLARATION_CARACTERE('u');
 1053:     DECLARATION_CARACTERE('v');
 1054:     DECLARATION_CARACTERE('w');
 1055:     DECLARATION_CARACTERE('x');
 1056:     DECLARATION_CARACTERE('y');
 1057:     DECLARATION_CARACTERE('z');
 1058: 
 1059:     DECLARATION_CARACTERE('_');
 1060: 
 1061:     DECLARATION_CARACTERE('1');
 1062:     DECLARATION_CARACTERE('2');
 1063:     DECLARATION_CARACTERE('3');
 1064:     DECLARATION_CARACTERE('4');
 1065:     DECLARATION_CARACTERE('5');
 1066:     DECLARATION_CARACTERE('6');
 1067:     DECLARATION_CARACTERE('7');
 1068:     DECLARATION_CARACTERE('8');
 1069:     DECLARATION_CARACTERE('9');
 1070:     DECLARATION_CARACTERE('0');
 1071: #undef DECLARATION_CARACTERE
 1072: 
 1073:     return;
 1074: }
 1075: 
 1076: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>