File:  [local] / rpl / src / interface_cas.cpp
Revision 1.15: download - view: text, annotated - select for diffs - revision graph
Tue Aug 9 11:31:36 2011 UTC (12 years, 8 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
En route pour la 4.1.3.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.3
    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: #ifdef RPLCAS
   24: #   include "giac.h"
   25: 
   26: #   undef PACKAGE
   27: #   undef PACKAGE_NAME
   28: #   undef PACKAGE_STRING
   29: #   undef PACKAGE_TARNAME
   30: #   undef PACKAGE_VERSION
   31: #   undef VERSION
   32: #endif
   33: 
   34: extern "C"
   35: {
   36: #   define __RPLCAS
   37: #   include "rpl-conv.h"
   38: }
   39: 
   40: #include <iostream>
   41: 
   42: using namespace std;
   43: 
   44: #ifdef RPLCAS
   45:     using namespace giac;
   46: #endif
   47: 
   48: void
   49: initialisation_contexte_cas(struct_processus *s_etat_processus)
   50: {
   51:     s_etat_processus->contexte_cas = NULL;
   52:     return;
   53: }
   54: 
   55: void
   56: liberation_contexte_cas(struct_processus *s_etat_processus)
   57: {
   58:     if (s_etat_processus->contexte_cas != NULL)
   59:     {
   60:         delete reinterpret_cast<giac::context *>(
   61:                 s_etat_processus->contexte_cas);
   62:         s_etat_processus->contexte_cas = NULL;
   63:     }
   64: 
   65:     return;
   66: }
   67: 
   68: static unsigned char *
   69: conversion_rpl_vers_cas(struct_processus *s_etat_processus,
   70:         struct_objet **s_objet)
   71: {
   72:     logical1                drapeau;
   73: 
   74:     struct_liste_chainee    *l_element_courant;
   75:     struct_liste_chainee    *l_element_precedent;
   76: 
   77:     struct_objet            *s_objet_temporaire;
   78: 
   79:     t_8_bits                registre[8];
   80: 
   81:     unsigned char           *resultat;
   82:     unsigned char           *index;
   83: 
   84:     for(int i = 0; i < 8; i++)
   85:     {
   86:         registre[i] = s_etat_processus->drapeaux_etat[i];
   87:     }
   88: 
   89:     sf(s_etat_processus, 35);
   90:     cf(s_etat_processus, 48);
   91:     cf(s_etat_processus, 49);
   92:     cf(s_etat_processus, 50);
   93:     cf(s_etat_processus, 53);
   94:     cf(s_etat_processus, 54);
   95:     cf(s_etat_processus, 55);
   96:     cf(s_etat_processus, 56);
   97: 
   98:     // GIAC considère que les fonctions sont écrites en minuscules. Le RPL/2
   99:     // part de l'hypothèse inverse. Il faut donc convertir en minuscules tous
  100:     // les noms de fonction. Les fonctions ne peuvent apparaître que dans le
  101:     // cas d'un objet de type ALG.
  102: 
  103:     if ((*s_objet)->type == NOM)
  104:     {
  105:         if (strcmp((const char *) reinterpret_cast<unsigned char *>(
  106:                 reinterpret_cast<struct_nom *>((*s_objet)->objet)->nom),
  107:                 "infinity") == 0)
  108:         {
  109:             if (evaluation(s_etat_processus, *s_objet, 'N') == d_erreur)
  110:             {
  111:                 return(NULL);
  112:             }
  113: 
  114:             liberation(s_etat_processus, *s_objet);
  115: 
  116:             if (depilement(s_etat_processus, &(s_etat_processus
  117:                     ->l_base_pile), s_objet) == d_erreur)
  118:             {
  119:                 return(NULL);
  120:             }
  121:         }
  122:     }
  123:     else if ((*s_objet)->type == ALG)
  124:     {
  125:         if ((s_objet_temporaire = copie_objet(s_etat_processus,
  126:                 (*s_objet), 'O')) == NULL)
  127:         {
  128:             s_etat_processus->erreur_systeme = d_es_allocation_memoire;
  129:             return(NULL);
  130:         }
  131: 
  132:         liberation(s_etat_processus, (*s_objet));
  133:         (*s_objet) = s_objet_temporaire;
  134: 
  135:         // Si l'expression contient la fonction infinity, on commence par
  136:         // forcer une évaluation numérique.
  137: 
  138:         l_element_courant = reinterpret_cast<struct_liste_chainee *>(
  139:                 (*s_objet)->objet);
  140:         drapeau = d_faux;
  141: 
  142:         while(l_element_courant != NULL)
  143:         {
  144:             if (l_element_courant->donnee->type == NOM)
  145:             {
  146:                 if (strcmp((const char *) reinterpret_cast<unsigned char *>(
  147:                         reinterpret_cast<struct_nom *>(
  148:                         l_element_courant->donnee->objet)->nom),
  149:                         "infinity") == 0)
  150:                 {
  151:                     drapeau = d_vrai;
  152:                     break;
  153:                 }
  154:             }
  155: 
  156:             l_element_courant = l_element_courant->suivant;
  157:         }
  158: 
  159:         if (drapeau == d_vrai)
  160:         {
  161:             if (evaluation(s_etat_processus, *s_objet, 'N') == d_erreur)
  162:             {
  163:                 return(NULL);
  164:             }
  165: 
  166:             liberation(s_etat_processus, *s_objet);
  167: 
  168:             if (depilement(s_etat_processus, &(s_etat_processus
  169:                     ->l_base_pile), s_objet) == d_erreur)
  170:             {
  171:                 return(NULL);
  172:             }
  173:         }
  174:     }
  175: 
  176:     if ((*s_objet)->type == ALG)
  177:     {
  178: 
  179:         l_element_courant = reinterpret_cast<struct_liste_chainee *>(
  180:                 (*s_objet)->objet);
  181: 
  182:         while(l_element_courant != NULL)
  183:         {
  184:             if (l_element_courant->donnee->type == FCT)
  185:             {
  186:                 unsigned char       *ptr;
  187: 
  188:                 ptr = reinterpret_cast<unsigned char *>(
  189:                         reinterpret_cast<struct_fonction *>(
  190:                         l_element_courant->donnee->objet)->nom_fonction);
  191: 
  192:                 while((*ptr) != d_code_fin_chaine)
  193:                 {
  194:                     int c = (*ptr);
  195: 
  196:                     if (isalpha(c))
  197:                     {
  198:                         c = tolower(c);
  199:                         (*ptr) = (unsigned char) c;
  200:                     }
  201: 
  202:                     ptr++;
  203:                 }
  204:             }
  205: 
  206:             l_element_precedent = l_element_courant;
  207:             l_element_courant = l_element_courant->suivant;
  208:         }
  209:     }
  210: 
  211:     resultat = formateur(s_etat_processus, 0, (*s_objet));
  212: 
  213:     // Il faut remplacer les occurrences de 'relax' par '    +'.
  214: 
  215:     index = resultat;
  216:     while((index = reinterpret_cast<unsigned char *>(
  217:             strstr(reinterpret_cast<char *>(index),
  218:             (const char *) "relax"))) != NULL)
  219:     {
  220:         strncpy(reinterpret_cast<char *>(index), "    +", 5);
  221:     }
  222: 
  223:     // Si le résultat vaut infinity, on rajoute le signe +.
  224: 
  225:     if (strcmp(reinterpret_cast<char *>(resultat), "infinity") == 0)
  226:     {
  227:         if ((resultat = reinterpret_cast<unsigned char *>(
  228:                 realloc(resultat, (strlen(reinterpret_cast<char *>(
  229:                 resultat)) + 2) * sizeof(unsigned char)))) == NULL)
  230:         {
  231:             s_etat_processus->erreur_systeme = d_es_allocation_memoire;
  232:             return(NULL);
  233:         }
  234: 
  235:         strcpy(reinterpret_cast<char *>(resultat), "+infinity");
  236:     }
  237: 
  238:     if (resultat[0] == '\'')
  239:     {
  240:         resultat[0] = ' ';
  241:         resultat[strlen((const char *) resultat) - 1] = ' ';
  242:     }
  243: 
  244:     for(int i = 0; i < 8; i++)
  245:     {
  246:         s_etat_processus->drapeaux_etat[i] = registre[i];
  247:     }
  248: 
  249:     return(resultat);
  250: }
  251: 
  252: 
  253: static void
  254: conversion_cas_vers_rpl(struct_processus *s_etat_processus,
  255:         unsigned char *expression)
  256: {
  257:     logical1                    drapeau;
  258: 
  259:     struct_liste_chainee        *l_element_courant;
  260:     struct_liste_chainee        *l_element_precedent;
  261: 
  262:     struct_objet                *s_objet;
  263: 
  264:     unsigned char               *registre;
  265: 
  266:     registre = s_etat_processus->instruction_courante;
  267:     s_etat_processus->instruction_courante = expression;
  268:     recherche_type(s_etat_processus);
  269:     s_etat_processus->instruction_courante = registre;
  270: 
  271:     if ((s_etat_processus->l_base_pile == NULL) ||
  272:             (s_etat_processus->erreur_execution != d_ex) ||
  273:             (s_etat_processus->erreur_systeme != d_es))
  274:     {
  275:         return;
  276:     }
  277: 
  278:     // Le niveau 1 de la pile opérationnelle contient l'expression
  279:     // à convertir.
  280: 
  281:     if (depilement(s_etat_processus, &(s_etat_processus
  282:             ->l_base_pile), &s_objet) == d_erreur)
  283:     {
  284:         return;
  285:     }
  286: 
  287:     if ((s_objet->type == ALG) || (s_objet->type == RPN))
  288:     {
  289:         // On transcrit les fonctions de GIAC vers le RPL/2.
  290: 
  291:         l_element_courant = reinterpret_cast<struct_liste_chainee *>(
  292:                 s_objet->objet);
  293:         drapeau = d_faux;
  294: 
  295:         // S'il y a une valeur infini, on force l'évaluation de l'expression.
  296: 
  297:         while(l_element_courant != NULL)
  298:         {
  299:             if (l_element_courant->donnee->type == NOM)
  300:             {
  301:                 if (strcmp((const char *) reinterpret_cast<unsigned char *>(
  302:                         reinterpret_cast<struct_nom *>(
  303:                         l_element_courant->donnee->objet)->nom),
  304:                         "infinity") == 0)
  305:                 {
  306:                     drapeau = d_vrai;
  307:                     break;
  308:                 }
  309:             }
  310: 
  311:             l_element_courant = l_element_courant->suivant;
  312:         }
  313: 
  314:         if (drapeau == d_vrai)
  315:         {
  316:             if (evaluation(s_etat_processus, s_objet, 'N') == d_erreur)
  317:             {
  318:                 return;
  319:             }
  320: 
  321:             liberation(s_etat_processus, s_objet);
  322: 
  323:             if (depilement(s_etat_processus, &(s_etat_processus
  324:                     ->l_base_pile), &s_objet) == d_erreur)
  325:             {
  326:                 return;
  327:             }
  328:         }
  329:     }
  330: 
  331:     if ((s_objet->type == ALG) || (s_objet->type == RPN))
  332:     {
  333:         l_element_precedent = NULL;
  334:         l_element_courant = reinterpret_cast<struct_liste_chainee *>(
  335:                 s_objet->objet);
  336: 
  337:         while(l_element_courant != NULL)
  338:         {
  339:             if (l_element_courant->donnee->type == FCT)
  340:             {
  341:                 // Nous sommes en présence d'un nom, donc de quelque chose
  342:                 // qui n'est pas reconnu comme un mot-clef du RPL/2. S'il
  343:                 // s'agit d'un mot-clef de GIAC, on le convertit.
  344: 
  345:                 if ((strcmp((const char *)
  346:                         reinterpret_cast<struct_fonction *>(l_element_courant
  347:                         ->donnee->objet)->nom_fonction, "quote") == 0) ||
  348:                         (strcmp((const char *)
  349:                         reinterpret_cast<struct_fonction *>(l_element_courant
  350:                         ->donnee->objet)->nom_fonction, "nop") == 0))
  351:                 {
  352:                     liberation(s_etat_processus, l_element_courant->donnee);
  353: 
  354:                     if ((l_element_courant->donnee =
  355:                             allocation(s_etat_processus, FCT)) == NULL)
  356:                     {
  357:                         s_etat_processus->erreur_systeme =
  358:                                 d_es_allocation_memoire;
  359:                         return;
  360:                     }
  361: 
  362:                     if ((((struct_fonction *) l_element_courant->donnee->objet)
  363:                             ->nom_fonction = reinterpret_cast<unsigned char *>(
  364:                             malloc(6 * sizeof(unsigned char))))
  365:                             == NULL)
  366:                     {
  367:                         s_etat_processus->erreur_systeme =
  368:                                 d_es_allocation_memoire;
  369:                         return;
  370:                     }
  371: 
  372:                     strcpy(reinterpret_cast<char *>(
  373:                             reinterpret_cast<struct_fonction *>(
  374:                             l_element_courant->donnee->objet)->nom_fonction),
  375:                             "RELAX");
  376:                 }
  377:             }
  378: 
  379:             l_element_precedent = l_element_courant;
  380:             l_element_courant = l_element_courant->suivant;
  381:         }
  382:     }
  383: 
  384:     if (empilement(s_etat_processus, &(s_etat_processus->l_base_pile),
  385:             s_objet) == d_erreur)
  386:     {
  387:         return;
  388:     }
  389: 
  390:     return;
  391: }
  392: 
  393: 
  394: /*
  395: ================================================================================
  396:   Fonction 'interface_cas'
  397: ================================================================================
  398:   Entrées : commande à effectuer.
  399:   Le contrôle des types est effectué dans la fonction appelant interface_cas().
  400: --------------------------------------------------------------------------------
  401:   Sorties : retour par la pile.
  402: --------------------------------------------------------------------------------
  403:   Effets de bord : néant
  404: ================================================================================
  405: */
  406: 
  407: void
  408: interface_cas(struct_processus *s_etat_processus,
  409:         enum t_rplcas_commandes commande)
  410: {
  411: #   ifdef RPLCAS
  412:     struct_objet            *s_objet_argument_1;
  413:     struct_objet            *s_objet_argument_2;
  414:     struct_objet            *s_objet_temporaire;
  415: 
  416:     struct_liste_chainee    *l_element_courant;
  417: 
  418:     unsigned char           *argument_1;
  419:     unsigned char           *argument_2;
  420:     unsigned char           *argument_3;
  421:     unsigned char           *argument_4;
  422: 
  423:     unsigned int            position;
  424: 
  425:     giac::context           *contexte;
  426: 
  427:     if (s_etat_processus->contexte_cas == NULL)
  428:     {
  429:         try
  430:         {
  431:             s_etat_processus->contexte_cas = new giac::context;
  432:         }
  433:         catch(bad_alloc exception)
  434:         {
  435:             s_etat_processus->erreur_systeme = d_es_allocation_memoire;
  436:             return;
  437:         }
  438:         catch(...)
  439:         {
  440:             s_etat_processus->erreur_execution = d_ex_erreur_interne_rplcas;
  441:             return;
  442:         }
  443:     }
  444: 
  445:     contexte = reinterpret_cast<giac::context *>(
  446:             s_etat_processus->contexte_cas);
  447: 
  448:     if ((s_etat_processus->erreur_execution != d_ex) ||
  449:             (s_etat_processus->erreur_systeme != d_es))
  450:     {
  451:         return;
  452:     }
  453: 
  454:     switch(commande)
  455:     {
  456:         case RPLCAS_INTEGRATION:
  457:         {
  458:             if (depilement(s_etat_processus, &(s_etat_processus->l_base_pile),
  459:                     &s_objet_argument_1) == d_erreur)
  460:             {
  461:                 s_etat_processus->erreur_execution = d_ex_manque_argument;
  462:                 return;
  463:             }
  464: 
  465:             if (depilement(s_etat_processus, &(s_etat_processus->l_base_pile),
  466:                     &s_objet_argument_2) == d_erreur)
  467:             {
  468:                 liberation(s_etat_processus, s_objet_argument_1);
  469:                 s_etat_processus->erreur_execution = d_ex_manque_argument;
  470:                 return;
  471:             }
  472: 
  473:             if ((argument_1 = conversion_rpl_vers_cas(s_etat_processus,
  474:                     &s_objet_argument_1)) == NULL)
  475:             {
  476:                 s_etat_processus->erreur_systeme = d_es_allocation_memoire;
  477:                 return;
  478:             }
  479: 
  480:             if ((argument_2 = conversion_rpl_vers_cas(s_etat_processus,
  481:                     &s_objet_argument_2)) == NULL)
  482:             {
  483:                 s_etat_processus->erreur_systeme = d_es_allocation_memoire;
  484:                 return;
  485:             }
  486: 
  487:             liberation(s_etat_processus, s_objet_argument_1);
  488:             liberation(s_etat_processus, s_objet_argument_2);
  489: 
  490:             try
  491:             {
  492:                 gen variable(
  493:                         string(reinterpret_cast<const char *>(argument_1)),
  494:                         contexte);
  495:                 gen expression(
  496:                         string(reinterpret_cast<const char *>(argument_2)),
  497:                         contexte);
  498: 
  499:                 gen resultat = integrate_gen(expression, variable,
  500:                         contexte);
  501:                 string chaine = "'" + resultat.print() + "'";
  502: 
  503:                 conversion_cas_vers_rpl(s_etat_processus,
  504:                         reinterpret_cast<unsigned char *>(const_cast<char *>(
  505:                         chaine.c_str())));
  506:             }
  507:             catch(bad_alloc exception)
  508:             {
  509:                 s_etat_processus->erreur_systeme = d_es_allocation_memoire;
  510:             }
  511:             catch(...)
  512:             {
  513:                 s_etat_processus->erreur_execution = d_ex_erreur_interne_rplcas;
  514:             }
  515: 
  516:             free(argument_1);
  517:             free(argument_2);
  518: 
  519:             break;
  520:         }
  521: 
  522:         case RPLCAS_LIMITE:
  523:         {
  524:             if (depilement(s_etat_processus, &(s_etat_processus->l_base_pile),
  525:                     &s_objet_argument_1) == d_erreur)
  526:             {
  527:                 s_etat_processus->erreur_execution = d_ex_manque_argument;
  528:                 return;
  529:             }
  530: 
  531:             if (depilement(s_etat_processus, &(s_etat_processus->l_base_pile),
  532:                     &s_objet_argument_2) == d_erreur)
  533:             {
  534:                 liberation(s_etat_processus, s_objet_argument_1);
  535:                 s_etat_processus->erreur_execution = d_ex_manque_argument;
  536:                 return;
  537:             }
  538: 
  539:             // Fonction
  540: 
  541:             if ((argument_2 = conversion_rpl_vers_cas(s_etat_processus,
  542:                     &s_objet_argument_2)) == NULL)
  543:             {
  544:                 s_etat_processus->erreur_systeme = d_es_allocation_memoire;
  545:                 return;
  546:             }
  547: 
  548:             // On parcourt la liste. Cette liste est tout d'abord copiée
  549:             // car on est susceptible de modifier le second élément.
  550: 
  551:             if ((s_objet_temporaire = copie_objet(s_etat_processus,
  552:                     s_objet_argument_1, 'O')) == NULL)
  553:             {
  554:                 s_etat_processus->erreur_systeme = d_es_allocation_memoire;
  555:                 return;
  556:             }
  557: 
  558:             liberation(s_etat_processus, s_objet_argument_1);
  559:             s_objet_argument_1 = s_objet_temporaire;
  560: 
  561:             l_element_courant = reinterpret_cast<struct_liste_chainee *>
  562:                     (s_objet_argument_1->objet);
  563:             position = 1;
  564:             argument_4 = NULL;
  565: 
  566:             while(l_element_courant != NULL)
  567:             {
  568:                 switch(position)
  569:                 {
  570:                     case 1:
  571:                     {
  572:                         // Variable
  573: 
  574:                         if ((argument_1 = reinterpret_cast<unsigned char *>
  575:                                 (malloc((strlen((const char *)
  576:                                 ((struct_variable *) (l_element_courant
  577:                                 ->donnee->objet))->nom)
  578:                                 + 1) * sizeof(unsigned char)))) == NULL)
  579:                         {
  580:                             s_etat_processus->erreur_systeme =
  581:                                     d_es_allocation_memoire;
  582:                             return;
  583:                         }
  584: 
  585:                         strcpy(reinterpret_cast<char *>(argument_1),
  586:                                 (const char *) ((struct_variable *)
  587:                                 (l_element_courant->donnee->objet))->nom);
  588:                         break;
  589:                     }
  590: 
  591:                     case 2:
  592:                     {
  593:                         // Valeur
  594:                         if ((argument_3 = conversion_rpl_vers_cas(
  595:                                 s_etat_processus,
  596:                                 &(l_element_courant->donnee))) == NULL)
  597:                         {
  598:                             s_etat_processus->erreur_systeme =
  599:                                     d_es_allocation_memoire;
  600:                             return;
  601:                         }
  602: 
  603:                         break;
  604:                     }
  605: 
  606:                     case 3:
  607:                     {
  608:                         // Direction
  609: 
  610:                         if ((argument_4 = reinterpret_cast<unsigned char *>
  611:                                 (malloc((strlen((const char *)
  612:                                 ((struct_fonction *) (l_element_courant
  613:                                 ->donnee->objet))->nom_fonction)
  614:                                 + 1) * sizeof(unsigned char)))) == NULL)
  615:                         {
  616:                             s_etat_processus->erreur_systeme =
  617:                                     d_es_allocation_memoire;
  618:                             return;
  619:                         }
  620: 
  621:                         strcpy(reinterpret_cast<char *>(argument_4),
  622:                                 (const char *) ((struct_fonction *)
  623:                                 (l_element_courant->donnee->objet))
  624:                                 ->nom_fonction);
  625:                         break;
  626:                     }
  627:                 }
  628: 
  629:                 l_element_courant = (*l_element_courant).suivant;
  630:                 position++;
  631:             }
  632: 
  633:             liberation(s_etat_processus, s_objet_argument_1);
  634:             liberation(s_etat_processus, s_objet_argument_2);
  635: 
  636:             try
  637:             {
  638:                 int             direction;
  639: 
  640:                 if (argument_4 == NULL)
  641:                 {
  642:                     direction = 0;
  643:                 }
  644:                 else
  645:                 {
  646:                     direction = (strcmp((const char *) argument_4, "+") == 0)
  647:                             ? 1 : -1;
  648:                 }
  649: 
  650:                 gen expression(
  651:                         string(reinterpret_cast<const char *>(argument_2)),
  652:                         contexte);
  653:                 identificateur variable(
  654:                         string(reinterpret_cast<const char *>(argument_1)));
  655:                 gen valeur(string(reinterpret_cast<const char *>
  656:                         (argument_3)), contexte);
  657: 
  658:                 gen resultat = limit(expression, variable, valeur, direction,
  659:                         contexte);
  660:                 string chaine = "'" + resultat.print() + "'";
  661: 
  662:                 conversion_cas_vers_rpl(s_etat_processus,
  663:                         reinterpret_cast<unsigned char *>(const_cast<char *>(
  664:                         chaine.c_str())));
  665:             }
  666:             catch(bad_alloc exception)
  667:             {
  668:                 s_etat_processus->erreur_systeme = d_es_allocation_memoire;
  669:             }
  670:             catch(...)
  671:             {
  672:                 s_etat_processus->erreur_execution = d_ex_erreur_interne_rplcas;
  673:             }
  674: 
  675:             free(argument_1);
  676:             free(argument_2);
  677:             free(argument_3);
  678: 
  679:             if (argument_4 != NULL)
  680:             {
  681:                 free(argument_4);
  682:             }
  683: 
  684:             break;
  685:         }
  686:     }
  687: 
  688:     return;
  689: 
  690: #else
  691: 
  692:     if (s_etat_processus->langue == 'F')
  693:     {
  694:         printf("+++Attention : RPL/CAS non compilé !\n");
  695:     }
  696:     else
  697:     {
  698:         printf("+++Warning : RPL/CAS not available !\n");
  699:     }
  700: 
  701:     fflush(stdout);
  702: 
  703:     return;
  704: 
  705: #endif
  706: }
  707: 
  708: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>