File:  [local] / rpl / src / gestion_variables_statiques.c
Revision 1.33: download - view: text, annotated - select for diffs - revision graph
Fri Apr 13 14:12:50 2012 UTC (12 years ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_8, HEAD
En route pour la 4.1.8 !

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.8
    4:   Copyright (C) 1989-2012 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 statique
   29: ================================================================================
   30:   Entrée :
   31: --------------------------------------------------------------------------------
   32:   Sortie :
   33: --------------------------------------------------------------------------------
   34:   Effets de bords : néant
   35: ================================================================================
   36: */
   37: 
   38: logical1
   39: creation_variable_statique(struct_processus *s_etat_processus,
   40:         struct_variable_statique *s_variable)
   41: {
   42:     struct_variable_statique            *s_nouvelle_base;
   43: 
   44:     long                                i;
   45: 
   46:     (*s_etat_processus).nombre_variables_statiques++;
   47: 
   48:     if ((*s_etat_processus).nombre_variables_statiques > (*s_etat_processus)
   49:             .nombre_variables_statiques_allouees)
   50:     {
   51:         // La nouvelle variable statique ne tient pas dans la table courante.
   52:         // Il convient donc d'en augmenter la taille.
   53: 
   54:         if ((*s_etat_processus).nombre_variables_statiques_allouees == 0)
   55:         {
   56:             (*s_etat_processus).nombre_variables_statiques_allouees =
   57:                     (*s_etat_processus).nombre_variables_statiques;
   58:         }
   59:         else
   60:         {
   61:             while((*s_etat_processus).nombre_variables_statiques >
   62:                     (*s_etat_processus).nombre_variables_statiques_allouees)
   63:             {
   64:                 (*s_etat_processus).nombre_variables_statiques_allouees *= 2;
   65:             }
   66:         }
   67: 
   68:         if ((s_nouvelle_base = realloc((*s_etat_processus)
   69:                 .s_liste_variables_statiques, (*s_etat_processus)
   70:                 .nombre_variables_statiques_allouees *
   71:                 sizeof(struct_variable_statique))) == NULL)
   72:         {
   73:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
   74:             (*s_etat_processus).nombre_variables_statiques--;
   75:             return(d_erreur);
   76:         }
   77: 
   78:         (*s_etat_processus).s_liste_variables_statiques = s_nouvelle_base;
   79:     }
   80: 
   81:     /*
   82:      * Positionnement de la variable statique au bon endroit
   83:      */
   84: 
   85:     // Nous avons (*s_etat_processus).nombre_variables_statiques - 1 variables
   86:     // dans la table qui sera balayée de la fin vers le début.
   87: 
   88:     if ((*s_etat_processus).nombre_variables_statiques == 1)
   89:     {
   90:         (*s_etat_processus).s_liste_variables_statiques[0] = (*s_variable);
   91:     }
   92:     else
   93:     {
   94:         for(i = (*s_etat_processus).nombre_variables_statiques - 2; i >= 0; i--)
   95:         {
   96:             if (strcmp((*s_variable).nom,
   97:                     (*s_etat_processus).s_liste_variables_statiques[i].nom) < 0)
   98:             {
   99:                 (*s_etat_processus).s_liste_variables_statiques[i + 1] =
  100:                         (*s_etat_processus).s_liste_variables_statiques[i];
  101:             }
  102:             else
  103:             {
  104:                 break;
  105:             }
  106:         }
  107: 
  108:         (*s_etat_processus).s_liste_variables_statiques[i + 1] = (*s_variable);
  109:     }
  110: 
  111:     return d_absence_erreur;
  112: }
  113: 
  114: 
  115: /*
  116: ================================================================================
  117:   Procédure de retrait d'une variable statique de la base
  118: ================================================================================
  119:   Entrée :
  120: --------------------------------------------------------------------------------
  121:   Sortie :
  122: --------------------------------------------------------------------------------
  123:   Effets de bord : néant
  124: ================================================================================
  125: */
  126: 
  127: logical1
  128: retrait_variable_statique(struct_processus *s_etat_processus,
  129:         unsigned char *nom_variable, union_position_variable position)
  130: {
  131:     struct_variable_statique        *s_nouvelle_base;
  132: 
  133:     logical1                        erreur;
  134: 
  135:     unsigned long                   position_courante;
  136:     unsigned long                   position_supprimee;
  137: 
  138:     if (recherche_variable_statique(s_etat_processus, nom_variable,
  139:             position, ((*s_etat_processus).mode_execution_programme == 'Y')
  140:             ? 'P' : 'E') == d_vrai)
  141:     {
  142:         if ((*s_etat_processus).nombre_variables_statiques <
  143:                 ((*s_etat_processus).nombre_variables_statiques_allouees / 2))
  144:         {
  145:             (*s_etat_processus).nombre_variables_statiques_allouees /= 2;
  146: 
  147:             if ((s_nouvelle_base =
  148:                     realloc((*s_etat_processus).s_liste_variables_statiques,
  149:                     (*s_etat_processus).nombre_variables_statiques_allouees *
  150:                     sizeof(struct_variable_statique))) == NULL)
  151:             {
  152:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  153:                 return(d_erreur);
  154:             }
  155: 
  156:             (*s_etat_processus).s_liste_variables_statiques = s_nouvelle_base;
  157:         }
  158: 
  159:         position_supprimee = (*s_etat_processus)
  160:                 .position_variable_statique_courante;
  161: 
  162:         liberation(s_etat_processus, (*s_etat_processus)
  163:                 .s_liste_variables_statiques[position_supprimee].objet);
  164:         free((*s_etat_processus).s_liste_variables_statiques
  165:                 [position_supprimee].nom);
  166: 
  167:         (*s_etat_processus).nombre_variables_statiques--;
  168: 
  169:         for(position_courante = position_supprimee; position_courante <
  170:                 (*s_etat_processus).nombre_variables_statiques;
  171:                 position_courante++)
  172:         {
  173:             (*s_etat_processus).s_liste_variables_statiques[position_courante]
  174:                     = (*s_etat_processus).s_liste_variables_statiques
  175:                     [position_courante + 1];
  176:         }
  177: 
  178:         erreur = d_absence_erreur;
  179:     }
  180:     else
  181:     {
  182:         erreur = d_erreur;
  183:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  184:     }
  185: 
  186:     return erreur;
  187: }
  188: 
  189: 
  190: /*
  191: ================================================================================
  192:   Procédure de recherche d'une variable statique par son nom dans la base
  193: ================================================================================
  194:   Entrée :
  195: --------------------------------------------------------------------------------
  196:   Sortie :
  197: --------------------------------------------------------------------------------
  198:   Effets de bord : néant
  199: ================================================================================
  200: */
  201: 
  202: logical1
  203: recherche_variable_statique(struct_processus *s_etat_processus,
  204:         unsigned char *nom_variable, union_position_variable position,
  205:         unsigned char origine)
  206: {
  207:     logical1                    existence_variable;
  208: 
  209:     long                        difference;
  210:     long                        difference_inferieure;
  211:     long                        difference_superieure;
  212: 
  213:     unsigned long               borne_inferieure;
  214:     unsigned long               borne_superieure;
  215:     unsigned long               moyenne;
  216:     unsigned long               nombre_iterations_maximal;
  217:     unsigned long               ordre_iteration;
  218: 
  219:     if ((*s_etat_processus).nombre_variables_statiques == 0)
  220:     {
  221:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  222:         return d_faux;
  223:     }
  224: 
  225:     ordre_iteration = 0;
  226:     nombre_iterations_maximal = ((unsigned long)
  227:             (log((*s_etat_processus).nombre_variables_statiques) / log(2))) + 2;
  228: 
  229:     borne_inferieure = 0;
  230:     borne_superieure = (*s_etat_processus).nombre_variables_statiques - 1;
  231: 
  232:     do
  233:     {
  234:         moyenne = (borne_inferieure + borne_superieure) / 2;
  235:         ordre_iteration++;
  236: 
  237:         if ((2 * ((unsigned long) ((borne_inferieure + borne_superieure) / 2)))
  238:                 == (borne_inferieure + borne_superieure))
  239:         {
  240:             difference = strcmp(nom_variable,
  241:                     ((*s_etat_processus).s_liste_variables_statiques)
  242:                     [moyenne].nom);
  243: 
  244:             if (difference != 0)
  245:             {
  246:                 if (difference > 0)
  247:                 {
  248:                     borne_inferieure = moyenne;
  249:                 }
  250:                 else
  251:                 {
  252:                     borne_superieure = moyenne;
  253:                 }
  254:             }
  255:         }
  256:         else
  257:         {
  258:             difference_inferieure = strcmp(nom_variable,
  259:                     ((*s_etat_processus).s_liste_variables_statiques)
  260:                     [moyenne].nom);
  261:             difference_superieure = strcmp(nom_variable,
  262:                     ((*s_etat_processus).s_liste_variables_statiques)
  263:                     [moyenne + 1].nom);
  264: 
  265:             if (difference_inferieure == 0)
  266:             {
  267:                 difference = 0;
  268:             }
  269:             else if (difference_superieure == 0)
  270:             {
  271:                 difference = 0;
  272:                 moyenne++;
  273:             }
  274:             else
  275:             {
  276:                 difference = difference_inferieure;
  277: 
  278:                 if (difference > 0)
  279:                 {
  280:                     borne_inferieure = moyenne;
  281:                 }
  282:                 else
  283:                 {
  284:                     borne_superieure = moyenne;
  285:                 }
  286:             }
  287:         }
  288:     } while((difference != 0) &&
  289:             (ordre_iteration <= nombre_iterations_maximal));
  290: 
  291:     if (ordre_iteration > nombre_iterations_maximal)
  292:     {
  293:         existence_variable = d_faux;
  294:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  295:     }
  296:     else
  297:     {
  298:         // Reste à rechercher la variable déclarée à la position 'position'...
  299: 
  300:         if (((*s_etat_processus).s_liste_variables_statiques)[moyenne]
  301:                 .origine == 'P')
  302:         {
  303:             if ((((*s_etat_processus).s_liste_variables_statiques)[moyenne]
  304:                     .variable_statique.adresse == position.adresse) &&
  305:                     (((*s_etat_processus).s_liste_variables_statiques)[moyenne]
  306:                     .origine == origine))
  307:             {
  308:                 existence_variable = d_vrai;
  309:             }
  310:             else
  311:             {
  312:                 existence_variable = d_faux;
  313:             }
  314:         }
  315:         else
  316:         {
  317:             if ((((*s_etat_processus).s_liste_variables_statiques)[moyenne]
  318:                     .variable_statique.pointeur == position.pointeur) &&
  319:                     (((*s_etat_processus).s_liste_variables_statiques)[moyenne]
  320:                     .origine == origine))
  321:             {
  322:                 existence_variable = d_vrai;
  323:             }
  324:             else
  325:             {
  326:                 existence_variable = d_faux;
  327:             }
  328:         }
  329: 
  330:         if (existence_variable == d_faux)
  331:         {
  332:             // On rembobine.
  333: 
  334:             if (moyenne > 0)
  335:             {
  336:                 while(strcmp(nom_variable, ((*s_etat_processus)
  337:                         .s_liste_variables_statiques)[moyenne - 1].nom) == 0)
  338:                 {
  339:                     moyenne--;
  340: 
  341:                     if (moyenne == 0)
  342:                     {
  343:                         break;
  344:                     }
  345:                 }
  346:             }
  347: 
  348:             // Un petit test pour voir si le premier élément du tableau
  349:             // peut correspondre au critère de recherche.
  350: 
  351:             existence_variable = d_faux;
  352: 
  353:             if (strcmp(((*s_etat_processus).s_liste_variables_statiques)
  354:                     [moyenne].nom, nom_variable) == 0)
  355:             {
  356:                 if (((*s_etat_processus).s_liste_variables_statiques)
  357:                         [moyenne].origine == 'P')
  358:                 {
  359:                     if ((((*s_etat_processus).s_liste_variables_statiques)
  360:                             [moyenne].variable_statique.adresse
  361:                             == position.adresse) &&
  362:                             (((*s_etat_processus).s_liste_variables_statiques)
  363:                             [moyenne].origine == origine))
  364:                     {
  365:                         existence_variable = d_vrai;
  366:                     }
  367:                 }
  368:                 else
  369:                 {
  370:                     if ((((*s_etat_processus).s_liste_variables_statiques)
  371:                             [moyenne].variable_statique.pointeur
  372:                             == position.pointeur) &&
  373:                             (((*s_etat_processus).s_liste_variables_statiques)
  374:                             [moyenne].origine == origine))
  375:                     {
  376:                         existence_variable = d_vrai;
  377:                     }
  378:                 }
  379:             }
  380: 
  381:             // Puis on balaye dans le sens croissant.
  382: 
  383:             if (((moyenne + 1) < (*s_etat_processus)
  384:                     .nombre_variables_statiques) &&
  385:                     (existence_variable == d_faux))
  386:             {
  387:                 while(strcmp(((*s_etat_processus)
  388:                         .s_liste_variables_statiques)[moyenne + 1].nom,
  389:                         nom_variable) == 0)
  390:                 {
  391:                     moyenne++;
  392: 
  393:                     if (((*s_etat_processus).s_liste_variables_statiques)
  394:                             [moyenne].origine == 'P')
  395:                     {
  396:                         if ((((*s_etat_processus).s_liste_variables_statiques)
  397:                                 [moyenne].variable_statique.adresse ==
  398:                                 position.adresse) && (((*s_etat_processus)
  399:                                 .s_liste_variables_statiques)
  400:                                 [moyenne].origine == origine))
  401:                         {
  402:                             existence_variable = d_vrai;
  403:                             break;
  404:                         }
  405:                     }
  406:                     else
  407:                     {
  408:                         if ((((*s_etat_processus).s_liste_variables_statiques)
  409:                                 [moyenne].variable_statique.pointeur ==
  410:                                 position.pointeur) && (((*s_etat_processus)
  411:                                 .s_liste_variables_statiques)
  412:                                 [moyenne].origine == origine))
  413:                         {
  414:                             existence_variable = d_vrai;
  415:                             break;
  416:                         }
  417:                     }
  418: 
  419:                     if ((moyenne + 1) >= (*s_etat_processus)
  420:                             .nombre_variables_statiques)
  421:                     {
  422:                         break;
  423:                     }
  424:                 }
  425:             }
  426:         }
  427: 
  428:         (*s_etat_processus).position_variable_statique_courante = moyenne;
  429:     }
  430: 
  431:     return existence_variable;
  432: }
  433: 
  434: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>