Annotation of rpl/src/formateur_flux.c, revision 1.19

1.1       bertrand    1: /*
                      2: ================================================================================
1.18      bertrand    3:   RPL/2 (R) version 4.1.5
1.19    ! bertrand    4:   Copyright (C) 1989-2012 Dr. BERTRAND Joël
1.1       bertrand    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: 
1.14      bertrand  244: 
                    245: /*
                    246: ================================================================================
1.15      bertrand  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:            {
1.16      bertrand  271:                chaine += 2;
1.15      bertrand  272:            }
                    273:            else if ((*(chaine + 1)) == 'b')
                    274:            {
1.16      bertrand  275:                chaine += 2;
1.15      bertrand  276:            }
                    277:            else if ((*(chaine + 1)) == 'n')
                    278:            {
1.16      bertrand  279:                chaine += 2;
1.15      bertrand  280:            }
                    281:            else if ((*(chaine + 1)) == 't')
                    282:            {
1.16      bertrand  283:                chaine += 2;
1.15      bertrand  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:                }
1.16      bertrand  350: 
                    351:                chaine += 4;
1.15      bertrand  352:            }
                    353:            else if ((*(chaine + 1)) == '\\')
                    354:            {
1.16      bertrand  355:                chaine += 2;
1.15      bertrand  356:            }
                    357:            else
                    358:            {
                    359:                // Tous les autres cas sont invalides
                    360:                return(d_faux);
                    361:            }
                    362:        }
                    363:        else
                    364:        {
1.16      bertrand  365:            chaine++;
1.15      bertrand  366:        }
                    367:    }
                    368: 
                    369:    return(d_vrai);
                    370: }
                    371: 
                    372: 
                    373: /*
                    374: ================================================================================
1.14      bertrand  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: 
1.15      bertrand  390:    if (chaine == NULL)
                    391:    {
                    392:        return(NULL);
                    393:    }
                    394: 
1.14      bertrand  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:        {
1.16      bertrand  530:            suivant = chaine + 2;
1.14      bertrand  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: 
1.15      bertrand  597: 
                    598: /*
                    599: ================================================================================
                    600:   Routine retournant un pointeur sur le i-ème caractère d'une chaîne
                    601: ================================================================================
1.17      bertrand  602:   Entrées : structure sur l'état du processus, chaîne et position du caractère
1.15      bertrand  603: --------------------------------------------------------------------------------
1.17      bertrand  604:   Sorties : pointeur sur le caractère
1.15      bertrand  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: 
1.17      bertrand  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: 
1.1       bertrand  729: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>