Version indépendante du jeu de codes à source unique et chemin unique

Le terme source unique - chemin unique fait référence à un chemin d'une seule application à utiliser pour traiter à la fois des jeux de codes à un octet et multi-octets. La méthode de source unique et chemin unique élimine tous les ifdef pour la globalisation. Tous les caractères sont traités de la même manière, qu'ils soient membres de jeux de codes à un octet ou multi-octets.

La méthode source unique - chemin unique est souhaitable mais peut dégrader les performances. Elle n'est donc pas recommandée pour tous les programmes. Il se peut que certains programmes ne subissent aucune dégradation des performances lorsqu'ils sont entièrement globalisés ; dans ces cas, utilisez la méthode source unique - chemin unique.

La version entièrement globalisée suivante de l'utilitaire my_example prend en charge tous les jeux de codes via une programmation indépendante du jeu de codes à source unique - chemin unique :

/*
 * COMPONENT_NAME:
 *
 * FUNCTIONS: my_example
 *
 * The following code shows how to count the number of bytes and
 * the number of characters in a text file.
 *
 * This example is for illustration purposes only. Performance
 * improvements may still be possible.
 *
 */

#include        <stdio.h>
#include        <ctype.h>
#include        <locale.h>
#include        <stdlib.h>
#include        "my_example_msg.h"

#define MSGSTR(Num,Str) catgets(catd,MS_MY_EXAMPLE,Num,Str)

/*
 * NAME: my_example
 *
 * FUNCTION: Counts the number of characters in a file.
 *
 */  

main(argc,argv)
int argc;
char **argv;
{
    int     bytesread,   /* number of bytes read */
        bytesprocessed;
    int     leftover;

   int     i;
    int     mbcnt;           /* number of bytes in a character */
    int     f;               /* File descriptor */
    int mb_cur_max;
    int    bytect;           /* name changed from charct... */
    int    charct;           /* for real character count */
    char   *curp, *cure;     /* current and end pointers into
                               ** buffer */
    char         buf[BUFSIZ+1];

    nl_catd      catd;

    wchar_t    wc;

    /* Obtain the current locale */
    (void) setlocale(LC_ALL,"");

    /* after setting the locale, open the message catalog */
    catd = catopen(MF_MY_EXAMPLE,NL_CAT_LOCALE);

    /* Parse the arguments if any */

    /*
    ** Obtain  the maximum number of bytes in a character in the
    ** current locale.
    */
    mb_cur_max = MB_CUR_MAX;
    i = 1;

    /* Open the specified file and issue error messages if any */
    f = open(argv[i],0);
    if(f<0){
        fprintf(stderr,MSGSTR(CANTOPEN,              /*MSG*/
            "my_example: cannot open %s\n"), argv[i]);      /*MSG*/
            exit(2);
    }

   /* Initialize the variables for the count */
    bytect = 0;
    charct = 0;

    /* Start count of bytes and characters  */

    leftover = 0;

    for(;;) {
        bytesread = read(f,buf+leftover, BUFSIZ-leftover);
        /* issue any error messages here, if needed */
        if(bytesread <= 0)
             break;

        buf[leftover+bytesread] = '\0';
                /* Protect partial reads */
        bytect += bytesread;
        curp=buf;
        cure = buf + bytesread+leftover;
        leftover=0;      /* No more leftover */

        for(; curp<cure ;){
            /* Convert to wide character */
            mbcnt= mbtowc(&wc, curp, mb_cur_max);
            if(mbcnt <= 0){
                mbcnt = 1;
            }else if (cure - curp >=mb_cur_max){
                wc = *curp;
                mbcnt =1;
            }else{
                /* Needs more data */
                leftover= cure - curp;
                strcpy(buf, curp, leftover);
                break;
            }
            curp +=mbcnt;
            charct++;
        }
    }

        /* print number of chars and bytes */
    fprintf(stderr,MSGSTR(BYTECNT, "number of bytes:%d\n"),
            bytect);
    fprintf(stderr,MSGSTR(CHARCNT, "number of characters:%d\n"),
            charct);
    close(f);
    exit(0);
}