/* ================================================================================ RPL/2 (R) version 4.1.32 Copyright (C) 1989-2020 Dr. BERTRAND Joël This file is part of RPL/2. RPL/2 is free software; you can redistribute it and/or modify it under the terms of the CeCILL V2 License as published by the french CEA, CNRS and INRIA. RPL/2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License for more details. You should have received a copy of the CeCILL License along with RPL/2. If not, write to info@cecill.info. ================================================================================ */ #include "rpl-conv.h" /* ================================================================================ Fonction 'recv' ================================================================================ Entrées : pointeur sur une structure struct_processus -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_recv(struct_processus *s_etat_processus) { integer8 nombre_donnees; sig_atomic_t registre_stop; ssize_t longueur_ecriture; struct_liste_chainee *l_element_courant; struct_objet *s_objet_argument; struct_objet *s_objet_resultat; struct sigaction action; struct sigaction registre; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n RECV "); if ((*s_etat_processus).langue == 'F') { printf("(réception de données d'un processus fils)\n\n"); } else { printf("(data reception from child process)\n\n"); } printf(" 1: %s\n", d_PRC); printf("-> 1: %s (0)\n\n", d_INT); printf(" 1: %s\n", d_PRC); printf("-> 2: %s, %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s, %s,\n" " %s, %s, %s, %s\n", d_INT, d_REL, d_CPL, d_VIN, d_VRL, d_VCX, d_MIN, d_MRL, d_MCX, d_BIN, d_NOM, d_CHN, d_LST, d_ALG, d_RPN); printf(" 1: %s (-1)\n", d_INT); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 1) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if ((*s_objet_argument).type == PRC) { /* * Le champ de la structure nombre_objets_dans_pipe à jour * est celui présent dans *s_etat_processus et non celui * de la structure présente dans la pile opérationnelle. */ if (pthread_mutex_lock(&((*s_etat_processus).mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; return; } l_element_courant = (struct_liste_chainee *) (*s_etat_processus).l_base_pile_processus; nombre_donnees = -1; while(l_element_courant != NULL) { if ((*(*((struct_processus_fils *) (*s_objet_argument).objet)) .thread).processus_detache == d_vrai) { if ((*(*((struct_processus_fils *) (*(*l_element_courant) .donnee).objet)).thread).processus_detache == d_faux) { l_element_courant = (*l_element_courant).suivant; continue; } if ((*(*((struct_processus_fils *) (*s_objet_argument).objet)) .thread).pid == (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread).pid) { if (pthread_mutex_lock(&((*(*((struct_processus_fils *) (*s_objet_argument).objet)).thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } nombre_donnees = (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread) .nombre_objets_dans_pipe; if (pthread_mutex_unlock(&((*(*((struct_processus_fils *) (*s_objet_argument).objet)).thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } break; } } else { if ((*(*((struct_processus_fils *) (*(*l_element_courant) .donnee).objet)).thread).processus_detache == d_vrai) { l_element_courant = (*l_element_courant).suivant; continue; } if ((pthread_equal((*(*((struct_processus_fils *) (*s_objet_argument).objet)).thread).tid, (*(*((struct_processus_fils *) (*(*l_element_courant) .donnee).objet)).thread).tid) != 0) && ((*(*((struct_processus_fils *) (*s_objet_argument).objet)).thread).pid == (*(*((struct_processus_fils *) (*(*l_element_courant) .donnee).objet)).thread).pid)) { if (pthread_mutex_lock(&((*(*((struct_processus_fils *) (*s_objet_argument).objet)).thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } nombre_donnees = (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread) .nombre_objets_dans_pipe; if (pthread_mutex_unlock(&((*(*((struct_processus_fils *) (*s_objet_argument).objet)).thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } break; } } l_element_courant = (*l_element_courant).suivant; } /* * 0 : aucune donnée dans le pipe du processus. * -1 : processus absent de la pile */ if (nombre_donnees == -1) { if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; return; } (*s_etat_processus).erreur_execution = d_ex_processus; return; } else if (nombre_donnees == 0) { /* * On empile une valeur nulle */ if (pthread_mutex_unlock(&((*s_etat_processus) .mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; return; } if ((s_objet_resultat = allocation(s_etat_processus, INT)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } (*((integer8 *) (*s_objet_resultat).objet)) = 0; if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_resultat) == d_erreur) { return; } liberation(s_etat_processus, s_objet_argument); return; } registre_stop = (*s_etat_processus) .var_volatile_traitement_retarde_stop; (*s_etat_processus).var_volatile_traitement_retarde_stop = 1; if ((*s_etat_processus).profilage == d_vrai) { profilage(s_etat_processus, "Interprocess or interthread " "communications (RECV)"); if ((*s_etat_processus).erreur_systeme != d_es) { return; } } # ifndef SEMAPHORES_NOMMES if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) # else if (sem_post((*s_etat_processus).semaphore_fork) != 0) # endif { (*s_etat_processus).erreur_systeme = d_es_processus; return; } if ((s_objet_resultat = lecture_pipe(s_etat_processus, (*(*((struct_processus_fils *) (*s_objet_argument).objet)) .thread).pipe_objets[0])) == NULL) { # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus).semaphore_fork) != 0) # endif { if (errno != EINTR) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } } if (registre_stop == 0) { if ((*s_etat_processus).var_volatile_traitement_retarde_stop == -1) { (*s_etat_processus).var_volatile_requete_arret = -1; } (*s_etat_processus).var_volatile_traitement_retarde_stop = registre_stop; } if ((*s_etat_processus).profilage == d_vrai) { profilage(s_etat_processus, NULL); } pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus)); return; } if (pthread_mutex_lock(&((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } (*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) .thread).nombre_objets_dans_pipe--; if (pthread_mutex_unlock(&((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } if (pthread_mutex_lock(&mutex_sigaction) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } action.sa_handler = SIG_IGN; action.sa_flags = 0; if (sigaction(SIGPIPE, &action, ®istre) != 0) { if (registre_stop == 0) { if ((*s_etat_processus).var_volatile_traitement_retarde_stop == -1) { (*s_etat_processus).var_volatile_requete_arret = -1; } (*s_etat_processus).var_volatile_traitement_retarde_stop = registre_stop; } pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus)); if ((*s_etat_processus).profilage == d_vrai) { profilage(s_etat_processus, NULL); } pthread_mutex_unlock(&mutex_sigaction); (*s_etat_processus).erreur_systeme = d_es_signal; return; } while((longueur_ecriture = write_atomic(s_etat_processus, (*(*((struct_processus_fils *) (*(*l_element_courant) .donnee).objet)).thread).pipe_nombre_injections[1], "+", sizeof(unsigned char))) != sizeof(unsigned char)) { if (longueur_ecriture == -1) { // Le processus n'existe plus. break; } } # ifndef SEMAPHORES_NOMMES while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0) # else while(sem_wait((*s_etat_processus).semaphore_fork) != 0) # endif { if (errno != EINTR) { pthread_mutex_unlock(&mutex_sigaction); (*s_etat_processus).erreur_systeme = d_es_processus; return; } } if ((*s_etat_processus).profilage == d_vrai) { profilage(s_etat_processus, NULL); } if (registre_stop == 0) { if ((*s_etat_processus).var_volatile_traitement_retarde_stop == -1) { (*s_etat_processus).var_volatile_requete_arret = -1; } (*s_etat_processus).var_volatile_traitement_retarde_stop = registre_stop; } if (sigaction(SIGPIPE, ®istre, NULL) != 0) { pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus)); (*s_etat_processus).erreur_systeme = d_es_signal; return; } if (pthread_mutex_unlock(&mutex_sigaction) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } if (pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus)) != 0) { (*s_etat_processus).erreur_systeme_processus_fils = d_es_processus; } } else { liberation(s_etat_processus, s_objet_argument); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } liberation(s_etat_processus, s_objet_argument); if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_resultat) == d_erreur) { return; } /* * On rajoute "-1" dans la pile. */ if ((s_objet_resultat = allocation(s_etat_processus, INT)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } (*((integer8 *) (*s_objet_resultat).objet)) = -1; if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_resultat) == d_erreur) { return; } return; } /* ================================================================================ Fonction 'row->' ================================================================================ Entrées : -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_row_fleche(struct_processus *s_etat_processus) { struct_objet *s_objet; struct_objet *s_objet_elementaire; integer8 i; integer8 j; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n ROW-> "); if ((*s_etat_processus).langue == 'F') { printf("(extraction des lignes d'une matrice)\n\n"); } else { printf("(extract matrix rows)\n\n"); } printf(" 1: %s, %s, %s\n", d_MIN, d_MRL, d_MCX); printf("-> n: %s, %s, %s\n", d_MIN, d_MRL, d_MCX); printf(" ...\n"); printf(" 2: %s, %s, %s\n", d_MIN, d_MRL, d_MCX); printf(" 1: %s\n", d_INT); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 1) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if ((*s_objet).type == MIN) { for(i = 0; i < (*((struct_matrice *) (*s_objet).objet)).nombre_lignes; i++) { if ((s_objet_elementaire = allocation(s_etat_processus, MIN)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } (*((struct_matrice *) (*s_objet_elementaire).objet)) .nombre_lignes = 1; (*((struct_matrice *) (*s_objet_elementaire).objet)) .nombre_colonnes = (*((struct_matrice *) (*s_objet).objet)) .nombre_colonnes; if (((*((struct_matrice *) (*s_objet_elementaire).objet)).tableau = malloc(sizeof(integer8 *))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if ((((integer8 **) (*((struct_matrice *) (*s_objet_elementaire) .objet)).tableau)[0] = malloc(((size_t) (*((struct_matrice *) (*s_objet_elementaire).objet)) .nombre_colonnes) * sizeof(integer8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } for(j = 0; j < (*((struct_matrice *) (*s_objet_elementaire).objet)) .nombre_colonnes; j++) { ((integer8 **) (*((struct_matrice *) (*s_objet_elementaire) .objet)).tableau)[0][j] = ((integer8 **) (*((struct_matrice *) (*s_objet).objet)).tableau)[i][j]; } if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_elementaire) == d_erreur) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } } } else if ((*s_objet).type == MRL) { for(i = 0; i < (*((struct_matrice *) (*s_objet).objet)).nombre_lignes; i++) { if ((s_objet_elementaire = allocation(s_etat_processus, MRL)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } (*((struct_matrice *) (*s_objet_elementaire).objet)) .nombre_lignes = 1; (*((struct_matrice *) (*s_objet_elementaire).objet)) .nombre_colonnes = (*((struct_matrice *) (*s_objet).objet)) .nombre_colonnes; if (((*((struct_matrice *) (*s_objet_elementaire).objet)).tableau = malloc(sizeof(real8 *))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if ((((real8 **) (*((struct_matrice *) (*s_objet_elementaire) .objet)).tableau)[0] = malloc(((size_t) (*((struct_matrice *) (*s_objet_elementaire).objet)) .nombre_colonnes) * sizeof(real8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } for(j = 0; j < (*((struct_matrice *) (*s_objet_elementaire).objet)) .nombre_colonnes; j++) { ((real8 **) (*((struct_matrice *) (*s_objet_elementaire) .objet)).tableau)[0][j] = ((real8 **) (*((struct_matrice *) (*s_objet).objet)).tableau)[i][j]; } if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_elementaire) == d_erreur) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } } } else if ((*s_objet).type == MCX) { for(i = 0; i < (*((struct_matrice *) (*s_objet).objet)).nombre_lignes; i++) { if ((s_objet_elementaire = allocation(s_etat_processus, MCX)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } (*((struct_matrice *) (*s_objet_elementaire).objet)) .nombre_lignes = 1; (*((struct_matrice *) (*s_objet_elementaire).objet)) .nombre_colonnes = (*((struct_matrice *) (*s_objet).objet)) .nombre_colonnes; if (((*((struct_matrice *) (*s_objet_elementaire).objet)).tableau = malloc(sizeof(complex16 *))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if ((((complex16 **) (*((struct_matrice *) (*s_objet_elementaire) .objet)).tableau)[0] = malloc(((size_t) (*((struct_matrice *) (*s_objet_elementaire).objet)) .nombre_colonnes) * sizeof(complex16))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } for(j = 0; j < (*((struct_matrice *) (*s_objet_elementaire).objet)) .nombre_colonnes; j++) { ((complex16 **) (*((struct_matrice *) (*s_objet_elementaire) .objet)).tableau)[0][j].partie_reelle = ((complex16 **) (*((struct_matrice *) (*s_objet).objet)).tableau)[i][j].partie_reelle; ((complex16 **) (*((struct_matrice *) (*s_objet_elementaire) .objet)).tableau)[0][j].partie_imaginaire = ((complex16 **) (*((struct_matrice *) (*s_objet).objet)).tableau)[i][j].partie_imaginaire; } if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_elementaire) == d_erreur) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } } } else { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } if ((s_objet_elementaire = allocation(s_etat_processus, INT)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } (*((integer8 *) (*s_objet_elementaire).objet)) = (*((struct_matrice *) (*s_objet).objet)).nombre_lignes; liberation(s_etat_processus, s_objet); if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_elementaire) == d_erreur) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } return; } /* ================================================================================ Fonction 'rdate' ================================================================================ Entrées : pointeur sur une structure struct_processus -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_rdate(struct_processus *s_etat_processus) { struct_objet *s_objet; struct_objet *s_objet_argument; struct timeval horodatage; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n RDATE "); if ((*s_etat_processus).langue == 'F') { printf("(information sur la date et l'heure avec offset)\n\n"); } else { printf("(date and time with offset)\n\n"); } printf(" 1: %s\n", d_INT); printf("-> 1: %s\n", d_LST); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = 1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 1) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if ((*s_objet_argument).type == INT) { gettimeofday(&horodatage, NULL); horodatage.tv_sec += (time_t) (*((integer8 *) (*s_objet_argument).objet)); if (horodatage.tv_sec < 0) { (*s_etat_processus).erreur_execution = d_ex_argument_invalide; liberation(s_etat_processus, s_objet_argument); return; } if ((s_objet = formateur_date(s_etat_processus, &horodatage)) == NULL) { liberation(s_etat_processus, s_objet_argument); return; } liberation(s_etat_processus, s_objet_argument); } else { liberation(s_etat_processus, s_objet_argument); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet) == d_erreur) { return; } return; } /* ================================================================================ Fonction 'rclswi' ================================================================================ Entrées : pointeur sur une structure struct_processus -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_rclswi(struct_processus *s_etat_processus) { integer8 interruption; struct_objet *s_objet_argument; struct_objet *s_objet_resultat; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n RCLSWI "); if ((*s_etat_processus).langue == 'F') { printf("(rappel d'une interruption logicielle)\n\n"); } else { printf("(recall software interrupt)\n\n"); } printf(" 1: %s\n", d_INT); printf("-> 1: %s, %s\n", d_NOM, d_RPN); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 1) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if ((*s_objet_argument).type == INT) { interruption = (*((integer8 *) (*s_objet_argument).objet)); if ((interruption < 1) || (interruption > d_NOMBRE_INTERRUPTIONS)) { liberation(s_etat_processus, s_objet_argument); (*s_etat_processus).erreur_execution = d_ex_interruption_invalide; return; } if ((*s_etat_processus).corps_interruptions[interruption - 1] == NULL) { liberation(s_etat_processus, s_objet_argument); (*s_etat_processus).erreur_execution = d_ex_interruption_invalide; return; } if ((s_objet_resultat = copie_objet(s_etat_processus, (*s_etat_processus).corps_interruptions[interruption - 1], 'P')) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } } else { liberation(s_etat_processus, s_objet_argument); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_resultat) == d_erreur) { return; } return; } /* ================================================================================ Fonction 'revlist' ================================================================================ Entrées : pointeur sur une structure struct_processus -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_revlist(struct_processus *s_etat_processus) { struct_liste_chainee *l_ancienne_base; struct_liste_chainee *l_nouvelle_base; struct_objet *s_objet_argument; struct_objet *s_objet_intermediaire; struct_objet *s_objet_resultat; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n REVLIST "); if ((*s_etat_processus).langue == 'F') { printf("(inverse les éléments d'une liste)\n\n"); } else { printf("(inverts list elements)\n\n"); } printf(" 1: %s\n", d_LST); printf("-> 1: %s\n", d_LST); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 1) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if ((*s_objet_argument).type == LST) { if ((s_objet_resultat = copie_objet(s_etat_processus, s_objet_argument, 'N')) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } l_ancienne_base = (*s_objet_resultat).objet; l_nouvelle_base = NULL; while(l_ancienne_base != NULL) { if (depilement(s_etat_processus, &l_ancienne_base, &s_objet_intermediaire) == d_erreur) { (*s_etat_processus).erreur_systeme = d_es_pile_vide; return; } if (empilement(s_etat_processus, &l_nouvelle_base, s_objet_intermediaire) == d_erreur) { return; } } (*s_objet_resultat).objet = l_nouvelle_base; } else { liberation(s_etat_processus, s_objet_argument); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } liberation(s_etat_processus, s_objet_argument); if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_resultat) == d_erreur) { return; } return; } /* ================================================================================ Fonction 'rstop' ================================================================================ Entrées : -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_rstop(struct_processus *s_etat_processus) { (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n RSTOP "); if ((*s_etat_processus).langue == 'F') { printf("(libère le signal stop)\n\n"); printf(" Aucun argument\n"); } else { printf("(release stop signal)\n\n"); printf(" No argument\n"); } return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 0) == d_erreur) { return; } } if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0) { (*s_etat_processus).erreur_execution = d_ex_stop; return; } if ((*s_etat_processus).var_volatile_traitement_retarde_stop == -1) { (*s_etat_processus).var_volatile_requete_arret = -1; } (*s_etat_processus).var_volatile_traitement_retarde_stop = 0; return; } /* ================================================================================ fonction 'rfuse' ================================================================================ entrées : -------------------------------------------------------------------------------- sorties : -------------------------------------------------------------------------------- effets de bord : néant ================================================================================ */ void instruction_rfuse(struct_processus *s_etat_processus) { struct_objet *s_objet_resultat; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n RFUSE "); if ((*s_etat_processus).langue == 'F') { printf("(valeur courante du fusible)\n\n"); } else { printf("(remaining fuse value)\n\n"); } printf("-> 1: %s\n", d_REL); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 0) == d_erreur) { return; } } if ((s_objet_resultat = allocation(s_etat_processus, REL)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } (*((real8 *) (*s_objet_resultat).objet)) = (*s_etat_processus).temps_maximal_cpu; if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_resultat) == d_erreur) { return; } return; } /* ================================================================================ fonction 'rdgn' ================================================================================ entrées : -------------------------------------------------------------------------------- sorties : -------------------------------------------------------------------------------- effets de bord : néant ================================================================================ */ void instruction_rdgn(struct_processus *s_etat_processus) { const gsl_rng_type **type_courant; const gsl_rng_type **types; const unsigned char *message = "UNINITIALIZED RANDOM GENERATOR"; long dernier; long i; long j; long nombre_types; long premier; struct_objet *s_objet_argument; struct_objet *s_objet_resultat; unsigned char *pointeur; unsigned char *requete; unsigned char **types_generateurs; (*s_etat_processus).erreur_execution = d_ex; types = gsl_rng_types_setup(); if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n RDGN "); if ((*s_etat_processus).langue == 'F') { printf("(choix du générateur de nombres aléatoires)\n\n"); } else { printf("(random number generator specification)\n\n"); } printf(" 1: %s\n\n", d_CHN); printf(" 1: \"QUERY\"\n"); printf("-> 1: %s\n\n", d_CHN); if ((*s_etat_processus).langue == 'F') { printf(" Générateurs disponibles :\n\n"); } else { printf(" Available generators:\n\n"); } for(nombre_types = 0, type_courant = types; (*type_courant) != NULL; type_courant++, nombre_types++); if ((types_generateurs = malloc(((size_t) nombre_types) * sizeof(unsigned char *))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } for(i = 0, type_courant = types; (*type_courant) != NULL; type_courant++, i++) { if ((types_generateurs[i] = malloc((strlen((**type_courant).name) + 1) * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } strcpy(types_generateurs[i], (**type_courant).name); pointeur = types_generateurs[i]; while((*pointeur) != d_code_fin_chaine) { if ((*pointeur) == '-') { (*pointeur) = '_'; } pointeur++; } } // Tri des types de générateurs (tri shaker) premier = 1; dernier = nombre_types - 2; while((dernier - premier) >= 2) { for(j = 2, i = premier; i <= dernier; i++) { if (strcmp(types_generateurs[i], types_generateurs[i + 1]) > 0) { swap(&(types_generateurs[i]), &(types_generateurs[i + 1]), sizeof(unsigned char *)); j = i; } } dernier = j; i = nombre_types - 2; for(i = dernier; i >= premier; i--) { if (strcmp(types_generateurs[i - 1], types_generateurs[i]) > 0) { swap(&(types_generateurs[i - 1]), &(types_generateurs[i]), sizeof(unsigned char *)); j = i; } } premier = j; } for(i = 0; i < nombre_types; i++) { printf(" - %s\n", types_generateurs[i]); free(types_generateurs[i]); } free(types_generateurs); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 1) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if ((*s_objet_argument).type == CHN) { if ((requete = conversion_majuscule(s_etat_processus, (unsigned char *) (*s_objet_argument).objet)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (strcmp(requete, "QUERY") == 0) { /* * Récupération du type du générateur */ free(requete); if ((s_objet_resultat = allocation(s_etat_processus, CHN)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if ((*s_etat_processus).type_generateur_aleatoire == NULL) { if (((*s_objet_resultat).objet = malloc((strlen(message) + 1) * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } strcpy((unsigned char *) (*s_objet_resultat).objet, message); } else { if (((*s_objet_resultat).objet = conversion_majuscule( s_etat_processus, (unsigned char *) gsl_rng_name( (*s_etat_processus).generateur_aleatoire))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } } if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_resultat) == d_erreur) { return; } } else { /* * Affectation d'un nouveau type de générateur */ # include "generateurs.c" free(requete); if ((*s_etat_processus).generateur_aleatoire != NULL) { liberation_generateur_aleatoire(s_etat_processus); } initialisation_generateur_aleatoire(s_etat_processus, d_vrai, 0); } } else { liberation(s_etat_processus, s_objet_argument); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } liberation(s_etat_processus, s_objet_argument); return; } /* ================================================================================ fonction 'rank' ================================================================================ entrées : -------------------------------------------------------------------------------- sorties : -------------------------------------------------------------------------------- effets de bord : néant ================================================================================ */ void instruction_rank(struct_processus *s_etat_processus) { struct_objet *s_objet_argument; struct_objet *s_objet_resultat; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n RANK "); if ((*s_etat_processus).langue == 'F') { printf("(rang de la matrice)\n\n"); } else { printf("(matrix rank)\n\n"); } printf(" 1: %s, %s, %s\n", d_MIN, d_REL, d_MCX); printf("-> 1: %s\n", d_INT); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 1) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if (((*s_objet_argument).type == MIN) || ((*s_objet_argument).type == MRL) || ((*s_objet_argument).type == MCX)) { if ((s_objet_resultat = allocation(s_etat_processus, INT)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } rang(s_etat_processus, (*s_objet_argument).objet, (*s_objet_resultat).objet); if ((*s_etat_processus).erreur_systeme != d_es) { return; } if (((*s_etat_processus).erreur_execution != d_ex) || ((*s_etat_processus).exception != d_ep)) { liberation(s_etat_processus, s_objet_argument); liberation(s_etat_processus, s_objet_resultat); return; } } else { liberation(s_etat_processus, s_objet_argument); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } liberation(s_etat_processus, s_objet_argument); if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_resultat) == d_erreur) { return; } return; } /* ================================================================================ Fonction 'recode' ================================================================================ Entrées : -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_recode(struct_processus *s_etat_processus) { struct_objet *s_objet_argument_1; struct_objet *s_objet_argument_2; struct_objet *s_objet_argument_3; struct_objet *s_objet_resultat; unsigned char *encodage_destination; unsigned char *encodage_source; unsigned char *tampon; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n RECODE "); if ((*s_etat_processus).langue == 'F') { printf("(conversion d'encodage d'une chaîne de caractères)\n\n"); } else { printf("(string recodage)\n\n"); } printf(" 3: %s\n", d_CHN); printf(" 2: %s\n", d_CHN); printf(" 1: %s\n", d_CHN); printf("-> 1: %s\n\n", d_CHN); if ((*s_etat_processus).langue == 'F') { printf(" Utilisation :\n\n"); } else { printf(" Usage:\n\n"); } printf(" \"string\" \"ISO8859-1\" \"UTF-8\" recode\n"); printf(" \"string\" \"ISO8859-1\" \"UTF-8//TRANSLIT\" recode\n"); printf(" \"string\" \"ISO8859-1\" \"UTF-8//IGNORE\" recode\n"); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 3) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument_1) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument_2) == d_erreur) { liberation(s_etat_processus, s_objet_argument_1); (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument_3) == d_erreur) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if (((*s_objet_argument_1).type == CHN) && ((*s_objet_argument_2).type == CHN) && ((*s_objet_argument_3).type == CHN)) { if ((encodage_source = conversion_majuscule(s_etat_processus, (unsigned char *) (*s_objet_argument_2).objet)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if ((encodage_destination = conversion_majuscule(s_etat_processus, (unsigned char *) (*s_objet_argument_1).objet)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } tampon = reencodage(s_etat_processus, (*s_objet_argument_3).objet, encodage_source, encodage_destination); free(encodage_destination); free(encodage_source); if (tampon == NULL) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); liberation(s_etat_processus, s_objet_argument_3); return; } if ((s_objet_resultat = allocation(s_etat_processus, CHN)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } (*s_objet_resultat).objet = tampon; } else { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); liberation(s_etat_processus, s_objet_argument_3); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); liberation(s_etat_processus, s_objet_argument_3); if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_resultat) == d_erreur) { return; } return; } /* ================================================================================ Fonction 'repl' ================================================================================ Entrées : -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_repl(struct_processus *s_etat_processus) { integer8 difference; integer8 difference_ecriture; integer8 difference_lecture; integer8 nombre_occurrences; integer8 position; struct_liste_chainee *l_element_a_supprimer; struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_courant_2; struct_liste_chainee *l_element_precedent; struct_liste_chainee *l_element_precedent_2; struct_objet *s_objet_argument_1; struct_objet *s_objet_argument_2; struct_objet *s_objet_argument_3; struct_objet *s_objet_intermediaire; struct_objet *s_objet_resultat; unsigned char *ancien_pointeur_ecriture; unsigned char *ancien_pointeur_lecture; unsigned char *pointeur_ecriture; unsigned char *pointeur_lecture; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n REPL "); if ((*s_etat_processus).langue == 'F') { printf("(remplacement d'éléments dans une liste ou une chaîne" ")\n\n"); } else { printf("(replace elements in list or string)\n\n"); } printf(" 3: %s\n", d_LST); printf(" 2: %s\n", d_INT); printf(" 1: %s\n", d_LST); printf("-> 1: %s\n\n", d_LST); printf(" 3: %s\n", d_CHN); printf(" 2: %s\n", d_CHN); printf(" 1: %s\n", d_CHN); printf("-> 1: %s\n\n", d_CHN); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 3) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument_1) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument_2) == d_erreur) { liberation(s_etat_processus, s_objet_argument_1); (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument_3) == d_erreur) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if (((*s_objet_argument_1).type == CHN) && ((*s_objet_argument_2).type == CHN) && ((*s_objet_argument_3).type == CHN)) { if (strcmp((unsigned char *) (*s_objet_argument_2).objet, "") == 0) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); liberation(s_etat_processus, s_objet_argument_3); (*s_etat_processus).erreur_execution = d_ex_argument_invalide; return; } nombre_occurrences = 0; pointeur_lecture = (unsigned char *) (*s_objet_argument_3).objet; for(;;) { pointeur_lecture = strstr(pointeur_lecture, (unsigned char *) (*s_objet_argument_2).objet); if (pointeur_lecture == NULL) { break; } pointeur_lecture++; nombre_occurrences++; } // Différence est positive si la nouvelle chaîne est plus longue // que la chaîne originelle. difference = ((integer8) strlen((unsigned char *) (*s_objet_argument_1) .objet)) - ((integer8) strlen((unsigned char *) (*s_objet_argument_2).objet)); if ((s_objet_resultat = allocation(s_etat_processus, CHN)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (((*s_objet_resultat).objet = malloc((strlen((unsigned char *) (*s_objet_argument_3).objet) + ((size_t) (nombre_occurrences * difference)) + 1) * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } pointeur_lecture = (unsigned char *) (*s_objet_argument_3).objet; pointeur_ecriture = (unsigned char *) (*s_objet_resultat).objet; difference_lecture = (integer8) strlen((unsigned char *) (*s_objet_argument_2).objet); difference_ecriture = (integer8) strlen((unsigned char *) (*s_objet_argument_1).objet); for(;;) { ancien_pointeur_lecture = pointeur_lecture; ancien_pointeur_ecriture = pointeur_ecriture; pointeur_lecture = strstr(ancien_pointeur_lecture, (unsigned char *) (*s_objet_argument_2).objet); if (pointeur_lecture == NULL) { strcpy(ancien_pointeur_ecriture, ancien_pointeur_lecture); break; } strncpy(ancien_pointeur_ecriture, ancien_pointeur_lecture, (size_t) (pointeur_lecture - ancien_pointeur_lecture)); strcpy(ancien_pointeur_ecriture + (pointeur_lecture - ancien_pointeur_lecture), (unsigned char *) (*s_objet_argument_1).objet); pointeur_ecriture += difference_ecriture + (pointeur_lecture - ancien_pointeur_lecture); pointeur_lecture += difference_lecture; } } else if (((*s_objet_argument_1).type == LST) && ((*s_objet_argument_2).type == INT) && ((*s_objet_argument_3).type == LST)) { if ((*((integer8 *) (*s_objet_argument_2).objet)) <= 0) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); liberation(s_etat_processus, s_objet_argument_3); (*s_etat_processus).erreur_execution = d_ex_element_inexistant; return; } if ((s_objet_resultat = copie_objet(s_etat_processus, s_objet_argument_3, 'N')) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } l_element_courant = (*s_objet_resultat).objet; l_element_precedent = NULL; position = 1; while(position < (*((integer8 *) (*s_objet_argument_2).objet))) { if (l_element_courant == NULL) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); liberation(s_etat_processus, s_objet_argument_3); liberation(s_etat_processus, s_objet_resultat); (*s_etat_processus).erreur_execution = d_ex_element_inexistant; return; } position++; l_element_precedent = l_element_courant; l_element_courant = (*l_element_courant).suivant; } l_element_a_supprimer = l_element_courant; if (l_element_courant == NULL) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); liberation(s_etat_processus, s_objet_argument_3); liberation(s_etat_processus, s_objet_resultat); (*s_etat_processus).erreur_execution = d_ex_element_inexistant; return; } if ((s_objet_intermediaire = copie_objet(s_etat_processus, s_objet_argument_1, 'N')) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (l_element_precedent == NULL) { (*s_objet_resultat).objet = (*s_objet_intermediaire).objet; } else { (*l_element_precedent).suivant = (*s_objet_intermediaire).objet; } // (*l_element_precedent).suivant contient le premier maillon // de la liste accrochée, l_element_a_supprimer est le premier maillons // à supprimer. l_element_courant = (*s_objet_intermediaire).objet; (*s_objet_intermediaire).objet = l_element_a_supprimer; l_element_courant_2 = l_element_a_supprimer; l_element_precedent_2 = NULL; for(;;) { if (l_element_courant == NULL) { // La nouvelle liste est plus courte. On raboute les éléments // restant de l'ancienne liste à la nouvelle. if (l_element_precedent == NULL) { (*s_objet_resultat).objet = l_element_courant_2; } else { (*l_element_precedent).suivant = l_element_courant_2; } if (l_element_precedent_2 == NULL) { (*s_objet_intermediaire).objet = NULL; } else { (*l_element_precedent_2).suivant = NULL; } break; } if (l_element_courant_2 == NULL) { // L'ancienne liste est plus courte. break; } l_element_precedent = l_element_courant; l_element_precedent_2 = l_element_courant_2; l_element_courant = (*l_element_courant).suivant; l_element_courant_2 = (*l_element_courant_2).suivant; } liberation(s_etat_processus, s_objet_intermediaire); } else { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); liberation(s_etat_processus, s_objet_argument_3); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); liberation(s_etat_processus, s_objet_argument_3); if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_resultat) == d_erreur) { return; } return; } // vim: ts=4