File:  [local] / rpl / src / formateur_flux.c
Revision 1.18: download - view: text, annotated - select for diffs - revision graph
Sat Nov 26 10:01:26 2011 UTC (12 years, 5 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
En route pour la 4.1.5. Correction d'un bug mineur sur les mutexes.
Préparation d'un mécanisme pour éviter qu'un mutex soit déverrouillé
depuis un thread qui ne l'a pas verrouillé.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.5
    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: #include "rpl-conv.h"
   24: 
   25: 
   26: /*
   27: ================================================================================
   28:   Routine de formation des données pour l'envoi de flux binaires
   29: ================================================================================
   30:   Entrées : structure sur l'état du processus et objet à afficher
   31: --------------------------------------------------------------------------------
   32:   Sorties : chaine de caractères
   33: --------------------------------------------------------------------------------
   34:   Effets de bord : néant
   35: ================================================================================
   36: */
   37: 
   38: unsigned char *
   39: formateur_flux(struct_processus *s_etat_processus, unsigned char *donnees,
   40:         long *longueur)
   41: {
   42:     unsigned char           *chaine;
   43: 
   44:     unsigned char           *ptr_ecriture;
   45:     unsigned char           *ptr_lecture;
   46: 
   47:     if ((chaine = malloc((strlen(donnees) + 1) * sizeof(unsigned char)))
   48:             == NULL)
   49:     {
   50:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
   51:         return(NULL);
   52:     }
   53: 
   54:     ptr_lecture = donnees;
   55:     ptr_ecriture = chaine;
   56: 
   57:     while((*ptr_lecture) != d_code_fin_chaine)
   58:     {
   59:         (*ptr_ecriture) = (*ptr_lecture);
   60: 
   61:         // Début de la séquence d'échappement
   62: 
   63:         if ((*ptr_lecture) == '\\')
   64:         {
   65:             if ((*(ptr_lecture + 1)) == '"')
   66:             {
   67:                 ptr_lecture++;
   68:                 (*ptr_ecriture) = '\"';
   69:             }
   70:             else if ((*(ptr_lecture + 1)) == 'b')
   71:             {
   72:                 ptr_lecture++;
   73:                 (*ptr_ecriture) = '\b';
   74:             }
   75:             else if ((*(ptr_lecture + 1)) == 'n')
   76:             {
   77:                 ptr_lecture++;
   78:                 (*ptr_ecriture) = '\n';
   79:             }
   80:             else if ((*(ptr_lecture + 1)) == 't')
   81:             {
   82:                 ptr_lecture++;
   83:                 (*ptr_ecriture) = '\t';
   84:             }
   85:             else if ((*(ptr_lecture + 1)) == 'x')
   86:             {
   87:                 ptr_lecture += 2;
   88: 
   89:                 if ((*ptr_lecture) != d_code_fin_chaine)
   90:                 {
   91:                     if ((*(ptr_lecture + 1)) != d_code_fin_chaine)
   92:                     {
   93:                         logical1        erreur;
   94:                         unsigned char   ec;
   95: 
   96:                         erreur = d_faux;
   97: 
   98:                         switch(*ptr_lecture)
   99:                         {
  100:                             case '0':
  101:                             case '1':
  102:                             case '2':
  103:                             case '3':
  104:                             case '4':
  105:                             case '5':
  106:                             case '6':
  107:                             case '7':
  108:                             case '8':
  109:                             case '9':
  110:                                 ec = (*ptr_lecture) - '0';
  111:                                 break;
  112: 
  113:                             case 'A':
  114:                             case 'B':
  115:                             case 'C':
  116:                             case 'D':
  117:                             case 'E':
  118:                             case 'F':
  119:                                 ec = ((*ptr_lecture) - 'A') + 10;
  120:                                 break;
  121: 
  122:                             default:
  123:                                 ec = 0;
  124:                                 erreur = d_vrai;
  125:                                 break;
  126:                         }
  127: 
  128:                         ec *= 0x10;
  129:                         ptr_lecture++;
  130: 
  131:                         switch(*ptr_lecture)
  132:                         {
  133:                             case '0':
  134:                             case '1':
  135:                             case '2':
  136:                             case '3':
  137:                             case '4':
  138:                             case '5':
  139:                             case '6':
  140:                             case '7':
  141:                             case '8':
  142:                             case '9':
  143:                                 ec += (*ptr_lecture) - '0';
  144:                                 break;
  145: 
  146:                             case 'A':
  147:                             case 'B':
  148:                             case 'C':
  149:                             case 'D':
  150:                             case 'E':
  151:                             case 'F':
  152:                                 ec += ((*ptr_lecture) - 'A') + 10;
  153:                                 break;
  154: 
  155:                             default:
  156:                                 erreur = d_vrai;
  157:                                 break;
  158:                         }
  159: 
  160:                         (*ptr_ecriture) = ec;
  161: 
  162:                         if (erreur == d_vrai)
  163:                         {
  164:                             if ((*s_etat_processus).langue == 'F')
  165:                             {
  166:                                 printf("+++Information : "
  167:                                         "Séquence d'échappement "
  168:                                         "inconnue [%d]\n",
  169:                                         (int) getpid());
  170:                             }
  171:                             else
  172:                             {
  173:                                 printf("+++Warning : Unknown "
  174:                                         "escape code "
  175:                                         "[%d]\n", (int) getpid());
  176:                             }
  177:                         }
  178:                     }
  179:                     else
  180:                     {
  181:                         if ((*s_etat_processus).langue == 'F')
  182:                         {
  183:                             printf("+++Information : "
  184:                                     "Séquence d'échappement "
  185:                                     "inconnue [%d]\n", (int) getpid());
  186:                         }
  187:                         else
  188:                         {
  189:                             printf("+++Warning : Unknown escape code "
  190:                                     "[%d]\n", (int) getpid());
  191:                         }
  192:                     }
  193:                 }
  194:                 else
  195:                 {
  196:                     if ((*s_etat_processus).langue == 'F')
  197:                     {
  198:                         printf("+++Information : "
  199:                                 "Séquence d'échappement "
  200:                                 "inconnue [%d]\n", (int) getpid());
  201:                     }
  202:                     else
  203:                     {
  204:                         printf("+++Warning : Unknown escape code "
  205:                                 "[%d]\n", (int) getpid());
  206:                     }
  207:                 }
  208:             }
  209:             else if ((*(ptr_lecture + 1)) == '\\')
  210:             {
  211:                 ptr_lecture++;
  212:             }
  213:             else
  214:             {
  215:                 if ((*s_etat_processus).langue == 'F')
  216:                 {
  217:                     printf("+++Information : Séquence d'échappement "
  218:                             "inconnue [%d]\n", (int) getpid());
  219:                 }
  220:                 else
  221:                 {
  222:                     printf("+++Warning : Unknown escape code "
  223:                             "[%d]\n", (int) getpid());
  224:                 }
  225:             }
  226:         }
  227: 
  228:         ptr_ecriture++;
  229:         ptr_lecture++;
  230:     }
  231: 
  232:     (*ptr_ecriture) = d_code_fin_chaine;
  233: 
  234:     if ((chaine = realloc(chaine, ((((*longueur) = ptr_ecriture - chaine)) + 1)
  235:             * sizeof(unsigned char))) == NULL)
  236:     {
  237:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  238:         return(NULL);
  239:     }
  240: 
  241:     return(chaine);
  242: }
  243: 
  244: 
  245: /*
  246: ================================================================================
  247:   Routine testant la validité d'une chaîne de caractères
  248: ================================================================================
  249:   Entrées : structure sur l'état du processus et chaîne courante
  250: --------------------------------------------------------------------------------
  251:   Sorties : pointeur sur le caractère suivant
  252: --------------------------------------------------------------------------------
  253:   Effets de bord : néant
  254: ================================================================================
  255: */
  256: 
  257: logical1
  258: validation_chaine(unsigned char *chaine)
  259: {
  260:     if (chaine == NULL)
  261:     {
  262:         return(d_faux);
  263:     }
  264: 
  265:     while((*chaine) != d_code_fin_chaine)
  266:     {
  267:         if ((*chaine) == '\\')
  268:         {
  269:             if ((*(chaine + 1)) == '"')
  270:             {
  271:                 chaine += 2;
  272:             }
  273:             else if ((*(chaine + 1)) == 'b')
  274:             {
  275:                 chaine += 2;
  276:             }
  277:             else if ((*(chaine + 1)) == 'n')
  278:             {
  279:                 chaine += 2;
  280:             }
  281:             else if ((*(chaine + 1)) == 't')
  282:             {
  283:                 chaine += 2;
  284:             }
  285:             else if ((*(chaine + 1)) == 'x')
  286:             {
  287:                 if ((*(chaine + 2)) != d_code_fin_chaine)
  288:                 {
  289:                     if ((*(chaine + 3)) != d_code_fin_chaine)
  290:                     {
  291:                         switch(*(chaine + 2))
  292:                         {
  293:                             case '0':
  294:                             case '1':
  295:                             case '2':
  296:                             case '3':
  297:                             case '4':
  298:                             case '5':
  299:                             case '6':
  300:                             case '7':
  301:                             case '8':
  302:                             case '9':
  303:                             case 'A':
  304:                             case 'B':
  305:                             case 'C':
  306:                             case 'D':
  307:                             case 'E':
  308:                             case 'F':
  309:                                 break;
  310: 
  311:                             default:
  312:                                 return(d_faux);
  313:                                 break;
  314:                         }
  315: 
  316:                         switch(*(chaine + 3))
  317:                         {
  318:                             case '0':
  319:                             case '1':
  320:                             case '2':
  321:                             case '3':
  322:                             case '4':
  323:                             case '5':
  324:                             case '6':
  325:                             case '7':
  326:                             case '8':
  327:                             case '9':
  328:                             case 'A':
  329:                             case 'B':
  330:                             case 'C':
  331:                             case 'D':
  332:                             case 'E':
  333:                             case 'F':
  334:                                 break;
  335: 
  336:                             default:
  337:                                 return(d_faux);
  338:                                 break;
  339:                         }
  340:                     }
  341:                     else
  342:                     {
  343:                         return(d_faux);
  344:                     }
  345:                 }
  346:                 else
  347:                 {
  348:                     return(d_faux);
  349:                 }
  350: 
  351:                 chaine += 4;
  352:             }
  353:             else if ((*(chaine + 1)) == '\\')
  354:             {
  355:                 chaine += 2;
  356:             }
  357:             else
  358:             {
  359:                 // Tous les autres cas sont invalides
  360:                 return(d_faux);
  361:             }
  362:         }
  363:         else
  364:         {
  365:             chaine++;
  366:         }
  367:     }
  368: 
  369:     return(d_vrai);
  370: }
  371: 
  372: 
  373: /*
  374: ================================================================================
  375:   Routine permettant de trouver le caractère suivant dans une chaîne
  376: ================================================================================
  377:   Entrées : structure sur l'état du processus et chaîne courante
  378: --------------------------------------------------------------------------------
  379:   Sorties : pointeur sur le caractère suivant
  380: --------------------------------------------------------------------------------
  381:   Effets de bord : néant
  382: ================================================================================
  383: */
  384: 
  385: static inline unsigned char *
  386: prochain_caractere(struct_processus *s_etat_processus, unsigned char *chaine)
  387: {
  388:     unsigned char       *suivant;
  389: 
  390:     if (chaine == NULL)
  391:     {
  392:         return(NULL);
  393:     }
  394: 
  395:     if ((*chaine) == '\\')
  396:     {
  397:         if ((*(chaine + 1)) == '"')
  398:         {
  399:             suivant = chaine + 2;
  400:         }
  401:         else if ((*(chaine + 1)) == 'b')
  402:         {
  403:             suivant = chaine + 2;
  404:         }
  405:         else if ((*(chaine + 1)) == 'n')
  406:         {
  407:             suivant = chaine + 2;
  408:         }
  409:         else if ((*(chaine + 1)) == 't')
  410:         {
  411:             suivant = chaine + 2;
  412:         }
  413:         else if ((*(chaine + 1)) == 'x')
  414:         {
  415:             if ((*(chaine + 2)) != d_code_fin_chaine)
  416:             {
  417:                 if ((*(chaine + 3)) != d_code_fin_chaine)
  418:                 {
  419:                     logical1        erreur;
  420: 
  421:                     erreur = d_faux;
  422: 
  423:                     switch(*(chaine + 2))
  424:                     {
  425:                         case '0':
  426:                         case '1':
  427:                         case '2':
  428:                         case '3':
  429:                         case '4':
  430:                         case '5':
  431:                         case '6':
  432:                         case '7':
  433:                         case '8':
  434:                         case '9':
  435:                         case 'A':
  436:                         case 'B':
  437:                         case 'C':
  438:                         case 'D':
  439:                         case 'E':
  440:                         case 'F':
  441:                             break;
  442: 
  443:                         default:
  444:                             erreur = d_vrai;
  445:                             break;
  446:                     }
  447: 
  448:                     switch(*(chaine + 3))
  449:                     {
  450:                         case '0':
  451:                         case '1':
  452:                         case '2':
  453:                         case '3':
  454:                         case '4':
  455:                         case '5':
  456:                         case '6':
  457:                         case '7':
  458:                         case '8':
  459:                         case '9':
  460:                         case 'A':
  461:                         case 'B':
  462:                         case 'C':
  463:                         case 'D':
  464:                         case 'E':
  465:                         case 'F':
  466:                             break;
  467: 
  468:                         default:
  469:                             erreur = d_vrai;
  470:                             break;
  471:                     }
  472: 
  473:                     if (erreur == d_vrai)
  474:                     {
  475:                         if ((*s_etat_processus).langue == 'F')
  476:                         {
  477:                             printf("+++Information : "
  478:                                     "Séquence d'échappement "
  479:                                     "inconnue [%d]\n",
  480:                                     (int) getpid());
  481:                         }
  482:                         else
  483:                         {
  484:                             printf("+++Warning : Unknown "
  485:                                     "escape code "
  486:                                     "[%d]\n", (int) getpid());
  487:                         }
  488: 
  489:                         return(NULL);
  490:                     }
  491: 
  492:                     suivant = chaine + 4;
  493:                 }
  494:                 else
  495:                 {
  496:                     if ((*s_etat_processus).langue == 'F')
  497:                     {
  498:                         printf("+++Information : "
  499:                                 "Séquence d'échappement "
  500:                                 "inconnue [%d]\n", (int) getpid());
  501:                     }
  502:                     else
  503:                     {
  504:                         printf("+++Warning : Unknown escape code "
  505:                                 "[%d]\n", (int) getpid());
  506:                     }
  507: 
  508:                     return(NULL);
  509:                 }
  510:             }
  511:             else
  512:             {
  513:                 if ((*s_etat_processus).langue == 'F')
  514:                 {
  515:                     printf("+++Information : "
  516:                             "Séquence d'échappement "
  517:                             "inconnue [%d]\n", (int) getpid());
  518:                 }
  519:                 else
  520:                 {
  521:                     printf("+++Warning : Unknown escape code "
  522:                             "[%d]\n", (int) getpid());
  523:                 }
  524: 
  525:                 return(NULL);
  526:             }
  527:         }
  528:         else if ((*(chaine + 1)) == '\\')
  529:         {
  530:             suivant = chaine + 2;
  531:         }
  532:         else
  533:         {
  534:             if ((*s_etat_processus).langue == 'F')
  535:             {
  536:                 printf("+++Information : Séquence d'échappement "
  537:                         "inconnue [%d]\n", (int) getpid());
  538:             }
  539:             else
  540:             {
  541:                 printf("+++Warning : Unknown escape code "
  542:                         "[%d]\n", (int) getpid());
  543:             }
  544: 
  545:             return(NULL);
  546:         }
  547:     }
  548:     else
  549:     {
  550:         suivant = chaine + 1;
  551:     }
  552: 
  553:     return(suivant);
  554: }
  555: 
  556: 
  557: /*
  558: ================================================================================
  559:   Routine donnant la longueur d'une chaîne de caractères
  560: ================================================================================
  561:   Entrées : structure sur l'état du processus et chaîne
  562: --------------------------------------------------------------------------------
  563:   Sorties : longueur de la chaîne
  564: --------------------------------------------------------------------------------
  565:   Effets de bord : néant
  566: ================================================================================
  567: */
  568: 
  569: integer8
  570: longueur_chaine(struct_processus *s_etat_processus, unsigned char *chaine)
  571: {
  572:     integer8        nombre_caracteres;
  573: 
  574:     unsigned char   *pointeur;
  575: 
  576:     pointeur = chaine;
  577:     nombre_caracteres = 0;
  578: 
  579:     if ((*pointeur) == '\0')
  580:     {
  581:         return(0);
  582:     }
  583: 
  584:     do
  585:     {
  586:         if ((pointeur = prochain_caractere(s_etat_processus, pointeur)) == NULL)
  587:         {
  588:             return(0);
  589:         }
  590: 
  591:         nombre_caracteres++;
  592:     } while((*pointeur) != 0);
  593: 
  594:     return(nombre_caracteres);
  595: }
  596: 
  597: 
  598: /*
  599: ================================================================================
  600:   Routine retournant un pointeur sur le i-ème caractère d'une chaîne
  601: ================================================================================
  602:   Entrées : structure sur l'état du processus, chaîne et position du caractère
  603: --------------------------------------------------------------------------------
  604:   Sorties : pointeur sur le caractère
  605: --------------------------------------------------------------------------------
  606:   Effets de bord : néant
  607: ================================================================================
  608: */
  609: 
  610: unsigned char *
  611: pointeur_ieme_caractere(struct_processus *s_etat_processus,
  612:         unsigned char *chaine, integer8 position)
  613: {
  614:     integer8            i;
  615: 
  616:     unsigned char       *pointeur;
  617: 
  618:     if ((pointeur = chaine) == NULL)
  619:     {
  620:         return(NULL);
  621:     }
  622: 
  623:     for(i = 0; i < position; i++)
  624:     {
  625:         pointeur = prochain_caractere(s_etat_processus, pointeur);
  626: 
  627:         if ((*pointeur) == d_code_fin_chaine)
  628:         {
  629:             return(pointeur);
  630:         }
  631:     }
  632: 
  633:     return(pointeur);
  634: }
  635: 
  636: 
  637: /*
  638: ================================================================================
  639:   Routine retournant la position du caractère en fonction du pointeur
  640:   dans la chaîne
  641: ================================================================================
  642:   Entrées : structure sur l'état du processus, chaîne et position
  643: --------------------------------------------------------------------------------
  644:   Sorties : quantième dans la chaîne
  645: --------------------------------------------------------------------------------
  646:   Effets de bord : néant
  647: ================================================================================
  648: */
  649: 
  650: integer8
  651: position_caractere_de_chaine(struct_processus *s_etat_processus,
  652:         unsigned char *chaine, unsigned char *position)
  653: {
  654:     integer8            i;
  655: 
  656:     i = 1;
  657: 
  658:     while(chaine != position)
  659:     {
  660:         chaine = prochain_caractere(s_etat_processus, chaine);
  661:         i++;
  662: 
  663:         if ((*chaine) == d_code_fin_chaine)
  664:         {
  665:             return(0);
  666:         }
  667:     }
  668: 
  669:     return(i);
  670: }
  671: 
  672: 
  673: /*
  674: ================================================================================
  675:   Conversion d'une chaîne en majuscule ou en minuscule
  676: ================================================================================
  677:   Entrées : chaîne et indicateur ('M' pour majuscules, 'm' pour minuscules)
  678: --------------------------------------------------------------------------------
  679:   Sorties : néant
  680: --------------------------------------------------------------------------------
  681:   Effets de bord : néant
  682: ================================================================================
  683: */
  684: 
  685: void
  686: conversion_chaine(struct_processus *s_etat_processus,
  687:         unsigned char *chaine, unsigned char type)
  688: {
  689:     int                 (*fonction_1)(int);
  690:     int                 (*fonction_2)(int);
  691: 
  692:     unsigned char       *ptr;
  693:     unsigned char       *ptr2;
  694:     unsigned char       registre;
  695: 
  696:     if (type == 'M')
  697:     {
  698:         fonction_1 = toupper;
  699:         fonction_2 = tolower;
  700:     }
  701:     else
  702:     {
  703:         fonction_1 = tolower;
  704:         fonction_2 = toupper;
  705:     }
  706: 
  707:     ptr = chaine;
  708: 
  709:     while((*ptr) != d_code_fin_chaine)
  710:     {
  711:         ptr2 = prochain_caractere(s_etat_processus, ptr);
  712: 
  713:         if ((ptr2 - ptr) == 1)
  714:         {
  715:             registre = fonction_1((*ptr));
  716: 
  717:             if (fonction_2(registre) == (*ptr))
  718:             {
  719:                 (*ptr) = registre;
  720:             }
  721:         }
  722: 
  723:         ptr = ptr2;
  724:     }
  725: 
  726:     return;
  727: }
  728: 
  729: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>