Single-source, single-path code set independent version
The term single-source single-path refers to one path in a single application to be used to process both single-byte and multibyte code sets. The single source single path method eliminates all ifdefs for globalization. All characters are handled the same way, whether they are members of single-byte or multibyte code sets.
Single-source single-path is desirable, but it can degrade performance. Thus, it is not recommended for all programs. There may be some programs that do not suffer any performance degradation when they are fully globalized; in those cases, use the single-source single-path method.
The following fully globalized version of the my_example
utility
supports all code sets through single source single path, code set
independent programming:
/*
* 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);
}