/* ================================================================================ RPL/2 (R) version 4.1.17 Copyright (C) 1989-2014 Dr. BERTRAND Joël This file is part of RPL/2. RPL/2 is free software; you can redistribute it and/or modify it under the terms of the CeCILL V2 License as published by the french CEA, CNRS and INRIA. RPL/2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License for more details. You should have received a copy of the CeCILL License along with RPL/2. If not, write to info@cecill.info. ================================================================================ */ #ifndef INCLUSION_RPLARGS # define INCLUSION_RPLARGS /* ================================================================================ INCLUSIONS ================================================================================ */ # define RPLARGS # define struct_processus void # include "rpl.h" /* ================================================================================ MACROS SPECIFIQUES ================================================================================ */ #define __RPL__ struct_rpl_arguments *rpl_arguments; \ rpl_arguments = &__static_rpl_arguments; #define __CATCH_SYSTEM_ERROR__ \ do { if (((*rpl_arguments).erreur != 0) && \ ((*rpl_arguments).type_erreur == 'S')) \ return 0; } while(0) #define leave do { return(0); } while(0) #define allocation(a) librpl_allocation((*rpl_arguments).s_etat_processus, a) #define copie_objet(a, b) librpl_copie_objet( \ (*rpl_arguments).s_etat_processus, a, b) #define liberation(a) librpl_liberation((*rpl_arguments).s_etat_processus, a) #ifdef __RPLC_MAIN struct_rpl_arguments __static_rpl_arguments; # define global # define initialize(a, b) a = b # define declarePersistantObject(object) declareObject(object) #else extern struct_rpl_arguments __static_rpl_arguments; # define global extern # define initialize(a, b) a; # define declarePersistantObject(object) extern struct_objet *object; #endif #define empty int /* -------------------------------------------------------------------------------- Types -------------------------------------------------------------------------------- */ #define declareObject(object) struct_objet *object = NULL #define declareInteger(integer) integer8 integer #define declareReal(real) real8 real #define declareComplex(complex) complex16 complex #define declareDaisyChain(daisyChain) struct_liste_chainee *daisyChain = NULL #define getDaisyChainFromList(list, daisyChain) \ __CATCH_SYSTEM_ERROR__; \ do { \ typeof(list) __list = list; \ daisyChain = NULL; \ ifIsList(__list) { daisyChain = (*__list).objet; } \ else executionError("Type mistmatch error"); } while(0) #define fetchElementFromDaisyChain(daisyChain) \ ({ __CATCH_SYSTEM_ERROR__; typeof(daisyChain) __daisyChain = daisyChain; \ if (__daisyChain == NULL) executionError("End of daisy chain"); \ (__daisyChain == NULL) ? NULL : (*__daisyChain).donnee; }) #define replaceElementIntoDaisyChain(daisyChain, element) \ __CATCH_SYSTEM_ERROR__; \ do { typeof(daisyChain) __daisyChain = daisyChain; \ if (__daisyChain == NULL) executionError("Nullified daisy chain"); \ freeObject((*__daisyChain).donnee); \ (*__daisyChain).donnee = element; } while(0) #define nextElementOfDaisyChain(daisyChain) \ ({ __CATCH_SYSTEM_ERROR__; typeof(daisyChain) __daisyChain = daisyChain; \ if (__daisyChain == NULL) executionError("End of daisy chain"); \ (__daisyChain == NULL) ? NULL : (*__daisyChain).suivant; }) #define null NULL #define nullify(ptr) __CATCH_SYSTEM_ERROR__; do { ptr = NULL; } while(0) #define nullified(ptr) ((ptr) == NULL) #define postIncr(x) (x++) #define preIncr(x) (++x) #define postDecr(x) (x--) #define preDecr(x) (--x) #define eq == #define ne != #define ge >= #define gt > #define le <= #define lt < #define not ! #define and && #define or || #define false 0 #define true -1 #define setFalse(a) a = false #define setTrue(a) a = true #define logical int #define string char * #define integer int #define object struct_objet * #define declareStructure typedef struct { #define declareUnion typedef union { #define as(name) } name; #define target(a) (*a) #define address(a) (&a) #define beginGroup { __CATCH_SYSTEM_ERROR__; #define endGroup __CATCH_SYSTEM_ERROR__; } #define beginMacro do beginGroup #define endMacro endGroup while(0) #define stopRequest __CATCH_SYSTEM_ERROR__; \ test_arret((*rpl_arguments).s_etat_processus) /* -------------------------------------------------------------------------------- Signaux --------------------------------------------------------------------------------*/ #define blockSignals \ { __CATCH_SYSTEM_ERROR__; sigset_t set, oldset; sigfillset(&set); \ pthread_sigmask(SIG_BLOCK, &set, &oldset); #define unblockSignals \ pthread_sigmask(SIG_SETMASK, &oldset, NULL); __CATCH_SYSTEM_ERROR__; } /* -------------------------------------------------------------------------------- Constructeurs -------------------------------------------------------------------------------- */ #define DISABLE_SET_BUT_NOT_USED_WARNING(a) if (&a != ((&a) + 1)); #define HEADER \ int __constante; \ logical1 __evaluation; \ logical1 __validation_instruction = d_faux; \ logical1 __presence_aide = d_faux; \ logical1 __presence_validation = d_faux; \ unsigned char __indice_bit; \ unsigned char __indice_bloc; \ unsigned char __taille_bloc; \ unsigned char __type; \ t_8_bits __masque; \ { \ (*rpl_arguments).instruction_valide = 'Y'; \ (*rpl_arguments).erreur = 0; \ __constante = 0; \ __evaluation = d_faux; \ DISABLE_SET_BUT_NOT_USED_WARNING(__evaluation); \ DISABLE_SET_BUT_NOT_USED_WARNING(__type); \ DISABLE_SET_BUT_NOT_USED_WARNING(__indice_bit); \ DISABLE_SET_BUT_NOT_USED_WARNING(__indice_bloc); \ DISABLE_SET_BUT_NOT_USED_WARNING(__taille_bloc); \ DISABLE_SET_BUT_NOT_USED_WARNING(__masque); #define FUNCTION \ if (__validation_instruction == d_vrai) return 0; \ if (__presence_aide == d_faux) \ { \ systemError("Help string not defined"); \ } \ else if (__presence_validation == d_faux) \ { \ systemError("Number of arguments not defined"); \ } \ __indice_bit = 0; \ __indice_bloc = 0; \ __taille_bloc = 0; \ __type = 0; \ __masque = 0; \ { #define END \ strcpy((char *) __function_name, ""); \ if (__constante != 0) \ systemError("Constant definition error"); \ __CATCH_SYSTEM_ERROR__; \ } } \ leave; /* -------------------------------------------------------------------------------- Destruction d'un objet -------------------------------------------------------------------------------- */ #define freeObject(object) \ __CATCH_SYSTEM_ERROR__; \ do { \ if (object == NULL) \ systemError("Nullified object"); \ liberation(object); \ object = NULL; \ } while(0) /* -------------------------------------------------------------------------------- Copie d'un objet -------------------------------------------------------------------------------- */ #define dupObject(object) \ __CATCH_SYSTEM_ERROR__; \ do { if (copie_objet(object, 'P') != object) \ systemError("Memory allocation error"); } while(0) /* -------------------------------------------------------------------------------- Déclaration des fonctions internes -------------------------------------------------------------------------------- */ #define CONCAT(a, b) __CONCAT(a, b) #define __CONCAT(a, b) a##b #define FIRST(...) FIRST_HELPER(__VA_ARGS__, throwaway) #define FIRST_HELPER(first, ...) first #define REST(...) REST_HELPER(NUM(__VA_ARGS__), __VA_ARGS__) #define REST_HELPER(qty, ...) REST_HELPER2(qty, __VA_ARGS__) #define REST_HELPER2(qty, ...) REST_HELPER_##qty(__VA_ARGS__) #define REST_HELPER_ONE(first) #define REST_HELPER_TWOORMORE(first, ...) , __VA_ARGS__ #define NUM(...) \ SELECT_10TH(__VA_ARGS__, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\ TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway) #define SELECT_10TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, ...) a10 #define declareInternalFunction(type, ...) \ type CONCAT(__internal_, FIRST(__VA_ARGS__)) \ (struct_rpl_arguments *rpl_arguments REST(__VA_ARGS__)) { \ type __internal_return; __internal_return = 0; int __type; \ DISABLE_SET_BUT_NOT_USED_WARNING(__type); #define endInternalFunction return(__internal_return); } #define useInternalFunction(type, ...) \ type CONCAT(__internal_, FIRST(__VA_ARGS__)) \ (struct_rpl_arguments *rpl_arguments REST(__VA_ARGS__)) #define callInternalFunction(...) \ CONCAT(__internal_, FIRST(__VA_ARGS__))(rpl_arguments REST(__VA_ARGS__)) /* -------------------------------------------------------------------------------- Déclaration des fonctions C -------------------------------------------------------------------------------- */ #define declareCFunction(type, name, ...) \ type name(__VA_ARGS__) { __RPL__ type __c_return; #define endCFunction return(__c_return); } #define useCFunction(type, name, ...) type name(__VA_ARGS__) /* -------------------------------------------------------------------------------- Déclaration des fonctions externes -------------------------------------------------------------------------------- */ #define declareExternalFunction(name) \ int __external_##name(struct_rpl_arguments *rpl_arguments) { \ char __function_name[] = "__external_"#name; \ __static_rpl_arguments = (*rpl_arguments); #define useExternalFunction(function) \ int __external_##function(struct_rpl_arguments *rpl_arguments) #define libraryName(name) char __library_name[] = #name; #define __onLoading int __runOnLoading(struct_rpl_arguments *rpl_arguments) #define __onClosing int __runOnClosing(struct_rpl_arguments *rpl_arguments) #define declareSubroutine(when) __##when { \ char __function_name[] = #when; \ __static_rpl_arguments = (*rpl_arguments); \ HEADER \ declareHelpString(""); \ numberOfArguments(0); \ FUNCTION #define endSubroutine END } #define notice(s, ...) __CATCH_SYSTEM_ERROR__; \ do { ufprintf(s, __VA_ARGS__); fflush(s); } while(0) #define logger(...) __CATCH_SYSTEM_ERROR__; \ do { syslog(LOG_NOTICE, __VA_ARGS__); } while(0) #define exportExternalFunctions(...) \ char **__external_symbols(struct_rpl_arguments *rpl_arguments, \ integer8 *nb_symbols, \ const char *version) { \ char arguments[] = #__VA_ARGS__; \ char **tableau; \ char *ptr1, *ptr2; \ int drapeau; \ unsigned long i; \ if (strcmp(version, _d_version_rpl) != 0) \ { \ notice(stdout, "Versions mismatch : library %s, expected %s\n", \ _d_version_rpl, version); \ (*nb_symbols) = -1; return(NULL); \ } \ (*nb_symbols) = 0; ptr1 = arguments; drapeau = 0; \ while((*ptr1) != 0) \ { \ if (((*ptr1) != ',') && ((*ptr1) != ' ')) drapeau = -1; \ ptr1++; \ } \ if (drapeau == 0) return(NULL); \ ptr1 = arguments; (*nb_symbols) = 1; \ while((*ptr1) != 0) if ((*ptr1++) == ',') (*nb_symbols)++; \ if ((tableau = malloc((*nb_symbols) * sizeof(char *))) == NULL) \ return(NULL); \ ptr2 = arguments; i = 0; \ while(*ptr2 != 0) \ { \ while(((*ptr2) == ' ') || ((*ptr2) == ',')) ptr2++; \ ptr1 = ptr2; \ while(((*ptr2) != 0) && ((*ptr2) != ',') && ((*ptr2) != ' ')) \ ptr2++; \ if ((tableau[i] = malloc((ptr2 + 2 + \ strlen(__library_name) - ptr1) * \ sizeof(unsigned char))) == NULL) \ return(NULL); \ sprintf(tableau[i], "%s$", __library_name); \ strncat(&tableau[i][strlen(tableau[i])], ptr1, ptr2 - ptr1); \ i++; \ if ((*ptr2) != 0) \ { \ while((*ptr2) == ' ') ptr2++; \ if ((*ptr2) == ',') ptr2++; \ } \ } \ (*nb_symbols) = i; \ return(tableau); \ } #define endExternalFunction leave; } #define callExternalFunction(function) do { \ __CATCH_SYSTEM_ERROR__; \ __taille_bloc = sizeof(t_8_bits) * 8; \ __indice_bloc = (35 - 1) / __taille_bloc; \ __indice_bit = (35 - 1) % __taille_bloc; \ __masque = ((t_8_bits) 1) << (__taille_bloc - __indice_bit - 1); \ __evaluation = ((*rpl_arguments).drapeaux_etat[__indice_bloc] & __masque) \ ? d_vrai : d_faux; \ __masque = ~(((t_8_bits) 1) << (__taille_bloc - __indice_bit - 1)); \ (*rpl_arguments).drapeaux_etat[__indice_bloc] &= __masque; \ __external_##function(rpl_arguments); \ if (__evaluation == d_vrai) \ { \ __masque = ((t_8_bits) 1) << (__taille_bloc - __indice_bit - 1); \ (*rpl_arguments).drapeaux_etat[__indice_bloc] |= __masque; \ } \ else \ { \ __masque = ~(((t_8_bits) 1) << (__taille_bloc - __indice_bit - 1)); \ (*rpl_arguments).drapeaux_etat[__indice_bloc] &= __masque; \ } } while(0) /* -------------------------------------------------------------------------------- Macros spécifiques à l'en-tête -------------------------------------------------------------------------------- */ #define declareHelpString(h) do { \ __presence_aide = d_vrai; \ if ((*rpl_arguments).affichage_arguments == 'Y') \ { \ uprintf("%s\n", h); \ return 0; \ } } while(0) #define declareSymbolicConstant do { \ numberOfArguments(0); \ (*rpl_arguments).constante_symbolique = 'Y'; \ __constante++; } while(0) #define numberOfArguments(n) do { \ __presence_validation = d_vrai; \ if ((*rpl_arguments).test_instruction == 'Y') \ { \ if (n < 0) \ systemError("Number of arguments must be positive or null"); \ (*rpl_arguments).nombre_arguments = n; \ __validation_instruction = d_vrai; \ } \ else \ { \ __taille_bloc = sizeof(t_8_bits) * 8; \ __indice_bloc = (31 - 1) / __taille_bloc; \ __indice_bit = (31 - 1) % __taille_bloc; \ __masque = ((t_8_bits) 1) << (__taille_bloc - __indice_bit - 1); \ if (((*rpl_arguments).drapeaux_etat[__indice_bloc] & __masque) != 0) \ { \ (*rpl_arguments).l_base_pile_last = \ sauvegarde_arguments(rpl_arguments, n); \ } \ } } while(0) /* -------------------------------------------------------------------------------- Gestion des boucles -------------------------------------------------------------------------------- */ #define loop(b, e, s) for(b; e; s) { #define endLoop __CATCH_SYSTEM_ERROR__; } #define repeatWhile(c) while(c) { #define endWhile __CATCH_SYSTEM_ERROR__; } #define doUntil do { #define repeatUntil(c) __CATCH_SYSTEM_ERROR__; } while(!(c)); #define select(s) switch(s) { #define endSelect __CATCH_SYSTEM_ERROR__; } #define nonExclusiveCase(c) case c: { #define endNonExclusiveCase __CATCH_SYSTEM_ERROR__; } #define exclusiveCase(c) case c: { #define endExclusiveCase break; __CATCH_SYSTEM_ERROR__; } #define defaultCase default: #define endDefaultCase break; __CATCH_SYSTEM_ERROR__; } /* -------------------------------------------------------------------------------- Gestion des erreurs -------------------------------------------------------------------------------- */ #define returnOnError(...) do { \ if ((*rpl_arguments).erreur != 0) \ { \ __VA_ARGS__; \ return 0; \ } } while(0) #define systemError(message) do { \ (*rpl_arguments).erreur = __LINE__; \ (*rpl_arguments).type_erreur = 'S'; \ (*rpl_arguments).message_erreur = (unsigned char *) message; \ return 0; } while(0) #define executionError(message) do { \ (*rpl_arguments).erreur = __LINE__; \ (*rpl_arguments).type_erreur = 'E'; \ (*rpl_arguments).message_erreur = (unsigned char *) message; } while(0) #define onSystemError(...) do { \ if (((*rpl_arguments).erreur != 0) && \ ((*rpl_arguments).type_erreur == 'S')) \ { \ blockSignals; \ kill(getpid(), SIGTERM); \ unblockSignals; \ __VA_ARGS__; \ } } while(0) #define onError(...) \ __CATCH_SYSTEM_ERROR__; \ do { if (((*rpl_arguments).type_erreur == 'E') && \ ((*rpl_arguments).erreur != 0)) { __VA_ARGS__; \ (*rpl_arguments).erreur = 0; } } while(0) #define onExecution(...) \ __CATCH_SYSTEM_ERROR__; \ do { if (((*rpl_arguments).type_erreur == 'E') && \ ((*rpl_arguments).erreur == 0)) { __VA_ARGS__; } } while(0) /* -------------------------------------------------------------------------------- Gestion de la pile opérationnelle -------------------------------------------------------------------------------- */ #define pushOnStack(object) do { \ __CATCH_SYSTEM_ERROR__; \ if (((*rpl_arguments).l_base_pile = \ empilement_pile_operationnelle(rpl_arguments, object)) == NULL) \ systemError("Memory allocation error"); \ if ((*object).nombre_occurrences == 1) object = NULL; } while(0) #define pullFromStack(object, ...) do { \ __CATCH_SYSTEM_ERROR__; \ (*rpl_arguments).l_base_pile = \ depilement_pile_operationnelle(rpl_arguments, &object); \ if (object == NULL) \ { \ executionError("Too few arguments"); \ } \ else \ { \ if (strlen(#__VA_ARGS__) == 0) \ { \ systemError("Undefined type"); \ } \ else \ { \ __type = 0; \ if (strstr(#__VA_ARGS__, "integer") != NULL) \ if ((*object).type == INT) __type = 1; \ if (strstr(#__VA_ARGS__, "real") != NULL) \ if ((*object).type == REL) __type = 1; \ if (strstr(#__VA_ARGS__, "complex") != NULL) \ if ((*object).type == CPL) __type = 1; \ if (strstr(#__VA_ARGS__, "string") != NULL) \ if ((*object).type == CHN) __type = 1; \ if (strstr(#__VA_ARGS__, "list") != NULL) \ if ((*object).type == LST) __type = 1; \ if (strstr(#__VA_ARGS__, "unknown") != NULL) \ __type = 1; \ if (__type == 0) \ { \ executionError("Type not allowed"); \ } \ } \ } } while(0) /* -------------------------------------------------------------------------------- Gestion des objets -------------------------------------------------------------------------------- */ #define then { #define endIf __CATCH_SYSTEM_ERROR__; } #define elseIf __CATCH_SYSTEM_ERROR__; } else if #define orElse __CATCH_SYSTEM_ERROR__; } else { // Constantes symboliques #define createSymbolicConstant(object, type, value) do { \ if ((strcmp(#type, "integer") != 0) && (strcmp(#type, "real") != 0)) \ systemError("Type not allowed for symbolic constant"); \ __taille_bloc = sizeof(t_8_bits) * 8; \ __indice_bloc = (35 - 1) / __taille_bloc; \ __indice_bit = (35 - 1) % __taille_bloc; \ __masque = ((t_8_bits) 1) << (__taille_bloc - __indice_bit - 1); \ if (((*rpl_arguments).drapeaux_etat[__indice_bloc] & __masque) != 0) \ { \ createNameObject(object); \ __CATCH_SYSTEM_ERROR__; \ { \ char *__constant_name; \ if ((__constant_name = malloc((strlen(__library_name) + \ strlen(__function_name) - 9) * sizeof(char))) == NULL) \ systemError("Memory allocation error"); \ sprintf(__constant_name, "%s$%s", __library_name, \ &(__function_name[11])); \ setName(object, __constant_name); \ free(__constant_name); \ } \ } \ else \ { \ if (strcmp(#type, "integer") == 0) \ { \ createIntegerObject(object); \ __CATCH_SYSTEM_ERROR__; \ setInteger(object, value); \ } \ else if (strcmp(#type, "real") == 0) \ { \ createRealObject(object); \ __CATCH_SYSTEM_ERROR__; \ setReal(object, value); \ } \ } \ __CATCH_SYSTEM_ERROR__; \ __constante--; } while(0) #define createSymbolicComplexConstant(object, rp, ip) do { \ __taille_bloc = sizeof(t_8_bits) * 8; \ __indice_bloc = (35 - 1) / __taille_bloc; \ __indice_bit = (35 - 1) % __taille_bloc; \ __masque = ((t_8_bits) 1) << (__taille_bloc - __indice_bit - 1); \ if (((*rpl_arguments).drapeaux_etat[__indice_bloc] & __masque) != 0) \ { \ createNameObject(object); \ __CATCH_SYSTEM_ERROR__; \ { \ char *__constant_name; \ if ((__constant_name = malloc((strlen(__library_name) + \ strlen(__function_name) + 2) * sizeof(char))) == NULL) \ systemError("Memory allocation error"); \ sprintf(__constant_name, "%s$%s", __library_name, \ __function_name); \ setName(object, __constant_name); \ free(__constant_name); \ } \ } \ else \ { \ createComplexObject(object); \ __CATCH_SYSTEM_ERROR__; \ setComplex(object, rp, im); \ } \ __CATCH_SYSTEM_ERROR__; \ __constante--; } while(0) // Integer #define setInteger(object, value) do { \ ifIsInteger(object) \ { \ if ((*object).nombre_occurrences > 1) \ { \ struct_objet *__tmp_object; \ if ((__tmp_object = copie_objet(object, 'O')) == NULL) \ systemError("Memory allocation error"); \ liberation(object); \ object = __tmp_object; \ } \ (*((integer8 *) (*object).objet)) = (integer8) value; \ } \ else executionError("Type mistmatch error"); } while(0) #define isInteger(object) \ ((*object).type == INT) #define ifIsInteger(object) if (isInteger(object)) #define elseIfIsInteger(object) } else ifIsInteger(object) #define getInteger(object, value) do { \ value = 0; \ ifIsInteger(object) value = (*((integer8 *) (*object).objet)); \ else executionError("Type mismatch error"); } while(0) #define createIntegerObject(object) do { \ if (object != NULL) \ systemError("Reallocated object"); \ if ((object = allocation(INT)) == NULL) \ systemError("Memory allocation error"); \ setInteger(object, 0); } while(0) // Real #define setReal(object, value) do { \ ifIsReal(object) \ { \ if ((*object).nombre_occurrences > 1) \ { \ struct_objet *__tmp_object; \ if ((__tmp_object = copie_objet(object, 'O')) == NULL) \ systemError("Memory allocation error"); \ liberation(object); \ object = __tmp_object; \ } \ (*((real8 *) (*object).objet)) = (real8) value; \ } \ else executionError("Type mistmatch error"); } while(0) #define isReal(object) \ ((*object).type == REL) #define ifIsReal(object) if (isReal(object)) #define elseIfIsReal(object) } else ifIsReal(object) #define getReal(object, value) do { \ value = 0; \ ifIsReal(object) value = (*((real8 *) (*object).objet)); \ else executionError("Type mismatch error"); } while(0) #define createRealObject(object) do { \ if (object != NULL) \ systemError("Reallocated object"); \ if ((object = allocation(REL)) == NULL) \ systemError("Memory allocation error"); \ setReal(object, 0); } while(0) // Complex #define setComplex(object, rp, ip) do { \ typeof(rp) __rp = rp; \ typeof(ip) __ip = ip; \ ifIsComplex(object) \ { \ if ((*object).nombre_occurrences > 1) \ { \ struct_objet *__tmp_object; \ if ((__tmp_object = copie_objet(object, 'O')) == NULL) \ systemError("Memory allocation error"); \ liberation(object); \ object = __tmp_object; \ } \ setRealPartOfComplex(object, __rp); \ setImaginaryPartOfComplex(object, __ip); \ } \ else executionError("Type mismatch error"); } while(0) #define setRealPartOfComplex(object, value) do { \ if ((*object).nombre_occurrences > 1) \ { \ struct_objet *__tmp_object; \ if ((__tmp_object = copie_objet(object, 'O')) == NULL) \ systemError("Memory allocation error"); \ liberation(object); \ object = __tmp_object; \ } \ ifIsComplex(object) (*((complex16 *) (*object).objet)).partie_reelle = \ value; \ else executionError("Type mismatch error"); } while(0) #define setImaginaryPartOfComplex(object, value) do { \ if ((*object).nombre_occurrences > 1) \ { \ struct_objet *__tmp_object; \ if ((__tmp_object = copie_objet(object, 'O')) == NULL) \ systemError("Memory allocation error"); \ liberation(object); \ object = __tmp_object; \ } \ (*((complex16 *) (*object).objet)).partie_imaginaire = value; \ else executionError("Type mismatch error"); } while(0) #define getRealPartOfComplex(object, value) \ value = (*((complex16 *) (*object).objet)).partie_reelle #define getImaginaryPartOfComplex(object, value) \ value = (*((complex16 *) (*object).objet)).partie_imaginaire #define isComplex(object) \ ((*object).type == CPL) #define ifIsComplex(object) if (isComplex(object)) #define elseIfIsComplex(object) } else ifIsComplex(object) #define getComplex(object, value) do { \ value.partie_reelle = 0; \ value.partie_imaginaire = 0; \ ifIsComplex(object) value = (*((complex16 *) (*object).objet)); \ else systemError("Not a complex"); } while(0) #define createComplexObject(object) do { \ if (object != NULL) \ systemError("Reallocated object"); \ if ((object = allocation(CPL)) == NULL) \ systemError("Memory allocation error"); \ setComplex(object, 0, 0); } while(0) // Generalized vectors #define createVectorObject(object, size, otype, structure, cat) do { \ integer8 i; \ if (object != NULL) \ systemError("Reallocated object"); \ if ((object = allocation(cat)) == NULL) \ systemError("Memory allocation error"); \ (*((structure *) (*object).objet)).taille = size; \ if (((*((structure *) (*object).objet)).tableau = \ malloc(size * sizeof(otype))) == NULL) \ systemError("Memory allocation error"); \ if (cat != VCX) \ { \ if (cat == VIN) \ (*((structure *) (*object).objet)).type = 'I'; \ else \ (*((structure *) (*object).objet)).type = 'R'; \ for(i = 0; i < size; ((otype *) (*((structure *) (*object).objet)) \ .tableau)[i++] = (otype) 0); \ } \ else \ { \ (*((structure *) (*object).objet)).type = 'C'; \ for(i = 0; i < size; i++) \ { \ ((complex16 *) (*((structure *) (*object).objet)).tableau)[i] \ .partie_reelle = 0; \ ((complex16 *) (*((structure *) (*object).objet)).tableau)[i] \ .partie_imaginaire = 0; \ } \ } } while(0) // Integer vector #define setIntegerIntoVector(object, value, position) do { \ typeof(position) __position = position; \ ifIsIntegerVector(object) \ { \ if ((*object).nombre_occurrences > 1) \ { \ struct_objet *__tmp_object; \ if ((__tmp_object = copie_objet(object, 'O')) == NULL) \ systemError("Memory allocation error"); \ liberation(object); \ object = __tmp_object; \ } \ __position--; \ if ((__position < 0) || (__position >= (*((struct_vecteur *) \ (*object).objet)).taille)) \ { executionError("Element out of range"); } \ else \ ((integer8 *) (*((struct_vecteur *) (*object).objet)).tableau) \ [__position] = (integer8) value; \ } \ else executionError("Type mistmatch error"); } while(0) #define isIntegerVector(object) \ ((*object).type == VIN) #define ifIsIntegerVector(object) if (isIntegerVector(object)) #define elseIfIsIntegerVector(object) } else ifIsIntegerVector(object) #define getIntegerFromVector(object, value, position) do { \ typeof(position) __position = position; \ value = 0; \ ifIsIntegerVector(object) \ { \ __position--; \ if ((__position < 0) || (__position >= (*((struct_vecteur *) \ (*object).objet)).taille)) \ executionError("Element out of range"); \ else \ value = ((integer8 *) (*((struct_vecteur *) (*object).objet)) \ .tableau)[__position]; \ } \ else executionError("Type mismatch error"); } while(0) #define createIntegerVectorObject(object, size) \ createVectorObject(object, size, integer8, struct_vecteur, VIN) // Real vector #define setRealIntoVector(object, value, position) do { \ typeof(position) __position = position; \ ifIsRealVector(object) \ { \ if ((*object).nombre_occurrences > 1) \ { \ struct_objet *__tmp_object; \ if ((__tmp_object = copie_objet(object, 'O')) == NULL) \ systemError("Memory allocation error"); \ liberation(object); \ object = __tmp_object; \ } \ __position--; \ if ((__position < 0) || (__position >= (*((struct_vecteur *) \ (*object).objet)).taille)) \ { executionError("Element out of range"); } \ else \ ((real8 *) (*((struct_vecteur *) (*object).objet)).tableau) \ [__position] = (real8) value; \ } \ else executionError("Type mistmatch error"); } while(0) #define isRealVector(object) \ ((*object).type == VRL) #define ifIsRealVector(object) if (isRealVector(object)) #define elseIfIsRealVector(object) } else ifIsRealVector(object) #define getRealFromVector(object, value, position) do { \ typeof(position) __position = position; \ value = 0; \ ifIsRealVector(object) \ { \ __position--; \ if ((__position < 0) || (__position >= (*((struct_vecteur *) \ (*object).objet)).taille)) \ executionError("Element out of range"); \ value = ((real8 *) (*((struct_vecteur *) (*object).objet)).tableau) \ [__position]; \ } \ else executionError("Type mismatch error"); } while(0) #define createRealVectorObject(object, size) \ createVectorObject(object, size, real8, struct_vecteur, VRL) // A FIXER #define createComplexVectorObject #define createIntegerMatrixObject #define createRealMatrixObject #define createComplexMatrixObject // Binary integer #define setBinaryInteger(object, value) do { \ ifIsBinaryInteger(object) \ { \ if ((*object).nombre_occurrences > 1) \ { \ struct_objet *__tmp_object; \ if ((__tmp_object = copie_objet(object, 'O')) == NULL) \ systemError("Memory allocation error"); \ liberation(object); \ object = __tmp_object; \ } \ (*((integer8 *) (*object).objet)) = (integer8) value; \ } \ else executionError("Type mistmatch error"); } while(0) #define isBinaryInteger(object) \ ((*object).type == BIN) #define ifIsBinaryInteger(object) if (isBinaryInteger(object)) #define elseIfIsBinaryInteger(object) } else ifIsBinaryInteger(object) #define getBinaryInteger(object, value) do { \ value = 0; \ ifIsBinaryInteger(object) value = (*((integer8 *) (*object).objet)); \ else executionError("Type mismatch error"); } while(0) #define createBinaryIntegerObject(object) do { \ if (object != NULL) \ systemError("Reallocated object"); \ if ((object = allocation(BIN)) == NULL) \ systemError("Memory allocation error"); \ setBinaryInteger(object, 0); } while(0) // Name #define isName(object) \ ((*object).type == NOM) #define ifIsName(object) if (isName(object)) #define elseIfIsName(object) } else if (isName(object)) #define setName(object, value) do { \ ifIsName(object) \ { \ if ((*object).nombre_occurrences > 1) \ { \ struct_objet *__tmp_object; \ if ((__tmp_object = copie_objet(object, 'O')) == NULL) \ systemError("Memory allocation error"); \ liberation(object); \ object = __tmp_object; \ } \ free((*((struct_nom *) (*object).objet)).nom); \ (*((struct_nom *) (*object).objet)).symbole = d_faux; \ if (((*((struct_nom *) (*object).objet)).nom = malloc( \ (strlen(value) + 1) * sizeof(unsigned char))) == NULL) \ systemError("Memory allocation error"); \ strcpy((char *) (*((struct_nom *) (*object).objet)).nom, \ (char *) value); \ } \ else executionError("Type mistmatch error"); } while(0) #define createNameObject(object) do { \ if (object != NULL) \ systemError("Reallocated object"); \ if ((object = allocation(NOM)) == NULL) \ systemError("Memory allocation error"); \ (*((struct_nom *) (*object).objet)).symbole = d_faux; \ if (((*((struct_nom *) (*object).objet)).nom = malloc( \ sizeof(unsigned char))) == NULL) \ systemError("Memory allocation error"); \ strcpy((char *) (*((struct_nom *) (*object).objet)).nom, ""); } while(0) // String #define isString(object) \ ((*object).type == CHN) #define ifIsString(object) if (isString(object)) #define elseIfIsString(object) else if (isString(objet)) #define setString(object, string) do { \ ifIsString(object) \ { \ if (string == NULL) executionError("Nullified string"); else \ { \ if ((*object).nombre_occurrences > 1) \ { \ struct_objet *__tmp_object; \ if ((__tmp_object = copie_objet(object, 'O')) == NULL) \ systemError("Memory allocation error"); \ liberation(object); \ object = __tmp_object; \ } \ free((unsigned char *) (*object).objet); \ if (((*object).objet = malloc((strlen(string) + 1) * \ sizeof(unsigned char))) == NULL) \ systemError("Memory allocation error"); \ strcpy((char *) (*object).objet, string); \ } \ } \ else executionError("Type mistmatch error"); } while(0) #define getString(object, string) do { \ string = NULL; \ ifIsString(object) string = (char *) (*object).objet; \ else executionError("Type mismatch error"); } while(0) #define createStringObject(object) do { \ if (object != NULL) \ systemError("Reallocated object"); \ if ((object = allocation(CHN)) == NULL) \ systemError("Memory allocation error"); \ if (((*object).objet = malloc(sizeof(unsigned char))) == NULL) \ systemError("Memory allocation error"); \ strcpy((char *) (*object).objet, ""); } while(0) // List #define isList(object) \ ((*object).type == LST) #define ifIsList(object) if (isList(object)) #define elseIfIsList(object) else if (isList(object)) #define createListObject(object) do { \ if (object != NULL) \ systemError("Reallocated object"); \ if ((object = allocation(LST)) == NULL) \ systemError("Memory allocation error"); \ (*object).objet = NULL; } while(0) #define addObjectToList(list, object) do { \ ifIsList(list) \ { \ struct_objet *__tmp_object; \ if ((__tmp_object = copie_objet(list, 'N')) == NULL) \ systemError("Memory allocation error"); \ liberation(list); \ list = __tmp_object; \ if ((*list).objet == NULL) \ { \ if (((*list).objet = malloc(sizeof(struct_liste_chainee))) \ == NULL) \ systemError("Memory allocation error"); \ (*((struct_liste_chainee *) (*list).objet)).suivant = NULL; \ (*((struct_liste_chainee *) (*list).objet)).donnee = object; \ } \ else \ { \ struct_liste_chainee *l_element_courant; \ l_element_courant = (*list).objet; \ while((*l_element_courant).suivant != NULL) \ l_element_courant = (*l_element_courant).suivant; \ if (((*l_element_courant).suivant = \ malloc(sizeof(struct_liste_chainee))) == NULL) \ systemError("Memory allocation error"); \ l_element_courant = (*l_element_courant).suivant; \ (*l_element_courant).suivant = NULL; \ (*l_element_courant).donnee = object; \ } \ object = NULL; \ } \ else executionError("Type mistmatch error"); } while(0) #define insertObjectIntoList(list, object) do { \ ifIsList(list) \ { \ struct_objet *__tmp_object; \ if ((__tmp_object = copie_objet(list, 'N')) == NULL) \ systemError("Memory allocation error"); \ liberation(list); \ list = __tmp_object; \ if ((*list).objet == NULL) \ { \ if (((*list).objet = malloc(sizeof(struct_liste_chainee))) \ == NULL) \ systemError("Memory allocation error"); \ (*((struct_liste_chainee *) (*list).objet)).suivant = NULL; \ (*((struct_liste_chainee *) (*list).objet)).donnee = object; \ } \ else \ { \ struct_liste_chainee *l_element_courant; \ if ((l_element_courant = \ malloc(sizeof(struct_liste_chainee))) == NULL) \ systemError("Memory allocation error"); \ (*l_element_courant).donnee = object; \ (*l_element_courant).suivant = (*list).objet; \ (*list).objet = l_element_courant; \ } \ object = NULL; \ } \ else executionError("Type mistmatch error"); } while(0) #define removeObjectFromList(list, object) do { \ ifIsList(list) \ { \ if ((*list).objet != NULL) \ { \ struct_liste_chainee *__current; \ struct_liste_chainee *__previous; \ __current = (*list).objet; \ __previous = NULL; \ if ((*__current).donnee == object) \ { \ (*list).objet = (*__current).suivant; \ } \ else \ { \ while(__current != NULL) \ { \ if ((*__current).donnee == object) \ { \ (*__previous).suivant = (*__current).suivant; \ break; \ } \ __previous = __current; \ __current = (*__current).suivant; \ } \ } \ liberation((*__current).donnee); \ free(__current); \ } \ } \ else executionError("Type mistmatch error"); } while(0) #define getObjectFromList(list, position, object) #define putObjectIntoList(list, position, object) #define getListFromList(list, position1, position2, object) #define listLength(list, length) do { \ if (list == NULL) executionError("Nullified object"); \ if ((*list).type != LST) \ executionError("Type mistmatch error"); \ { \ struct_liste_chainee *l_element_courant; \ length = 0; \ l_element_courant = (*list).objet; \ while(l_element_courant != NULL) \ { \ l_element_courant = (*l_element_courant).suivant; \ length++; \ } \ } } while(0) /* -------------------------------------------------------------------------------- Allocation mémoire -------------------------------------------------------------------------------- */ #define size(a) sizeof(a) #define allocate(a) ({ void *ptr; \ if ((ptr = malloc(a)) == NULL) \ systemError("Memory allocation error"); ptr; }) #define deallocate(a) free(a) /* -------------------------------------------------------------------------------- Récupération des interruptions et des signaux -------------------------------------------------------------------------------- */ #define pollSignalsAndInterrupts() \ __CATCH_SYSTEM_ERROR__; \ do { scrutation_injection((*rpl_arguments).s_etat_processus); } while(0) /* -------------------------------------------------------------------------------- Exécution d'une fonction intrinsèque -------------------------------------------------------------------------------- */ #define intrinsic(function) do { \ int __status; \ __CATCH_SYSTEM_ERROR__; \ __status = wrapper_instruction_intrinseque( \ instruction_##function, rpl_arguments); \ if (__status == 1) executionError(#function); \ if (__status == 2) systemError(#function); \ } while(0) #endif // vim: ts=4