Return to formateur_flux.c CVS log | Up to [local] / rpl / src |
1.1 bertrand 1: /*
2: ================================================================================
1.32 bertrand 3: RPL/2 (R) version 4.1.13
1.30 bertrand 4: Copyright (C) 1989-2013 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,
1.34 bertrand 40: integer8 *longueur)
1.1 bertrand 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':
1.34 bertrand 110: ec = (unsigned char) ((*ptr_lecture) - '0');
1.1 bertrand 111: break;
112:
113: case 'A':
114: case 'B':
115: case 'C':
116: case 'D':
117: case 'E':
118: case 'F':
1.34 bertrand 119: ec = (unsigned char) (((*ptr_lecture) - 'A')
120: + 10);
1.1 bertrand 121: break;
122:
123: default:
124: ec = 0;
125: erreur = d_vrai;
126: break;
127: }
128:
1.34 bertrand 129: ec = (unsigned char) (ec * (unsigned char) 0x10);
1.1 bertrand 130: ptr_lecture++;
131:
132: switch(*ptr_lecture)
133: {
134: case '0':
135: case '1':
136: case '2':
137: case '3':
138: case '4':
139: case '5':
140: case '6':
141: case '7':
142: case '8':
143: case '9':
1.34 bertrand 144: ec = (unsigned char) (ec +
145: ((*ptr_lecture) - '0'));
1.1 bertrand 146: break;
147:
148: case 'A':
149: case 'B':
150: case 'C':
151: case 'D':
152: case 'E':
153: case 'F':
1.34 bertrand 154: ec = (unsigned char) (ec +
155: (((*ptr_lecture) - 'A') + 10));
1.1 bertrand 156: break;
157:
158: default:
159: erreur = d_vrai;
160: break;
161: }
162:
163: (*ptr_ecriture) = ec;
164:
165: if (erreur == d_vrai)
166: {
167: if ((*s_etat_processus).langue == 'F')
168: {
169: printf("+++Information : "
170: "Séquence d'échappement "
1.33 bertrand 171: "inconnue (\\x%c%c) [%d]\n",
172: *ptr_lecture, *(ptr_lecture + 1),
1.1 bertrand 173: (int) getpid());
174: }
175: else
176: {
177: printf("+++Warning : Unknown "
1.33 bertrand 178: "escape code (\\x%c%c) [%d]\n",
179: *ptr_lecture, *(ptr_lecture + 1),
180: (int) getpid());
1.1 bertrand 181: }
182: }
183: }
184: else
185: {
186: if ((*s_etat_processus).langue == 'F')
187: {
188: printf("+++Information : "
189: "Séquence d'échappement "
1.33 bertrand 190: "tronquée [%d]\n", (int) getpid());
1.1 bertrand 191: }
192: else
193: {
1.33 bertrand 194: printf("+++Warning : Truncated escape code "
1.1 bertrand 195: "[%d]\n", (int) getpid());
196: }
197: }
198: }
199: else
200: {
201: if ((*s_etat_processus).langue == 'F')
202: {
203: printf("+++Information : "
204: "Séquence d'échappement "
205: "inconnue [%d]\n", (int) getpid());
206: }
207: else
208: {
209: printf("+++Warning : Unknown escape code "
210: "[%d]\n", (int) getpid());
211: }
212: }
213: }
214: else if ((*(ptr_lecture + 1)) == '\\')
215: {
216: ptr_lecture++;
217: }
218: else
219: {
1.33 bertrand 220: if ((*(ptr_lecture + 1)) == d_code_fin_chaine)
1.1 bertrand 221: {
1.33 bertrand 222: if ((*s_etat_processus).langue == 'F')
223: {
224: printf("+++Information : "
225: "Séquence d'échappement "
226: "tronquée [%d]\n", (int) getpid());
227: }
228: else
229: {
230: printf("+++Warning : Truncated escape code "
231: "[%d]\n", (int) getpid());
232: }
1.1 bertrand 233: }
234: else
1.33 bertrand 235: {
236: if ((*s_etat_processus).langue == 'F')
237: {
238: printf("+++Information : Séquence d'échappement "
239: "inconnue (%c%c) [%d]\n",
240: *ptr_lecture, *(ptr_lecture + 1),
241: (int) getpid());
242: }
243: else
244: {
245: printf("+++Warning : Unknown escape code (%c%c) "
246: "[%d]\n", *ptr_lecture, *(ptr_lecture + 1),
247: (int) getpid());
248: }
1.1 bertrand 249: }
250: }
251: }
252:
253: ptr_ecriture++;
254: ptr_lecture++;
255: }
256:
257: (*ptr_ecriture) = d_code_fin_chaine;
258:
1.34 bertrand 259: if ((chaine = realloc(chaine, (((size_t) ((*longueur) =
1.35 ! bertrand 260: ptr_ecriture - chaine)) + 1) * sizeof(unsigned char))) == NULL)
1.1 bertrand 261: {
262: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
263: return(NULL);
264: }
265:
266: return(chaine);
267: }
268:
1.14 bertrand 269:
270: /*
271: ================================================================================
1.24 bertrand 272: Routine de d'analyse d'un flux
273: ================================================================================
274: Entrées : structure sur l'état du processus et objet à afficher
275: --------------------------------------------------------------------------------
276: Sorties : chaine de caractères
277: --------------------------------------------------------------------------------
278: Effets de bord : néant
279: ================================================================================
280: */
281:
282: unsigned char *
283: analyse_flux(struct_processus *s_etat_processus, unsigned char *donnees,
1.34 bertrand 284: integer8 longueur)
1.24 bertrand 285: {
1.25 bertrand 286: long longueur_courante;
1.24 bertrand 287: long offset;
288:
289: unsigned char *chaine;
290: unsigned char hexadecimal[3];
291: unsigned char *ptr_ecriture;
292: unsigned char *ptr_lecture;
293:
1.34 bertrand 294: if ((chaine = malloc(((size_t) (longueur_courante = longueur + 1)) *
1.25 bertrand 295: sizeof(unsigned char))) == NULL)
1.24 bertrand 296: {
297: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
298: return(NULL);
299: }
300:
301: ptr_lecture = donnees;
302: ptr_ecriture = chaine;
303:
1.25 bertrand 304: while(longueur > 0)
1.24 bertrand 305: {
306: // Début de la séquence d'échappement
307:
308: switch((*ptr_lecture))
309: {
310: case '"':
311: case '\b':
312: case '\n':
313: case '\t':
1.33 bertrand 314: case '\\':
1.24 bertrand 315: {
316: offset = ptr_ecriture - chaine;
317:
1.34 bertrand 318: if ((chaine = realloc(chaine, ((size_t) (++longueur_courante))
1.24 bertrand 319: * sizeof(unsigned char))) == NULL)
320: {
321: (*s_etat_processus).erreur_systeme =
322: d_es_allocation_memoire;
323: return(NULL);
324: }
325:
326: ptr_ecriture = chaine + offset;
327: *ptr_ecriture++ = '\\';
1.25 bertrand 328:
329: switch((*ptr_lecture++))
330: {
331: case '"':
332: {
333: *ptr_ecriture++ = '"';
334: break;
335: }
336:
337: case '\b':
338: {
339: *ptr_ecriture++ = 'b';
340: break;
341: }
342:
343: case '\n':
344: {
345: *ptr_ecriture++ = 'n';
346: break;
347: }
348:
349: case '\t':
350: {
351: *ptr_ecriture++ = 't';
352: break;
353: }
1.33 bertrand 354:
355: case '\\':
356: {
357: *ptr_ecriture++ = '\\';
358: break;
359: }
1.25 bertrand 360: }
361:
1.24 bertrand 362: break;
363: }
364:
365: case ' ':
366: {
367: *ptr_ecriture++ = *ptr_lecture++;
368: break;
369: }
370:
371: default:
372: {
373: if (isgraph((*ptr_lecture)))
374: {
375: *ptr_ecriture++ = *ptr_lecture++;
376: }
377: else
378: {
379: offset = ptr_ecriture - chaine;
380:
1.34 bertrand 381: if ((chaine = realloc(chaine, ((size_t) (longueur_courante =
382: longueur_courante + 3)) * sizeof(unsigned char)))
1.25 bertrand 383: == NULL)
1.24 bertrand 384: {
385: (*s_etat_processus).erreur_systeme =
386: d_es_allocation_memoire;
387: return(NULL);
388: }
389:
390: ptr_ecriture = chaine + offset;
391: *ptr_ecriture++ = '\\';
392: *ptr_ecriture++ = 'x';
393:
394: sprintf(hexadecimal, "%02X", *ptr_lecture++);
395:
396: *ptr_ecriture++ = hexadecimal[0];
397: *ptr_ecriture++ = hexadecimal[1];
398: }
399:
400: break;
401: }
402: }
1.25 bertrand 403:
404: longueur--;
1.24 bertrand 405: }
406:
407: (*ptr_ecriture) = d_code_fin_chaine;
408:
409: return(chaine);
410: }
411:
412:
413: /*
414: ================================================================================
1.15 bertrand 415: Routine testant la validité d'une chaîne de caractères
416: ================================================================================
417: Entrées : structure sur l'état du processus et chaîne courante
418: --------------------------------------------------------------------------------
419: Sorties : pointeur sur le caractère suivant
420: --------------------------------------------------------------------------------
421: Effets de bord : néant
422: ================================================================================
423: */
424:
425: logical1
426: validation_chaine(unsigned char *chaine)
427: {
428: if (chaine == NULL)
429: {
430: return(d_faux);
431: }
432:
433: while((*chaine) != d_code_fin_chaine)
434: {
435: if ((*chaine) == '\\')
436: {
437: if ((*(chaine + 1)) == '"')
438: {
1.16 bertrand 439: chaine += 2;
1.15 bertrand 440: }
441: else if ((*(chaine + 1)) == 'b')
442: {
1.16 bertrand 443: chaine += 2;
1.15 bertrand 444: }
445: else if ((*(chaine + 1)) == 'n')
446: {
1.16 bertrand 447: chaine += 2;
1.15 bertrand 448: }
449: else if ((*(chaine + 1)) == 't')
450: {
1.16 bertrand 451: chaine += 2;
1.15 bertrand 452: }
453: else if ((*(chaine + 1)) == 'x')
454: {
455: if ((*(chaine + 2)) != d_code_fin_chaine)
456: {
457: if ((*(chaine + 3)) != d_code_fin_chaine)
458: {
459: switch(*(chaine + 2))
460: {
461: case '0':
462: case '1':
463: case '2':
464: case '3':
465: case '4':
466: case '5':
467: case '6':
468: case '7':
469: case '8':
470: case '9':
471: case 'A':
472: case 'B':
473: case 'C':
474: case 'D':
475: case 'E':
476: case 'F':
477: break;
478:
479: default:
480: return(d_faux);
481: break;
482: }
483:
484: switch(*(chaine + 3))
485: {
486: case '0':
487: case '1':
488: case '2':
489: case '3':
490: case '4':
491: case '5':
492: case '6':
493: case '7':
494: case '8':
495: case '9':
496: case 'A':
497: case 'B':
498: case 'C':
499: case 'D':
500: case 'E':
501: case 'F':
502: break;
503:
504: default:
505: return(d_faux);
506: break;
507: }
508: }
509: else
510: {
511: return(d_faux);
512: }
513: }
514: else
515: {
516: return(d_faux);
517: }
1.16 bertrand 518:
519: chaine += 4;
1.15 bertrand 520: }
521: else if ((*(chaine + 1)) == '\\')
522: {
1.16 bertrand 523: chaine += 2;
1.15 bertrand 524: }
525: else
526: {
527: // Tous les autres cas sont invalides
528: return(d_faux);
529: }
530: }
531: else
532: {
1.16 bertrand 533: chaine++;
1.15 bertrand 534: }
535: }
536:
537: return(d_vrai);
538: }
539:
540:
541: /*
542: ================================================================================
1.14 bertrand 543: Routine permettant de trouver le caractère suivant dans une chaîne
544: ================================================================================
545: Entrées : structure sur l'état du processus et chaîne courante
546: --------------------------------------------------------------------------------
547: Sorties : pointeur sur le caractère suivant
548: --------------------------------------------------------------------------------
549: Effets de bord : néant
550: ================================================================================
551: */
552:
553: static inline unsigned char *
554: prochain_caractere(struct_processus *s_etat_processus, unsigned char *chaine)
555: {
556: unsigned char *suivant;
557:
1.15 bertrand 558: if (chaine == NULL)
559: {
560: return(NULL);
561: }
562:
1.14 bertrand 563: if ((*chaine) == '\\')
564: {
565: if ((*(chaine + 1)) == '"')
566: {
567: suivant = chaine + 2;
568: }
569: else if ((*(chaine + 1)) == 'b')
570: {
571: suivant = chaine + 2;
572: }
573: else if ((*(chaine + 1)) == 'n')
574: {
575: suivant = chaine + 2;
576: }
577: else if ((*(chaine + 1)) == 't')
578: {
579: suivant = chaine + 2;
580: }
581: else if ((*(chaine + 1)) == 'x')
582: {
583: if ((*(chaine + 2)) != d_code_fin_chaine)
584: {
585: if ((*(chaine + 3)) != d_code_fin_chaine)
586: {
587: logical1 erreur;
588:
589: erreur = d_faux;
590:
591: switch(*(chaine + 2))
592: {
593: case '0':
594: case '1':
595: case '2':
596: case '3':
597: case '4':
598: case '5':
599: case '6':
600: case '7':
601: case '8':
602: case '9':
603: case 'A':
604: case 'B':
605: case 'C':
606: case 'D':
607: case 'E':
608: case 'F':
609: break;
610:
611: default:
612: erreur = d_vrai;
613: break;
614: }
615:
616: switch(*(chaine + 3))
617: {
618: case '0':
619: case '1':
620: case '2':
621: case '3':
622: case '4':
623: case '5':
624: case '6':
625: case '7':
626: case '8':
627: case '9':
628: case 'A':
629: case 'B':
630: case 'C':
631: case 'D':
632: case 'E':
633: case 'F':
634: break;
635:
636: default:
637: erreur = d_vrai;
638: break;
639: }
640:
641: if (erreur == d_vrai)
642: {
643: if ((*s_etat_processus).langue == 'F')
644: {
645: printf("+++Information : "
646: "Séquence d'échappement "
647: "inconnue [%d]\n",
648: (int) getpid());
649: }
650: else
651: {
652: printf("+++Warning : Unknown "
653: "escape code "
654: "[%d]\n", (int) getpid());
655: }
656:
657: return(NULL);
658: }
659:
660: suivant = chaine + 4;
661: }
662: else
663: {
664: if ((*s_etat_processus).langue == 'F')
665: {
666: printf("+++Information : "
667: "Séquence d'échappement "
668: "inconnue [%d]\n", (int) getpid());
669: }
670: else
671: {
672: printf("+++Warning : Unknown escape code "
673: "[%d]\n", (int) getpid());
674: }
675:
676: return(NULL);
677: }
678: }
679: else
680: {
681: if ((*s_etat_processus).langue == 'F')
682: {
683: printf("+++Information : "
684: "Séquence d'échappement "
685: "inconnue [%d]\n", (int) getpid());
686: }
687: else
688: {
689: printf("+++Warning : Unknown escape code "
690: "[%d]\n", (int) getpid());
691: }
692:
693: return(NULL);
694: }
695: }
696: else if ((*(chaine + 1)) == '\\')
697: {
1.16 bertrand 698: suivant = chaine + 2;
1.14 bertrand 699: }
700: else
701: {
702: if ((*s_etat_processus).langue == 'F')
703: {
704: printf("+++Information : Séquence d'échappement "
705: "inconnue [%d]\n", (int) getpid());
706: }
707: else
708: {
709: printf("+++Warning : Unknown escape code "
710: "[%d]\n", (int) getpid());
711: }
712:
713: return(NULL);
714: }
715: }
716: else
717: {
718: suivant = chaine + 1;
719: }
720:
721: return(suivant);
722: }
723:
724:
725: /*
726: ================================================================================
727: Routine donnant la longueur d'une chaîne de caractères
728: ================================================================================
729: Entrées : structure sur l'état du processus et chaîne
730: --------------------------------------------------------------------------------
731: Sorties : longueur de la chaîne
732: --------------------------------------------------------------------------------
733: Effets de bord : néant
734: ================================================================================
735: */
736:
737: integer8
738: longueur_chaine(struct_processus *s_etat_processus, unsigned char *chaine)
739: {
740: integer8 nombre_caracteres;
741:
742: unsigned char *pointeur;
743:
744: pointeur = chaine;
745: nombre_caracteres = 0;
746:
747: if ((*pointeur) == '\0')
748: {
749: return(0);
750: }
751:
752: do
753: {
754: if ((pointeur = prochain_caractere(s_etat_processus, pointeur)) == NULL)
755: {
756: return(0);
757: }
758:
759: nombre_caracteres++;
760: } while((*pointeur) != 0);
761:
762: return(nombre_caracteres);
763: }
764:
1.15 bertrand 765:
766: /*
767: ================================================================================
768: Routine retournant un pointeur sur le i-ème caractère d'une chaîne
769: ================================================================================
1.17 bertrand 770: Entrées : structure sur l'état du processus, chaîne et position du caractère
1.15 bertrand 771: --------------------------------------------------------------------------------
1.17 bertrand 772: Sorties : pointeur sur le caractère
1.15 bertrand 773: --------------------------------------------------------------------------------
774: Effets de bord : néant
775: ================================================================================
776: */
777:
778: unsigned char *
779: pointeur_ieme_caractere(struct_processus *s_etat_processus,
780: unsigned char *chaine, integer8 position)
781: {
782: integer8 i;
783:
784: unsigned char *pointeur;
785:
786: if ((pointeur = chaine) == NULL)
787: {
788: return(NULL);
789: }
790:
791: for(i = 0; i < position; i++)
792: {
793: pointeur = prochain_caractere(s_etat_processus, pointeur);
794:
795: if ((*pointeur) == d_code_fin_chaine)
796: {
797: return(pointeur);
798: }
799: }
800:
801: return(pointeur);
802: }
803:
1.17 bertrand 804:
805: /*
806: ================================================================================
807: Routine retournant la position du caractère en fonction du pointeur
808: dans la chaîne
809: ================================================================================
810: Entrées : structure sur l'état du processus, chaîne et position
811: --------------------------------------------------------------------------------
812: Sorties : quantième dans la chaîne
813: --------------------------------------------------------------------------------
814: Effets de bord : néant
815: ================================================================================
816: */
817:
818: integer8
819: position_caractere_de_chaine(struct_processus *s_etat_processus,
820: unsigned char *chaine, unsigned char *position)
821: {
822: integer8 i;
823:
824: i = 1;
825:
826: while(chaine != position)
827: {
828: chaine = prochain_caractere(s_etat_processus, chaine);
829: i++;
830:
831: if ((*chaine) == d_code_fin_chaine)
832: {
833: return(0);
834: }
835: }
836:
837: return(i);
838: }
839:
840:
841: /*
842: ================================================================================
843: Conversion d'une chaîne en majuscule ou en minuscule
844: ================================================================================
845: Entrées : chaîne et indicateur ('M' pour majuscules, 'm' pour minuscules)
846: --------------------------------------------------------------------------------
847: Sorties : néant
848: --------------------------------------------------------------------------------
849: Effets de bord : néant
850: ================================================================================
851: */
852:
853: void
854: conversion_chaine(struct_processus *s_etat_processus,
855: unsigned char *chaine, unsigned char type)
856: {
857: int (*fonction_1)(int);
858: int (*fonction_2)(int);
1.34 bertrand 859: int registre;
1.17 bertrand 860:
861: unsigned char *ptr;
862: unsigned char *ptr2;
863:
864: if (type == 'M')
865: {
866: fonction_1 = toupper;
867: fonction_2 = tolower;
868: }
869: else
870: {
871: fonction_1 = tolower;
872: fonction_2 = toupper;
873: }
874:
875: ptr = chaine;
876:
877: while((*ptr) != d_code_fin_chaine)
878: {
879: ptr2 = prochain_caractere(s_etat_processus, ptr);
880:
881: if ((ptr2 - ptr) == 1)
882: {
883: registre = fonction_1((*ptr));
884:
885: if (fonction_2(registre) == (*ptr))
886: {
1.34 bertrand 887: (*ptr) = (unsigned char) registre;
1.17 bertrand 888: }
889: }
890:
891: ptr = ptr2;
892: }
893:
894: return;
895: }
896:
1.1 bertrand 897: // vim: ts=4