--- rpl/src/sequenceur.c 2010/02/10 10:14:26 1.5 +++ rpl/src/sequenceur.c 2013/02/27 17:11:45 1.66 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.0.11 - Copyright (C) 1989-2010 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.13 + Copyright (C) 1989-2013 Dr. BERTRAND Joël This file is part of RPL/2. @@ -20,7 +20,7 @@ */ -#include "rpl.conv.h" +#include "rpl-conv.h" /* @@ -29,7 +29,7 @@ ================================================================================ Entrées : structure sur l'état du processus -------------------------------------------------------------------------------- - Sorties : Néant + Sorties : néant -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ @@ -48,6 +48,7 @@ sequenceur(struct_processus *s_etat_proc logical1 drapeau_fin; logical1 drapeau_then; logical1 erreur; + logical1 presence_compteur; static logical1 completion_valide = d_faux; @@ -63,11 +64,12 @@ sequenceur(struct_processus *s_etat_proc unsigned char tampon_retour; unsigned char *t_ligne; - unsigned long i; - unsigned long j; unsigned long niveau; unsigned long position_courante; + Keymap ancien_keymap; + Keymap nouveau_keymap; + (*s_etat_processus).retour_routine_evaluation = 'N'; if ((*s_etat_processus).debug == d_vrai) @@ -78,7 +80,7 @@ sequenceur(struct_processus *s_etat_proc { if ((*s_etat_processus).langue == 'F') { - printf("[%d] Exécution récursive de niveau %lu\n", + printf("[%d] Exécution récursive de niveau %lu\n", (int) getpid(), (*s_etat_processus).niveau_recursivite); } else @@ -91,7 +93,7 @@ sequenceur(struct_processus *s_etat_proc { if ((*s_etat_processus).langue == 'F') { - printf("[%d] Exécution\n", (int) getpid()); + printf("[%d] Exécution\n", (int) getpid()); } else { @@ -109,9 +111,6 @@ sequenceur(struct_processus *s_etat_proc -------------------------------------------------------------------------------- */ - i = 0; - j = 0; - do { drapeau_appel_definition = d_faux; @@ -182,8 +181,20 @@ sequenceur(struct_processus *s_etat_proc flockfile(stdin); flockfile(stdout); + ancien_keymap = rl_get_keymap(); + nouveau_keymap = rl_copy_keymap(ancien_keymap); + rl_set_keymap(nouveau_keymap); + + rl_bind_key(NEWLINE, readline_analyse_syntaxique); + rl_bind_key(RETURN, readline_analyse_syntaxique); + rl_bind_key(CTRL('g'), readline_effacement); + rl_done = 0; + ligne = readline("RPL/2> "); + rl_set_keymap(ancien_keymap); + rl_free(nouveau_keymap); + funlockfile(stdin); funlockfile(stdout); @@ -199,6 +210,7 @@ sequenceur(struct_processus *s_etat_proc (*s_etat_processus).localisation, d_locale)) == NULL) { + free((*s_etat_processus).instruction_courante); return(d_erreur); } @@ -283,8 +295,11 @@ sequenceur(struct_processus *s_etat_proc tampon = (*s_etat_processus).instruction_courante; (*s_etat_processus).instruction_courante = ligne; + recherche_type(s_etat_processus); + (*s_etat_processus).instruction_courante = tampon; + if ((((*s_etat_processus).erreur_execution != d_ex) || ((*s_etat_processus).erreur_systeme != d_es)) && ((*s_etat_processus).invalidation_message_erreur @@ -302,6 +317,7 @@ sequenceur(struct_processus *s_etat_proc if ((message = messages(s_etat_processus)) == NULL) { + free((*s_etat_processus).instruction_courante); return(d_erreur); } @@ -333,7 +349,7 @@ sequenceur(struct_processus *s_etat_proc if ((*s_etat_processus).langue == 'F') { - printf("+++Erreur : Défaut d'argument\n"); + printf("+++Erreur : Défaut d'argument\n"); } else { @@ -361,12 +377,15 @@ sequenceur(struct_processus *s_etat_proc if ((message = messages(s_etat_processus)) == NULL) { + free((*s_etat_processus) + .instruction_courante); return(d_erreur); } printf("%s [%d]\n", message, (int) getpid()); - free(message); + free(message); + free((*s_etat_processus).instruction_courante); return(d_erreur); } else if ((*s_etat_processus) @@ -384,6 +403,8 @@ sequenceur(struct_processus *s_etat_proc if ((message = messages(s_etat_processus)) == NULL) { + free((*s_etat_processus) + .instruction_courante); return(d_erreur); } @@ -434,8 +455,6 @@ sequenceur(struct_processus *s_etat_proc (*(*s_etat_processus).l_base_pile_systeme) .retour_definition = tampon_retour; } - - (*s_etat_processus).instruction_courante = tampon; } else if ((*s_etat_processus).invalidation_message_erreur == d_faux) @@ -451,6 +470,7 @@ sequenceur(struct_processus *s_etat_proc if ((message = messages(s_etat_processus)) == NULL) { + free((*s_etat_processus).instruction_courante); free(ligne); return(d_erreur); } @@ -546,9 +566,8 @@ sequenceur(struct_processus *s_etat_proc d_vrai) && ((*s_etat_processus) .autorisation_evaluation_nom == 'Y')) { - if (((*s_etat_processus).s_liste_variables - [(*s_etat_processus) - .position_variable_courante]).objet == NULL) + if ((*(*s_etat_processus).pointeur_variable_courante) + .objet == NULL) { /* @@ -563,14 +582,12 @@ sequenceur(struct_processus *s_etat_proc { if ((*s_etat_processus).langue == 'F') { - printf("[%d] Empilement de la variable " + printf("[%d] Évaluation de la variable " "partagée %s de type %d\n", - (int) getpid(), - (*s_etat_processus) + (int) getpid(), (*s_etat_processus) .instruction_courante, - (*((*s_etat_processus).s_liste_variables - [(*s_etat_processus) - .position_variable_courante]).objet) + (*(*(*s_etat_processus) + .pointeur_variable_courante).objet) .type); } else @@ -579,41 +596,27 @@ sequenceur(struct_processus *s_etat_proc "variable \n", (int) getpid(), (*s_etat_processus) .instruction_courante, - (*((*s_etat_processus).s_liste_variables - [(*s_etat_processus) - .position_variable_courante]).objet) + (*(*(*s_etat_processus) + .pointeur_variable_courante).objet) .type); } fflush(stdout); } - if (pthread_mutex_lock(&((*(*s_etat_processus) - .s_liste_variables_partagees).mutex)) != 0) - { - (*s_etat_processus).erreur_systeme = - d_es_processus; - return(d_erreur); - } - if (recherche_variable_partagee(s_etat_processus, - ((*s_etat_processus).s_liste_variables - [(*s_etat_processus) - .position_variable_courante]).nom, - ((*s_etat_processus).s_liste_variables - [(*s_etat_processus) - .position_variable_courante]) - .variable_partagee, 'P') == d_vrai) + (*(*s_etat_processus) + .pointeur_variable_courante).nom, + (*(*s_etat_processus) + .pointeur_variable_courante).variable_partagee, + 'P') != NULL) { // La variable existe. if ((s_objet = copie_objet(s_etat_processus, (*(*s_etat_processus) - .s_liste_variables_partagees) - .table[(*(*s_etat_processus) - .s_liste_variables_partagees) - .position_variable].objet, 'P')) - == NULL) + .pointeur_variable_partagee_courante) + .objet, 'P')) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -621,39 +624,26 @@ sequenceur(struct_processus *s_etat_proc } if (pthread_mutex_unlock(&((*(*s_etat_processus) - .s_liste_variables_partagees).mutex)) - != 0) + .pointeur_variable_partagee_courante) + .mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return(d_erreur); } - if (empilement(s_etat_processus, - &((*s_etat_processus).l_base_pile), - s_objet) == d_erreur) + if (evaluation(s_etat_processus, s_objet, 'E') + == d_erreur) { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; + liberation(s_etat_processus, s_objet); return(d_erreur); } + + liberation(s_etat_processus, s_objet); } else { // La variable n'existe plus. - - (*s_etat_processus).erreur_systeme = d_es; - - if (pthread_mutex_unlock(&((*(*s_etat_processus) - .s_liste_variables_partagees).mutex)) - != 0) - { - (*s_etat_processus).erreur_systeme = - d_es_processus; - return(d_erreur); - } - - recherche_type(s_etat_processus); } } @@ -663,8 +653,7 @@ sequenceur(struct_processus *s_etat_proc -------------------------------------------------------------------------------- */ - else if ((*((*s_etat_processus).s_liste_variables - [(*s_etat_processus).position_variable_courante]) + else if ((*(*(*s_etat_processus).pointeur_variable_courante) .objet).type == ADR) { @@ -733,10 +722,9 @@ sequenceur(struct_processus *s_etat_proc (*s_etat_processus).position_courante = (*((unsigned long *) - ((*((*s_etat_processus).s_liste_variables - [(*s_etat_processus) - .position_variable_courante] - .objet)).objet))); + ((*(*(*s_etat_processus) + .pointeur_variable_courante) + .objet).objet))); drapeau_appel_definition = d_vrai; } @@ -749,14 +737,13 @@ sequenceur(struct_processus *s_etat_proc { if ((*s_etat_processus).langue == 'F') { - printf("[%d] Empilement de la variable " + printf("[%d] Évaluation de la variable " "%s de type %d\n", (int) getpid(), (*s_etat_processus) .instruction_courante, - (*((*s_etat_processus).s_liste_variables - [(*s_etat_processus) - .position_variable_courante]).objet) + (*(*(*s_etat_processus) + .pointeur_variable_courante).objet) .type); } else @@ -765,9 +752,8 @@ sequenceur(struct_processus *s_etat_proc "\n", (int) getpid(), (*s_etat_processus) .instruction_courante, - (*((*s_etat_processus).s_liste_variables - [(*s_etat_processus) - .position_variable_courante]).objet) + (*(*(*s_etat_processus) + .pointeur_variable_courante).objet) .type); } @@ -775,9 +761,8 @@ sequenceur(struct_processus *s_etat_proc } if ((s_objet = copie_objet(s_etat_processus, - ((*s_etat_processus) - .s_liste_variables[(*s_etat_processus) - .position_variable_courante]).objet, 'P')) + (*(*s_etat_processus) + .pointeur_variable_courante).objet, 'P')) == NULL) { (*s_etat_processus).erreur_systeme = @@ -785,14 +770,14 @@ sequenceur(struct_processus *s_etat_proc return(d_erreur); } - if (empilement(s_etat_processus, - &((*s_etat_processus).l_base_pile), - s_objet) == d_erreur) + if (evaluation(s_etat_processus, s_objet, 'E') + == d_erreur) { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; + liberation(s_etat_processus, s_objet); return(d_erreur); } + + liberation(s_etat_processus, s_objet); } } else @@ -807,6 +792,42 @@ sequenceur(struct_processus *s_etat_proc (*s_etat_processus).erreur_systeme = d_es; recherche_type(s_etat_processus); + if ((*s_etat_processus).autorisation_nom_implicite == 'N') + { + if ((*s_etat_processus).l_base_pile == NULL) + { + if ((*s_etat_processus).erreur_execution != + d_ex_nom_implicite) + { + (*s_etat_processus).erreur_execution = + d_ex_manque_argument; + } + } + else if ((*(*(*s_etat_processus).l_base_pile).donnee) + .type == NOM) + { + if ((*((struct_nom *) (*(*(*s_etat_processus) + .l_base_pile).donnee).objet)).symbole + == d_faux) + { + (*s_etat_processus).erreur_execution = + d_ex_nom_implicite; + + // Si le niveau de récursivité est non nul, on + // arrive ici depuis la fonction + // recherche_type(). On retourne à cette + // dernière en indiquant une erreur. + + if ((*s_etat_processus).niveau_recursivite != 0) + { + free((*s_etat_processus) + .instruction_courante); + return(d_erreur); + } + } + } + } + // Le séquenceur est appelé depuis la routine d'évaluation if ((*s_etat_processus).evaluation_forcee == 'Y') @@ -815,6 +836,7 @@ sequenceur(struct_processus *s_etat_proc &((*s_etat_processus).l_base_pile), &s_objet_evaluation) == d_erreur) { + free((*s_etat_processus).instruction_courante); (*s_etat_processus).erreur_execution = d_ex_manque_argument; return(d_erreur); @@ -823,12 +845,25 @@ sequenceur(struct_processus *s_etat_proc if (evaluation(s_etat_processus, s_objet_evaluation, 'N') == d_erreur) { + free((*s_etat_processus).instruction_courante); liberation(s_etat_processus, s_objet_evaluation); return(d_erreur); } liberation(s_etat_processus, s_objet_evaluation); } + + // Le séquenceur est appelé depuis la routine de + // recherche de type + + else if ((*s_etat_processus).recherche_type == 'Y') + { + if ((*s_etat_processus).erreur_execution != d_ex) + { + free((*s_etat_processus).instruction_courante); + return(d_erreur); + } + } } } else if (((*s_etat_processus).test_instruction == 'Y') && @@ -853,19 +888,7 @@ sequenceur(struct_processus *s_etat_proc != 0) && (strcmp((*s_etat_processus) .instruction_courante, ">>") != 0)) { - if ((s_objet = (struct_objet *) malloc( - sizeof(struct_objet))) == NULL) - { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; - return(d_erreur); - } - - initialisation_objet(s_objet); - (*s_objet).type = FCT; - - if (((*s_objet).objet = allocation(s_etat_processus, FCT)) - == NULL) + if ((s_objet = allocation(s_etat_processus, FCT)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -948,6 +971,7 @@ sequenceur(struct_processus *s_etat_proc fflush(stdout); + free((*s_etat_processus).instruction_courante); return(d_erreur); } @@ -969,7 +993,7 @@ sequenceur(struct_processus *s_etat_proc { if (strncmp(getenv("LANG"), "fr", 2) == 0) { - printf("[%d] Arrêt\n", (int) getpid()); + printf("[%d] Arrêt\n", (int) getpid()); } else { @@ -1029,6 +1053,7 @@ sequenceur(struct_processus *s_etat_proc if ((message = messages(s_etat_processus)) == NULL) { + free((*s_etat_processus).instruction_courante); return(d_erreur); } @@ -1115,27 +1140,26 @@ sequenceur(struct_processus *s_etat_proc if (erreur == d_erreur) { + free((*s_etat_processus).instruction_courante); return(d_erreur); } if (recherche_variable(s_etat_processus, (*s_etat_processus).instruction_courante) == d_vrai) { - if (((*s_etat_processus).s_liste_variables - [(*s_etat_processus) - .position_variable_courante]).objet == NULL) + if ((*(*s_etat_processus).pointeur_variable_courante) + .objet == NULL) { // Variable partagée } - else if ((*((*s_etat_processus).s_liste_variables - [(*s_etat_processus) - .position_variable_courante]).objet).type == - ADR) + else if ((*(*(*s_etat_processus) + .pointeur_variable_courante).objet).type == ADR) { empilement_pile_systeme(s_etat_processus); if ((*s_etat_processus).erreur_systeme != d_es) { + free((*s_etat_processus).instruction_courante); return(d_erreur); } @@ -1152,10 +1176,9 @@ sequenceur(struct_processus *s_etat_proc (*s_etat_processus).position_courante = (*((unsigned long *) - ((*((*s_etat_processus).s_liste_variables - [(*s_etat_processus) - .position_variable_courante] - .objet)).objet))); + ((*(*(*s_etat_processus) + .pointeur_variable_courante) + .objet).objet))); (*s_etat_processus) .autorisation_empilement_programme = 'N'; @@ -1169,6 +1192,7 @@ sequenceur(struct_processus *s_etat_proc if (instruction_majuscule == NULL) { + free((*s_etat_processus).instruction_courante); return(d_erreur); } @@ -1182,8 +1206,12 @@ sequenceur(struct_processus *s_etat_proc (strcmp(instruction_majuscule, "DO") == 0) || (strcmp(instruction_majuscule, "WHILE") == 0) || (strcmp(instruction_majuscule, "FOR") == 0) || + (strcmp(instruction_majuscule, "FORALL") == 0) + || (strcmp(instruction_majuscule, "START") == 0) || (strcmp(instruction_majuscule, "SELECT") == 0) + || + (strcmp(instruction_majuscule, "CRITICAL") == 0) || (strcmp(instruction_majuscule, "CASE") == 0) || (strcmp(instruction_majuscule, "<<") == 0)) { @@ -1191,6 +1219,21 @@ sequenceur(struct_processus *s_etat_proc { analyse(s_etat_processus, NULL); } + else if ((strcmp(instruction_majuscule, "FOR") == 0) + || (strcmp(instruction_majuscule, "FORALL") + == 0) || (strcmp(instruction_majuscule, + "START") == 0)) + { + empilement_pile_systeme(s_etat_processus); + + if ((*s_etat_processus).erreur_systeme != d_es) + { + return(d_erreur); + } + + (*(*s_etat_processus).l_base_pile_systeme) + .type_cloture = 'L'; + } else { empilement_pile_systeme(s_etat_processus); @@ -1223,8 +1266,88 @@ sequenceur(struct_processus *s_etat_proc return(d_absence_erreur); } } + else if (((strcmp(instruction_majuscule, "NEXT") + == 0) || (strcmp(instruction_majuscule, + "STEP") == 0)) && ((*(*s_etat_processus) + .l_base_pile_systeme).type_cloture != 'L')) + { + /* + * Libération des compteurs de boucle. + */ + + presence_compteur = (((*(*s_etat_processus) + .l_base_pile_systeme).type_cloture + == 'F') || ((*(*s_etat_processus) + .l_base_pile_systeme).type_cloture + == 'A')) ? d_vrai : d_faux; + + if (((*(*s_etat_processus).l_base_pile_systeme) + .type_cloture != 'S') && + (presence_compteur == d_faux)) + { + return(d_erreur); + } + + if (presence_compteur == d_vrai) + { + if (recherche_variable(s_etat_processus, + (*(*s_etat_processus) + .l_base_pile_systeme).nom_variable) + == d_faux) + { + return(d_erreur); + } + + if ((*(*s_etat_processus) + .pointeur_variable_courante).objet + == NULL) + { + return(d_erreur); + } + + (*s_etat_processus).niveau_courant--; + + if (retrait_variables_par_niveau( + s_etat_processus) == d_erreur) + { + return(d_erreur); + } + } + + depilement_pile_systeme(s_etat_processus); + + if ((*s_etat_processus).erreur_systeme != d_es) + { + return(d_erreur); + } + } else { + // Traitement spécifique pour la fin + // d'une section critique + + if ((*s_etat_processus).l_base_pile_systeme + == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_processus; + return(d_erreur); + } + + if ((*(*s_etat_processus).l_base_pile_systeme) + .type_cloture == 'Q') + { + if (pthread_mutex_unlock( + &mutex_sections_critiques) != 0) + { + (*s_etat_processus).erreur_systeme = + d_es_processus; + return(d_erreur); + } + + (*s_etat_processus).sections_critiques--; + } + depilement_pile_systeme(s_etat_processus); if ((*s_etat_processus).erreur_systeme != d_es) @@ -1265,8 +1388,10 @@ sequenceur(struct_processus *s_etat_proc (strcmp(instruction_majuscule, "DO") == 0) || (strcmp(instruction_majuscule, "WHILE") == 0) || (strcmp(instruction_majuscule, "FOR") == 0) || + (strcmp(instruction_majuscule, "FORALL") == 0) || (strcmp(instruction_majuscule, "START") == 0) || (strcmp(instruction_majuscule, "SELECT") == 0) + || (strcmp(instruction_majuscule, "CRITICAL") == 0) || (strcmp(instruction_majuscule, "CASE") == 0) || (strcmp(instruction_majuscule, "<<") == 0)) { @@ -1361,7 +1486,8 @@ sequenceur(struct_processus *s_etat_proc if ((*s_etat_processus).var_volatile_processus_pere == 0) { - kill((*s_etat_processus).pid_processus_pere, SIGALRM); + envoi_signal_processus((*s_etat_processus).pid_processus_pere, + rpl_sigalrm); } else {