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