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