File:  [local] / rpl / modules / sets / types.rplc
Revision 1.5: download - view: text, annotated - select for diffs - revision graph
Wed Jul 12 15:42:24 2017 UTC (6 years, 10 months ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_28, rpl-4_1_27, HEAD
Correction d'un bug dans les fonctions __type.

    1: #define TYPE_DECLARATION
    2: #include "src/rplexternals.h"
    3: #include "sets.h"
    4: 
    5: // Les objets de type ensemble sont délimités par ([ ]) et ne contiennent
    6: // que des entiers.
    7: 
    8: // Attention : ces fonctions sont à écrire directement en C et non
    9: // en RPL/C car elles interviennent dans le noyau RPL/2.
   10: 
   11: /*
   12: ================================================================================
   13:   Fonction permettant d'extraire un objet d'une suite de caractères
   14: 
   15:   Cette fonction est utilisée par la routine recherche_instruction_suivante()
   16:   du RPL/2.
   17: ================================================================================
   18: */
   19: 
   20: declareTypeExtension(parse)
   21:     if ((*rptr) == '(')
   22:     {
   23:         rptr++;
   24: 
   25:         if ((*rptr) == '[')
   26:         {
   27:             rptr++;
   28:             while((*rptr) != 0)
   29:             {
   30:                 switch (*rptr)
   31:                 {
   32:                     case '0':
   33:                     case '1':
   34:                     case '2':
   35:                     case '3':
   36:                     case '4':
   37:                     case '5':
   38:                     case '6':
   39:                     case '7':
   40:                     case '8':
   41:                     case '9':
   42:                     case ' ':
   43:                     {
   44:                         break;
   45:                     }
   46: 
   47:                     case ']':
   48:                     {
   49:                         rptr++;
   50: 
   51:                         if ((*rptr) == ')')
   52:                         {
   53:                             rptr++;
   54:                             return(sizeOfParse);
   55:                         }
   56:                         else
   57:                         {
   58:                             parseError;
   59:                         }
   60:                     }
   61: 
   62:                     default:
   63:                     {
   64:                         parseError;
   65:                     }
   66:                 }
   67: 
   68:                 rptr++;
   69:             }
   70:         }
   71:     }
   72: endTypeExtension
   73: 
   74: 
   75: /*
   76: ================================================================================
   77:   La fonction declareTypeExtension(new) est utilisée par la fonction
   78:   recherche_type() du RPL/2. Elle se charge d'allouer et d'initialiser
   79:   le champ objet de la struct_objet allouée par recherche_type().
   80: ================================================================================
   81: */
   82: 
   83: static int
   84: fonction_ordre(const void *a, const void *b)
   85: {
   86:     if ((*((integer8 *) a)) < (*((integer8 *) b)))
   87:     {
   88:         return(-1);
   89:     }
   90:     if ((*((integer8 *) a)) > (*((integer8 *) b)))
   91:     {
   92:         return(1);
   93:     }
   94: 
   95:     return(0);
   96: }
   97: 
   98: declareTypeExtension(new)
   99:     // Si le premier caractère de la chaîne est '(' et que le dernier est ')',
  100:     // on les retire.
  101: 
  102:     char            *tmp;
  103: 
  104:     integer8        current_value;
  105:     integer8        i;
  106:     integer8        j;
  107:     integer8        nb_elements;
  108:     integer8        *vecteur;
  109: 
  110:     if (((*iptr) == '(') && ((*(iptr + strlen(iptr) - 1)) == ')'))
  111:     {
  112:         if ((tmp = malloc((strlen(iptr) + 1) * sizeof(unsigned char)))
  113:                 == NULL)
  114:         {
  115:             typeSystemError;
  116:         }
  117: 
  118:         // Sauvegarde de l'instruction courante.
  119:         strcpy(tmp, iptr);
  120: 
  121:         // Création d'une nouvelle instruction courante amputée de ses premier
  122:         // et dernier caractères.
  123:         memmove(iptr, iptr + 1, strlen(iptr) - 2);
  124:         *(iptr + strlen(iptr) - 2) = 0;
  125: 
  126:         searchType(strcpy(iptr, tmp), free(tmp));
  127: 
  128:         // Restauration de l'instruction courante
  129:         strcpy(iptr, tmp);
  130:         free(tmp);
  131: 
  132:         // On doit avoir un vecteur d'entiers au niveau 1 de la pile.
  133:         // Si ce n'est pas le cas, il y a une erreur.
  134: 
  135:         if ((*(*(*s_etat_processus).l_base_pile).donnee).type != VIN)
  136:         {
  137:             typeError;
  138:         }
  139: 
  140:         nb_elements = (*((struct_vecteur *) (*(*(*s_etat_processus)
  141:                 .l_base_pile).donnee).objet)).taille;
  142: 
  143:         if (nb_elements > 0)
  144:         {
  145:             if ((vecteur = malloc(nb_elements * sizeof(integer8))) == NULL)
  146:             {
  147:                 typeSystemError;
  148:             }
  149: 
  150:             for(i = 0; i < nb_elements; i++)
  151:             {
  152:                 vecteur[i] = ((integer8 *) (*((struct_vecteur *)
  153:                         (*(*(*s_etat_processus)
  154:                         .l_base_pile).donnee).objet)).tableau)[i];
  155:             }
  156: 
  157:             qsort(vecteur, nb_elements, sizeof(integer8), fonction_ordre);
  158: 
  159:             // Élimination des doublons
  160: 
  161:             current_value = vecteur[0];
  162: 
  163:             for(i = 1, j = 1; i < nb_elements; i++)
  164:             {
  165:                 if (vecteur[i] != current_value)
  166:                 {
  167:                     vecteur[j++] = vecteur[i];
  168:                     current_value = vecteur[i];
  169:                 }
  170:             }
  171: 
  172:             nb_elements = j;
  173: 
  174:             if ((vecteur = realloc(vecteur, nb_elements * sizeof(integer8)))
  175:                     == NULL)
  176:             {
  177:                 typeSystemError;
  178:             }
  179:         }
  180:         else
  181:         {
  182:             // cas de l'ensemble vide
  183:             if ((vecteur = malloc(0)) == NULL)
  184:             {
  185:                 typeSystemError;
  186:             }
  187:         }
  188: 
  189:         if (((*arg) = malloc(sizeof(set_t))) == NULL)
  190:         {
  191:             typeSystemError;
  192:         }
  193: 
  194:         (**((set_t **) arg)).size = nb_elements;
  195:         (**((set_t **) arg)).values = vecteur;
  196: 
  197:         instruction_drop(s_etat_processus);
  198:         typeFound(ISET);
  199:     }
  200: 
  201:     typeError;
  202: endTypeExtension
  203: 
  204: 
  205: /*
  206: ================================================================================
  207:   Fonction de duplication d'un objet.
  208: 
  209:   Cet objet doit être alloué puis copié.
  210: ================================================================================
  211: */
  212: 
  213: declareTypeExtension(dup)
  214:     integer8        i;
  215: 
  216:     struct_objet    *n_arg;
  217: 
  218:     if ((n_arg = allocation(s_etat_processus, EXT)) == NULL)
  219:     {
  220:         typeSystemError;
  221:     }
  222: 
  223:     if (((*n_arg).objet = malloc(sizeof(set_t))) == NULL)
  224:     {
  225:         typeSystemError;
  226:     }
  227: 
  228:     (*((set_t *) ((*n_arg).objet))).size = (*((set_t *) (**((struct_objet **)
  229:             arg)).objet)).size;
  230:     (*n_arg).descripteur_bibliotheque =
  231:             (**((struct_objet **) arg)).descripteur_bibliotheque;
  232:     (*n_arg).extension_type =
  233:             (**((struct_objet **) arg)).extension_type;
  234: 
  235:     if (((*((set_t *) ((*n_arg).objet))).values = malloc((*((set_t *)
  236:             ((*n_arg).objet))).size * sizeof(integer8))) == NULL)
  237:     {
  238:         typeSystemError;
  239:     }
  240: 
  241:     for(i = 0; i < (*((set_t *) (**((struct_objet **) arg)).objet)).size; i++)
  242:     {
  243:         (*((set_t *) ((*n_arg).objet))).values[i] =
  244:                 (*((set_t *) (**((struct_objet **) arg)).objet)).values[i];
  245:     }
  246: 
  247:     (*((struct_objet **) arg)) = n_arg;
  248:     typeSuccess;
  249: endTypeExtension
  250: 
  251: 
  252: /*
  253: ================================================================================
  254:   Fonction de libération d'un objet. À l'instar de la fonction new qui n'alloue
  255:   pas la struct_objet, la fonction drop ne doit pas la libérer.
  256: ================================================================================
  257: */
  258: 
  259: declareTypeExtension(drop)
  260:     free((*((set_t *) (**((struct_objet **) arg)).objet)).values);
  261:     free((**((struct_objet **) arg)).objet);
  262:     typeSuccess;
  263: endTypeExtension
  264: 
  265: 
  266: /*
  267: ================================================================================
  268:   Fonction créant une chaîne de caractère depuis l'objet pour affichage
  269: ================================================================================
  270: */
  271: 
  272: declareTypeExtension(disp)
  273:     int     i;
  274: 
  275:     string  e;
  276:     string  s;
  277:     string  t;
  278: 
  279:     if ((s = malloc(3 * sizeof(unsigned char))) == NULL)
  280:     {
  281:         typeSystemError;
  282:     }
  283: 
  284:     strcpy(s, "([");
  285: 
  286:     for(i = 0; i < (*((set_t *) (*((struct_objet *) (*arg))).objet)).size; i++)
  287:     {
  288:         if ((e = (string) integerFormat(&((*((set_t *)
  289:                 (*((struct_objet *) (*arg))).objet)).values[i]))) == NULL)
  290:         {
  291:             typeSystemError;
  292:         }
  293: 
  294:         t = s;
  295: 
  296:         if ((s = malloc((strlen(t) + strlen(e) + 2) * sizeof(unsigned char)))
  297:                 == NULL)
  298:         {
  299:             typeSystemError;
  300:         }
  301: 
  302:         strcpy(s, t);
  303:         free(t);
  304:         strcat(s, " ");
  305:         strcat(s, e);
  306:         free(e);
  307:     }
  308: 
  309:     t = s;
  310: 
  311:     if ((s = malloc((strlen(t) + 4) * sizeof(unsigned char))) == NULL)
  312:     {
  313:         typeSystemError;
  314:     }
  315: 
  316:     strcpy(s, t);
  317:     free(t);
  318:     strcat(s, " ])");
  319: 
  320:     (*arg) = s;
  321:     typeSuccess;
  322: endTypeExtension
  323: 
  324: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>