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