Annotation of rpl/src/transliteration.c, revision 1.43
1.1 bertrand 1: /*
2: ================================================================================
1.37 bertrand 3: RPL/2 (R) version 4.1.3
1.25 bertrand 4: Copyright (C) 1989-2011 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:
1.14 bertrand 23: #include "rpl-conv.h"
24: #include "tex-conv.h"
1.5 bertrand 25:
1.1 bertrand 26: #include <stdarg.h>
1.5 bertrand 27:
1.1 bertrand 28: #undef fprintf
29: #undef printf
30:
31:
32: /*
33: ================================================================================
34: Fonction de translitération
35: ================================================================================
36: Entrées :
37: --------------------------------------------------------------------------------
38: Sorties :
39: --------------------------------------------------------------------------------
40: Effets de bord : néant
41: ================================================================================
42: */
43:
44: unsigned char *
45: transliteration(struct_processus *s_etat_processus,
46: unsigned char *chaine_entree,
47: unsigned char *codage_entree,
48: unsigned char *codage_sortie)
49: {
50: unsigned char *codage_sortie_transliteral;
51: unsigned char *tampon;
52:
53: if ((codage_sortie_transliteral = malloc((strlen(codage_sortie)
54: + strlen("//TRANSLIT") + 1) * sizeof(unsigned char))) == NULL)
55: {
56: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
57: return(NULL);
58: }
59:
60: sprintf(codage_sortie_transliteral, "%s//TRANSLIT", codage_sortie);
61:
62: tampon = reencodage(s_etat_processus, chaine_entree,
63: codage_entree, codage_sortie_transliteral);
64: free(codage_sortie_transliteral);
65:
66: return(tampon);
67: }
68:
69:
70: unsigned char *
71: reencodage(struct_processus *s_etat_processus,
72: unsigned char *chaine_entree,
73: unsigned char *codage_entree,
74: unsigned char *codage_sortie)
75: {
76: # define d_LONGUEUR 1024
77:
78: iconv_t transcodage;
79:
80: size_t ios;
81: size_t longueur_entree;
82: size_t longueur_sortie;
83:
84: unsigned char *buffer_entree;
85: unsigned char *buffer_sortie;
86: unsigned char *chaine_sortie;
87: unsigned char *pointeur;
88: unsigned char *tampon;
89:
90: if ((transcodage = iconv_open(codage_sortie, codage_entree)) ==
91: (iconv_t) -1)
92: {
93: (*s_etat_processus).erreur_execution = d_ex_erreur_transcodage;
94: return(NULL);
95: }
96:
97: buffer_entree = chaine_entree;
98: longueur_entree = strlen(chaine_entree);
99:
100: if ((chaine_sortie = malloc(sizeof(unsigned char))) == NULL)
101: {
102: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
103: return(NULL);
104: }
105:
106: chaine_sortie[0] = d_code_fin_chaine;
107:
1.39 bertrand 108: if ((buffer_sortie = malloc((d_LONGUEUR + 1) * sizeof(unsigned char)))
109: == NULL)
1.1 bertrand 110: {
111: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
112: return(NULL);
113: }
114:
115: do
116: {
117: longueur_sortie = d_LONGUEUR;
118: pointeur = buffer_sortie;
119:
120: if ((ios = iconv(transcodage, (char **) &buffer_entree,
121: &longueur_entree, (char **) &pointeur, &longueur_sortie))
122: == (size_t) -1)
123: {
124: // On autorise les erreurs EINVAL et EILSEQ
125: if (errno == EILSEQ)
126: {
127: free(buffer_sortie);
1.3 bertrand 128: free(chaine_sortie);
129:
1.1 bertrand 130: (*s_etat_processus).erreur_execution = d_ex_erreur_transcodage;
131: return(NULL);
132: }
133: }
134:
1.38 bertrand 135: tampon = chaine_sortie;
1.1 bertrand 136: (*pointeur) = d_code_fin_chaine;
137:
138: if ((chaine_sortie = malloc((strlen(tampon) + strlen(buffer_sortie) + 1)
139: * sizeof(unsigned char))) == NULL)
140: {
141: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
142: return(NULL);
143: }
144:
145: sprintf(chaine_sortie, "%s%s", tampon, buffer_sortie);
146: free(tampon);
147: } while((*buffer_entree) != d_code_fin_chaine);
148:
149: free(buffer_sortie);
150: iconv_close(transcodage);
151:
152: return(chaine_sortie);
153: }
154:
155:
156: /*
157: ================================================================================
158: Fonctions spécifiques
159: ================================================================================
160: Entrées :
161: --------------------------------------------------------------------------------
1.26 bertrand 162: Sorties :
1.1 bertrand 163: --------------------------------------------------------------------------------
164: Effets de bord : néant
165: ================================================================================
166: */
167:
168: void
169: localisation_courante(struct_processus *s_etat_processus)
170: {
171: char **arguments;
172:
173: int ios;
174: int pipes_entree[2];
175: int pipes_erreur[2];
176: int pipes_sortie[2];
177: int status;
178:
179: long i;
180: long nombre_arguments;
181:
182: pid_t pid;
183:
184: struct sigaction action_passee;
185:
186: unsigned char *tampon;
187:
188: unsigned long longueur_lecture;
189: unsigned long nombre_iterations;
190: unsigned long pointeur;
191:
192: if ((arguments = malloc(3 * sizeof(char **))) == NULL)
193: {
194: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
195: return;
196: }
197:
198: if ((arguments[0] = malloc((strlen("locale") + 1) * sizeof(char))) == NULL)
199: {
200: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
201: return;
202: }
203:
204: if ((arguments[1] = malloc((strlen("charmap") + 1) * sizeof(char))) == NULL)
205: {
206: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
207: return;
208: }
209:
210: strcpy(arguments[0], "locale");
211: strcpy(arguments[1], "charmap");
212: arguments[2] = NULL;
213:
214: nombre_arguments = 2;
215:
216: if (pipe(pipes_entree) != 0)
217: {
218: (*s_etat_processus).erreur_systeme = d_es_processus;
219: return;
220: }
221:
222: if (pipe(pipes_sortie) != 0)
223: {
224: (*s_etat_processus).erreur_systeme = d_es_processus;
225: return;
226: }
227:
228: if (pipe(pipes_erreur) != 0)
229: {
230: (*s_etat_processus).erreur_systeme = d_es_processus;
231: return;
232: }
233:
234: verrouillage_threads_concurrents(s_etat_processus);
235: pid = fork();
236: deverrouillage_threads_concurrents(s_etat_processus);
237:
238: if (pid < 0)
239: {
240: if (close(pipes_entree[0]) != 0)
241: {
242: (*s_etat_processus).erreur_systeme = d_es_processus;
243: return;
244: }
245:
246: if (close(pipes_entree[1]) != 0)
247: {
248: (*s_etat_processus).erreur_systeme = d_es_processus;
249: return;
250: }
251:
252: if (close(pipes_sortie[0]) != 0)
253: {
254: (*s_etat_processus).erreur_systeme = d_es_processus;
255: return;
256: }
257:
258: if (close(pipes_sortie[1]) != 0)
259: {
260: (*s_etat_processus).erreur_systeme = d_es_processus;
261: return;
262: }
263:
264: if (close(pipes_erreur[0]) != 0)
265: {
266: (*s_etat_processus).erreur_systeme = d_es_processus;
267: return;
268: }
269:
270: if (close(pipes_erreur[1]) != 0)
271: {
272: (*s_etat_processus).erreur_systeme = d_es_processus;
273: return;
274: }
275:
276: (*s_etat_processus).erreur_systeme = d_es_processus;
277: return;
278: }
279: else if (pid == 0)
280: {
281: if (close(pipes_entree[1]) != 0)
282: {
283: (*s_etat_processus).erreur_systeme = d_es_processus;
284: return;
285: }
286:
287: if (close(pipes_sortie[0]) != 0)
288: {
289: (*s_etat_processus).erreur_systeme = d_es_processus;
290: return;
291: }
292:
293: if (close(pipes_erreur[0]) != 0)
294: {
295: (*s_etat_processus).erreur_systeme = d_es_processus;
296: return;
297: }
298:
299: if (pipes_entree[0] != STDIN_FILENO)
300: {
301: if (dup2(pipes_entree[0], STDIN_FILENO) == -1)
302: {
303: (*s_etat_processus).erreur_systeme = d_es_processus;
304: return;
305: }
306: }
307:
308: if (pipes_sortie[1] != STDOUT_FILENO)
309: {
310: if (dup2(pipes_sortie[1], STDOUT_FILENO) == -1)
311: {
312: (*s_etat_processus).erreur_systeme = d_es_processus;
313: return;
314: }
315: }
316:
317: if (pipes_sortie[1] != STDERR_FILENO)
318: {
319: if (dup2(pipes_sortie[1], STDERR_FILENO) == -1)
320: {
321: (*s_etat_processus).erreur_systeme = d_es_processus;
322: return;
323: }
324: }
325:
326: if (nombre_arguments != 0)
327: {
328: execvp(arguments[0], arguments);
329: }
330: else
331: {
332: exit(EXIT_SUCCESS);
333: }
334:
335: /*
336: * L'appel système execvp() a généré une erreur et n'a pu exécuter
337: * argument[0] (fichier non exécutable ou inexistant).
338: */
339:
340: close(pipes_entree[0]);
341: close(pipes_sortie[1]);
342:
343: for(i = 0; i < nombre_arguments; i++)
344: {
345: free(arguments[i]);
346: }
347:
348: free(arguments);
349: (*s_etat_processus).erreur_systeme = d_es_processus;
350:
351: /*
352: * Envoi d'une erreur dans le pipe idoine. On ne regarde pas
353: * le nombre d'octets écrits car l'erreur ne pourra de toute
354: * façon pas être traitée.
355: */
356:
357: write_atomic(s_etat_processus, pipes_erreur[1], " ", 1);
358: close(pipes_erreur[1]);
359:
360: exit(EXIT_SUCCESS);
361: }
362: else
363: {
364: if (close(pipes_entree[0]) != 0)
365: {
366: (*s_etat_processus).erreur_systeme = d_es_processus;
367: return;
368: }
369:
370: if (close(pipes_sortie[1]) != 0)
371: {
372: (*s_etat_processus).erreur_systeme = d_es_processus;
373: return;
374: }
375:
376: if (close(pipes_erreur[1]) != 0)
377: {
378: (*s_etat_processus).erreur_systeme = d_es_processus;
379: return;
380: }
381:
382: if (close(pipes_entree[1]) != 0)
383: {
384: (*s_etat_processus).erreur_systeme = d_es_processus;
385: return;
386: }
387:
388: do
389: {
390: if (kill(pid, 0) != 0)
391: {
392: break;
393: }
394:
395: /*
396: * Récupération de la valeur de retour du processus détaché
397: */
398:
1.42 bertrand 399: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
1.1 bertrand 400: {
401: (*s_etat_processus).erreur_systeme = d_es_processus;
402: return;
403: }
404:
405: if (waitpid(pid, &status, 0) == -1)
406: {
1.43 ! bertrand 407: while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
1.1 bertrand 408: {
1.43 ! bertrand 409: if (errno != EINTR)
! 410: {
! 411: (*s_etat_processus).erreur_systeme = d_es_processus;
! 412: return;
! 413: }
1.1 bertrand 414: }
415:
416: (*s_etat_processus).erreur_systeme = d_es_processus;
417: return;
418: }
419:
1.43 ! bertrand 420: while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
1.1 bertrand 421: {
1.43 ! bertrand 422: if (errno != EINTR)
! 423: {
! 424: (*s_etat_processus).erreur_systeme = d_es_processus;
! 425: return;
! 426: }
1.1 bertrand 427: }
428: } while((!WIFEXITED(status)) && (!WIFSIGNALED(status)));
429:
430: longueur_lecture = 256;
431: pointeur = 0;
432: nombre_iterations = 1;
433:
434: if ((tampon = malloc((longueur_lecture + 1) *
435: sizeof(unsigned char))) == NULL)
436: {
437: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
438: return;
439: }
440:
1.18 bertrand 441: tampon[0] = d_code_fin_chaine;
442:
1.42 bertrand 443: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
1.1 bertrand 444: {
445: (*s_etat_processus).erreur_systeme = d_es_processus;
446: return;
447: }
448:
449: while((ios = read_atomic(s_etat_processus,
450: pipes_sortie[0], &(tampon[pointeur]),
451: longueur_lecture)) > 0)
452: {
1.43 ! bertrand 453: while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
1.1 bertrand 454: {
1.43 ! bertrand 455: if (errno != EINTR)
! 456: {
! 457: (*s_etat_processus).erreur_systeme = d_es_processus;
! 458: return;
! 459: }
1.1 bertrand 460: }
461:
462: tampon[pointeur + ios] = d_code_fin_chaine;
463: pointeur += longueur_lecture;
464: nombre_iterations++;
465:
466: if ((tampon = realloc(tampon,
467: ((nombre_iterations * longueur_lecture) + 1) *
468: sizeof(unsigned char))) == NULL)
469: {
470: (*s_etat_processus).erreur_systeme =
471: d_es_allocation_memoire;
472: return;
473: }
474:
1.42 bertrand 475: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
1.1 bertrand 476: {
477: (*s_etat_processus).erreur_systeme = d_es_processus;
478: return;
479: }
480: }
481:
1.43 ! bertrand 482: while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
1.1 bertrand 483: {
1.43 ! bertrand 484: if (errno != EINTR)
! 485: {
! 486: (*s_etat_processus).erreur_systeme = d_es_processus;
! 487: return;
! 488: }
1.1 bertrand 489: }
490:
491: if (strlen(tampon) == 0)
492: {
493: (*s_etat_processus).erreur_systeme = d_es_processus;
494: return;
495: }
496:
497: tampon[strlen(tampon) - 1] = d_code_fin_chaine;
498:
499: if (ios == -1)
500: {
501: (*s_etat_processus).erreur_systeme = d_es_processus;
502: return;
503: }
504:
505: if (close(pipes_sortie[0]) != 0)
506: {
507: (*s_etat_processus).erreur_systeme = d_es_processus;
508: return;
509: }
510:
1.17 bertrand 511: if (strlen(tampon) > 0)
512: {
513: (*s_etat_processus).localisation = tampon;
514: }
515: else
516: {
517: free(tampon);
518:
519: if (((*s_etat_processus).localisation = malloc((strlen(d_locale)
520: + 1) * sizeof(unsigned char))) == NULL)
521: {
522: (*s_etat_processus).erreur_systeme = d_es_processus;
523: return;
524: }
525:
526: strcpy((*s_etat_processus).localisation, d_locale);
527: }
1.1 bertrand 528:
529: if (sigaction(SIGINT, &action_passee, NULL) != 0)
530: {
531: for(i = 0; i < nombre_arguments; i++)
532: {
533: free(arguments[i]);
534: }
535:
536: free(arguments);
537: (*s_etat_processus).erreur_systeme = d_es_signal;
538: return;
539: }
540:
541: for(i = 0; i < nombre_arguments; i++)
542: {
543: free(arguments[i]);
544: }
545:
546: free(arguments);
547:
1.42 bertrand 548: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
1.1 bertrand 549: {
550: (*s_etat_processus).erreur_systeme = d_es_processus;
551: return;
552: }
553:
554: if (read_atomic(s_etat_processus, pipes_erreur[0], tampon, 1) > 0)
555: {
556: // Le processus fils renvoie une erreur.
557:
1.18 bertrand 558: free(tampon);
559:
560: if (((*s_etat_processus).localisation = malloc((strlen(d_locale)
561: + 1) * sizeof(unsigned char))) == NULL)
1.1 bertrand 562: {
1.18 bertrand 563: (*s_etat_processus).erreur_systeme = d_es_processus;
564: return;
1.1 bertrand 565: }
566:
1.18 bertrand 567: strcpy((*s_etat_processus).localisation, d_locale);
1.1 bertrand 568: }
569:
1.43 ! bertrand 570: while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
1.1 bertrand 571: {
1.43 ! bertrand 572: if (errno != EINTR)
! 573: {
! 574: (*s_etat_processus).erreur_systeme = d_es_processus;
! 575: return;
! 576: }
1.1 bertrand 577: }
578:
579: if (close(pipes_erreur[0]) != 0)
580: {
581: (*s_etat_processus).erreur_systeme = d_es_processus;
582: return;
583: }
584: }
585:
586: return;
587: }
588:
589:
590: int
591: transliterated_fprintf(struct_processus *s_etat_processus, file *flux,
592: const char *format, ...)
593: {
594: int ios;
1.5 bertrand 595:
596: unsigned char *tampon;
1.1 bertrand 597: unsigned char *tampon2;
1.5 bertrand 598:
1.1 bertrand 599: va_list arguments;
600:
601: va_start(arguments, format);
602:
1.17 bertrand 603: # ifdef OS2
604: unsigned char *ptr_e;;
605: unsigned char *ptr_l;;
606: unsigned char *tampon3;
607:
608: unsigned long i;
609: # endif
610:
1.5 bertrand 611: if (valsprintf(&tampon, format, arguments) < 0)
1.1 bertrand 612: {
613: va_end(arguments);
614:
615: if (s_etat_processus != NULL)
616: {
617: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
618: }
619:
620: return(-1);
621: }
622:
623: va_end(arguments);
624:
625: if (s_etat_processus != NULL)
626: {
627: if ((tampon2 = transliteration(s_etat_processus, tampon,
628: d_locale, (*s_etat_processus).localisation)) == NULL)
629: {
630: free(tampon);
631: return(-1);
632: }
633:
634: free(tampon);
635: }
636: else
637: {
638: tampon2 = tampon;
639: }
640:
1.17 bertrand 641: # ifdef OS2
1.23 bertrand 642: if ((flux == stdin) || (flux == stdout))
643: {
644: i = 0;
645: ptr_l = tampon2;
1.17 bertrand 646:
1.23 bertrand 647: while((*ptr_l) != d_code_fin_chaine)
1.17 bertrand 648: {
1.23 bertrand 649: if ((*ptr_l) == '\n')
650: {
651: i++;
652: }
653:
654: ptr_l++;
1.17 bertrand 655: }
656:
1.23 bertrand 657: if ((tampon3 = malloc((strlen(tampon2) + i + 1) *
658: sizeof(unsigned char))) == NULL)
659: {
660: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
661: return(NULL);
662: }
1.17 bertrand 663:
1.23 bertrand 664: ptr_e = tampon3;
665: ptr_l = tampon2;
1.17 bertrand 666:
1.23 bertrand 667: while((*ptr_l) != d_code_fin_chaine)
668: {
669: (*ptr_e) = (*ptr_l);
1.17 bertrand 670:
1.23 bertrand 671: if ((*ptr_l) == '\n')
672: {
673: (*(++ptr_e)) = '\r';
674: ptr_e++;
675: ptr_l++;
676: }
677: else
678: {
679: ptr_e++;
680: ptr_l++;
681: }
1.17 bertrand 682: }
683:
1.23 bertrand 684: (*ptr_e) = d_code_fin_chaine;
1.17 bertrand 685:
1.23 bertrand 686: free(tampon2);
687: tampon2 = tampon3;
688: }
1.17 bertrand 689: # endif
690:
1.1 bertrand 691: # ifdef SunOS
692: while((ios = fprintf(flux, "%s", tampon2)) < 0)
693: {
694: if ((errno != EINTR) && (errno != 0))
695: {
696: break;
697: }
698: }
699: # else
700: ios = fprintf(flux, "%s", tampon2);
701: # endif
702:
703: free(tampon2);
704:
705: return(ios);
706: }
707:
1.5 bertrand 708:
709: int
710: tex_fprintf(struct_processus *s_etat_processus,
711: file *flux, const char *format, ...)
712: {
713: int ios;
714:
715: unsigned char *tampon;
716: unsigned char *tampon2;
717:
718: va_list arguments;
719:
720: va_start(arguments, format);
721:
722: if (valsprintf(&tampon, format, arguments) < 0)
723: {
724: va_end(arguments);
725:
726: if (s_etat_processus != NULL)
727: {
728: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
729: }
730:
731: return(-1);
732: }
733:
734: va_end(arguments);
735:
736: if ((tampon2 = transliteration(s_etat_processus, tampon,
737: d_locale, ds_tex_encodage_3)) == NULL)
738: {
739: free(tampon);
740: return(-1);
741: }
742:
743: free(tampon);
744:
745: # ifdef SunOS
746: while((ios = fprintf(flux, "%s", tampon2)) < 0)
747: {
748: if ((errno != EINTR) && (errno != 0))
749: {
750: break;
751: }
752: }
753: # else
754: ios = fprintf(flux, "%s", tampon2);
755: # endif
756:
757: free(tampon2);
758:
759: return(ios);
760: }
761:
1.21 bertrand 762: #undef readline
1.19 bertrand 763:
764: unsigned char *
765: readline_wrapper(unsigned char *invite)
766: {
767: unsigned char *chaine;
768:
769: chaine = readline(invite);
770: printf("\r");
771:
772: return(chaine);
773: }
774:
775:
1.1 bertrand 776: #define fprintf NULL
777: #define printf NULL
778:
779: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>