/*
    Fichier iso8859-utf8.c
    Auteur Bernard Chardonneau

    Logiciel libre, droits d'utilisation précisés en français
    dans le fichier : licence-fr.txt

    Traductions des droits d'utilisation dans les fichiers :
    licence-de.txt , licence-en.txt , licence-es.txt ,
    licence-it.txt , licence-nl.txt , licence-pt.txt ,
    licence-eo.txt , licence-eo-utf.txt

    Droits d'utilisation également sur la page web :
    http://libremail.tuxfamily.org/voir.php?page=droits


    Remplacement des caractères ASCII étendu par leur équivalent UTF-8
    (pour les caractères correspondant à un code entre A0h et FFh)
*/


#include <stdio.h>


/* programme principal */

int main (int narg, char *varg[])
{
    int car;  // caractère du fichier à convertir
    int carp; // caractère précédent


    // utiliser fichiers passés en paramètre à la place du clavier et de l'écran
    if (narg > 1)
        freopen (varg [1], "r", stdin);

    if (narg > 2)
        freopen (varg [2], "w", stdout);

    // lire un caractère
    car = getchar ();

    // tantque non fin de fichier
    while (car != EOF)
    {
        // si le caractère est le début d'une séquence UTF-8
        if (0xC0 <= car)
        {
            // lire le caractère suivant
            carp = car;
            car = getchar ();

            // si on a bien une séquence UTF-8 d'au moins 2 octets
            if ((car & 0xC0) == 0x80)
            {
                // on la recopie telle quelle
                putchar (carp);
                putchar (car);

                // cas des séquences UTF-8 sur 3 ou 4 octets
                if (carp > 0xDF)
                {
                    // lire le caractère suivant
                    car = getchar ();

                    // si c'est la suite ou la fin d'une séquence UTF-8
                    if ((car & 0xC0) == 0x80)
                    {
                        // recopier le caractère
                        putchar (car);

                        // si séquence UFT-8 sur 4 octets
                        if (carp > 0xDF)
                            // traitement simplifié
                            putchar (getchar ());
                    }
                    // sinon
                    else
                        // annuler la lecture du caractère suivant
                        ungetc (car, stdin);
                }
            }
            // sinon
            else
            {
                // convertir en UTF-8 l'avant dernier caractère
                putchar (0xC3);
                putchar (0x80 | (carp & 0X3F));

                // annuler la lecture du caractère suivant
                ungetc (car, stdin);
            }
        }

        // sinon si autre caractère ASCII étendu
        else if (car & 0x80)
        {
            // le convertir en UTF-8
            putchar (0xC2 | ((car & 0x40) >> 6));
            putchar (0x80 | (car & 0X3F));
        }

        // sinon (caractère ASCII non étendu)
        else
            // simple copie de ce caractère
            putchar (car);

        // lire le caractère suivant
        car = getchar ();
    }

    // pour faire plaisir à gcc qui veut une fonction main de type int
    return (0);
}