File:  [local] / rpl / src / rplexternals.h
Revision 1.23: download - view: text, annotated - select for diffs - revision graph
Tue Jun 21 15:26:35 2011 UTC (12 years, 10 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Correction d'une réinitialisation sauvage de la pile des variables par niveau
dans la copie de la structure de description du processus. Cela corrige
la fonction SPAWN qui échouait sur un segmentation fault car la pile des
variables par niveau était vide alors même que l'arbre des variables contenait
bien les variables. Passage à la prerelease 2.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.0.prerelease.2
    4:   Copyright (C) 1989-2011 Dr. BERTRAND Joël
    5: 
    6:   This file is part of RPL/2.
    7: 
    8:   RPL/2 is free software; you can redistribute it and/or modify it
    9:   under the terms of the CeCILL V2 License as published by the french
   10:   CEA, CNRS and INRIA.
   11:  
   12:   RPL/2 is distributed in the hope that it will be useful, but WITHOUT
   13:   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14:   FITNESS FOR A PARTICULAR PURPOSE.  See the CeCILL V2 License
   15:   for more details.
   16:  
   17:   You should have received a copy of the CeCILL License
   18:   along with RPL/2. If not, write to info@cecill.info.
   19: ================================================================================
   20: */
   21: 
   22: 
   23: #ifndef INCLUSION_RPLARGS
   24: #   define INCLUSION_RPLARGS
   25: 
   26: /*
   27: ================================================================================
   28:   INCLUSIONS
   29: ================================================================================
   30: */
   31: 
   32: #   define RPLARGS
   33: #   define struct_processus void
   34: #   include "rpl.h"
   35: 
   36: /*
   37: ================================================================================
   38:   MACROS SPECIFIQUES
   39: ================================================================================
   40: */
   41: 
   42: #define allocation(a) librpl_allocation((*rpl_arguments).s_etat_processus, a)
   43: #define copie_objet(a, b) librpl_copie_objet( \
   44:             (*rpl_arguments).s_etat_processus, a, b)
   45: #define liberation(a) librpl_liberation((*rpl_arguments).s_etat_processus, a)
   46: 
   47: /*
   48: --------------------------------------------------------------------------------
   49:   Types
   50: --------------------------------------------------------------------------------
   51: */
   52: 
   53: #define declareObject(object) struct_objet *object = NULL
   54: #define declareInteger(integer) integer8 integer
   55: #define declareReal(real) real8 real
   56: #define declareComplex(complex) complex16 complex
   57: #define declareDaisyChain(daisyChain) struct_liste_chainee *daisyChain = NULL
   58: 
   59: #define getDaisyChainFromList(list, daisyChain) { \
   60:     typeof(list) __list = list; \
   61:     daisyChain = NULL; \
   62:     ifIsList(__list) { daisyChain = (*__list).objet; } \
   63:     else executionError("Type mistmatch error"); } while(0)
   64: 
   65: #define fetchElementFromDaisyChain(daisyChain) \
   66:     ({ typeof(daisyChain) __daisyChain = daisyChain; \
   67:     if (__daisyChain == NULL) executionError("End of daisy chain"); \
   68:     (__daisyChain == NULL) ? NULL : (*__daisyChain).donnee; })
   69: 
   70: #define replaceElementIntoDaisyChain(daisyChain, element) \
   71:     do { typeof(daisyChain) __daisyChain = daisyChain; \
   72:     if (__daisyChain == NULL) executionError("Nullified daisy chain"); \
   73:     (*__daisyChain).donnee = element; } while(0)
   74: 
   75: #define nextElementOfDaisyChain(daisyChain) \
   76:     ({ typeof(daisyChain) __daisyChain = daisyChain; \
   77:     if (__daisyChain == NULL) executionError("End of daisy chain"); \
   78:     (__daisyChain == NULL) ? NULL : (*__daisyChain).suivant; })
   79:     
   80: #define null NULL
   81: #define nullify(ptr) { ptr = NULL; } while(0)
   82: #define nullified(ptr) ((ptr) == NULL)
   83: 
   84: #define postIncr(x) (x++)
   85: #define preIncr(x) (++x)
   86: #define postDecr(x) (x--)
   87: #define preDecr(x) (--x)
   88: 
   89: #define eq ==
   90: #define ne !=
   91: #define ge >=
   92: #define gt >
   93: #define le <=
   94: #define lt <
   95: #define not !
   96: #define and &&
   97: #define or ||
   98: #define false 0
   99: #define true -1
  100: 
  101: #define setFalse(a) a = false
  102: #define setTrue(a) a = true
  103: 
  104: #define logical int
  105: #define string char *
  106: #define integer int
  107: 
  108: #define declareStructure typedef struct {
  109: #define declareUnion typedef union {
  110: #define as(name) } name;
  111: 
  112: #define target(a) (*a)
  113: #define address(a) (&a)
  114: 
  115: #define beginGroup {
  116: #define endGroup }
  117: #define beginMacro beginGroup
  118: #define endMacro endGroup while(0)
  119: #define stopRequest test_arret((*rpl_arguments).s_etat_processus)
  120: 
  121: /*
  122: --------------------------------------------------------------------------------
  123:   Constructeurs
  124: --------------------------------------------------------------------------------
  125: */
  126: 
  127: #define HEADER \
  128:     int             __constante; \
  129:     logical1        __evaluation; \
  130:     logical1        __validation_instruction = d_faux; \
  131:     logical1        __presence_aide = d_faux; \
  132:     logical1        __presence_validation = d_faux; \
  133:     unsigned char   __indice_bit; \
  134:     unsigned char   __indice_bloc; \
  135:     unsigned char   __taille_bloc; \
  136:     unsigned char   __type; \
  137:     t_8_bits        __masque; \
  138:     { \
  139:         (*rpl_arguments).instruction_valide = 'Y'; \
  140:         (*rpl_arguments).erreur = 0; \
  141:         __constante = 0; \
  142:         __evaluation = d_faux;
  143: 
  144: #define FUNCTION \
  145:     if (__validation_instruction == d_vrai) return; \
  146:     if (__presence_aide == d_faux) \
  147:     { \
  148:         systemError("Help string not defined"); \
  149:     } \
  150:     else if (__presence_validation == d_faux) \
  151:     { \
  152:         systemError("Number of arguments not defined"); \
  153:     } \
  154:     __indice_bit = 0; \
  155:     __indice_bloc = 0; \
  156:     __taille_bloc = 0; \
  157:     __type = 0; \
  158:     __masque = 0; \
  159:     {
  160: 
  161: #define END \
  162:         strcpy((char *) __function_name, ""); \
  163:         if (__constante != 0) \
  164:             systemError("Constant definition error"); \
  165:     } } \
  166:     return;
  167: 
  168: /*
  169: --------------------------------------------------------------------------------
  170:   Déclaration des fonctions externes
  171: --------------------------------------------------------------------------------
  172: */
  173: 
  174: #define declareExternalFunction(name) \
  175:     void __external_##name(struct_rpl_arguments *rpl_arguments) { \
  176:     char __function_name[] = "__external_"#name;
  177: 
  178: #define useExternalFunction(function) \
  179:     void __external_##function(struct_rpl_arguments *rpl_arguments)
  180: 
  181: #define libraryName(name) char __library_name[] = #name;
  182: 
  183: #define __onLoading void __runOnLoading(struct_rpl_arguments *rpl_arguments)
  184: #define __onClosing void __runOnClosing(struct_rpl_arguments *rpl_arguments)
  185: #define declareSubroutine(when) __##when { \
  186:     char __function_name[] = #when; \
  187:     HEADER \
  188:         declareHelpString(""); \
  189:         numberOfArguments(0); \
  190:     FUNCTION
  191: #define endSubroutine END }
  192: 
  193: #define notice(s, ...) do { ufprintf(s, __VA_ARGS__); fflush(s); } while(0)
  194: #define logger(...) do { syslog(LOG_NOTICE, __VA_ARGS__); } while(0) 
  195: 
  196: #define exportExternalFunctions(...) \
  197:     char **__external_symbols(unsigned long *nb_symbols, \
  198:             const char *version) { \
  199:         char arguments[] = #__VA_ARGS__; \
  200:         char **tableau; \
  201:         char *ptr1, *ptr2; \
  202:         int drapeau; \
  203:         unsigned long i; \
  204:         if (strcmp(version, _d_version_rpl) != 0) \
  205:         { \
  206:             notice(stdout, "Versions mismatch : library %s, expected %s\n", \
  207:                     _d_version_rpl, version); \
  208:             (*nb_symbols) = -1; return(NULL); \
  209:         } \
  210:         (*nb_symbols) = 0; ptr1 = arguments; drapeau = 0; \
  211:         while((*ptr1) != 0) \
  212:         { \
  213:             if (((*ptr1) != ',') && ((*ptr1) != ' ')) drapeau = -1; \
  214:             ptr1++; \
  215:         } \
  216:         if (drapeau == 0) return(NULL); \
  217:         ptr1 = arguments; (*nb_symbols) = 1; \
  218:         while((*ptr1) != 0) if ((*ptr1++) == ',') (*nb_symbols)++; \
  219:         if ((tableau = malloc((*nb_symbols) * sizeof(char *))) == NULL) \
  220:             return(NULL); \
  221:         ptr2 = arguments; i = 0; \
  222:         while(*ptr2 != 0) \
  223:         { \
  224:             while(((*ptr2) == ' ') || ((*ptr2) == ',')) ptr2++; \
  225:             ptr1 = ptr2; \
  226:             while(((*ptr2) != 0) && ((*ptr2) != ',') && ((*ptr2) != ' ')) \
  227:                     ptr2++; \
  228:             if ((tableau[i] = malloc((ptr2 + 2 + \
  229:                     strlen(__library_name) - ptr1) * \
  230:                     sizeof(unsigned char))) == NULL) \
  231:                 return(NULL); \
  232:             sprintf(tableau[i], "%s$", __library_name); \
  233:             strncat(&tableau[i][strlen(tableau[i])], ptr1, ptr2 - ptr1); \
  234:             i++; \
  235:             if ((*ptr2) != 0) \
  236:             { \
  237:                 while((*ptr2) == ' ') ptr2++; \
  238:                 if ((*ptr2) == ',') ptr2++; \
  239:             } \
  240:         } \
  241:         (*nb_symbols) = i; \
  242:         return(tableau); \
  243:     }
  244: 
  245: #define endExternalFunction return; }
  246: 
  247: #define callExternalFunction(function) { \
  248:     __taille_bloc = sizeof(t_8_bits) * 8; \
  249:     __indice_bloc = (35 - 1) / __taille_bloc; \
  250:     __indice_bit = (35 - 1) % __taille_bloc; \
  251:     __masque = ((t_8_bits) 1) << (__taille_bloc - __indice_bit - 1); \
  252:     __evaluation = ((*rpl_arguments).drapeaux_etat[__indice_bloc] & __masque) \
  253:             ? d_vrai : d_faux; \
  254:     __masque = ~(((t_8_bits) 1) << (__taille_bloc - __indice_bit - 1)); \
  255:     (*rpl_arguments).drapeaux_etat[__indice_bloc] &= __masque; \
  256:     __external_##function(rpl_arguments); \
  257:     if (__evaluation == d_vrai) \
  258:     { \
  259:         __masque = ((t_8_bits) 1) << (__taille_bloc - __indice_bit - 1); \
  260:         (*rpl_arguments).drapeaux_etat[__indice_bloc] |= __masque; \
  261:     } \
  262:     else \
  263:     { \
  264:         __masque = ~(((t_8_bits) 1) << (__taille_bloc - __indice_bit - 1)); \
  265:         (*rpl_arguments).drapeaux_etat[__indice_bloc] &= __masque; \
  266:     } } while(0)
  267: 
  268: /*
  269: --------------------------------------------------------------------------------
  270:   Macros spécifiques à l'en-tête
  271: --------------------------------------------------------------------------------
  272: */
  273: 
  274: #define declareHelpString(h) { \
  275:     __presence_aide = d_vrai; \
  276:     if ((*rpl_arguments).affichage_arguments == 'Y') \
  277:     { \
  278:         uprintf("%s\n", h); \
  279:         return; \
  280:     } } while(0)
  281: 
  282: #define declareSymbolicConstant { \
  283:     numberOfArguments(0); \
  284:     (*rpl_arguments).constante_symbolique = 'Y'; \
  285:     __constante++; } while(0)
  286: 
  287: #define numberOfArguments(n) { \
  288:     __presence_validation = d_vrai; \
  289:     if ((*rpl_arguments).test_instruction == 'Y') \
  290:     { \
  291:         if (n < 0) \
  292:             systemError("Number of arguments must be positive or null"); \
  293:         (*rpl_arguments).nombre_arguments = n; \
  294:         __validation_instruction = d_vrai; \
  295:     } \
  296:     else \
  297:     { \
  298:         __taille_bloc = sizeof(t_8_bits) * 8; \
  299:         __indice_bloc = (31 - 1) / __taille_bloc; \
  300:         __indice_bit = (31 - 1) % __taille_bloc; \
  301:         __masque = ((t_8_bits) 1) << (__taille_bloc - __indice_bit - 1); \
  302:         if (((*rpl_arguments).drapeaux_etat[__indice_bloc] & __masque) != 0) \
  303:         { \
  304:             (*rpl_arguments).l_base_pile_last = \
  305:                     sauvegarde_arguments(rpl_arguments, n); \
  306:         } \
  307:     } } while(0)
  308: 
  309: /*
  310: --------------------------------------------------------------------------------
  311:   Gestion des boucles
  312: --------------------------------------------------------------------------------
  313: */
  314: 
  315: #define loop(b, e, s) for(b; e; s) {
  316: #define endLoop }
  317: 
  318: #define repeatWhile(c) while(c) {
  319: #define endWhile }
  320: 
  321: #define doUntil do {
  322: #define repeatUntil(c) } while(!(c));
  323: 
  324: #define select(s) switch(s) {
  325: #define endSelect }
  326: #define nonExclusiveCase(c) case c: {
  327: #define endNonExclusiveCase }
  328: #define exclusiveCase(c) case c: {
  329: #define endExclusiveCase break; }
  330: #define defaultCase default:
  331: #define endDefaultCase break; }
  332: 
  333: /*
  334: --------------------------------------------------------------------------------
  335:   Gestion des erreurs
  336: --------------------------------------------------------------------------------
  337: */
  338: 
  339: #define returnOnError(...) { \
  340:     if ((*rpl_arguments).erreur != 0) \
  341:     { \
  342:         __VA_ARGS__; \
  343:         return; \
  344:     } } while(0)
  345: 
  346: #define systemError(message) { \
  347:     (*rpl_arguments).erreur = __LINE__; \
  348:     (*rpl_arguments).type_erreur = 'S'; \
  349:     (*rpl_arguments).message_erreur = (unsigned char *) message; \
  350:     return; } while(0)
  351: 
  352: #define executionError(message) { \
  353:     (*rpl_arguments).erreur = __LINE__; \
  354:     (*rpl_arguments).type_erreur = 'E'; \
  355:     (*rpl_arguments).message_erreur = (unsigned char *) message; } while(0)
  356: 
  357: #define onError(...) \
  358:     do { if (((*rpl_arguments).type_erreur == 'E') && \
  359:             ((*rpl_arguments).erreur != 0)) { __VA_ARGS__; \
  360:             (*rpl_arguments).erreur = 0; } } while(0)
  361: 
  362: #define onExecution(...) \
  363:     do { if (((*rpl_arguments).type_erreur == 'E') && \
  364:             ((*rpl_arguments).erreur == 0)) { __VA_ARGS__; } } while(0)
  365: 
  366: /*
  367: --------------------------------------------------------------------------------
  368:   Gestion de la pile opérationnelle
  369: --------------------------------------------------------------------------------
  370: */
  371: 
  372: #define pushOnStack(object) { \
  373:     if (((*rpl_arguments).l_base_pile = \
  374:             empilement_pile_operationnelle(rpl_arguments, object)) == NULL) \
  375:         systemError("Memory allocation error"); \
  376:     if ((*object).nombre_occurrences == 1) object = NULL; } while(0)
  377: 
  378: #define pullFromStack(object, ...) { \
  379:     (*rpl_arguments).l_base_pile = \
  380:             depilement_pile_operationnelle(rpl_arguments, &object); \
  381:     if (object == NULL) \
  382:     { \
  383:         executionError("Too few arguments"); \
  384:     } \
  385:     else \
  386:     { \
  387:         if (strlen(#__VA_ARGS__) == 0) \
  388:         { \
  389:             systemError("Undefined type"); \
  390:         } \
  391:         else \
  392:         { \
  393:             __type = 0; \
  394:             if (strstr(#__VA_ARGS__, "integer") != NULL) \
  395:                 if ((*object).type == INT) __type = 1; \
  396:             if (strstr(#__VA_ARGS__, "real") != NULL) \
  397:                 if ((*object).type == REL) __type = 1; \
  398:             if (strstr(#__VA_ARGS__, "complex") != NULL) \
  399:                 if ((*object).type == CPL) __type = 1; \
  400:             if (strstr(#__VA_ARGS__, "string") != NULL) \
  401:                 if ((*object).type == CHN) __type = 1; \
  402:             if (strstr(#__VA_ARGS__, "list") != NULL) \
  403:                 if ((*object).type == LST) __type = 1; \
  404:             if (strstr(#__VA_ARGS__, "unknown") != NULL) \
  405:                 __type = 1; \
  406:             if (__type == 0) \
  407:             { \
  408:                 executionError("Type not allowed"); \
  409:             } \
  410:         } \
  411:     } } while(0)
  412: 
  413: /*
  414: --------------------------------------------------------------------------------
  415:   Gestion des objets
  416: --------------------------------------------------------------------------------
  417: */
  418: 
  419: #define then {
  420: #define endIf }
  421: #define elseIf } else if
  422: #define orElse } else {
  423: 
  424: //  Constantes symboliques
  425: 
  426: #define createSymbolicConstant(object, type, value) { \
  427:     if ((strcmp(#type, "integer") != 0) && (strcmp(#type, "real") != 0)) \
  428:         systemError("Type not allowed for symbolic constant"); \
  429:     __taille_bloc = sizeof(t_8_bits) * 8; \
  430:     __indice_bloc = (35 - 1) / __taille_bloc; \
  431:     __indice_bit = (35 - 1) % __taille_bloc; \
  432:     __masque = ((t_8_bits) 1) << (__taille_bloc - __indice_bit - 1); \
  433:     if (((*rpl_arguments).drapeaux_etat[__indice_bloc] & __masque) != 0) \
  434:     { \
  435:         createNameObject(object); \
  436:         { \
  437:             char *__constant_name; \
  438:             if ((__constant_name = malloc((strlen(__library_name) + \
  439:                     strlen(__function_name) - 9) * sizeof(char))) == NULL) \
  440:                 systemError("Memory allocation error"); \
  441:             sprintf(__constant_name, "%s$%s", __library_name, \
  442:                     &(__function_name[11])); \
  443:             setName(object, __constant_name); \
  444:             free(__constant_name); \
  445:         } \
  446:     } \
  447:     else \
  448:     { \
  449:         if (strcmp(#type, "integer") == 0) \
  450:         { \
  451:             createIntegerObject(object); \
  452:             setInteger(object, value); \
  453:         } \
  454:         else if (strcmp(#type, "real") == 0) \
  455:         { \
  456:             createRealObject(object); \
  457:             setReal(object, value); \
  458:         } \
  459:     } \
  460:     __constante--; } while(0)
  461: 
  462: #define createSymbolicComplexConstant(object, rp, ip) { \
  463:     __taille_bloc = sizeof(t_8_bits) * 8; \
  464:     __indice_bloc = (35 - 1) / __taille_bloc; \
  465:     __indice_bit = (35 - 1) % __taille_bloc; \
  466:     __masque = ((t_8_bits) 1) << (__taille_bloc - __indice_bit - 1); \
  467:     if (((*rpl_arguments).drapeaux_etat[__indice_bloc] & __masque) != 0) \
  468:     { \
  469:         createNameObject(object); \
  470:         { \
  471:             char *__constant_name; \
  472:             if ((__constant_name = malloc((strlen(__library_name) + \
  473:                     strlen(__function_name) + 2) * sizeof(char))) == NULL) \
  474:                 systemError("Memory allocation error"); \
  475:             sprintf(__constant_name, "%s$%s", __library_name, \
  476:                     __function_name); \
  477:             setName(object, __constant_name); \
  478:             free(__constant_name); \
  479:         } \
  480:     } \
  481:     else \
  482:     { \
  483:         createComplexObject(object); \
  484:         setComplex(object, rp, im); \
  485:     } \
  486:     __constante--; } while(0)
  487: 
  488: // Integer
  489: 
  490: #define setInteger(object, value) { \
  491:     ifIsInteger(object) \
  492:     { \
  493:         if ((*object).nombre_occurrences > 1) \
  494:         { \
  495:             struct_objet *__tmp_object; \
  496:             if ((__tmp_object = copie_objet(object, 'O')) == NULL) \
  497:                 systemError("Memory allocation error"); \
  498:             liberation(object); \
  499:             object = __tmp_object; \
  500:         } \
  501:         (*((integer8 *) (*object).objet)) = (integer8) value; \
  502:     } \
  503:     else executionError("Type mistmatch error"); } while(0)
  504: 
  505: #define isInteger(object) \
  506:     ((*object).type == INT)
  507: 
  508: #define ifIsInteger(object) if (isInteger(object))
  509: #define elseIfIsInteger(object) } else ifIsInteger(object)
  510: 
  511: #define getInteger(object, value) { \
  512:     value = 0; \
  513:     ifIsInteger(object) value = (*((integer8 *) (*object).objet)); \
  514:     else executionError("Type mismatch error"); } while(0)
  515: 
  516: #define createIntegerObject(object) { \
  517:     if (object != NULL) \
  518:         systemError("Reallocated object"); \
  519:     if ((object = allocation(INT)) == NULL) \
  520:         systemError("Memory allocation error"); \
  521:     setInteger(object, 0); } while(0)
  522: 
  523: // Real
  524: 
  525: #define setReal(object, value) { \
  526:     ifIsReal(object) \
  527:     { \
  528:         if ((*object).nombre_occurrences > 1) \
  529:         { \
  530:             struct_objet *__tmp_object; \
  531:             if ((__tmp_object = copie_objet(object, 'O')) == NULL) \
  532:                 systemError("Memory allocation error"); \
  533:             liberation(object); \
  534:             object = __tmp_object; \
  535:         } \
  536:         (*((real8 *) (*object).objet)) = (real8) value; \
  537:     } \
  538:     else executionError("Type mistmatch error"); } while(0)
  539: 
  540: #define isReal(object) \
  541:     ((*object).type == REL)
  542: 
  543: #define ifIsReal(object) if (isReal(object))
  544: #define elseIfIsReal(object) } else ifIsReal(object)
  545: 
  546: #define getReal(object, value) { \
  547:     value = 0; \
  548:     ifIsReal(object) value = (*((real8 *) (*object).objet)); \
  549:     else executionError("Type mismatch error"); } while(0)
  550: 
  551: #define createRealObject(object) { \
  552:     if (object != NULL) \
  553:         systemError("Reallocated object"); \
  554:     if ((object = allocation(REL)) == NULL) \
  555:         systemError("Memory allocation error"); \
  556:     setReal(object, 0); } while(0)
  557: 
  558: // Complex
  559: 
  560: #define setComplex(object, rp, ip) { \
  561:     typeof(rp) __rp = rp; \
  562:     typeof(ip) __ip = ip; \
  563:     ifIsComplex(object) \
  564:     { \
  565:         if ((*object).nombre_occurrences > 1) \
  566:         { \
  567:             struct_objet *__tmp_object; \
  568:             if ((__tmp_object = copie_objet(object, 'O')) == NULL) \
  569:                 systemError("Memory allocation error"); \
  570:             liberation(object); \
  571:             object = __tmp_object; \
  572:         } \
  573:         setRealPartOfComplex(object, __rp); \
  574:         setImaginaryPartOfComplex(object, __ip); \
  575:     } \
  576:     else executionError("Type mismatch error"); } while(0)
  577: 
  578: #define setRealPartOfComplex(object, value) { \
  579:     if ((*object).nombre_occurrences > 1) \
  580:     { \
  581:         struct_objet *__tmp_object; \
  582:         if ((__tmp_object = copie_objet(object, 'O')) == NULL) \
  583:             systemError("Memory allocation error"); \
  584:         liberation(object); \
  585:         object = __tmp_object; \
  586:     } \
  587:     ifIsComplex(object) (*((complex16 *) (*object).objet)).partie_reelle = \
  588:             value; \
  589:     else executionError("Type mismatch error"); } while(0)
  590: 
  591: #define setImaginaryPartOfComplex(object, value) { \
  592:     if ((*object).nombre_occurrences > 1) \
  593:     { \
  594:         struct_objet *__tmp_object; \
  595:         if ((__tmp_object = copie_objet(object, 'O')) == NULL) \
  596:             systemError("Memory allocation error"); \
  597:         liberation(object); \
  598:         object = __tmp_object; \
  599:     } \
  600:     (*((complex16 *) (*object).objet)).partie_imaginaire = value; \
  601:     else executionError("Type mismatch error"); } while(0)
  602: 
  603: #define getRealPartOfComplex(object, value) \
  604:     value = (*((complex16 *) (*object).objet)).partie_reelle
  605: 
  606: #define getImaginaryPartOfComplex(object, value) \
  607:     value = (*((complex16 *) (*object).objet)).partie_imaginaire
  608: 
  609: #define isComplex(object) \
  610:     ((*object).type == CPL)
  611: 
  612: #define ifIsComplex(object) if (isComplex(object))
  613: #define elseIfIsComplex(object) } else ifIsComplex(object)
  614: 
  615: #define getComplex(object, value) { \
  616:     value.partie_reelle = 0; \
  617:     value.partie_imaginaire = 0; \
  618:     ifIsComplex(object) value = (*((complex16 *) (*object).objet)); \
  619:     else systemError("Not a complex"); } while(0)
  620: 
  621: #define createComplexObject(object) { \
  622:     if (object != NULL) \
  623:         systemError("Reallocated object"); \
  624:     if ((object = allocation(CPL)) == NULL) \
  625:         systemError("Memory allocation error"); \
  626:     setComplex(object, 0, 0); } while(0)
  627: 
  628: // Generalized vectors
  629: 
  630: #define createVectorObject(object, size, otype, structure, cat) { \
  631:     integer8 i; \
  632:     if (object != NULL) \
  633:         systemError("Reallocated object"); \
  634:     if ((object = allocation(cat)) == NULL) \
  635:         systemError("Memory allocation error"); \
  636:     (*((structure *) (*object).objet)).taille = size; \
  637:     if (((*((structure *) (*object).objet)).tableau = \
  638:             malloc(size * sizeof(otype))) == NULL) \
  639:         systemError("Memory allocation error"); \
  640:     if (cat != VCX) \
  641:     { \
  642:         if (cat == VIN) \
  643:             (*((structure *) (*object).objet)).type = 'I'; \
  644:         else \
  645:             (*((structure *) (*object).objet)).type = 'R'; \
  646:         for(i = 0; i < size; ((otype *) (*((structure *) (*object).objet)) \
  647:                 .tableau)[i++] = (otype) 0); \
  648:     } \
  649:     else \
  650:     { \
  651:         (*((structure *) (*object).objet)).type = 'C'; \
  652:         for(i = 0; i < size; i++) \
  653:         { \
  654:             ((complex16 *) (*((structure *) (*object).objet)).tableau)[i] \
  655:                     .partie_reelle = 0; \
  656:             ((complex16 *) (*((structure *) (*object).objet)).tableau)[i] \
  657:                     .partie_imaginaire = 0; \
  658:         } \
  659:     } } while(0)
  660: 
  661: // Integer vector
  662: 
  663: #define setIntegerIntoVector(object, value, position) { \
  664:     typeof(position) __position = position; \
  665:     ifIsIntegerVector(object) \
  666:     { \
  667:         if ((*object).nombre_occurrences > 1) \
  668:         { \
  669:             struct_objet *__tmp_object; \
  670:             if ((__tmp_object = copie_objet(object, 'O')) == NULL) \
  671:                 systemError("Memory allocation error"); \
  672:             liberation(object); \
  673:             object = __tmp_object; \
  674:         } \
  675:         __position--; \
  676:         if ((__position < 0) || (__position >= (*((struct_vecteur *) \
  677:                 (*object).objet)).taille)) \
  678:             { executionError("Element out of range"); } \
  679:         else \
  680:             ((integer8 *) (*((struct_vecteur *) (*object).objet)).tableau) \
  681:                     [__position] = (integer8) value; \
  682:     } \
  683:     else executionError("Type mistmatch error"); } while(0)
  684: 
  685: #define isIntegerVector(object) \
  686:     ((*object).type == VIN)
  687: 
  688: #define ifIsIntegerVector(object) if (isIntegerVector(object))
  689: #define elseIfIsIntegerVector(object) } else ifIsIntegerVector(object)
  690: 
  691: #define getIntegerFromVector(object, value, position) { \
  692:     typeof(position) __position = position; \
  693:     value = 0; \
  694:     ifIsIntegerVector(object) \
  695:     { \
  696:         __position--; \
  697:         if ((__position < 0) || (__position >= (*((struct_vecteur *) \
  698:                 (*object).objet)).taille)) \
  699:             executionError("Element out of range"); \
  700:         else \
  701:             value = ((integer8 *) (*((struct_vecteur *) (*object).objet)) \
  702:                 .tableau)[__position]; \
  703:     } \
  704:     else executionError("Type mismatch error"); } while(0)
  705: 
  706: #define createIntegerVectorObject(object, size) \
  707:     createVectorObject(object, size, integer8, struct_vecteur, VIN)
  708: 
  709: // Real vector
  710: 
  711: #define setRealIntoVector(object, value, position) { \
  712:     typeof(position) __position = position; \
  713:     ifIsRealVector(object) \
  714:     { \
  715:         if ((*object).nombre_occurrences > 1) \
  716:         { \
  717:             struct_objet *__tmp_object; \
  718:             if ((__tmp_object = copie_objet(object, 'O')) == NULL) \
  719:                 systemError("Memory allocation error"); \
  720:             liberation(object); \
  721:             object = __tmp_object; \
  722:         } \
  723:         __position--; \
  724:         if ((__position < 0) || (__position >= (*((struct_vecteur *) \
  725:                 (*object).objet)).taille)) \
  726:             { executionError("Element out of range"); } \
  727:         else \
  728:             ((real8 *) (*((struct_vecteur *) (*object).objet)).tableau) \
  729:                     [__position] = (real8) value; \
  730:     } \
  731:     else executionError("Type mistmatch error"); } while(0)
  732: 
  733: #define isRealVector(object) \
  734:     ((*object).type == VRL)
  735: 
  736: #define ifIsRealVector(object) if (isRealVector(object))
  737: #define elseIfIsRealVector(object) } else ifIsRealVector(object)
  738: 
  739: #define getRealFromVector(object, value, position) { \
  740:     typeof(position) __position = position; \
  741:     value = 0; \
  742:     ifIsRealVector(object) \
  743:     { \
  744:         __position--; \
  745:         if ((__position < 0) || (__position >= (*((struct_vecteur *) \
  746:                 (*object).objet)).taille)) \
  747:             executionError("Element out of range"); \
  748:         value = ((real8 *) (*((struct_vecteur *) (*object).objet)).tableau) \
  749:                 [__position]; \
  750:     } \
  751:     else executionError("Type mismatch error"); } while(0)
  752: 
  753: #define createRealVectorObject(object, size) \
  754:     createVectorObject(object, size, real8, struct_vecteur, VRL)
  755: 
  756: // A FIXER
  757: 
  758: #define createComplexVectorObject
  759: 
  760: #define createIntegerMatrixObject
  761: 
  762: #define createRealMatrixObject
  763: 
  764: #define createComplexMatrixObject
  765: 
  766: // Binary integer
  767: 
  768: #define setBinaryInteger(object, value) { \
  769:     ifIsBinaryInteger(object) \
  770:     { \
  771:         if ((*object).nombre_occurrences > 1) \
  772:         { \
  773:             struct_objet *__tmp_object; \
  774:             if ((__tmp_object = copie_objet(object, 'O')) == NULL) \
  775:                 systemError("Memory allocation error"); \
  776:             liberation(object); \
  777:             object = __tmp_object; \
  778:         } \
  779:         (*((integer8 *) (*object).objet)) = (integer8) value; \
  780:     } \
  781:     else executionError("Type mistmatch error"); } while(0)
  782: 
  783: #define isBinaryInteger(object) \
  784:     ((*object).type == BIN)
  785: 
  786: #define ifIsBinaryInteger(object) if (isBinaryInteger(object))
  787: #define elseIfIsBinaryInteger(object) } else ifIsBinaryInteger(object)
  788: 
  789: #define getBinaryInteger(object, value) { \
  790:     value = 0; \
  791:     ifIsBinaryInteger(object) value = (*((integer8 *) (*object).objet)); \
  792:     else executionError("Type mismatch error"); } while(0)
  793: 
  794: #define createBinaryIntegerObject(object) { \
  795:     if (object != NULL) \
  796:         systemError("Reallocated object"); \
  797:     if ((object = allocation(BIN)) == NULL) \
  798:         systemError("Memory allocation error"); \
  799:     setBinaryInteger(object, 0); } while(0)
  800: 
  801: // Name
  802: 
  803: #define isName(object) \
  804:     ((*object).type == NOM)
  805: 
  806: #define ifIsName(object) if (isName(object))
  807: #define elseIfIsName(object)  } else if (isName(object))
  808: 
  809: #define setName(object, value) { \
  810:     ifIsName(object) \
  811:     { \
  812:         if ((*object).nombre_occurrences > 1) \
  813:         { \
  814:             struct_objet *__tmp_object; \
  815:             if ((__tmp_object = copie_objet(object, 'O')) == NULL) \
  816:                 systemError("Memory allocation error"); \
  817:             liberation(object); \
  818:             object = __tmp_object; \
  819:         } \
  820:         free((*((struct_nom *) (*object).objet)).nom); \
  821:         (*((struct_nom *) (*object).objet)).symbole = d_faux; \
  822:         if (((*((struct_nom *) (*object).objet)).nom = malloc( \
  823:                 (strlen(value) + 1) * sizeof(unsigned char))) == NULL) \
  824:             systemError("Memory allocation error"); \
  825:         strcpy((char *) (*((struct_nom *) (*object).objet)).nom, \
  826:                 (char *) value); \
  827:     } \
  828:     else executionError("Type mistmatch error"); } while(0)
  829: 
  830: #define createNameObject(object) { \
  831:     if (object != NULL) \
  832:         systemError("Reallocated object"); \
  833:     if ((object = allocation(NOM)) == NULL) \
  834:         systemError("Memory allocation error"); \
  835:     (*((struct_nom *) (*object).objet)).symbole = d_faux; \
  836:     if (((*((struct_nom *) (*object).objet)).nom = malloc( \
  837:             sizeof(unsigned char))) == NULL) \
  838:         systemError("Memory allocation error"); \
  839:     strcpy((char *) (*((struct_nom *) (*object).objet)).nom, ""); } while(0)
  840: 
  841: // String
  842: 
  843: #define isString(object) \
  844:     ((*object).type == CHN)
  845: 
  846: #define ifIsString(object) if (isString(object))
  847: #define elseIfIsString(object) else if (isString(objet))
  848: 
  849: #define setString(object, string) { \
  850:     ifIsString(object) \
  851:     { \
  852:         if ((*object).nombre_occurrences > 1) \
  853:         { \
  854:             struct_objet *__tmp_object; \
  855:             if ((__tmp_object = copie_objet(object, 'O')) == NULL) \
  856:                 systemError("Memory allocation error"); \
  857:             liberation(object); \
  858:             object = __tmp_object; \
  859:         } \
  860:         free((unsigned char *) (*object).objet); \
  861:         if (((*object).objet = malloc((strlen(string) + 1) * \
  862:                 sizeof(unsigned char))) == NULL) \
  863:             systemError("Memory allocation error"); \
  864:         strcpy((char *) (*object).objet, string); \
  865:     } \
  866:     else executionError("Type mistmatch error"); } while(0)
  867: 
  868: #define getString(object, string) { \
  869:     string = NULL; \
  870:     ifIsString(object) string = (char *) (*object).objet; \
  871:     else executionError("Type mismatch error"); } while(0)
  872: 
  873: #define createStringObject(object) { \
  874:     if (object != NULL) \
  875:         systemError("Reallocated object"); \
  876:     if ((object = allocation(CHN)) == NULL) \
  877:         systemError("Memory allocation error"); \
  878:     if (((*object).objet = malloc(sizeof(unsigned char))) == NULL) \
  879:         systemError("Memory allocation error"); \
  880:     strcpy((char *) (*object).objet, ""); } while(0)
  881: 
  882: // List
  883: 
  884: #define isList(object) \
  885:     ((*object).type == LST)
  886: 
  887: #define ifIsList(object) if (isList(object))
  888: #define elseIfIsList(object) else if (isList(object))
  889: 
  890: #define createListObject(object) { \
  891:     if (object != NULL) \
  892:         systemError("Reallocated object"); \
  893:     if ((object = allocation(LST)) == NULL) \
  894:         systemError("Memory allocation error"); \
  895:     (*object).objet = NULL; } while(0)
  896: 
  897: #define addObjectToList(list, object) { \
  898:     ifIsList(list) \
  899:     { \
  900:         struct_objet *__tmp_object; \
  901:         if ((__tmp_object = copie_objet(list, 'N')) == NULL) \
  902:             systemError("Memory allocation error"); \
  903:         liberation(list); \
  904:         list = __tmp_object; \
  905:         if ((*list).objet == NULL) \
  906:         { \
  907:             if (((*list).objet = malloc(sizeof(struct_liste_chainee))) \
  908:                     == NULL) \
  909:                 systemError("Memory allocation error"); \
  910:             (*((struct_liste_chainee *) (*list).objet)).suivant = NULL; \
  911:             (*((struct_liste_chainee *) (*list).objet)).donnee = object; \
  912:         } \
  913:         else \
  914:         { \
  915:             struct_liste_chainee    *l_element_courant; \
  916:             l_element_courant = (*list).objet; \
  917:             while((*l_element_courant).suivant != NULL) \
  918:                 l_element_courant = (*l_element_courant).suivant; \
  919:             if (((*l_element_courant).suivant = \
  920:                     malloc(sizeof(struct_liste_chainee))) == NULL) \
  921:                 systemError("Memory allocation error"); \
  922:             l_element_courant = (*l_element_courant).suivant; \
  923:             (*l_element_courant).suivant = NULL; \
  924:             (*l_element_courant).donnee = object; \
  925:         } \
  926:         object = NULL; \
  927:     } \
  928:     else executionError("Type mistmatch error"); } while(0)
  929: 
  930: #define insertObjectIntoList(list, object) { \
  931:     ifIsList(list) \
  932:     { \
  933:         struct_objet *__tmp_object; \
  934:         if ((__tmp_object = copie_objet(list, 'N')) == NULL) \
  935:             systemError("Memory allocation error"); \
  936:         liberation(list); \
  937:         list = __tmp_object; \
  938:         if ((*list).objet == NULL) \
  939:         { \
  940:             if (((*list).objet = malloc(sizeof(struct_liste_chainee))) \
  941:                     == NULL) \
  942:                 systemError("Memory allocation error"); \
  943:             (*((struct_liste_chainee *) (*list).objet)).suivant = NULL; \
  944:             (*((struct_liste_chainee *) (*list).objet)).donnee = object; \
  945:         } \
  946:         else \
  947:         { \
  948:             struct_liste_chainee    *l_element_courant; \
  949:             if ((l_element_courant = \
  950:                     malloc(sizeof(struct_liste_chainee))) == NULL) \
  951:                 systemError("Memory allocation error"); \
  952:             (*l_element_courant).donnee = object; \
  953:             (*l_element_courant).suivant = (*list).objet; \
  954:             (*list).objet = l_element_courant; \
  955:         } \
  956:         object = NULL; \
  957:     } \
  958:     else executionError("Type mistmatch error"); } while(0)
  959: 
  960: #define removeObjectFromList(list, object) \
  961:     ifIsList(list) \
  962:     { \
  963:         if ((*object).objet == NULL) \
  964:         { \
  965:             struct_objet *__tmp_object; \
  966:             if ((__tmp_object = copie_objet(list, 'N')) == NULL) \
  967:                 systemError("Memory allocation error"); \
  968:             liberation(object); \
  969:             object = __tmp_object; \
  970:             \
  971:             \
  972:             \
  973:             \
  974:         } \
  975:     } \
  976:     else executionError("Type mistmatch error"); } while(0)
  977: 
  978: #define getObjectFromList(list, position, object)
  979: 
  980: #define putObjectIntoList(list, position, object)
  981: 
  982: #define getListFromList(list, position1, position2, object)
  983: 
  984: #define listLength(list, length) { \
  985:     if (list == NULL) executionError("Nullified object"); \
  986:     if ((*list).type != LST) \
  987:             executionError("Type mistmatch error"); \
  988:     { \
  989:         struct_liste_chainee        *l_element_courant; \
  990:         length = 0; \
  991:         l_element_courant = (*list).objet; \
  992:         while(l_element_courant != NULL) \
  993:         { \
  994:             l_element_courant = (*l_element_courant).suivant; \
  995:             length++; \
  996:         } \
  997:     } } while(0)
  998: 
  999: 
 1000: /*
 1001: --------------------------------------------------------------------------------
 1002:   Destruction d'un objet
 1003: --------------------------------------------------------------------------------
 1004: */
 1005: 
 1006: #define freeObject(object) \
 1007:     { \
 1008:         if (object == NULL) \
 1009:             systemError("Nullified object"); \
 1010:         liberation(object); \
 1011:         object = NULL; \
 1012:     } while(0)
 1013: 
 1014: /*
 1015: --------------------------------------------------------------------------------
 1016:   Copie d'un objet
 1017: --------------------------------------------------------------------------------
 1018: */
 1019: 
 1020: #define dupObject(object) \
 1021:     { if (copie_objet(object, 'P') != object) \
 1022:         systemError("Memory allocation error"); } while(0)
 1023: 
 1024: /*
 1025: --------------------------------------------------------------------------------
 1026:   Allocation mémoire
 1027: --------------------------------------------------------------------------------
 1028: */
 1029: 
 1030: #define size(a) sizeof(a)
 1031: 
 1032: #define allocate(a) ({ void *ptr; \
 1033:     if ((ptr = malloc(a)) == NULL) \
 1034:             systemError("Memory allocation error"); ptr; })
 1035: 
 1036: #define deallocate(a) free(a)
 1037: 
 1038: /*
 1039: --------------------------------------------------------------------------------
 1040:   Exécution d'une fonction intrinsèque
 1041: --------------------------------------------------------------------------------
 1042: */
 1043: 
 1044: #define intrinsic(function) { \
 1045:     int __status; \
 1046:     __status = wrapper_instruction_intrinseque( \
 1047:             instruction_##function, rpl_arguments); \
 1048:     if (__status == 1) executionError(#function); \
 1049:     if (__status == 2) systemError(#function); \
 1050:     } while(0)
 1051: 
 1052: #endif
 1053: 
 1054: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>