--- rpl/src/rpl.h 2011/09/10 20:45:07 1.119 +++ rpl/src/rpl.h 2023/08/07 17:42:59 1.346 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.1.3 - Copyright (C) 1989-2011 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.35 + Copyright (C) 1989-2023 Dr. BERTRAND Joël This file is part of RPL/2. @@ -38,12 +38,15 @@ # ifdef OpenBSD # define _BSD_SOURCE # endif + +# ifdef FreeBSD +# define __BSD_VISIBLE 1 +# endif #endif #ifdef OS2 # ifndef __RPLCAS # define _BSD_SOURCE -# define _XOPEN_SOURCE 600 # endif # include @@ -57,6 +60,20 @@ # define sched_yield(arg) #endif +#ifdef CYGWIN +# define SA_ONSTACK 0 +#endif + +#ifdef BROKEN_SIGSEGV +# undef HAVE_STACK_OVERFLOW_RECOVERY +# undef HAVE_SIGSEGV_RECOVERY +#endif + +#define DEBUG_TRACE uprintf("[%d/%X] %s(%d)\n", \ + getpid(), pthread_self(), __FILE__, __LINE__); +#define TEST_ABSENCE_FICHIER(nom) \ + { int ios; struct stat *buf; ios = stat(nom, buf); \ + if (ios == 0) BUG(1, uprintf("File %s found!\n", nom)); } /* ================================================================================ @@ -66,16 +83,19 @@ #include #include +#include #include #include #include #include #include #include +#include +#include +#include #ifndef RPLARGS # include -# include # include # include # include @@ -84,6 +104,7 @@ # include # include # include +# include # include # include @@ -92,6 +113,7 @@ # include # include # include +# include # ifdef OS2 # undef pthread_mutexattr_settype @@ -99,9 +121,7 @@ # endif # include - -# ifdef _BROKEN_SIGINFO -# include +# ifdef SHARED_MEMORY # include # endif @@ -126,30 +146,34 @@ ULONG *nopened; ULONG allocated; } sem_t; -# else +# else // IPCS_SYSV typedef struct { int sem; + int alloue; unsigned char *path; pid_t pid; + pthread_t tid; } sem_t; # endif -# define SEM_FAILED NULL +# ifndef SEM_FAILED +# define SEM_FAILED NULL +# endif sem_t *sem_open_SysV(const char *nom, int oflag, ...); int sem_init_SysV(sem_t *sem, int shared, unsigned int value); int sem_close_SysV(sem_t *sem); int sem_wait_SysV(sem_t *sem); int sem_trywait_SysV(sem_t *sem); + int sem_timedwait_SysV(sem_t *sem, struct timespec *ts); int sem_post_SysV(sem_t *sem); int sem_getvalue_SysV(sem_t *sem, int *value); - int sem_unlink_SysV(const char *nom); + int sem_unlink_SysV(char *nom); int sem_destroy_SysV(sem_t *sem); # endif # include -# include # include # include # include @@ -159,11 +183,56 @@ # include "readline.h" # include "termcap.h" # include "iconv.h" +# include "zlib.h" # include "openssl/evp.h" +# ifndef RPLCXX +# ifndef OPENSSL_NO_MD2 +# include "openssl/md2.h" +# endif +# ifndef OPENSSL_NO_MD4 +# include "openssl/md4.h" +# endif +# ifndef OPENSSL_NO_MD5 +# include "openssl/md5.h" +# endif +# ifndef OPENSSL_NO_MDC2 +# include "openssl/mdc2.h" +# endif +# ifndef OPENSSL_NO_RIPEMD +# include "openssl/ripemd.h" +# endif +# ifndef OPENSSL_NO_SHA +# include "openssl/sha.h" +# endif +# ifndef OPENSSL_NO_WHIRLPOOL +# include "openssl/whrlpool.h" +# endif +# ifndef OPENSSL_NO_AES +# include "openssl/aes.h" +# endif +# ifndef OPENSSL_NO_CAMELLIA +# include "openssl/camellia.h" +# endif +# ifndef OPENSSL_NO_RC2 +# include "openssl/rc2.h" +# endif +# ifndef OPENSSL_NO_IDEA +# include "openssl/idea.h" +# endif +# endif + # include "sqlite3.h" -# define HAVE_INLINE +# ifndef BROKEN_SIGSEGV +# include "sigsegv.h" +# endif + +# ifdef OS2 + // Bug de libsigsegv +# undef HAVE_STACK_OVERFLOW_RECOVERY +# endif + # define GSL_RANGE_CHECK_OFF # include "gsl/gsl_cdf.h" # include "gsl/gsl_cblas.h" @@ -202,53 +271,106 @@ #ifndef RPLARGS # ifndef UNIX_PATH_MAX - struct sockaddr_un sizecheck; +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-variable" + static struct sockaddr_un sizecheck; # define UNIX_PATH_MAX sizeof(sizecheck.sun_path) +# pragma GCC diagnostic pop # endif #endif +#ifdef MAIN_RPL +# define __EXTERN__ +# define __STATIC_MUTEX_INITIALIZATION__ = PTHREAD_MUTEX_INITIALIZER +#else +# define __EXTERN__ extern +# define __STATIC_MUTEX_INITIALIZATION__ +#endif + + /* ================================================================================ Bugs spécifiques ================================================================================ */ -#ifdef _BROKEN_SIGINFO -# define SIGHANDLER_ARGS int signal -# ifdef SA_SIGINFO -# undef SA_SIGINFO -# endif -# define SA_SIGINFO 0 +// Néant -# ifndef __BROKEN_SIGINFO_ROUTINES__ - -// pthread_kill() est une macro sous OS/2. -# ifdef pthread_kill -# undef pthread_kill -# endif +/* +================================================================================ + TYPES +================================================================================ +*/ -# define kill(a, b) kill_broken_siginfo(a, b) -# define pthread_kill(a, b) pthread_kill_broken_siginfo(a, b) -# endif +typedef FILE file; +typedef unsigned char t_8_bits; - int kill_broken_siginfo(pid_t pid, int signal); - int pthread_kill_broken_siginfo(pthread_t tid, int signal); - pid_t origine_signal(int signal); - int queue_in(pid_t pid, int signal); +#ifndef RPLARGS +# include "rpltypes-conv.h" #else -# define SIGHANDLER_ARGS int signal, siginfo_t *siginfo, void *context +# include "rpltypes.h" #endif -#ifdef OpenBSD -# ifdef PTHREAD_SCOPE_SYSTEM -# undef PTHREAD_SCOPE_SYSTEM +enum signaux_rpl +{ + rpl_signull = 0, + rpl_sigint, + rpl_sigterm, + rpl_sigstart, // Signal envoyé par un père pour lancer son fils. + rpl_sigcont, // Signal de redémarrage d'un processus arrêté par + // SUSPEND + rpl_sigstop, // Signal d'arrêt envoyé par l'instruction STOP ou + // FUSE. (FSTOP) + rpl_sigabort, // Signal envoyé par l'instruction ABORT (à regrouper + // avec FABORT) + rpl_sigurg, // Signal d'arrêt urgent + rpl_siginject, // Signal indiquant la présence d'une donnée à lire + // envoyée depuis le père + rpl_sigalrm, // Signal d'alarme (erreur système) depuis un fils + rpl_sighup, + rpl_sigtstp, + rpl_sigexcept, + rpl_sigmax, + rpl_siguser // Base des signaux à la discrétion de l'utilisateur +}; + +#define LONGUEUR_QUEUE_SIGNAUX 1024 + +// Une structure s_queue_signaux est créée par processus (et non par thread). +// Elle est projetée dans un segment de mémoire partagée pour qu'elle soit +// accessible à la fois du père et des fils. + +#ifndef RPLARGS +typedef struct queue_signaux +{ + volatile int pointeur_lecture; + volatile int pointeur_ecriture; + volatile logical1 requete_arret; + + pthread_t thread_signaux; + pid_t controle; + + volatile struct + { + pid_t pid; + enum signaux_rpl signal; + } queue[LONGUEUR_QUEUE_SIGNAUX]; + +# ifdef OS2 + sem_t semaphore; + sem_t signalisation; + sem_t arret_signalisation; # endif -# define PTHREAD_SCOPE_SYSTEM 0 -#endif +} struct_queue_signaux; -#ifdef OS2 -# define readline(s) readline_wrapper(s) - unsigned char *readline_wrapper(unsigned char *s); +__EXTERN__ struct_queue_signaux *s_queue_signaux; +__EXTERN__ int f_queue_signaux; + +# ifndef OS2 + __EXTERN__ sem_t *semaphore_queue_signaux; + __EXTERN__ sem_t *semaphore_signalisation; + __EXTERN__ sem_t *semaphore_arret_signalisation; +# endif #endif #if ! defined(UNION_SEMUN) && defined(IPCS_SYSV) @@ -261,6 +383,14 @@ union semun }; #endif +#ifndef RTLD_LOCAL +# define RTLD_LOCAL 0 +#endif + +#ifndef SIGSTKSZ +# define SIGSTKSZ 65536 +#endif + /* ================================================================================ @@ -269,15 +399,95 @@ union semun */ #ifdef IPCS_SYSV +# ifdef DEBUG_SEMAPHORES +# define sem_init(a, b, c) ({ \ + uprintf("[%d-%llu] Semaphore %s (%p) "\ + "initialization at %s() " \ + "line #%d <%d>\n", (int) getpid(), (unsigned long long) \ + pthread_self(), \ + #a, a, __FUNCTION__, __LINE__, value), fflush(stdout); \ + sem_init_SysV(a, b, c); }) +# define sem_wait(a) ({ int value; sem_getvalue(a, &value); \ + uprintf("[%d-%llu] Semaphore %s (%p) "\ + "waiting at %s() " \ + "line #%d <%d>\n", (int) getpid(), (unsigned long long) i\ + pthread_self(), \ + #a, a, __FUNCTION__, __LINE__, value), fflush(stdout); \ + sem_wait_SysV(a); }) +# define sem_trywait(a) ({ int value; sem_getvalue(a, &value); \ + uprintf("[%d-%llu] Semaphore %s (%p) "\ + "trywaiting at %s() " \ + "line #%d <%d>\n", (int) getpid(), (unsigned long long) i\ + pthread_self(), \ + #a, a, __FUNCTION__, __LINE__, value), fflush(stdout); \ + sem_trywait_SysV(a); }) +# define sem_post(a) ({ int value; sem_getvalue(a, &value); \ + uprintf("[%d-%llu] Semaphore %s (%p) "\ + "posting at %s() " \ + "line #%d <%d>\n", (int) getpid(), (unsigned long long) \ + pthread_self(), \ + #a, a, __FUNCTION__, __LINE__, value), fflush(stdout); \ + sem_post_SysV(a); }) +# define sem_destroy(a) ({ int value; sem_getvalue(a, &value); \ + uprintf("[%d-%llu] Semaphore %s (%p) "\ + "destroying at %s() " \ + "line #%d <%d>\n", (int) getpid(), (unsigned long long) \ + pthread_self(), \ + #a, a, __FUNCTION__, __LINE__, value), fflush(stdout); \ + if (value == 0) BUG(1, uprintf("Value %d\n", value)); \ + sem_destroy_SysV(a); }) +# else +# define sem_destroy(a) sem_destroy_SysV(a) +# define sem_wait(a) sem_wait_SysV(a) +# define sem_post(a) sem_post_SysV(a) +# endif + # define sem_init(a, b, c) sem_init_SysV(a, b, c) -# define sem_destroy(a) sem_destroy_SysV(a) -# define sem_wait(a) sem_wait_SysV(a) # define sem_trywait(a) sem_trywait_SysV(a) -# define sem_post(a) sem_post_SysV(a) +# define sem_timedwait(a, b) sem_timedwait_SysV(a, b) # define sem_getvalue(a, b) sem_getvalue_SysV(a, b) # define sem_open(...) sem_open_SysV(__VA_ARGS__) # define sem_close(a) sem_close_SysV(a) # define sem_unlink(a) sem_unlink_SysV(a) +#else +# ifdef DEBUG_SEMAPHORES +# define sem_init(a, b, c) ({ \ + uprintf("[%d-%llu] Semaphore %s (%p) "\ + "initialization at %s() " \ + "line #%d <%d>\n", (int) getpid(), (unsigned long long) \ + pthread_self(), \ + #a, a, __FUNCTION__, __LINE__, c), fflush(stdout); \ + sem_init(a, b, c); }) +# define sem_wait(a) ({ int value; sem_getvalue(a, &value); \ + uprintf("[%d-%llu] Semaphore %s (%p) "\ + "waiting at %s() " \ + "line #%d <%d>\n", (int) getpid(), (unsigned long long) \ + pthread_self(), \ + #a, a, __FUNCTION__, __LINE__, value), fflush(stdout); \ + sem_wait(a); }) +# define sem_trywait(a) ({ int value; sem_getvalue(a, &value); \ + uprintf("[%d-%llu] Semaphore %s (%p) "\ + "trywaiting at %s() " \ + "line #%d <%d>\n", (int) getpid(), (unsigned long long) \ + pthread_self(), \ + #a, a, __FUNCTION__, __LINE__, value), fflush(stdout); \ + sem_trywait(a); }) +# define sem_post(a) ({ int value; sem_getvalue(a, &value); \ + uprintf("[%d-%llu] Semaphore %s (%p) "\ + "posting at %s() " \ + "line #%d <%d>\n", (int) getpid(), (unsigned long long) \ + pthread_self(), \ + #a, a, __FUNCTION__, __LINE__, value), fflush(stdout); \ + sem_post(a); }) +# define sem_destroy(a) ({ int value; sem_getvalue(a, &value); \ + uprintf("[%d-%llu] Semaphore %s (%p) "\ + "destroying at %s() " \ + "line #%d <%d>\n", (int) getpid(), (unsigned long long) \ + pthread_self(), \ + #a, a, __FUNCTION__, __LINE__, value), fflush(stdout); \ + if (value == 0) BUG(1, uprintf("Value %d\n", value)); \ + sem_destroy(a); }) +# endif #endif @@ -293,31 +503,12 @@ union semun // SIGINT // SIGTSTP // SIGCONT -// SIGURG // SIGPIPE +// SIGUSR1 et SIGUSR2 sont utilisé par libsigsegv. +// SIGHUP // SIGALRM -// Arrêt par STOP -# define SIGFSTOP SIGUSR1 -// Démarrage d'un processus fils -# define SIGSTART SIGUSR2 -// Injection de données -# define SIGINJECT SIGQUIT -// Arrêt général -# ifndef OpenBSD -// La libpthread d'OpenBSD utilise SIGPROF -# define SIGABORT SIGPROF -# else -# define SIGABORT SIGTHR -# endif -// Arrêt d'un processus fils depuis autre chose que STOP -# if defined(Darwin) || defined(OpenBSD) || defined(NetBSD) -# define SIGFABORT SIGINFO -# else -# define SIGFABORT SIGPOLL -# endif - -# define SIGTEST SIGILL +# define SIGTEST 255 // Nombre d'interruptions disponibles # define d_NOMBRE_INTERRUPTIONS 64 @@ -360,21 +551,6 @@ union semun /* ================================================================================ - TYPES -================================================================================ -*/ - -typedef FILE file; -typedef unsigned char t_8_bits; - -#ifndef RPLARGS -# include "rpltypes-conv.h" -#else -# include "rpltypes.h" -#endif - -/* -================================================================================ Variables globales ================================================================================ */ @@ -382,109 +558,51 @@ typedef unsigned char t_8_bits; #ifndef RPLARGS # ifdef SEMAPHORES_NOMMES # define LONGUEUR_NOM_SEMAPHORE 64 -# endif - -# ifndef MAIN_RPL -# ifdef _BROKEN_SIGINFO - extern int *fifos_signaux; -# endif - - extern jmp_buf contexte; - extern jmp_buf contexte_initial; - extern jmp_buf contexte_processus; - extern jmp_buf contexte_thread; - - extern int signal_test; - - extern pid_t pid_processus_pere; - -# ifdef SEMAPHORES_NOMMES - extern pthread_mutex_t mutex_sem; -# endif - - extern pthread_key_t semaphore_fork_processus_courant; - - extern sem_t -# ifdef SEMAPHORES_NOMMES - * -# endif - semaphore_liste_threads; - - extern sem_t -# ifdef SEMAPHORES_NOMMES - * -# endif - semaphore_gestionnaires_signaux; - - extern sem_t -# ifdef SEMAPHORES_NOMMES - * -# endif - semaphore_gestionnaires_signaux_atomique; - -# ifdef SEMAPHORES_NOMMES - // 0 -> liste_threads - // 1 -> gestionnaire_signaux - // 2 -> gestionnaire_signaux_atomique - // 3 -> &((*s_etat_processus).semaphore_fork) - extern unsigned char noms_semaphores[4][LONGUEUR_NOM_SEMAPHORE]; - extern sem_t *semaphores_nommes[4]; -# endif +# define __PTR__ * # else -# ifdef _BROKEN_SIGINFO - int *fifos_signaux; -# endif - - jmp_buf contexte; - jmp_buf contexte_initial; - jmp_buf contexte_processus; - jmp_buf contexte_thread; - - int signal_test; - - pid_t pid_processus_pere; - -# ifdef SEMAPHORES_NOMMES - pthread_mutex_t mutex_sem = PTHREAD_MUTEX_INITIALIZER; -# endif - - pthread_key_t semaphore_fork_processus_courant; - - sem_t -# ifdef SEMAPHORES_NOMMES - * -# endif - semaphore_liste_threads; - - sem_t -# ifdef SEMAPHORES_NOMMES - * -# endif - semaphore_gestionnaires_signaux; - - sem_t -# ifdef SEMAPHORES_NOMMES - * -# endif - semaphore_gestionnaires_signaux_atomique; - -# ifdef SEMAPHORES_NOMMES - unsigned char noms_semaphores[4][LONGUEUR_NOM_SEMAPHORE]; - sem_t *semaphores_nommes[4]; -# endif +# define __PTR__ # endif -#endif -#ifdef SEMAPHORES_NOMMES -enum t_semaphore { sem_liste_threads = 0, - sem_gestionnaires_signaux = 1, - sem_gestionnaires_signaux_atomique = 2, - sem_fork = 3 }; - -sem_t *sem_init2(unsigned int valeur, enum t_semaphore semaphore); -int sem_destroy2(sem_t *semaphore_p, enum t_semaphore semaphore); -int sem_getvalue2(sem_t *semaphore, int *valeur); + __EXTERN__ jmp_buf contexte_ecriture; + __EXTERN__ jmp_buf contexte_impression; + __EXTERN__ jmp_buf contexte_initial; + __EXTERN__ jmp_buf contexte_processus; + __EXTERN__ jmp_buf contexte_thread; + + __EXTERN__ volatile int signal_test; + + __EXTERN__ pid_t pid_processus_pere; + + __EXTERN__ pthread_mutex_t mutex_sigaction; + __EXTERN__ pthread_mutex_t mutex_liste_threads; + __EXTERN__ pthread_mutex_t mutex_liste_threads_surveillance; + __EXTERN__ pthread_mutex_t mutex_creation_variable_partagee + __STATIC_MUTEX_INITIALIZATION__; + __EXTERN__ pthread_mutex_t mutex_sections_critiques; + __EXTERN__ pthread_mutex_t mutex_liste_variables_partagees; + __EXTERN__ pthread_mutex_t mutex_sem __STATIC_MUTEX_INITIALIZATION__; + + __EXTERN__ volatile int routine_recursive; + __EXTERN__ volatile int nombre_threads_surveillance_processus; + +# define SEM_FORK 0 +# define SEM_QUEUE 1 +# define SEM_SIGNALISATION 2 +# define SEM_ARRET_SIGNALISATION 3 + + sem_t *sem_init2(unsigned int valeur, pid_t pid, int ordre); + sem_t *sem_init3(unsigned int valeur, pid_t pid, pthread_t tid, int ordre); + int sem_destroy2(sem_t *semaphore_p, pid_t pid, int ordre); + int sem_destroy3(sem_t *semaphore_p, pid_t pid, pthread_t tid, int ordre); + int sem_getvalue2(sem_t *semaphore, int *valeur); + sem_t *sem_open2(pid_t pid, int ordre); +#endif + +// Le mutex est là uniquement pour pouvoir émuler le comportement +// de sem_getvalue() sur un système comme MacOS X qui ne possède pas +// cette fonction. +#ifdef Darwin #define sem_getvalue(semaphore, value) sem_getvalue2(semaphore, value) #define sem_post(semaphore) \ ({ int r; pthread_mutex_lock(&mutex_sem); \ @@ -510,14 +628,8 @@ int sem_getvalue2(sem_t *semaphore, int stderr, __VA_ARGS__) #define fprintf(flux, ...) transliterated_fprintf(s_etat_processus, \ flux, __VA_ARGS__) -#define uprintf(...) transliterated_fprintf(NULL, \ - stderr, __VA_ARGS__) -#define ufprintf(flux, ...) transliterated_fprintf(NULL, \ - flux, __VA_ARGS__) - -// Tous les messages pour DISP, INPUT et les E/S par readline sont sur stderr. -// Cela évite aux messages envoyés par les gestionnaires de signaux d'être -// indéfiniment bloqués. +#define uprintf(...) std_fprintf(stderr, __VA_ARGS__) +#define ufprintf(flux, ...) std_fprintf(flux, __VA_ARGS__) #ifdef SunOS # define fopen(...) ({ FILE *desc; \ @@ -529,9 +641,6 @@ int sem_getvalue2(sem_t *semaphore, int # define fclose(...) ({ int ios; \ while((ios = fclose(__VA_ARGS__)) != 0) \ { if ((errno != EINTR) && (errno != 0)) break; } ios; }) -# define fread(...) ({ int ios; \ - while((ios = fread(__VA_ARGS__)) < 0) \ - { if ((errno != EINTR) && (errno != 0)) break; } ios; }) # define fflush(flux) ({ int ios; \ while((ios = fflush((flux == stdout) ? stderr : flux)) != 0) \ { if ((errno != EINTR) && (errno != 0)) break; } ios; }) @@ -542,26 +651,6 @@ int sem_getvalue2(sem_t *semaphore, int # define fflush(flux) fflush((flux == stdout) ? stderr : flux) #endif -// Ajout d'un timeout sur les fonctions pipe() pour éviter une erreur -// système dans le cas où l'on a atteint le nombre maximale de fichiers -// ouverts. - -#define pipe(descripteurs) \ - ({ \ - struct timespec temporisation; \ - int erreur, nombre_echecs; \ - nombre_echecs = 0; \ - do \ - { \ - if ((erreur = pipe(descripteurs)) == 0) break; \ - nombre_echecs++; \ - temporisation.tv_sec = 0; \ - temporisation.tv_nsec = ((long) 1000000000) * rand(); \ - nanosleep(&temporisation, NULL); \ - } while(nombre_echecs < 100); \ - erreur; \ - }) - // Redéfinition de abs pour un fonctionnement en entier de type long long int #ifdef __GNUC__ @@ -584,9 +673,9 @@ int sem_getvalue2(sem_t *semaphore, int } while(0) #ifdef __GLIBC__ -#include -#define __BACKTRACE -#define BACKTRACE(n) \ +# include +# define __BACKTRACE +# define BACKTRACE(n) \ do \ { \ void *buffer[n]; \ @@ -602,7 +691,7 @@ int sem_getvalue2(sem_t *semaphore, int { \ for(i = 0; i < nb; i++) \ uprintf(" %s\n", appels[i]); \ - free(appels); \ + sys_free(appels); \ } \ else \ uprintf("Nullified backtrace\n"); \ @@ -611,7 +700,7 @@ int sem_getvalue2(sem_t *semaphore, int pthread_mutex_unlock(&mutex); \ } while(0) #else -#define BACKTRACE(n) NOTICE("BACKTRACE only defined in glibc") +# define BACKTRACE(n) NOTICE("BACKTRACE only defined in glibc") #endif #ifdef __BACKTRACE @@ -647,50 +736,55 @@ void *debug_memoire_modification(void *p void debug_memoire_retrait(void *ptr); void debug_memoire_verification(); -pid_t debug_fork(); - -#define malloc(s) debug_memoire_ajout(s, __FUNCTION__, __LINE__, #s) #define free(s) debug_memoire_retrait(s) -#define realloc(s, t) debug_memoire_modification(s, t, \ - __FUNCTION__, __LINE__, #t) -#define fork() debug_fork() +#ifdef RPLCXX +# define malloc(s) debug_memoire_ajout(s, \ + const_cast \ + (reinterpret_cast \ + (const_cast(__FUNCTION__))), __LINE__, \ + const_cast \ + (reinterpret_cast \ + (const_cast(#s)))) +# define realloc(s, t) debug_memoire_modification(s, t, \ + const_cast \ + (reinterpret_cast \ + (const_cast(__FUNCTION__))), __LINE__, \ + const_cast \ + (reinterpret_cast \ + (const_cast(#t)))) +#else +# define malloc(s) debug_memoire_ajout(s, __FUNCTION__, __LINE__, \ + (const unsigned char *) #s) +# define realloc(s, t) debug_memoire_modification(s, t, \ + __FUNCTION__, __LINE__, (const unsigned char *) #t) +#endif +#define fork() debug_fork(s_etat_processus) #endif #ifdef DEBUG_RETURN -#define return uprintf("[%d] Return from <%s()> at line #%d " \ +# define return uprintf("[%d] Return from <%s()> at line #%d " \ "(%s [%d])\n", (int) getpid(), __FUNCTION__, \ __LINE__, strerror(errno), errno); fflush(stdout); errno = 0; return #endif #ifdef DEBUG_MUTEX -#define pthread_mutex_lock(mutex) uprintf("[%d-%llu] Mutex %s (%p) " \ +# define pthread_mutex_lock(mutex) uprintf("[%d-%llu] Mutex %s (%p) " \ "locking at %s() " \ "line #%d\n", (int) getpid(), (unsigned long long) pthread_self(), \ #mutex, mutex, __FUNCTION__, __LINE__), fflush(stdout), \ pthread_mutex_lock(mutex) -#define pthread_mutex_unlock(mutex) uprintf("[%d-%llu] Mutex %s (%p) " \ +# define pthread_mutex_unlock(mutex) uprintf("[%d-%llu] Mutex %s (%p) " \ "unlocking at " \ "%s() line #%d\n", (int) getpid(), (unsigned long long) \ pthread_self(), #mutex, mutex, __FUNCTION__, __LINE__), \ fflush(stdout), \ pthread_mutex_unlock(mutex) -#endif - -#ifdef DEBUG_SEMAPHORES -#define sem_wait(a) ({ int value; sem_getvalue(a, &value); \ - uprintf("[%d-%llu] Semaphore %s (%p) "\ - "waiting at %s() " \ - "line #%d\n", (int) getpid(), (unsigned long long) pthread_self(), \ - #a, a, __FUNCTION__, __LINE__), fflush(stdout); \ - if (value > 1) BUG(1, uprintf("Value %d\n", value)); sem_wait(a); }) -#define sem_post(a) ({ int value; sem_getvalue(a, &value); \ - uprintf("[%d-%llu] Semaphore %s (%p) "\ - "posting at %s() " \ - "line #%d\n", (int) getpid(), (unsigned long long) pthread_self(), \ - #a, a, __FUNCTION__, __LINE__), fflush(stdout); \ - if (value > 0) BUG(1, uprintf("Value %d\n", value)); sem_post(a); }) -#define sem_destroy(a) ({ int value; sem_getvalue(a, &value); \ - if (value == 0) BUG(1, uprintf("Value %d\n", value)); sem_destroy(a); }) +# define pthread_mutex_trylock(mutex) uprintf("[%d-%llu] Mutex %s (%p) " \ + "trylocking at " \ + "%s() line #%d\n", (int) getpid(), (unsigned long long) \ + pthread_self(), #mutex, mutex, __FUNCTION__, __LINE__), \ + fflush(stdout), \ + pthread_mutex_trylock(mutex) #endif @@ -741,6 +835,7 @@ pid_t debug_fork(); #define d_SPH "Semaphore $n 'name'" #define d_TAB "<[ table ]>" #define d_MTX "Mutex $n" +#define d_REC "|[ record ]|" /* -------------------------------------------------------------------------------- @@ -778,16 +873,48 @@ pid_t debug_fork(); # else # define __erreur_(i) i # endif -# define __erreur(i) ({ if (strstr(__FUNCTION__, "recherche_variable") \ - == NULL) ufprintf(stderr, \ - "ERROR %d AT %s() FROM %s LINE %d\n", \ - i, __FUNCTION__, __FILE__, __LINE__); i; }) +# define __erreur(i) ({ int ios; ios = errno; \ + if (strstr(__FUNCTION__, "recherche_variable") \ + == NULL) { if(ios != 0) \ + ufprintf(stderr, "LAST ERROR: %s\n", strerror(ios)); \ + ufprintf(stderr, "ERROR %d AT %s() FROM %s LINE %d\n", \ + i, __FUNCTION__, __FILE__, __LINE__); BACKTRACE(16); } i; }) # endif #else # define __erreur(i) i # define __erreur_(i) i #endif +#ifdef DEBUG_FICHIERS +# define open(a, ...) \ + ({ ufprintf(stderr, "[%d] OPEN %s AT %s() FROM %s LINE %d\n", \ + getpid(), a, \ + __FUNCTION__, __FILE__, __LINE__); open(a, __VA_ARGS__); }) +# define pipe(a) \ + ({ ufprintf(stderr, "[%d] PIPE %s AT %s() FROM %s LINE %d\n", \ + getpid(), a, \ + __FUNCTION__, __FILE__, __LINE__); pipe(a); }) +# define shm_open(a, ...) \ + ({ ufprintf(stderr, "[%d] SHM_OPEN %s AT %s() FROM %s LINE %d\n", \ + getpid(), a, \ + __FUNCTION__, __FILE__, __LINE__); shm_open(a, __VA_ARGS__); }) +# define shm_unlink(a) \ + ({ ufprintf(stderr, "[%d] SHM_UNLINK %s AT %s() FROM %s LINE %d\n", \ + getpid(), a, \ + __FUNCTION__, __FILE__, __LINE__); shm_unlink(a); }) +# define sem_open(a, ...) \ + ({ ufprintf(stderr, "[%d] SEM_OPEN %s AT %s() FROM %s LINE %d\n", \ + getpid(), a, \ + __FUNCTION__, __FILE__, __LINE__); sem_open(a, __VA_ARGS__); }) +# define sem_unlink(a) \ + ({ ufprintf(stderr, "[%d] SEM_UNLINK %s AT %s() FROM %s LINE %d\n", \ + getpid(), a, \ + __FUNCTION__, __FILE__, __LINE__); sem_unlink(a); }) +# define close(a) \ + ({ ufprintf(stderr, "[%d] CLOSE %s AT %s() FROM %s LINE %d\n", \ + getpid(), a, \ + __FUNCTION__, __FILE__, __LINE__); close(a); }) +#endif // -1 : erreur provoquée par une bibliothèque externe #ifndef RPLARGS @@ -807,6 +934,7 @@ pid_t debug_fork(); # define d_es_contexte __erreur(2013) # define d_es_somme_controle __erreur(2014) # define d_es_semaphore __erreur(2015) +# define d_es_mutex_acquis_autre_thread __erreur(2016) #endif /* @@ -945,6 +1073,17 @@ pid_t debug_fork(); # define d_ex_version_bibliotheque __erreur(82) # define d_ex_creation_variable_globale __erreur(83) # define d_ex_erreur_interne_rplcas __erreur(84) +# define d_ex_fichier_corrompu __erreur(85) +# define d_ex_mutex_acquis_autre_thread __erreur(86) +# define d_ex_expression_reguliere __erreur(87) +# define d_ex_instruction_indisponible __erreur(88) +# define d_ex_chiffrement __erreur(89) +# define d_ex_chiffrement_indisponible __erreur(90) +# define d_ex_longueur_clef_chiffrement __erreur(91) +# define d_ex_taille_message __erreur(92) +# define d_ex_type_externe_dup __erreur(93) +# define d_ex_type_externe_drop __erreur(94) +# define d_ex_simplification __erreur(95) #endif @@ -973,6 +1112,7 @@ pid_t debug_fork(); #define BIN __RPL_BIN #define CHN __RPL_CHN #define CPL __RPL_CPL +#define EXT __RPL_EXT #define FCH __RPL_FCH #define FCT __RPL_FCT #define INT __RPL_INT @@ -984,6 +1124,7 @@ pid_t debug_fork(); #define NOM __RPL_NOM #define NON __RPL_NON #define PRC __RPL_PRC +#define REC __RPL_REC #define REL __RPL_REL #define RPN __RPL_RPN #define SCK __RPL_SCK @@ -995,14 +1136,15 @@ pid_t debug_fork(); #define VIN __RPL_VIN #define VRL __RPL_VRL -enum t_rplcas_commandes { RPLCAS_INTEGRATION = 0, RPLCAS_LIMITE }; +enum t_rplcas_commandes { RPLCAS_INTEGRATION = 0, RPLCAS_LIMITE, + RPLCAS_SIMPLIFICATION }; -enum t_type { ADR = 0, ALG, BIN, CHN, CPL, FCH, FCT, INT, LST, - MCX, MIN, MRL, MTX, NOM, NON, PRC, REL, RPN, SCK, +enum t_type { ADR = 0, ALG, BIN, CHN, CPL, EXT, FCH, FCT, INT, LST, + MCX, MIN, MRL, MTX, NOM, NON, PRC, REC, REL, RPN, SCK, SLB, SPH, SQL, TBL, VCX, VIN, VRL }; /* - ADR : adresse sur 32 bits (au moins) non signés (unsigned long) + ADR : adresse sur 64 bits signés. Adresse d'une définition à interpréter. ALG : expression algébrique (struct_liste_chainee *) @@ -1014,13 +1156,15 @@ enum t_type { ADR = 0, ALG, BIN, CHN, C Sans objet. Type C/Fortran : unsigned integer8 - CHN : chaine de caracteres (character*(*), unsigned char *) + CHN : chaine de caracteres (unsigned char *) Sans objet. CPL : complexe sur 2*64 bits (complex*16, struct_complexe16 *) Sans objet. Type C/Fortran : complex16 + EXT : type géré dans une bibliothèque externe. + FCH : descripteur de fichier (struct_fichier *). FCT : déclaration d'une fonction et de son nombre d'arguments @@ -1055,6 +1199,8 @@ enum t_type { ADR = 0, ALG, BIN, CHN, C PRC : processus (struct_processus_fils *) Sans objet. + REC : enregistrement (struct_record *) + REL : reel sur 64 bits (real*8, real8 *) Sans objet. @@ -1086,6 +1232,8 @@ enum t_type { ADR = 0, ALG, BIN, CHN, C typedef struct objet { enum t_type type; + integer8 extension_type; + void *descripteur_bibliotheque; volatile long nombre_occurrences; @@ -1104,7 +1252,7 @@ typedef struct objet #ifndef RPLARGS typedef struct fichier { - unsigned long descripteur; + int descripteur; unsigned char acces; /* S/D/I */ unsigned char binaire; /* Y/N/F */ @@ -1132,6 +1280,7 @@ typedef struct fichier typedef struct rpl_mutex { pthread_mutex_t mutex; + pthread_t tid; } struct_mutex; #endif @@ -1196,7 +1345,7 @@ typedef struct bibliotheque #ifndef RPLARGS typedef struct descripteur_fichier { - unsigned long identifiant; + int identifiant; unsigned char effacement; unsigned char type; // C (file *) ou S (sqlite *) @@ -1205,8 +1354,11 @@ typedef struct descripteur_fichier pid_t pid; pthread_t tid; - file *descripteur_c; - sqlite3 *descripteur_sqlite; + union + { + file *descripteur_c; + sqlite3 *descripteur_sqlite; + }; } struct_descripteur_fichier; #endif @@ -1239,6 +1391,7 @@ typedef struct connecteur_sql # ifdef POSTGRESQL_SUPPORT PGconn *postgresql; # endif + sqlite3 *sqlite; } descripteur; } struct_connecteur_sql; #endif @@ -1252,6 +1405,10 @@ typedef struct connecteur_sql "POSTGRESQL") == 0) \ postgresqlclose((*((struct_connecteur_sql *) (*s_objet).objet)) \ .descripteur); \ + else if (strcmp((*((struct_connecteur_sql *) (*s_objet).objet)).type, \ + "SQLITE") == 0) \ + sqlite3_close((*((struct_connecteur_sql *) (*s_objet).objet)) \ + .descripteur.sqlite); \ else \ BUG(1, uprintf("SQL type '%s' not allowed!", \ (*((struct_connecteur_sql *) (*s_objet).objet)).type)); @@ -1263,6 +1420,20 @@ typedef struct connecteur_sql */ #ifndef RPLARGS + +# define d_BIND_TO_DEVICE 0 +# define d_BROADCAST 1 +# define d_DONT_ROUTE 2 +# define d_KEEP_ALIVE 3 +# define d_PRIORITY 4 +# define d_RECEIVE_BUFFER 5 +# define d_FORCE_RECEIVE_BUFFER 6 +# define d_SEND_BUFFER 7 +# define d_FORCE_SEND_BUFFER 8 +# define d_RECEIVING_TIMEOUT 9 +# define d_SENDING_TIMEOUT 10 +# define d_REUSE_ADDRESS 11 + typedef struct socket { int domaine; @@ -1281,6 +1452,13 @@ typedef struct socket unsigned char protection; unsigned char type[19 + 1]; + integer8 options; + int priorite; + int buffer_reception; + int buffer_emission; + int timeout_emission; + int timeout_reception; + struct_objet *format; } struct_socket; #endif @@ -1301,6 +1479,41 @@ typedef struct liste_chainee /* -------------------------------------------------------------------------------- + Structure de gestion des signaux en provenance de rplsignal +-------------------------------------------------------------------------------- +*/ + +#define d_NOMBRE_SIGNAUX 64 + +typedef struct gestion_signaux +{ + unsigned char masque_signaux[d_NOMBRE_SIGNAUX]; + + /* + * 'I' : signal ignoré + * 'Q' : signal mis en queue pour un traitement ultérieur + * 'N' : traitement normal du signal + */ + + integer8 queue_signaux[d_NOMBRE_SIGNAUX]; + integer8 nombre_signaux_en_queue; + struct_objet *corps_signaux[d_NOMBRE_SIGNAUX]; + + pthread_mutex_t mutex; +} struct_gestion_signaux; + +#ifndef MAIN_RPL +# define __STATIC_GESTION_SIGNAUX__ +#else +# define __STATIC_GESTION_SIGNAUX__ = { .mutex = PTHREAD_MUTEX_INITIALIZER } +#endif + +__EXTERN__ volatile struct_gestion_signaux signaux_externes + __STATIC_GESTION_SIGNAUX__; + + +/* +-------------------------------------------------------------------------------- Structure liste profilage -------------------------------------------------------------------------------- */ @@ -1392,8 +1605,10 @@ typedef struct descripteur_thread int pipe_injections[2]; int pipe_nombre_injections[2]; int pipe_interruptions[2]; - int pipe_nombre_objets_attente[2]; - int pipe_nombre_interruptions_attente[2]; + // pipe_nombre_elements_attente == 0 => initialisation ou terminaison + // pipe_nombre_elements_attente == 1 => objet en attente + // pipe_nombre_elements_attente == 2 => interruption en attente + int pipe_nombre_elements_attente[2]; int pipe_acquittement[2]; volatile integer8 nombre_objets_dans_pipe; @@ -1402,9 +1617,6 @@ typedef struct descripteur_thread logical1 processus_detache; logical1 destruction_objet; - sigset_t oldset; - sigset_t set; - volatile signed long nombre_references; } struct_descripteur_thread; @@ -1426,8 +1638,6 @@ typedef struct liste_pile_systeme { struct liste_pile_systeme *suivant; - struct_liste_chainee *pointeur_objet_retour; - struct_objet *indice_boucle; struct_objet *limite_indice_boucle; struct_objet *objet_de_test; @@ -1436,6 +1646,7 @@ typedef struct liste_pile_systeme logical1 creation_variables_statiques; logical1 creation_variables_partagees; logical1 evaluation_expression; + logical1 debug_programme; unsigned char clause; @@ -1465,23 +1676,25 @@ typedef struct liste_pile_systeme /* type clôture : - C SELECT : END termine un test SELECT/DEFAULT/END. - D DO : END termine une boucle DO/UNTIL/END. - I IF : END termine un test IF/THEN (ELSE)/END. - J IFERR : END termine un test IFERR/THEN (ELSE)/END. - K CASE : END termine un test CASE/THEN/END - W WHILE : END termine une boucle WHILE/REPEAT/END. + C SELECT : END termine un test SELECT/DEFAULT/END. + D DO : END termine une boucle DO/UNTIL/END. + I IF : END termine un test IF/THEN (ELSE)/END. + J IFERR : END termine un test IFERR/THEN (ELSE)/END. + K CASE : END termine un test CASE/THEN/END + W WHILE : END termine une boucle WHILE/REPEAT/END. + Q CRITICAL : END termine une section critique CRITICAL/END F FOR : NEXT ou STEP termine une boucle avec compteur. S START : NEXT ou STEP termine une boucle sans compteur. L LOOP : boucle utilisé dans le traitement de l'instruction RETURN. Elle correspond à une boucle FOR ou START mais sans son initialisation. + A FORALL : NEXT termine une boucle sur un objet. */ - unsigned long adresse_retour; - unsigned long niveau_courant; - struct_objet *pointeur_adresse_retour; + integer8 adresse_retour; + integer8 niveau_courant; + struct_liste_chainee *pointeur_objet_retour; } struct_liste_pile_systeme; #endif @@ -1495,16 +1708,16 @@ typedef struct liste_pile_systeme #ifndef RPLARGS typedef union position_variable { - unsigned long adresse; + integer8 adresse; struct_objet *pointeur; } union_position_variable; typedef struct variable { unsigned char *nom; - unsigned char origine; + unsigned char origine; // P(rogramme) ou E(valuation) - unsigned long niveau; + integer8 niveau; union_position_variable variable_statique; union_position_variable variable_partagee; @@ -1529,24 +1742,14 @@ typedef struct variable_partage unsigned char *nom; unsigned char origine; - unsigned long niveau; + integer8 niveau; union_position_variable variable_partagee; struct_objet *objet; -} struct_variable_partagee; - -typedef struct table_variables_partagees -{ - pthread_mutex_t mutex; - - volatile struct_variable_partagee *table; - - volatile unsigned long nombre_variables; - volatile unsigned long nombre_variables_allouees; - unsigned long position_variable; -} struct_table_variables_partagees; + pthread_mutex_t mutex; +} struct_variable_partagee; #endif @@ -1566,7 +1769,7 @@ typedef struct variable_statique // Position de création de la variable statique dans le programme ou dans // l'expression. 'origine' vaut 'P' pour programme ou 'E' pour expression. - unsigned long niveau; + integer8 niveau; union_position_variable variable_statique; @@ -1583,7 +1786,7 @@ typedef struct variable_statique typedef struct vecteur { - unsigned long taille; + integer8 taille; unsigned char type; /* C (complex*16), R (real*8), I (integer*8) */ @@ -1599,8 +1802,8 @@ typedef struct vecteur typedef struct matrice { - unsigned long nombre_lignes; - unsigned long nombre_colonnes; + integer8 nombre_lignes; + integer8 nombre_colonnes; unsigned char type; /* C (complex*16), R (real*8), I (integer*8) */ @@ -1616,7 +1819,7 @@ typedef struct matrice typedef struct tableau { - unsigned long nombre_elements; + integer8 nombre_elements; struct_objet **elements; } struct_tableau; @@ -1624,16 +1827,29 @@ typedef struct tableau /* -------------------------------------------------------------------------------- + Structure enregistrement +-------------------------------------------------------------------------------- +*/ + +typedef struct record +{ + struct_objet *noms; + struct_objet *donnees; +} struct_record; + + +/* +-------------------------------------------------------------------------------- Structure arbre -------------------------------------------------------------------------------- */ typedef struct arbre { - struct_objet *objet; + struct_liste_chainee *feuille; - unsigned long nombre_feuilles; - struct arbre **feuilles; + integer8 nombre_branches; + struct arbre **branches; } struct_arbre; @@ -1648,6 +1864,7 @@ typedef struct instruction_externe unsigned char *nom; unsigned char *nom_bibliotheque; void *descripteur_bibliotheque; + integer8 position_fleche; } struct_instruction_externe; @@ -1689,7 +1906,10 @@ typedef struct rpl_arguments unsigned char test_instruction; integer8 nombre_arguments; - // Nombre d'arguments de la fonction, positif ou nul. + // Nombre d'arguments de la fonction + // 0 : instruction infixe + // positif : nombre d'arguments (notation algébrique possible) + // -1 : notation algrébrique non autorisée void *s_etat_processus; } struct_rpl_arguments; @@ -1710,35 +1930,71 @@ typedef struct instruction /* -------------------------------------------------------------------------------- - Structure d'arbre des variables variable globales et locales + Structure d'arbre des variables globales et locales -------------------------------------------------------------------------------- */ #ifndef RPLARGS typedef struct arbre_variables { - unsigned int noeuds_utilises; - signed int indice_tableau_pere; - struct arbre_variables *noeud_pere; - struct arbre_variables **noeuds; - struct liste_variables *feuille; + unsigned int noeuds_utilises; + // Nombre de noeuds utilisés dans le + // tableau **noeuds + signed int indice_tableau_pere; + // Position de la structure dans le + // tableau **noeuds du père + + struct arbre_variables *noeud_pere; + struct arbre_variables **noeuds; + + struct liste_variables *feuille; + struct liste_variables_statiques *feuille_statique; } struct_arbre_variables; +typedef struct arbre_variables_partagees +{ + unsigned int noeuds_utilises; + // Nombre de noeuds utilisés dans le + // tableau **noeuds + signed int indice_tableau_pere; + // Position de la structure dans le + // tableau **noeuds du père + + struct arbre_variables_partagees *noeud_pere; + struct arbre_variables_partagees **noeuds; + + struct liste_variables_partagees *feuille; + + pthread_mutex_t mutex_feuille; +} struct_arbre_variables_partagees; + +#define INITIALISATION_MUTEX(mutex) \ + do { \ + pthread_mutexattr_t attributs_mutex; \ + pthread_mutexattr_init(&attributs_mutex); \ + pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE); \ + pthread_mutex_init(&(mutex), &attributs_mutex); \ + pthread_mutexattr_destroy(&attributs_mutex); \ + } while(0) + typedef struct tableau_variables { unsigned char origine; unsigned char *nom; // pointeur sur la struct_variable // réelle et non copie de la chaîne - unsigned long niveau; + integer8 niveau; struct_objet *objet; // pointeur sur l'objet et non copie // de l'objet. logical1 variable_verrouillee; + logical1 variable_masquee; + pthread_mutex_t *mutex; union_position_variable variable_statique; union_position_variable variable_partagee; } struct_tableau_variables; +// La liste des variables est une liste doublement chaînée et circulaire. typedef struct liste_variables { union @@ -1755,8 +2011,65 @@ typedef struct liste_variables struct liste_variables *precedent; } struct_liste_variables; +// La liste des variables statiques et une liste double chaînée et non +// circulaire. +typedef struct liste_variables_statiques +{ + struct liste_variables_statiques *suivant; + struct liste_variables_statiques *precedent; + struct liste_variables_statiques *reference; + struct_arbre_variables *feuille; + struct_variable_statique *variable; +} struct_liste_variables_statiques; + +typedef struct liste_variables_partagees +{ + struct liste_variables_partagees *suivant; + struct liste_variables_partagees *precedent; + struct liste_variables_partagees *reference; + struct_arbre_variables_partagees *feuille; + struct_variable_partagee *variable; + pthread_t tid; + pid_t pid; +} struct_liste_variables_partagees; #endif + +/* +-------------------------------------------------------------------------------- + Structure fonction +-------------------------------------------------------------------------------- +*/ + +#ifndef RPLARGS +typedef struct fonction +{ + unsigned char *nom_fonction; + integer8 nombre_arguments; + + void (*fonction)(struct processus *); + + volatile struct_liste_chainee *prediction_saut; + volatile logical1 prediction_execution; +} struct_fonction; +#endif + + +/* +-------------------------------------------------------------------------------- + Structure buffer +-------------------------------------------------------------------------------- +*/ + +typedef struct buffer +{ + unsigned char *buffer; + + size_t longueur_requise; + int classe; +} struct_buffer; + + /* -------------------------------------------------------------------------------- Structure processus @@ -1785,6 +2098,7 @@ typedef struct processus unsigned char evaluation_forcee; /*Y/N*/ unsigned char instruction_valide; /*Y/N*/ unsigned char instruction_intrinseque; /*Y/I/N*/ + unsigned char instruction_sensible; /*Y/N*/ unsigned char test_instruction; /*Y/N*/ unsigned char affichage_arguments; /*Y/N*/ unsigned char constante_symbolique; /*Y/N*/ @@ -1795,8 +2109,8 @@ typedef struct processus unsigned char traitement_cycle_exit; /*N/E/C*/ unsigned char recherche_type; /*Y/N*/ - unsigned long position_courante; - unsigned long longueur_definitions_chainees; + integer8 position_courante; + integer8 longueur_definitions_chainees; /* Pointeurs sur les instructions */ @@ -1813,13 +2127,13 @@ typedef struct processus struct_liste_chainee *l_base_pile; struct_liste_chainee *l_base_pile_last; - unsigned long hauteur_pile_operationnelle; + integer8 hauteur_pile_operationnelle; /* Piles systemes */ struct_liste_pile_systeme *l_base_pile_systeme; - unsigned long hauteur_pile_systeme; + integer8 hauteur_pile_systeme; /* Gestion des processus */ @@ -1833,8 +2147,7 @@ typedef struct processus int pipe_injections; int pipe_nombre_injections; int pipe_interruptions; - int pipe_nombre_objets_attente; - int pipe_nombre_interruptions_attente; + int pipe_nombre_elements_attente; int nombre_objets_envoyes_non_lus; int nombre_objets_injectes; @@ -1844,24 +2157,14 @@ typedef struct processus logical1 presence_fusible; pthread_t thread_fusible; pthread_t thread_surveille_par_fusible; + pthread_t thread_signaux; + int pipe_signaux[2]; -# if !defined(Cygwin) -# if !(OpenBSD) - stack_t pile_signal; -# else -# ifdef SA_ONSTACK -# undef SA_ONSTACK -# endif -# define SA_ONSTACK 0 -# endif -# else -# define SA_ONSTACK 0 -# define RTLD_LOCAL 0 -# endif - - int signal; - pid_t origine_signal; - logical1 signal_a_traiter; + volatile int pointeur_signal_ecriture; + volatile int pointeur_signal_lecture; + volatile enum signaux_rpl signaux_en_queue[LONGUEUR_QUEUE_SIGNAUX]; + volatile logical1 demarrage_fils; + volatile logical1 redemarrage_processus; /* Contextes */ @@ -1882,24 +2185,26 @@ typedef struct processus struct_arbre_variables *s_arbre_variables; struct_liste_variables *l_liste_variables_par_niveau; + struct_liste_variables_statiques + *l_liste_variables_statiques; + + struct_arbre_variables_partagees + **s_arbre_variables_partagees; + struct_liste_variables_partagees + **l_liste_variables_partagees; + logical1 niveau_supprime; struct_variable *pointeur_variable_courante; struct_liste_variables *pointeur_feuille_courante; + struct_variable_statique *pointeur_variable_statique_courante; + struct_variable_partagee *pointeur_variable_partagee_courante; int *pointeurs_caracteres_variables; int nombre_caracteres_variables; - struct_variable_statique *s_liste_variables_statiques; - unsigned long nombre_variables_statiques; - unsigned long nombre_variables_statiques_allouees; - - struct_table_variables_partagees - *s_liste_variables_partagees; - - unsigned long niveau_courant; - unsigned long niveau_initial; - unsigned long position_variable_statique_courante; + integer8 niveau_courant; + integer8 niveau_initial; logical1 creation_variables_statiques; logical1 creation_variables_partagees; @@ -1921,7 +2226,7 @@ typedef struct processus struct_liste_chainee *s_bibliotheques; struct_instruction_externe *s_instructions_externes; - unsigned long nombre_instructions_externes; + integer8 nombre_instructions_externes; /* Fichier d'impression */ @@ -2071,24 +2376,23 @@ typedef struct processus /* Traitement des exceptions */ logical1 arret_si_exception; - unsigned int exception; - unsigned int derniere_exception; - unsigned int exception_processus_fils; + int exception; + int derniere_exception; + int exception_processus_fils; /* Traitement des erreurs */ - unsigned int compteur_violation_d_acces; - unsigned int erreur_compilation; - unsigned int erreur_execution; - unsigned int erreur_systeme; + int erreur_compilation; + volatile int erreur_execution; + volatile int erreur_systeme; struct_objet *s_objet_errone; struct_objet *s_objet_erreur; logical1 erreur_scrutation; - volatile unsigned int erreur_systeme_processus_fils; - unsigned int erreur_execution_processus_fils; + volatile int erreur_systeme_processus_fils; + int erreur_execution_processus_fils; pid_t pid_erreur_processus_fils; @@ -2096,13 +2400,13 @@ typedef struct processus integer8 derniere_erreur_fonction_externe; - unsigned int derniere_erreur_systeme; - unsigned int derniere_erreur_execution; - unsigned int derniere_erreur_evaluation; + int derniere_erreur_systeme; + int derniere_erreur_execution; + int derniere_erreur_evaluation; unsigned char *instruction_derniere_erreur; - unsigned long niveau_derniere_erreur; + integer8 niveau_derniere_erreur; logical1 core; logical1 invalidation_message_erreur; @@ -2110,7 +2414,7 @@ typedef struct processus /* Debug */ logical1 debug; - integer8 type_debug; + logical8 type_debug; logical1 debug_programme; logical1 execution_pas_suivant; logical1 traitement_instruction_halt; @@ -2185,13 +2489,16 @@ typedef struct processus unsigned char retour_routine_evaluation; unsigned char *localisation; - unsigned long niveau_recursivite; + integer8 niveau_recursivite; pid_t pid_processus_pere; pthread_t tid_processus_pere; + pthread_t tid; logical1 processus_detache; + enum t_type type_en_cours; + /* Profilage */ logical1 profilage; @@ -2200,102 +2507,109 @@ typedef struct processus struct_liste_profilage2 *pile_profilage_fonctions; struct timeval horodatage_profilage; - // Mutex spécifique au processus et donnant accès à la pile des processus - pthread_mutex_t mutex; pthread_mutex_t mutex_allocation; + pthread_mutex_t mutex_allocation_buffer; + pthread_mutex_t mutex_interruptions; + pthread_mutex_t mutex_pile_processus; + pthread_mutex_t mutex_signaux; - // Sémaphore autorisant les fork() - sem_t -# ifdef SEMAPHORES_NOMMES - * -# endif - semaphore_fork; + // Mutex autorisant les fork() + sem_t __PTR__ semaphore_fork; /* Mutexes */ struct_liste_chainee *liste_mutexes; pthread_mutex_t protection_liste_mutexes; + unsigned int sections_critiques; + +/* Variable d'initialisation pour SCHED */ + + logical1 initialisation_scheduler; + +/* Drapeau nécessaire à RESTART */ + + volatile logical1 requete_redemarrage; /* Gestion optimisée de la mémoire */ double estimation_taille_pile_tampon; - unsigned long taille_pile_tampon; + integer8 taille_pile_tampon; struct_liste_chainee *pile_tampon; double estimation_taille_pile_systeme_tampon; - unsigned long taille_pile_systeme_tampon; + integer8 taille_pile_systeme_tampon; struct_liste_pile_systeme *pile_systeme_tampon; - unsigned long taille_pile_objets; + integer8 taille_pile_objets; struct_objet *pile_objets; -# define TAILLE_CACHE 16384 - - unsigned long *objets_adr[TAILLE_CACHE]; - int pointeur_adr; - - logical8 *objets_bin[TAILLE_CACHE]; - int pointeur_bin; - - complex16 *objets_cpl[TAILLE_CACHE]; - int pointeur_cpl; - - struct fonction *objets_fct[TAILLE_CACHE]; - int pointeur_fct; - - integer8 *objets_int[TAILLE_CACHE]; - int pointeur_int; - - struct_matrice *objets_mat[TAILLE_CACHE]; - int pointeur_mat; - - struct_nom *objets_nom[TAILLE_CACHE]; - int pointeur_nom; - - real8 *objets_rel[TAILLE_CACHE]; - int pointeur_rel; - - struct_tableau *objets_tab[TAILLE_CACHE]; - int pointeur_tab; - - struct_vecteur *objets_vec[TAILLE_CACHE]; - int pointeur_vec; - - struct_liste_chainee *maillons[TAILLE_CACHE]; - int pointeur_maillons; +# define TAILLE_CACHE 1024 +# define CACHE(type, nom) \ + type *objets_##nom[TAILLE_CACHE]; \ + volatile int pointeur_##nom; + +# define CACHE2(type, nom) \ + type *nom[TAILLE_CACHE]; \ + volatile int pointeur_##nom; + + CACHE(integer8, adr) + CACHE(logical8, bin) + CACHE(complex16, cpl) + CACHE(struct_fonction, fct) + CACHE(integer8, int) + CACHE(struct_matrice, mat) + CACHE(struct_nom, nom) + CACHE(struct_record, rec) + CACHE(real8, rel) + CACHE(struct_tableau, tab) + CACHE(struct_vecteur, vec) + + CACHE2(struct_liste_chainee, maillons) + CACHE2(struct_arbre_variables, variables_noeud) + CACHE2(struct_arbre_variables_partagees, variables_partagees_noeud) + CACHE2(struct_liste_variables, variables_feuille) + CACHE2(struct_variable, variables_variable) + CACHE2(struct_arbre_variables *, variables_tableau_noeuds) + CACHE2(struct_arbre_variables_partagees *, + variables_tableau_noeuds_partages) + + CACHE2(struct_buffer, enveloppes_buffers) + unsigned char ***cache_buffer; + int *pointeur_cache_buffer; +} struct_processus; +#endif - struct_arbre_variables *variables_noeud[TAILLE_CACHE]; - int pointeur_variables_noeud; +#ifdef DEBUG_MEMOIRE +pid_t debug_fork(struct_processus *s_etat_processus); +#endif - struct_liste_variables *variables_feuille[TAILLE_CACHE]; - int pointeur_variables_feuille; - struct_variable *variables_variable[TAILLE_CACHE]; - int pointeur_variables_variable; +/* +================================================================================ + MISE EN PLACE DE L'ALLOCATEUR SPÉCIFIQUE +================================================================================*/ - struct_arbre_variables **variables_tableau_noeuds[TAILLE_CACHE]; - int pointeur_variables_tableau_noeuds; -} struct_processus; +#ifndef DEBUG_MEMOIRE +# define malloc(a) rpl_malloc(s_etat_processus, a) +# define realloc(a, b) rpl_realloc(s_etat_processus, a, b) +# define free(a) rpl_free(s_etat_processus, a) #endif -/* --------------------------------------------------------------------------------- - Structure fonction --------------------------------------------------------------------------------- -*/ +void *rpl_malloc(struct_processus *s_etat_processus, size_t s); +void *rpl_realloc(struct_processus *s_etat_processus, void *ptr, size_t s); +void rpl_free(struct_processus *s_etat_processus, void *ptr); +void *sys_malloc(size_t s); +void *sys_realloc(void *ptr, size_t s); +void sys_free(void *ptr); -#ifndef RPLARGS -typedef struct fonction -{ - unsigned char *nom_fonction; - unsigned long nombre_arguments; +/* + * Wrapper de readline() pour que la fonction renvoie un pointeur sur un + * buffer alloué par rpl_malloc(). + */ - void (*fonction)(struct_processus *); - - volatile struct_liste_chainee *prediction_saut; - volatile logical1 prediction_execution; -} struct_fonction; -#endif +#define readline(s) readline_wrapper(s_etat_processus, s) +unsigned char *readline_wrapper(struct_processus *s_etat_processus, + unsigned char *s); /* @@ -2349,6 +2663,7 @@ void instruction_ceil(struct_processus * void instruction_centr(struct_processus *s_etat_processus); void instruction_cf(struct_processus *s_etat_processus); void instruction_chr(struct_processus *s_etat_processus); +void instruction_cipher(struct_processus *s_etat_processus); void instruction_clear(struct_processus *s_etat_processus); void instruction_cllcd(struct_processus *s_etat_processus); void instruction_clmf(struct_processus *s_etat_processus); @@ -2369,6 +2684,7 @@ void instruction_col_fleche(struct_proce void instruction_col_moins(struct_processus *s_etat_processus); void instruction_col_plus(struct_processus *s_etat_processus); void instruction_comb(struct_processus *s_etat_processus); +void instruction_compress(struct_processus *s_etat_processus); void instruction_con(struct_processus *s_etat_processus); void instruction_cond(struct_processus *s_etat_processus); void instruction_cont(struct_processus *s_etat_processus); @@ -2383,6 +2699,7 @@ void instruction_cosh(struct_processus * void instruction_cov(struct_processus *s_etat_processus); void instruction_cr(struct_processus *s_etat_processus); void instruction_create(struct_processus *s_etat_processus); +void instruction_critical(struct_processus *s_etat_processus); void instruction_crmtx(struct_processus *s_etat_processus); void instruction_cross(struct_processus *s_etat_processus); void instruction_crsmphr(struct_processus *s_etat_processus); @@ -2408,6 +2725,7 @@ void instruction_detach(struct_processus void instruction_dft(struct_processus *s_etat_processus); void instruction_dgtiz(struct_processus *s_etat_processus); void instruction_diag_fleche(struct_processus *s_etat_processus); +void instruction_digest(struct_processus *s_etat_processus); void instruction_disp(struct_processus *s_etat_processus); void instruction_division(struct_processus *s_etat_processus); void instruction_do(struct_processus *s_etat_processus); @@ -2434,6 +2752,7 @@ void instruction_elseif(struct_processus void instruction_end(struct_processus *s_etat_processus); void instruction_eng(struct_processus *s_etat_processus); void instruction_epsilon(struct_processus *s_etat_processus); +void instruction_eqv(struct_processus *s_etat_processus); void instruction_erase(struct_processus *s_etat_processus); void instruction_errm(struct_processus *s_etat_processus); void instruction_errn(struct_processus *s_etat_processus); @@ -2467,6 +2786,7 @@ void instruction_fleche_str(struct_proce void instruction_fleche_table(struct_processus *s_etat_processus); void instruction_floor(struct_processus *s_etat_processus); void instruction_for(struct_processus *s_etat_processus); +void instruction_forall(struct_processus *s_etat_processus); void instruction_format(struct_processus *s_etat_processus); void instruction_fp(struct_processus *s_etat_processus); void instruction_fs_test(struct_processus *s_etat_processus); @@ -2569,6 +2889,7 @@ void instruction_mtxtrylock(struct_proce void instruction_mtxunlock(struct_processus *s_etat_processus); void instruction_multiplication(struct_processus *s_etat_processus); +void instruction_nbrcpus(struct_processus *s_etat_prorcessus); void instruction_ne(struct_processus *s_etat_processus); void instruction_neg(struct_processus *s_etat_processus); void instruction_next(struct_processus *s_etat_processus); @@ -2603,6 +2924,7 @@ void instruction_pmax(struct_processus * void instruction_pmin(struct_processus *s_etat_processus); void instruction_poke(struct_processus *s_etat_processus); void instruction_polar(struct_processus *s_etat_processus); +void instruction_poll(struct_processus *s_etat_processus); void instruction_pos(struct_processus *s_etat_processus); void instruction_pourcent(struct_processus *s_etat_processus); void instruction_pourcent_ch(struct_processus *s_etat_processus); @@ -2657,11 +2979,14 @@ void instruction_rdz(struct_processus *s void instruction_re(struct_processus *s_etat_processus); void instruction_read(struct_processus *s_etat_processus); void instruction_recode(struct_processus *s_etat_processus); +void instruction_record(struct_processus *s_etat_processus); void instruction_recv(struct_processus *s_etat_processus); void instruction_redraw(struct_processus *s_etat_processus); +void instruction_regex(struct_processus *s_etat_processus); void instruction_relax(struct_processus *s_etat_processus); void instruction_remove(struct_processus *s_etat_processus); void instruction_res(struct_processus *s_etat_processus); +void instruction_restart(struct_processus *s_etat_processus); void instruction_recall(struct_processus *s_etat_processus); void instruction_regv(struct_processus *s_etat_processus); void instruction_repeat(struct_processus *s_etat_processus); @@ -2670,6 +2995,8 @@ void instruction_return(struct_processus void instruction_revlist(struct_processus *s_etat_processus); void instruction_rewind(struct_processus *s_etat_processus); void instruction_rfuse(struct_processus *s_etat_processus); +void instruction_rgdl(struct_processus *s_etat_processus); +void instruction_rgdr(struct_processus *s_etat_processus); void instruction_rl(struct_processus *s_etat_processus); void instruction_rlb(struct_processus *s_etat_processus); void instruction_rnd(struct_processus *s_etat_processus); @@ -2789,6 +3116,7 @@ void instruction_t_vers_l(struct_process void instruction_ucase(struct_processus *s_etat_processus); void instruction_uchol(struct_processus *s_etat_processus); +void instruction_uncompress(struct_processus *s_etat_processus); void instruction_unlock(struct_processus *s_etat_processus); void instruction_unprotect(struct_processus *s_etat_processus); void instruction_until(struct_processus *s_etat_processus); @@ -2839,8 +3167,7 @@ void instruction_yield(struct_processus #ifndef RPLARGS void affectation_interruptions_logicielles(struct_processus *s_etat_processus); void affichage_pile(struct_processus *s_etat_processus, - struct_liste_chainee *l_element_courant, unsigned long - niveau_courant); + struct_liste_chainee *l_element_courant, integer8 niveau_courant); #endif void *allocation_maillon(struct_processus *s_etat_processus); @@ -2854,14 +3181,18 @@ void appel_gnuplot(struct_processus *s_e void cf(struct_processus *s_etat_processus, unsigned char indice_drapeau); void cond(struct_processus *s_etat_processus, struct_matrice *s_matrice, real8 *condition); +void conversion_chaine(struct_processus *s_etat_processus, + unsigned char *chaine, unsigned char type); void conversion_decimal_vers_hms(real8 *angle); void conversion_degres_vers_radians(real8 *angle); -void conversion_element_tex(unsigned char **element, unsigned char *fonction); +void conversion_element_tex(struct_processus *s_etat_processus, + unsigned char **element, unsigned char *fonction); void conversion_format(struct_processus *s_etat_processus, unsigned char *chaine); void conversion_hms_vers_decimal(real8 *angle); -void conversion_majuscule_limitee(unsigned char *chaine_entree, - unsigned char *chaine_sortie, unsigned long longueur); +void conversion_majuscule_limitee( + unsigned char *chaine_entree, unsigned char *chaine_sortie, + integer8 longueur); void conversion_radians_vers_degres(real8 *angle); void copie_arbre_variables(struct_processus *s_etat_processus, struct_processus *s_nouvel_etat_processus); @@ -2874,11 +3205,11 @@ void determinant(struct_processus *s_eta void *valeur); void deverrouillage_threads_concurrents(struct_processus *s_etat_processus); void ecriture_pile(struct_processus *s_etat_processus, file *flux, - struct_liste_chainee *l_element_courant, unsigned long niveau_courant); + struct_liste_chainee *l_element_courant, integer8 niveau_courant); void ecriture_profil(struct_processus *s_etat_processus); void effacement_pile_systeme(struct_processus *s_etat_processus); void empilement_pile_systeme(struct_processus *s_etat_processus); -void encart(struct_processus *s_etat_processus, unsigned long duree); +void encart(struct_processus *s_etat_processus, integer8 duree); void evaluation_romberg(struct_processus *s_etat_processus, struct_objet *s_expression, unsigned char *variable, real8 *point, real8 *valeur, logical1 *validite); @@ -2899,7 +3230,7 @@ void formateur_elementaire_tex(struct_pr file *fichier, struct_objet *s_objet, unsigned char environnement); void impression_pile(struct_processus *s_etat_processus, struct_liste_chainee *l_element_courant, - unsigned char methode, unsigned long niveau_courant); + unsigned char methode, integer8 niveau_courant); void impression_tex(struct_processus *s_etat_processus); void informations(struct_processus *s_etat_processus); void initialisation_allocateur(struct_processus *s_etat_processus); @@ -2907,7 +3238,7 @@ void initialisation_completion(void); void initialisation_contexte_cas(struct_processus *s_etat_processus); void initialisation_drapeaux(struct_processus *s_etat_processus); void initialisation_generateur_aleatoire(struct_processus *s_etat_processus, - logical1 initialisation_automatique, unsigned long int racine); + logical1 initialisation_automatique, integer8 racine); void initialisation_instructions(struct_processus *s_etat_processus); void initialisation_variables(struct_processus *s_etat_processus); #endif @@ -2924,17 +3255,16 @@ void integrale_romberg(struct_processus real8 a, real8 b, real8 precision); void interface_cas(struct_processus *s_etat_processus, enum t_rplcas_commandes commande); -void interruption1(SIGHANDLER_ARGS); -void interruption2(SIGHANDLER_ARGS); -void interruption3(SIGHANDLER_ARGS); -void interruption4(SIGHANDLER_ARGS); -void interruption5(SIGHANDLER_ARGS); -void interruption6(SIGHANDLER_ARGS); -void interruption7(SIGHANDLER_ARGS); -void interruption8(SIGHANDLER_ARGS); -void interruption9(SIGHANDLER_ARGS); -void interruption10(SIGHANDLER_ARGS); -void interruption11(SIGHANDLER_ARGS); +void interruption1(int signal); +void interruption2(int signal); +void interruption3(int signal); +void interruption4(int signal); +void interruption5(int signal); +void interruption6(int signal); +#ifdef HAVE_SIGSEGV_RECOVERY + void interruption_depassement_pile(int urgence, + stackoverflow_context_t scp); +#endif void inversion_matrice(struct_processus *s_etat_processus, struct_matrice *s_matrice); void lancement_daemon(struct_processus *s_etat_processus); @@ -2951,8 +3281,12 @@ void liberation_arbre_instructions(struc struct_instruction *arbre); void liberation_arbre_variables(struct_processus *s_etat_processus, struct_arbre_variables *arbre, logical1 definitions); +void liberation_arbre_variables_partagees(struct_processus *s_etat_processus, + struct_arbre_variables_partagees *arbre); void liberation_contexte_cas(struct_processus *s_etat_processus); void liberation_generateur_aleatoire(struct_processus *s_etat_processus); +void liberation_mutexes_arbre_variables_partagees(struct_processus + *s_etat_processus, struct_arbre_variables_partagees *l_element_courant); void liberation_threads(struct_processus *s_etat_processus); void liberation_profil(struct_processus *s_etat_processus); void localisation_courante(struct_processus *s_etat_processus); @@ -2968,18 +3302,23 @@ void retrait_thread(struct_processus *s_ void retrait_thread_surveillance(struct_processus *s_etat_processus, struct_descripteur_thread *s_argument_thread); void rplcore(struct_processus *s_etat_processus); +#endif + void scrutation_injection(struct_processus *s_etat_processus); + +#ifndef RPLARGS void scrutation_interruptions(struct_processus *s_etat_processus); void sf(struct_processus *s_etat_processus, unsigned char indice_drapeau); void *surveillance_processus(void *argument); -void swap(void *variable_1, void *variable_2, unsigned long taille_octets); +void swap(void *variable_1, void *variable_2, integer8 taille_octets); +void *thread_signaux(void *argument); void trace(struct_processus *s_etat_processus, FILE *flux); void traitement_asynchrone_exceptions_gsl(struct_processus *s_etat_processus); void traitement_exceptions_gsl(const char *reason, const char *file, int line, int gsl_errno); void traitement_interruptions_logicielles(struct_processus *s_etat_processus); void tri_base_symboles_externes(struct_processus *s_etat_processus); -void tri_vecteur(real8 *vecteur, unsigned long taille); +void tri_vecteur(real8 *vecteur, integer8 taille); void valeurs_propres(struct_processus *s_etat_processus, struct_matrice *s_matrice, struct_vecteur *s_valeurs_propres, @@ -2997,12 +3336,22 @@ void valeurs_singulieres(struct_processu void verrouillage_threads_concurrents(struct_processus *s_etat_processus); #endif +/* +-------------------------------------------------------------------------------- + Fonctions de gestion des signaux +-------------------------------------------------------------------------------- +*/ + #ifndef RPLARGS -#ifdef _BROKEN_SIGINFO -void creation_fifos_signaux(struct_processus *s_etat_processus); -void destruction_fifos_signaux(struct_processus *s_etat_processus); -void liberation_fifos_signaux(struct_processus *s_etat_processus); -#endif +void creation_queue_signaux(struct_processus *s_etat_processus); +void liberation_queue_signaux(struct_processus *s_etat_processus); +void destruction_queue_signaux(struct_processus *s_etat_processus); +int envoi_signal_contexte(struct_processus *s_etat_processus, + enum signaux_rpl signal); +int envoi_signal_processus(pid_t pid, enum signaux_rpl signal, + logical1 test_ouverture); +int envoi_signal_thread(struct_processus *s_etat_processus, + pthread_t tid, enum signaux_rpl signal); #endif /* @@ -3011,9 +3360,9 @@ void liberation_fifos_signaux(struct_pro -------------------------------------------------------------------------------- */ -real8 sommation_vecteur_reel(real8 *vecteur, unsigned long *taille, +real8 sommation_vecteur_reel(real8 *vecteur, integer8 *taille, logical1 *erreur_memoire); -complex16 sommation_vecteur_complexe(complex16 *vecteur, unsigned long *taille, +complex16 sommation_vecteur_complexe(complex16 *vecteur, integer8 *taille, logical1 *erreur_memoire); /* @@ -3023,7 +3372,8 @@ complex16 sommation_vecteur_complexe(com */ #ifndef RPLARGS -int rplinit(int argc, char *argv[], unsigned char ***resultats, char *rpl_home); +int rplinit(int argc, char *argv[], char *envp[], + unsigned char ***resultats, char *rpl_home); #endif /* @@ -3034,20 +3384,24 @@ int rplinit(int argc, char *argv[], unsi #ifndef RPLARGS real8 correlation_statistique(struct_matrice *s_matrice, - unsigned long colonne_1, unsigned long colonne_2, logical1 *erreur); + integer8 colonne_1, integer8 colonne_2, logical1 *erreur); real8 covariance_statistique(struct_matrice *s_matrice, - unsigned long colonne_1, unsigned long colonne_2, + integer8 colonne_1, integer8 colonne_2, unsigned char type, logical1 *erreur); -struct_vecteur *ecart_type_statistique(struct_matrice *s_matrice, - unsigned char type); -struct_vecteur *moyenne_statistique(struct_matrice *s_matrice); -struct_vecteur *sommation_colonne_statistique(struct_matrice *s_matrice, - unsigned long colonne); -struct_vecteur *sommation_produits_colonnes_statistiques(struct_matrice - *s_matrice, unsigned long colonne_1, unsigned long colonne_2); -struct_vecteur *sommation_statistique(struct_matrice *s_matrice); -struct_vecteur *variance_statistique(struct_matrice *s_matrice, - unsigned char type); +struct_vecteur *ecart_type_statistique(struct_processus *s_etat_processus, + struct_matrice *s_matrice, unsigned char type); +struct_vecteur *moyenne_statistique(struct_processus *s_etat_processus, + struct_matrice *s_matrice); +struct_vecteur *sommation_colonne_statistique( + struct_processus *s_etat_processus, struct_matrice *s_matrice, + integer8 colonne); +struct_vecteur *sommation_produits_colonnes_statistiques( + struct_processus *s_etat_processus, struct_matrice + *s_matrice, integer8 colonne_1, integer8 colonne_2); +struct_vecteur *sommation_statistique(struct_processus *s_etat_processus, + struct_matrice *s_matrice); +struct_vecteur *variance_statistique(struct_processus *s_etat_processus, + struct_matrice *s_matrice, unsigned char type); #endif /* @@ -3070,7 +3424,7 @@ struct_liste_chainee *depilement_pile_op struct_liste_chainee *empilement_pile_operationnelle(struct_rpl_arguments *s_rpl_arguments, struct_objet *s_objet); struct_liste_chainee *sauvegarde_arguments(struct_rpl_arguments - *s_rpl_arguments, unsigned long nombre_arguments); + *s_rpl_arguments, integer8 nombre_arguments); /* -------------------------------------------------------------------------------- @@ -3081,34 +3435,56 @@ struct_liste_chainee *sauvegarde_argumen #ifndef RPLARGS unsigned char *analyse_algebrique(struct_processus *s_etat_processus, unsigned char *chaine_algebrique, struct_liste_chainee **l_base_liste); -unsigned char *recherche_chemin_fichiers_temporaires(struct_processus - *s_etat_processus); -unsigned char *compactage(unsigned char *chaine); -unsigned char *conversion_majuscule(unsigned char *chaine); +#endif +unsigned char *analyse_flux(struct_processus *s_etat_processus, + unsigned char *flux, integer8 longueur); +#ifndef RPLARGS +unsigned char *chiffrement(struct_processus *s_etat_processus, + const EVP_CIPHER *type_chiffrement, + logical1 encodage, unsigned char *message, integer8 longueur_message, + unsigned char *clef, integer8 longueur_clef, + unsigned char *vecteur_initialisation, + integer8 *longueur_message_chiffre); +unsigned char *compactage(struct_processus *s_etat_processus, + unsigned char *chaine); +unsigned char *conversion_majuscule(struct_processus *s_etat_processus, + unsigned char *chaine); unsigned char *creation_nom_fichier(struct_processus *s_etat_processus, unsigned char *chemin); -unsigned char *extraction_chaine(unsigned char *chaine, unsigned long i, - unsigned long j); +unsigned char *date_compilation(struct_processus *s_etat_processus); +unsigned char *extraction_chaine(struct_processus *s_etat_processus, + unsigned char *chaine, integer8 i, integer8 j); unsigned char *formateur(struct_processus *s_etat_processus, long offset, struct_objet *s_objet); unsigned char *formateur_fichier(struct_processus *s_etat_processus, struct_objet *s_objet, struct_objet *s_format, - long longueur, long longueur_champ, unsigned char format, - unsigned char type, long *longueur_effective, long *recursivite); + integer8 longueur, integer8 longueur_champ, unsigned char format, + unsigned char type, integer8 *longueur_effective, integer8 *recursivite, + logical1 export_fichier); +#endif unsigned char *formateur_flux(struct_processus *s_etat_processus, - unsigned char *donnees, long *longueur); + unsigned char *donnees, integer8 *longueur); +#ifndef RPLARGS unsigned char *formateur_fichier_nombre(struct_processus *s_etat_processus, void *valeur_numerique, unsigned char type, - long longueur, long longueur_champ, unsigned char format); + integer8 longueur, integer8 longueur_champ, unsigned char format); +unsigned char *formateur_fichier_binaire_nombre(struct_processus + *s_etat_processus, void *valeur_numerique, unsigned char type_entree, + unsigned char type, integer8 longueur, integer8 *longueur_conversion); unsigned char *formateur_fichier_reel(struct_processus *s_etat_processus, void *valeur_numerique, unsigned char type, - long longueur, long longueur_champ, unsigned char format); + integer8 longueur, integer8 longueur_champ, unsigned char format); unsigned char *formateur_nombre(struct_processus *s_etat_processus, void *valeur_numerique, unsigned char type); unsigned char *formateur_reel(struct_processus *s_etat_processus, void *valeur_numerique, unsigned char type); unsigned char *messages(struct_processus *s_etat_processus); -unsigned char *purification_chaine(unsigned char *chaine); +unsigned char *pointeur_ieme_caractere(struct_processus *s_etat_processus, + unsigned char *chaine, integer8 position); +unsigned char *purification_chaine(struct_processus *s_etat_processus, + unsigned char *chaine); +unsigned char *recherche_chemin_fichiers_temporaires(struct_processus + *s_etat_processus); unsigned char *reencodage(struct_processus *s_etat_processus, unsigned char *chaine_entree, unsigned char *codage_entree, unsigned char *codage_sortie); @@ -3125,11 +3501,14 @@ unsigned char *transliteration(struct_pr #ifndef RPLARGS logical1 analyse_syntaxique(struct_processus *s_etat_processus); +logical1 arret_thread_signaux(struct_processus *s_etat_processus); logical1 caracteristiques_fichier(struct_processus *s_etat_processus, unsigned char *nom, logical1 *existence, logical1 *ouverture, unsigned long *unite); logical1 controle(struct_processus *s_etat_processus, unsigned char *fichier, unsigned char *type, unsigned char *somme_candidate); +logical1 controle_integrite(struct_processus *s_etat_processus, + unsigned char *executable_candidat, unsigned char *executable); logical1 creation_variable(struct_processus *s_etat_processus, struct_variable *s_variable, unsigned char autorisation_creation_variable_statique, @@ -3146,23 +3525,31 @@ logical1 destruction_fichier(unsigned ch logical1 empilement(struct_processus *s_etat_processus, struct_liste_chainee **l_base_liste, struct_objet *s_objet); logical1 empilement_pile_last(struct_processus *s_etat_processus, - unsigned long nombre_arguments); + integer8 nombre_arguments); logical1 evaluation(struct_processus *s_etat_processus, struct_objet *s_objet, unsigned char type_evaluation); logical1 initialisation_fichier_acces_direct(struct_processus *s_etat_processus, sqlite3 *sqlite, logical1 binaire); logical1 initialisation_fichier_acces_indexe(struct_processus *s_etat_processus, sqlite3 *sqlite, integer8 position_clef, logical1 binaire); +logical1 lancement_thread_signaux(struct_processus *s_etat_processus); logical1 recherche_instruction_suivante(struct_processus *s_etat_processus); +logical1 recherche_instruction_suivante_recursive( + struct_processus *s_etat_processus, integer8 recursivite); logical1 retrait_variable(struct_processus *s_etat_processus, unsigned char *nom_variable, unsigned char type); -logical1 retrait_variable_par_niveau(struct_processus *s_etat_processus); +logical1 retrait_variables_par_niveau(struct_processus *s_etat_processus); logical1 retrait_variable_partagee(struct_processus *s_etat_processus, unsigned char *nom_variable, union_position_variable position); +logical1 retrait_variables_partagees_locales( + struct_processus *s_etat_processus); logical1 retrait_variable_statique(struct_processus *s_etat_processus, unsigned char *nom_variable, union_position_variable position); +logical1 retrait_variables_statiques_locales( + struct_processus *s_etat_processus); logical1 sequenceur(struct_processus *s_etat_processus); -logical1 sequenceur_optimise(struct_processus *s_etat_processus); +logical1 sequenceur_optimise(struct_processus *s_etat_processus, + struct_liste_chainee *l_bibliotheques); #endif /* @@ -3174,6 +3561,7 @@ logical1 sequenceur_optimise(struct_proc logical1 depassement_addition(integer8 *a, integer8 *b, integer8 *resultat); logical1 depassement_multiplication(integer8 *a, integer8 *b, integer8 *resultat); +logical1 depassement_soustraction(integer8 *a, integer8 *b, integer8 *resultat); logical1 depassement_puissance(integer8 *a, integer8 *b, integer8 *resultat); #ifndef RPLARGS @@ -3183,16 +3571,11 @@ logical1 recherche_variable(struct_proce unsigned char *nom_variable); logical1 recherche_variable_globale(struct_processus *s_etat_processus, unsigned char *nom_variable); -logical1 recherche_variable_partagee(struct_processus *s_etat_processus, - unsigned char *nom_variable, union_position_variable position, - unsigned char origine); -logical1 recherche_variable_statique(struct_processus *s_etat_processus, - unsigned char *nom_variable, union_position_variable position, - unsigned char origine); logical1 test_cfsf(struct_processus *s_etat_processus, unsigned char indice_drapeau); logical1 test_expression_rpn(unsigned char *chaine); logical1 test_fonction(unsigned char *chaine); +logical1 validation_chaine(unsigned char *chaine); #endif /* @@ -3204,6 +3587,8 @@ logical1 test_fonction(unsigned char *ch #ifndef RPLARGS ssize_t read_atomic(struct_processus *s_etat_processus, int fd, void *buf, size_t count); +ssize_t read_atomic_signal(struct_processus *s_etat_processus, + int fd, void *buf, size_t count); ssize_t write_atomic(struct_processus *s_etat_processus, int fd, void *buf, size_t count); #endif @@ -3214,17 +3599,28 @@ ssize_t write_atomic(struct_processus *s -------------------------------------------------------------------------------- */ -int alsprintf(unsigned char **strp, const char *fmt, ...); -int liste_variables(struct_processus *s_etat_processus, - struct_tableau_variables *tableau, int position, - struct_arbre_variables *l_element_courant); -int nombre_variables(struct_processus *s_etat_processus, - struct_arbre_variables *l_element_courant); +int alsprintf(struct_processus *s_etat_processus, + unsigned char **strp, const char *fmt, ...); +#ifndef RPLARGS +int association_etat_processus_readline(); +#endif +int interruption_violation_access(void *adresse_fautive, int gravite); +#ifndef RPLARGS +int initialisation_etat_processus_readline(); +int liberation_etat_processus_readline(); +integer8 liste_variables(struct_processus *s_etat_processus, + struct_tableau_variables *tableau); +integer8 nombre_variables(struct_processus *s_etat_processus); +int readline_analyse_syntaxique(int count, int key); +int readline_effacement(int count, int key); +#endif +int std_fprintf(file *flux, const char *format, ...); int tex_fprintf(struct_processus *s_etat_processus, file *flux, const char *format, ...); int transliterated_fprintf(struct_processus *s_etat_processus, file *flux, const char *format, ...); -int valsprintf(unsigned char **strp, const char *fmt, va_list ap); +int valsprintf(struct_processus *s_etat_processus, + unsigned char **strp, const char *fmt, va_list ap); int wrapper_instruction_intrinseque(void (*fonction)(), struct_rpl_arguments *rpl_arguments); @@ -3236,7 +3632,6 @@ int wrapper_instruction_intrinseque(void #ifndef RPLARGS unsigned char longueur_entiers_binaires(struct_processus *s_etat_processus); -unsigned char recherche_longueur_optimale(integer8 parametre); #endif /* @@ -3257,6 +3652,10 @@ logical8 masque_entiers_binaires(struct_ #ifndef RPLARGS integer8 occupation_memoire(struct_objet *s_objet); +integer8 longueur_chaine(struct_processus *s_etat_processus, + unsigned char *chaine); +integer8 position_caractere_de_chaine(struct_processus *s_etat_processus, + unsigned char *chaine, unsigned char *position); #endif /* @@ -3272,6 +3671,19 @@ struct_liste_chainee *analyse_rpn(struct /* -------------------------------------------------------------------------------- + Allocateur de buffers à cache +-------------------------------------------------------------------------------- +*/ + +void initialisation_allocateur_buffer(struct_processus *s_etat_processus); +void liberation_allocateur_buffer(struct_processus *s_etat_pocessus); +struct_buffer *allocation_buffer(struct_processus *s_etat_processus, + size_t longueur); +void liberation_buffer(struct_processus *s_etat_processus, + struct_buffer *buffer); + +/* +-------------------------------------------------------------------------------- Fonctions renvoyant une copie de la structure de description des processus -------------------------------------------------------------------------------- */ @@ -3301,32 +3713,35 @@ struct_descripteur_fichier *descripteur_ struct_objet *copie_objet(struct_processus *s_etat_processus, struct_objet *s_objet, unsigned char type); -#ifndef RPLARGS struct_objet *allocation(struct_processus *s_etat_processus, enum t_type type); +#ifndef RPLARGS struct_objet *formateur_date(struct_processus *s_etat_processus, struct timeval *temps); +struct_objet *lecture_fichier_non_formate(struct_processus *s_etat_processus, + void *argument, integer8 longueur_buffer, logical1 recursivite); struct_objet *lecture_pipe(struct_processus *s_etat_processus, int pipe); struct_objet *parametres_sql(struct_processus *s_etat_processus, struct_objet *s_parametres); struct_objet *simplification(struct_processus *s_etat_processus, struct_objet *s_objet); -#endif + +struct_arbre_variables *allocation_noeud(struct_processus *s_etat_processus); +struct_arbre_variables **allocation_tableau_noeuds( + struct_processus *s_etat_processus); /* -------------------------------------------------------------------------------- - Fonctions gérant les arbres de simplification + Fonctions renvoyant un pointeur sur une *struct_liste_variables_statiques + ou *struct_liste_variables_partagees -------------------------------------------------------------------------------- */ -#ifndef RPLARGS -struct_arbre *creation_arbre(struct_processus *s_etat_processus, - struct_objet **t_objets, unsigned long indice, - unsigned long indice_maximal); -void liberation_arbre(struct_processus *s_etat_processus, - struct_arbre *s_noeud); -void parcours_arbre(struct_processus *s_etat_processus, struct_arbre *s_noeud); -void simplification_arbre(struct_processus *s_etat_processus, - struct_arbre *s_noeud); +struct_liste_variables_statiques *recherche_variable_statique(struct_processus + *s_etat_processus, unsigned char *nom_variable, + union_position_variable position, unsigned char origine); +struct_liste_variables_partagees *recherche_variable_partagee(struct_processus + *s_etat_processus, unsigned char *nom_variable, + union_position_variable position, unsigned char origine); #endif /* @@ -3364,15 +3779,13 @@ void f77multiplicationci_(complex16 *ca, void f77multiplicationcr_(complex16 *ca, real8 *rb, complex16 *resultat); void f77puissancecc_(complex16 *ca, complex16 *cb, complex16 *resultat); -void f77puissanceci_(complex16 *ca, integer8 *ib, complex16 *resultat, - integer4 *troncature); +void f77puissanceci_(complex16 *ca, integer8 *ib, complex16 *resultat); void f77puissancecr_(complex16 *ca, real8 *rb, complex16 *resultat); void f77puissanceic_(integer8 *ia, complex16 *cb, complex16 *resultat); void f77puissanceii_(integer8 *ia, integer8 *ib, integer8 *resultat); void f77puissanceir_(integer8 *ia, real8 *rb, real8 *resultat); void f77puissancerc_(real8 *ra, complex16 *cb, complex16 *resultat); -void f77puissanceri_(real8 *ra, integer8 *ib, real8 *resultat, - integer4 *troncature); +void f77puissanceri_(real8 *ra, integer8 *ib, real8 *resultat); void f77puissancerr_(real8 *ra, real8 *rb, real8 *resultat); void f77racinecarreec_(complex16 *ca, complex16 *resultat);