/* ================================================================================ RPLiconv ================================================================================ */ #include #include #include #include #include #include "iconv.h" #define file FILE #define d_LONGUEUR 1024 unsigned char * reencodage(unsigned char *chaine_entree, unsigned char *codage_entree, unsigned char *codage_sortie) { iconv_t transcodage; size_t ios; size_t longueur_entree; size_t longueur_sortie; unsigned char *buffer_entree; unsigned char *buffer_sortie; unsigned char *chaine_sortie; unsigned char *pointeur; unsigned char *tampon; if ((transcodage = iconv_open(codage_sortie, codage_entree)) == (iconv_t) -1) { perror("iconv_open"); return(NULL); } buffer_entree = chaine_entree; longueur_entree = strlen(chaine_entree); if ((chaine_sortie = malloc(sizeof(unsigned char))) == NULL) { return(NULL); } chaine_sortie[0] = 0; if ((buffer_sortie = malloc((d_LONGUEUR + 1) * sizeof(char))) == NULL) { return(NULL); } do { longueur_sortie = d_LONGUEUR; longueur_entree = strlen(buffer_entree); pointeur = buffer_sortie; if ((ios = iconv(transcodage, (char **) &buffer_entree, &longueur_entree, (char **) &pointeur, &longueur_sortie)) == (size_t) -1) { // On autorise les erreurs EINVAL et E2BIG if (errno == EILSEQ) { perror("iconv"); free(buffer_sortie); return(NULL); } } tampon = (unsigned char *) chaine_sortie; (*pointeur) = 0; if ((chaine_sortie = malloc((strlen(tampon) + strlen(buffer_sortie) + 1) * sizeof(unsigned char))) == NULL) { return(NULL); } sprintf(chaine_sortie, "%s%s", tampon, buffer_sortie); free(tampon); } while((*buffer_entree) != 0); free(buffer_sortie); iconv_close(transcodage); return(chaine_sortie); } int main(int argc, char *argv[]) { file *f_source; int ios; unsigned char *encodage_destination; unsigned char *encodage_source; unsigned char *nom_fichier_source; unsigned char option; unsigned char *pointeur; unsigned char *fichier_source; unsigned char *fichier_destination; unsigned long drapeau; unsigned long i; unsigned long j; unsigned long nombre_caracteres; nom_fichier_source = NULL; encodage_destination = NULL; encodage_source = NULL; option = ' '; while((--argc) > 0) { if ((*(++argv))[0] == '-') { // Options while((option = *(++argv[0])) != 0) { switch(option) { case 'f' : { if (encodage_source != NULL) { fprintf(stderr, "More than one 'from' option\n"); return(-1); } while(*(++argv[0]) == ' '); argv[0]--; if ((*(++argv[0])) != 0) { encodage_source = argv[0]; } else if ((--argc) > 0) { argv++; encodage_source = argv[0]; } else { fprintf(stderr, "-f option waits for argument\n"); return(-1); } while(*(argv[0]) != 0) { argv[0]++; } argv[0]--; break; } case 't' : { if (encodage_destination != NULL) { fprintf(stderr, "More than one 'from' option\n"); return(-1); } while(*(++argv[0]) == ' '); argv[0]--; if ((*(++argv[0])) != 0) { encodage_destination = argv[0]; } else if ((--argc) > 0) { argv++; encodage_destination = argv[0]; } else { fprintf(stderr, "-f option waits for argument\n"); return(-1); } while(*(argv[0]) != 0) { argv[0]++; } argv[0]--; break; } default : { fprintf(stderr, "Unknown option\n"); return(-1); } } } } else { // Nom du fichier à convertir if (nom_fichier_source != NULL) { fprintf(stderr, "More than one file\n"); return(-1); } nom_fichier_source = argv[0]; } } if (encodage_source == NULL) { fprintf(stderr, "Source encodage not found\n"); return(-1); } if (encodage_destination == NULL) { fprintf(stderr, "Destination encodage not found\n"); return(-1); } if (nom_fichier_source != NULL) { // Lecture à partir d'un fichier if ((f_source = fopen(nom_fichier_source, "r")) == NULL) { fprintf(stderr, "Source file not found\n"); return(-1); } nombre_caracteres = 0; while(getc(f_source) != EOF) { nombre_caracteres++; } if ((fichier_source = malloc((nombre_caracteres + 1) * sizeof(unsigned char))) == NULL) { fprintf(stderr, "Not enough memory\n"); return(-1); } rewind(f_source); pointeur = fichier_source; for(i = 0; i < nombre_caracteres; i++) { (*pointeur) = getc(f_source); pointeur++; } (*pointeur) = 0; fclose(f_source); } else { // Lecture depuis stdin fichier_source = NULL; drapeau = 0; for(i = 1; drapeau == 0; i++) { if ((fichier_source = realloc(fichier_source, ((d_LONGUEUR * i) + 1) * sizeof(unsigned char))) == NULL) { fprintf(stderr, "Not enough memory\n"); return(-1); } for(j = 0; (j < d_LONGUEUR) && (drapeau == 0); j++) { if ((fichier_source[(d_LONGUEUR * (i - 1)) + j] = getc(stdin)) == (unsigned char) EOF) { fichier_source[(d_LONGUEUR * (i - 1)) + j] = 0; drapeau = 1; } } } } if ((fichier_destination = reencodage(fichier_source, encodage_source, encodage_destination)) == NULL) { free(fichier_source); free(fichier_destination); fprintf(stderr, "Conversion error\n"); return(-1); } free(fichier_source); while((ios = fprintf(stdout, "%s", fichier_destination)) < 0) { if ((errno != EINTR) && (errno != 0)) { free(fichier_destination); perror("fprintf(stdout, ...)"); return(-1); } } free(fichier_destination); return(0); } // vim: ts=4