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