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