--- rpl/src/analyse.c 2010/01/26 15:22:44 1.1.1.1 +++ rpl/src/analyse.c 2015/11/26 11:44:28 1.102 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.0.9 - Copyright (C) 1989-2010 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.24 + Copyright (C) 1989-2015 Dr. BERTRAND Joël This file is part of RPL/2. @@ -20,12 +20,12 @@ */ -#include "rpl.conv.h" +#include "rpl-conv.h" /* ================================================================================ - Analyseur syntaxique de l'interpréteur RPL/2 + Analyseur syntaxique de l'interprète RPL/2 ================================================================================ Entrées : -------------------------------------------------------------------------------- @@ -35,7 +35,6 @@ ================================================================================ */ - static void creation_instruction(struct_processus *s_etat_processus, unsigned char *instruction, void (*routine)()) @@ -46,6 +45,10 @@ creation_instruction(struct_processus *s unsigned char *ptr; + BUG(strlen(instruction) >= d_longueur_maximale_instruction, + printf("%s -> %d >= %d\n", instruction, (int) strlen(instruction), + d_longueur_maximale_instruction)); + if ((*s_etat_processus).arbre_instructions == NULL) { if (((*s_etat_processus).arbre_instructions = @@ -57,8 +60,8 @@ creation_instruction(struct_processus *s (*(*s_etat_processus).arbre_instructions).feuille = NULL; - if (((*(*s_etat_processus).arbre_instructions).noeud = - malloc((*s_etat_processus).nombre_caracteres + if (((*(*s_etat_processus).arbre_instructions).noeuds = + malloc(((size_t) (*s_etat_processus).nombre_caracteres) * sizeof(struct_instruction))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -67,7 +70,7 @@ creation_instruction(struct_processus *s for(i = 0; i < (*s_etat_processus).nombre_caracteres; i++) { - (*(*s_etat_processus).arbre_instructions).noeud[i] = NULL; + (*(*s_etat_processus).arbre_instructions).noeuds[i] = NULL; } } @@ -80,12 +83,12 @@ creation_instruction(struct_processus *s printf("Instruction=\"%s\", (*ptr)='%c'\n", instruction, *ptr)); - if ((*l_instruction_courante).noeud[(*s_etat_processus) + if ((*l_instruction_courante).noeuds[(*s_etat_processus) .pointeurs_caracteres[*ptr]] == NULL) { // Le noeud suivant n'existe pas, on le crée. - if (((*l_instruction_courante).noeud[(*s_etat_processus) + if (((*l_instruction_courante).noeuds[(*s_etat_processus) .pointeurs_caracteres[*ptr]] = malloc(sizeof(struct_instruction))) == NULL) { @@ -93,12 +96,12 @@ creation_instruction(struct_processus *s return; } - (*(*l_instruction_courante).noeud[(*s_etat_processus) + (*(*l_instruction_courante).noeuds[(*s_etat_processus) .pointeurs_caracteres[*ptr]]).feuille = NULL; - if (((*(*l_instruction_courante).noeud[(*s_etat_processus) - .pointeurs_caracteres[*ptr]]).noeud = - malloc((*s_etat_processus).nombre_caracteres + if (((*(*l_instruction_courante).noeuds[(*s_etat_processus) + .pointeurs_caracteres[*ptr]]).noeuds = + malloc(((size_t) (*s_etat_processus).nombre_caracteres) * sizeof(struct_instruction))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -107,12 +110,12 @@ creation_instruction(struct_processus *s for(i = 0; i < (*s_etat_processus).nombre_caracteres; i++) { - (*(*l_instruction_courante).noeud[(*s_etat_processus) - .pointeurs_caracteres[*ptr]]).noeud[i] = NULL; + (*(*l_instruction_courante).noeuds[(*s_etat_processus) + .pointeurs_caracteres[*ptr]]).noeuds[i] = NULL; } } - l_instruction_courante = (*l_instruction_courante).noeud + l_instruction_courante = (*l_instruction_courante).noeuds [(*s_etat_processus).pointeurs_caracteres[*ptr]]; ptr++; } @@ -134,13 +137,13 @@ liberation_arbre_instructions(struct_pro for(i = 0; i < (*s_etat_processus).nombre_caracteres; i++) { - if ((*arbre).noeud[i] != NULL) + if ((*arbre).noeuds[i] != NULL) { - liberation_arbre_instructions(s_etat_processus, (*arbre).noeud[i]); + liberation_arbre_instructions(s_etat_processus, (*arbre).noeuds[i]); } } - free((*arbre).noeud); + free((*arbre).noeuds); free(arbre); return; @@ -177,7 +180,7 @@ initialisation_instructions(struct_proce } if (((*s_etat_processus).pointeurs_caracteres = - malloc(longueur_tableau * sizeof(int))) == NULL) + malloc(((size_t) longueur_tableau * sizeof(int)))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; @@ -320,6 +323,7 @@ initialisation_instructions(struct_proce INSTRUCTION("EGV", instruction_egv); INSTRUCTION("END", instruction_end); INSTRUCTION("ENG", instruction_eng); + INSTRUCTION("EQV", instruction_eqv); INSTRUCTION("EXP", instruction_exp); INSTRUCTION("FC?", instruction_fc_test); INSTRUCTION("FFT", instruction_fft); @@ -462,6 +466,7 @@ initialisation_instructions(struct_proce INSTRUCTION("LINE", instruction_line); INSTRUCTION("LNP1", instruction_lnp1); INSTRUCTION("LOCK", instruction_lock); + INSTRUCTION("L->T", instruction_l_vers_t); INSTRUCTION("MANT", instruction_mant); INSTRUCTION("MARK", instruction_mark); //INSTRUCTION("MAXR") @@ -483,6 +488,7 @@ initialisation_instructions(struct_proce INSTRUCTION("PMAX", instruction_pmax); INSTRUCTION("PMIN", instruction_pmin); INSTRUCTION("POKE", instruction_poke); + INSTRUCTION("POLL", instruction_poll); INSTRUCTION("PPAR", instruction_ppar); INSTRUCTION("PRMD", instruction_prmd); INSTRUCTION("PRST", instruction_prst); @@ -508,6 +514,8 @@ initialisation_instructions(struct_proce INSTRUCTION("RECV", instruction_recv); INSTRUCTION("REGV", instruction_regv); INSTRUCTION("REPL", instruction_repl); + INSTRUCTION("RGDL", instruction_rgdl); + INSTRUCTION("RGDR", instruction_rgdr); INSTRUCTION("RNRM", instruction_rnrm); INSTRUCTION("ROLL", instruction_roll); //INSTRUCTION("ROOT") @@ -536,6 +544,7 @@ initialisation_instructions(struct_proce INSTRUCTION("SPAR", instruction_spar); INSTRUCTION("SQRT", instruction_sqrt); //INSTRUCTION("SRAD"); + INSTRUCTION("SREV", instruction_srev); //INSTRUCTION("SRNM") //Instruction HP48 (renvoie la norme spectrale d'un tableau. Pour une //matrice, @@ -561,6 +570,7 @@ initialisation_instructions(struct_proce INSTRUCTION("TRNC", instruction_trnc); INSTRUCTION("TRUE", instruction_true); INSTRUCTION("TYPE", instruction_type); + INSTRUCTION("T->L", instruction_t_vers_l); INSTRUCTION("UTPC", instruction_utpc); INSTRUCTION("UTPF", instruction_utpf); INSTRUCTION("UTPN", instruction_utpn); @@ -641,6 +651,7 @@ initialisation_instructions(struct_proce INSTRUCTION("LCASE", instruction_lcase); INSTRUCTION("LCHOL", instruction_lchol); INSTRUCTION("LCD->", instruction_lcd_fleche); + INSTRUCTION("LIMIT", instruction_limit); //INSTRUCTION("NDIST") //Instruction HP48 (distribution normale, prend la moyenne au niveau 3, //la variance au niveau 2, un réel x au niveau 1 et renvoie la probabilité @@ -669,6 +680,7 @@ initialisation_instructions(struct_proce INSTRUCTION("PSDEV", instruction_psdev); INSTRUCTION("PURGE", instruction_purge); INSTRUCTION("RDATE", instruction_rdate); + INSTRUCTION("REGEX", instruction_regex); INSTRUCTION("RELAX", instruction_relax); INSTRUCTION("RFUSE", instruction_rfuse); INSTRUCTION("RSTOP", instruction_rstop); @@ -710,14 +722,35 @@ initialisation_instructions(struct_proce INSTRUCTION("APPEND", instruction_append); INSTRUCTION("ARRY->", instruction_array_fleche); + INSTRUCTION("ATEXIT", instruction_atexit); + INSTRUCTION("ATPOKE", instruction_atpoke); INSTRUCTION("BESSEL", instruction_bessel); + INSTRUCTION("CIPHER", instruction_cipher); INSTRUCTION("CLRERR", instruction_clrerr); INSTRUCTION("CLRMTX", instruction_clrmtx); INSTRUCTION("CLRSWI", instruction_clrswi); INSTRUCTION("CREATE", instruction_create); INSTRUCTION("DELETE", instruction_delete); - INSTRUCTION("DETACH", instruction_detach); +# ifdef SHARED_MEMORY + INSTRUCTION("DETACH", instruction_detach); +# else + if ((*s_etat_processus).langue == 'F') + { + printf("+++Attention : DETACH est émulé par SPAWN car le système" + " hôte ne supporte\n" + " pas de mémoire partagée !\n"); + } + else + { + printf("+++Warning : DETACH is replaced by SPAWN as host system" + " does not support\n" + " shared memory !\n"); + } + + INSTRUCTION("DETACH", instruction_spawn); +# endif INSTRUCTION("DIAG->", instruction_diag_fleche); + INSTRUCTION("DIGEST", instruction_digest); //INSTRUCTION("DOLIST") //Instruction HP48 (application d'une fonction à une liste) //liste(s) nombre_de_listes_a_traiter fonction DOLIST @@ -729,6 +762,7 @@ initialisation_instructions(struct_proce //DOLIST //=> { 29 42 57 } INSTRUCTION("ELSEIF", instruction_elseif); + INSTRUCTION("FORALL", instruction_forall); INSTRUCTION("FORMAT", instruction_format); //INSTRUCTION("HEIGHT") INSTRUCTION("ITRACE", instruction_itrace); @@ -736,6 +770,7 @@ initialisation_instructions(struct_proce INSTRUCTION("LOGGER", instruction_logger); INSTRUCTION("MCLRIN", instruction_mclrin); INSTRUCTION("NRPROC", instruction_nrproc); + INSTRUCTION("PROCID", instruction_procid); INSTRUCTION("PROMPT", instruction_prompt); INSTRUCTION("RCLSWI", instruction_rclswi); INSTRUCTION("RECALL", instruction_recall); @@ -788,6 +823,7 @@ initialisation_instructions(struct_proce //f(x,y)=fnct complexe évaluée sur la grille (x,y) et affichée comme une //fonction paramétrique. INSTRUCTION("INQUIRE", instruction_inquire); + INSTRUCTION("MEMLOCK", instruction_memlock); INSTRUCTION("MTXLOCK", instruction_mtxlock); INSTRUCTION("PERSIST", instruction_persist); INSTRUCTION("PLOTTER", instruction_plotter); @@ -795,6 +831,7 @@ initialisation_instructions(struct_proce INSTRUCTION("PROTECT", instruction_protect); INSTRUCTION("PSHPRFL", instruction_pshprfl); INSTRUCTION("PULPRFL", instruction_pulprfl); + INSTRUCTION("RESTART", instruction_restart); INSTRUCTION("REVLIST", instruction_revlist); INSTRUCTION("SCATTER", instruction_scatter); INSTRUCTION("SUSPEND", instruction_suspend); @@ -808,9 +845,13 @@ initialisation_instructions(struct_proce INSTRUCTION("CLRCNTXT", instruction_clrcntxt); INSTRUCTION("CLRSMPHR", instruction_clrsmphr); + INSTRUCTION("COMPRESS", instruction_compress); INSTRUCTION("CONTINUE", instruction_continue); + INSTRUCTION("CRITICAL", instruction_critical); INSTRUCTION("DUPCNTXT", instruction_dupcntxt); INSTRUCTION("FUNCTION", instruction_function); + INSTRUCTION("IMPLICIT", instruction_implicit); + INSTRUCTION("INFINITY", instruction_sensible_infinity); INSTRUCTION("KEYLABEL", instruction_keylabel); INSTRUCTION("KEYTITLE", instruction_keytitle); INSTRUCTION("LOGSCALE", instruction_logscale); @@ -826,12 +867,16 @@ initialisation_instructions(struct_proce INSTRUCTION("AUTOSCALE", instruction_autoscale); INSTRUCTION("BACKSPACE", instruction_backspace); + INSTRUCTION("BACKTRACE", instruction_backtrace); + INSTRUCTION("CLRATEXIT", instruction_clratexit); + INSTRUCTION("CLRATPOKE", instruction_clratpoke); INSTRUCTION("COPYRIGHT", instruction_copyright); //INSTRUCTION("CYLINDRIC"); INSTRUCTION("DAEMONIZE", instruction_daemonize); INSTRUCTION("DROPCNTXT", instruction_dropcntxt); INSTRUCTION("EXTERNALS", instruction_externals); INSTRUCTION("HISTOGRAM", instruction_histogram); + INSTRUCTION("MEMUNLOCK", instruction_memunlock); INSTRUCTION("MTXSTATUS", instruction_mtxstatus); INSTRUCTION("MTXUNLOCK", instruction_mtxunlock); INSTRUCTION("PARAMETER", instruction_parameter); @@ -860,6 +905,7 @@ initialisation_instructions(struct_proce //pentes //représentent la valeur de la fonction (x,y) en leur milieu. //=> utile pour y'=F(x,y) + INSTRUCTION("UNCOMPRESS", instruction_uncompress); INSTRUCTION("LOCALIZATION", instruction_localization); INSTRUCTION("SMPHRTRYDECR", instruction_smphrtrydecr); @@ -871,7 +917,7 @@ initialisation_instructions(struct_proce } -inline void * +void * analyse_instruction(struct_processus *s_etat_processus, unsigned char *ptr) { int pointeur; @@ -891,14 +937,14 @@ analyse_instruction(struct_processus *s_ return(NULL); } - if ((*l_instruction_courante).noeud[pointeur] == NULL) + if ((*l_instruction_courante).noeuds[pointeur] == NULL) { // Le chemin de l'instruction candidate n'existe pas. return(NULL); } - l_instruction_courante = (*l_instruction_courante).noeud[pointeur]; + l_instruction_courante = (*l_instruction_courante).noeuds[pointeur]; ptr++; if ((l_instruction_courante == NULL) && ((*ptr) != d_code_fin_chaine)) @@ -921,8 +967,6 @@ analyse_instruction(struct_processus *s_ void analyse(struct_processus *s_etat_processus, void (*fonction)()) { - static logical1 initialisation = d_faux; - real8 attente; real8 pourcentage; real8 temps_cpu; @@ -931,14 +975,20 @@ analyse(struct_processus *s_etat_process static struct timeval horodatage_initial; struct timeval horodatage_final; +# ifndef OS2 static struct rusage usage_initial; struct rusage usage_final; +# else + static clock_t usage_initial; + clock_t usage_final; +# endif struct timespec temporisation; unsigned char *position; unsigned char *bibliotheque_candidate; - unsigned char *instruction_majuscule; + unsigned char instruction_majuscule + [d_longueur_maximale_instruction]; unsigned char registre_instruction_valide; void (*instruction)(); @@ -955,13 +1005,21 @@ analyse(struct_processus *s_etat_process * On autorise l'exécution d'un fork() dans un thread concurrent. */ - if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) +# 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; } - while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1) +# 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) { @@ -970,17 +1028,28 @@ analyse(struct_processus *s_etat_process } } + /* + * Verrou pour les sections_critiques + */ + + if (pthread_mutex_lock(&mutex_sections_critiques) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } + + if (pthread_mutex_unlock(&mutex_sections_critiques) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } + scrutation_injection(s_etat_processus); if (fonction == NULL) { - if ((instruction_majuscule = conversion_majuscule( - (*s_etat_processus).instruction_courante)) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - + conversion_majuscule_limitee((*s_etat_processus).instruction_courante, + instruction_majuscule, d_longueur_maximale_instruction); instruction = analyse_instruction(s_etat_processus, instruction_majuscule); @@ -1009,8 +1078,6 @@ analyse(struct_processus *s_etat_process profilage(s_etat_processus, NULL); } } - - free(instruction_majuscule); } else { @@ -1039,8 +1106,8 @@ analyse(struct_processus *s_etat_process if ((position = index((*s_etat_processus).instruction_courante, '$')) != NULL) { - if ((bibliotheque_candidate = malloc((position + 1 - - (*s_etat_processus).instruction_courante) + if ((bibliotheque_candidate = malloc(((size_t) (position + 1 + - (*s_etat_processus).instruction_courante)) * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -1049,8 +1116,8 @@ analyse(struct_processus *s_etat_process (*bibliotheque_candidate) = d_code_fin_chaine; strncat(bibliotheque_candidate, - (*s_etat_processus).instruction_courante, - position - (*s_etat_processus).instruction_courante); + (*s_etat_processus).instruction_courante, ((size_t) + (position - (*s_etat_processus).instruction_courante))); position++; @@ -1095,9 +1162,23 @@ analyse(struct_processus *s_etat_process { if ((*s_etat_processus).test_instruction == 'N') { - if ((*s_etat_processus).nombre_interruptions_non_affectees != 0) + if (pthread_mutex_lock(&(*s_etat_processus).mutex_interruptions) + != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + } + else { - affectation_interruptions_logicielles(s_etat_processus); + if ((*s_etat_processus).nombre_interruptions_non_affectees != 0) + { + affectation_interruptions_logicielles(s_etat_processus); + } + + if (pthread_mutex_unlock(&(*s_etat_processus) + .mutex_interruptions) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + } } if (((*s_etat_processus).nombre_interruptions_en_queue != 0) && @@ -1122,18 +1203,27 @@ analyse(struct_processus *s_etat_process if ((*s_etat_processus).pourcentage_maximal_cpu < 100) { +# ifndef OS2 getrusage(RUSAGE_SELF, &usage_final); +# else + usage_final = clock(); +# endif + gettimeofday(&horodatage_final, NULL); - if (initialisation == d_vrai) + if ((*s_etat_processus).initialisation_scheduler == d_vrai) { temps_reel = ((real8) (horodatage_final.tv_sec - horodatage_initial.tv_sec)) + (((real8) (horodatage_final.tv_usec - horodatage_initial.tv_usec)) / ((real8) 1E6)); + // Le temps depuis la dernière limitation est de plus de un + // dixième de seconde. + if (temps_reel >= 0.1) { +# ifndef OS2 temps_cpu = ((real8) ((usage_final.ru_utime.tv_sec + usage_final.ru_stime.tv_sec) - (usage_initial.ru_utime.tv_sec + @@ -1142,6 +1232,9 @@ analyse(struct_processus *s_etat_process usage_final.ru_stime.tv_usec) - (usage_initial.ru_utime.tv_usec + usage_initial.ru_stime.tv_usec))) / ((real8) 1E6)); +# else + temps_cpu = (usage_final - usage_initial) / CLOCKS_PER_SEC; +# endif pourcentage = 100 * temps_cpu / temps_reel; @@ -1156,11 +1249,17 @@ analyse(struct_processus *s_etat_process (*s_etat_processus).pourcentage_maximal_cpu) - (pourcentage * temps_cpu / 100); - temporisation.tv_sec = floor(attente); - temporisation.tv_nsec = (attente - temporisation.tv_sec) * - 1E9; + temporisation.tv_sec = (time_t) floor(attente); + temporisation.tv_nsec = (suseconds_t) ((attente + - ((real8) temporisation.tv_sec)) * 1E9); - nanosleep(&temporisation, NULL); + while(nanosleep(&temporisation, &temporisation) == -1) + { + if (errno != EINTR) + { + break; + } + } } horodatage_initial = horodatage_final; @@ -1169,12 +1268,16 @@ analyse(struct_processus *s_etat_process } else { - initialisation = d_vrai; + (*s_etat_processus).initialisation_scheduler = d_vrai; horodatage_initial = horodatage_final; usage_initial = usage_final; } } + else + { + (*s_etat_processus).initialisation_scheduler = d_faux; + } /* -------------------------------------------------------------------------------- @@ -1211,17 +1314,17 @@ analyse(struct_processus *s_etat_process ((*s_etat_processus).erreur_systeme != d_es) || ((*s_etat_processus).exception != d_ep)) { - if ((*s_etat_processus).instruction_derniere_erreur != NULL) - { - free((*s_etat_processus).instruction_derniere_erreur); - (*s_etat_processus).instruction_derniere_erreur = NULL; - } - (*s_etat_processus).niveau_derniere_erreur = (*s_etat_processus).niveau_courant; if ((*s_etat_processus).mode_execution_programme == 'Y') { + if ((*s_etat_processus).instruction_derniere_erreur != NULL) + { + free((*s_etat_processus).instruction_derniere_erreur); + (*s_etat_processus).instruction_derniere_erreur = NULL; + } + if ((*s_etat_processus).instruction_courante == NULL) { if (((*s_etat_processus).instruction_derniere_erreur = @@ -1253,11 +1356,22 @@ analyse(struct_processus *s_etat_process } else { - if (((*s_etat_processus).instruction_derniere_erreur = - formateur(s_etat_processus, 0, - (*s_etat_processus).objet_courant)) == NULL) + if ((*s_etat_processus).objet_courant != NULL) { - return; + if ((*s_etat_processus).instruction_derniere_erreur != NULL) + { + free((*s_etat_processus).instruction_derniere_erreur); + (*s_etat_processus).instruction_derniere_erreur = NULL; + } + + if (((*s_etat_processus).instruction_derniere_erreur = + formateur(s_etat_processus, 0, + (*s_etat_processus).objet_courant)) == NULL) + { + return; + } + + (*s_etat_processus).objet_courant = NULL; } } }