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