#define TYPE_DECLARATION #include "src/rplexternals.h" #include "sets.h" // Les objets de type ensemble sont délimités par ([ ]) et ne contiennent // que des entiers. // Attention : ces fonctions sont à écrire directement en C et non // en RPL/C car elles interviennent dans le noyau RPL/2. /* ================================================================================ Fonction permettant d'extraire un objet d'une suite de caractères Cette fonction est utilisée par la routine recherche_instruction_suivante() du RPL/2. ================================================================================ */ declareTypeExtension(parse) if ((*rptr) == '(') { rptr++; if ((*rptr) == '[') { rptr++; while((*rptr) != 0) { switch (*rptr) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case ' ': { break; } case ']': { rptr++; if ((*rptr) == ')') { rptr++; return(sizeOfParse); } else { parseError; } } default: { parseError; } } rptr++; } } } endTypeExtension /* ================================================================================ La fonction declareTypeExtension(new) est utilisée par la fonction recherche_type() du RPL/2. Elle se charge d'allouer et d'initialiser le champ objet de la struct_objet allouée par recherche_type(). ================================================================================ */ static int fonction_ordre(const void *a, const void *b) { if ((*((integer8 *) a)) < (*((integer8 *) b))) { return(-1); } if ((*((integer8 *) a)) > (*((integer8 *) b))) { return(1); } return(0); } declareTypeExtension(new) // Si le premier caractère de la chaîne est '(' et que le dernier est ')', // on les retire. char *tmp; integer8 current_value; integer8 i; integer8 j; integer8 nb_elements; integer8 *vecteur; if (((*iptr) == '(') && ((*(iptr + strlen(iptr) - 1)) == ')')) { if ((tmp = malloc((strlen(iptr) + 1) * sizeof(unsigned char))) == NULL) { typeSystemError; } // Sauvegarde de l'instruction courante. strcpy(tmp, iptr); // Création d'une nouvelle instruction courante amputée de ses premier // et dernier caractères. memmove(iptr, iptr + 1, strlen(iptr) - 2); *(iptr + strlen(iptr) - 2) = 0; searchType(strcpy(iptr, tmp), free(tmp)); // Restauration de l'instruction courante strcpy(iptr, tmp); free(tmp); // On doit avoir un vecteur d'entiers au niveau 1 de la pile. // Si ce n'est pas le cas, il y a une erreur. if ((*(*(*s_etat_processus).l_base_pile).donnee).type != VIN) { typeError; } nb_elements = (*((struct_vecteur *) (*(*(*s_etat_processus) .l_base_pile).donnee).objet)).taille; if (nb_elements > 0) { if ((vecteur = malloc(nb_elements * sizeof(integer8))) == NULL) { typeSystemError; } for(i = 0; i < nb_elements; i++) { vecteur[i] = ((integer8 *) (*((struct_vecteur *) (*(*(*s_etat_processus) .l_base_pile).donnee).objet)).tableau)[i]; } qsort(vecteur, nb_elements, sizeof(integer8), fonction_ordre); // Élimination des doublons current_value = vecteur[0]; for(i = 1, j = 1; i < nb_elements; i++) { if (vecteur[i] != current_value) { vecteur[j++] = vecteur[i]; current_value = vecteur[i]; } } nb_elements = j; if ((vecteur = realloc(vecteur, nb_elements * sizeof(integer8))) == NULL) { typeSystemError; } } else { // cas de l'ensemble vide if ((vecteur = malloc(0)) == NULL) { typeSystemError; } } if (((*arg) = malloc(sizeof(set_t))) == NULL) { typeSystemError; } (**((set_t **) arg)).size = nb_elements; (**((set_t **) arg)).values = vecteur; instruction_drop(s_etat_processus); typeFound(ISET); } typeError; endTypeExtension /* ================================================================================ Fonction de duplication d'un objet. Cet objet doit être alloué puis copié. ================================================================================ */ declareTypeExtension(dup) integer8 i; struct_objet *n_arg; if ((n_arg = allocation(s_etat_processus, EXT)) == NULL) { typeSystemError; } if (((*n_arg).objet = malloc(sizeof(set_t))) == NULL) { typeSystemError; } (*((set_t *) ((*n_arg).objet))).size = (*((set_t *) (**((struct_objet **) arg)).objet)).size; (*n_arg).descripteur_bibliotheque = (**((struct_objet **) arg)).descripteur_bibliotheque; (*n_arg).extension_type = (**((struct_objet **) arg)).extension_type; if (((*((set_t *) ((*n_arg).objet))).values = malloc((*((set_t *) ((*n_arg).objet))).size * sizeof(integer8))) == NULL) { typeSystemError; } for(i = 0; i < (*((set_t *) (**((struct_objet **) arg)).objet)).size; i++) { (*((set_t *) ((*n_arg).objet))).values[i] = (*((set_t *) (**((struct_objet **) arg)).objet)).values[i]; } (*((struct_objet **) arg)) = n_arg; typeSuccess; endTypeExtension /* ================================================================================ Fonction de libération d'un objet. À l'instar de la fonction new qui n'alloue pas la struct_objet, la fonction drop ne doit pas la libérer. ================================================================================ */ declareTypeExtension(drop) free((*((set_t *) (**((struct_objet **) arg)).objet)).values); free((**((struct_objet **) arg)).objet); typeSuccess; endTypeExtension /* ================================================================================ Fonction créant une chaîne de caractère depuis l'objet pour affichage ================================================================================ */ declareTypeExtension(disp) int i; string e; string s; string t; if ((s = malloc(3 * sizeof(unsigned char))) == NULL) { typeSystemError; } strcpy(s, "(["); for(i = 0; i < (*((set_t *) (*((struct_objet *) (*arg))).objet)).size; i++) { if ((e = (string) integerFormat(&((*((set_t *) (*((struct_objet *) (*arg))).objet)).values[i]))) == NULL) { typeSystemError; } t = s; if ((s = malloc((strlen(t) + strlen(e) + 2) * sizeof(unsigned char))) == NULL) { typeSystemError; } strcpy(s, t); free(t); strcat(s, " "); strcat(s, e); free(e); } t = s; if ((s = malloc((strlen(t) + 4) * sizeof(unsigned char))) == NULL) { typeSystemError; } strcpy(s, t); free(t); strcat(s, " ])"); (*arg) = s; typeSuccess; endTypeExtension // vim: ts=4