This section provides a general background on the iconv subroutines and structures in preparation for writing code set converters. This section gives an overview of the control flow and the order in which the framework operates, details about writing code set converters, and an example including the code, header file, and a makefile. This section applies to the iconv framework within AIX.
Under the framework of the iconv_open, iconv and iconv_close subroutines, you can create and use several different types of converters. Applications can call these subroutines to convert characters in one code set into characters in a different code set. The access and use of the iconv_open, iconv and iconv_close subroutines is standardized by X/Open XPG4.
Code sets can be classified into two categories: stateful encodings and stateless encodings.
The stateful encodings use shift-in and shift-out codes to change state. For instance, the shift-out can be used to indicate the start of host double-byte data in a data stream of characters, and shift-in can be used to indicate the end of this double-byte character data. When the double-byte data is off, it signals the start of single-byte character data. An example of such a stateful code set is IBM-930 used mainly on mainframes (hosts).
Converters written to do the conversion of stateful encodings to other code sets tend to be complex due to the extra processing needed.
The stateless code sets are those that can be classified as one of two types:
Note that conversions are meaningful only if the code sets represent the same characters.
The simplest types of code set conversion can be found in single-byte code set converters, such as the converter from ISO8859-1 to IBM-850. These single-byte code set converters are based on simple table-based conversions. The conversion of multibyte character encodings, such as IBM-eucJP to IBM-932, are in general based on an algorithm and not on tables, because the tables can get lengthy.
The iconv framework consists of the iconv_open, iconv and iconv_close subroutines. It is based on a common core structure that is part of all converters. The core structure is initialized at the load time of the converter object module. After the loading of the converter is complete, the main entry point, which is always the instantiate subroutine, is invoked. This initializes the core structure and returns the core converter descriptor. This is further used during the call to the init subroutine provided by the converter to allocate the converter-specific structures. This init subroutine returns another converter descriptor that has a pointer to the core converter descriptor. The init subroutine allocates memory as needed and may invoke other converters if needed. The init subroutine is the place for any converter-specific initialization whereas the instantiate subroutine is a generic entry point.
Once the converter descriptor for this converter is allocated and initialized, the next step is to provide the actual code needed for the exec part of the functionality. If the converter is a table-based converter, the only need is to provide a source file format that conforms to the input needs of the genxlt utility, which takes this source table as the input and generates an output file format usable by the iconv framework.
The iconv.h file in /usr/include defines the following structures:
typedef struct __iconv_rec iconv_rec, *iconv_t; struct __iconv_rec { _LC_object_t hdr; iconv_t (*open)(const char *tocode, const char *fromcode); size_t (*exec)(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); void (*close)(iconv_t cd); };
The common core structure is as follows (/usr/include/iconv.h):
typedef struct _LC_core_iconv_type _LC_core_iconv_t; struct _LC_core_iconv_type { _LC_object_t hdr; /* implementation initialization */ _LC_core_iconv_t *(*init)(); size_t (*exec)(); void (*close)(); };
Every converter has a static memory area which contains the _LC_core_iconv_t structure. It is initialized in the instantiate subroutine provided as part of the converter program.
The following sections describe the iconv control flow.
An application invokes a code set converter by the following call:
iconv_open(char *to_codeset, char *from_codeset)
The to and from code sets are used in selecting the converter by way of the search path defined by the LOCPATH environment variable. The iconv_open subroutine uses the _lc_load subroutine to load the object module specified by concatenating the from and to code set names to the iconv_open subroutine.
CONVERTER NAME= "from_codeset" + "_" +"to_codeset"
If the from_codeset is IBM-850 and the to_codeset is ISO8859-1, the converter name is IBM-850_ISO8859-1.
After loading the converter, its entry point is invoked by the _lc_load loader subroutine. This is the first call to the converter. The instantiate subroutine then initializes the _LC_core_iconv_t core structure. The iconv_open subroutine then calls the init subroutine associated with the core structure thus returned. The init subroutine is responsible for allocating the converter specific descriptor structure and initializing it as needed by the converter. The iconv_open subroutine returns this converter-specific structure. However, the return value is typecast to iconv_t in the user's application. Thus, the application does not see the whole of the converter-specific structure; it sees only the public iconv_t structure. The converter code itself uses the private converter structure. Applications that use iconv converters should not change the converter descriptor; the converter descriptor should be used as an opaque structure.
An entry point is declared in every converter such that when the converter is opened by a call to the iconv_open subroutine, that entry point is automatically invoked. The entry point is the instantiate subroutine that should be provided in all converters. The entry point is specified in the makefile as follows:
LDENTRY=-einstantiate
When the converter is loaded on a call to iconv_open(), the instantiate subroutine is invoked. This subroutine knows how the converter works. It initializes a static core conversion descriptor structure _LC_core_iconv_t cd.
The core conversion descriptor cd contains pointers to the init, _iconv_exec, and _iconv_close subroutines supplied by the specific converter. The instantiate subroutine returns the core conversion descriptor to be used later. The _LC_core_iconv_t structure is defined in /usr/include/iconv.h.
When the iconv_open subroutine is called, the following actions occur:
typedef struct _LC_sample_iconv_rec { LC_core_iconv_t core; } _LC_sample_iconv_t; To initialize this, the converter has to do the following in the init subroutine: static _LC_sample_iconv_t* init (_LC_core_iconv_t *core_cd, char* toname,char* fromname) { _LC_sample_iconv_t *cd; /* converter descriptor */ /* ** Allocate a converter descriptor **/ if(!(cd = ( _LC_sample_iconv_t *) malloc ( sizeof(_LC_sample_iconv_t )))) return (NULL); /* ** Copy the core part of converter descriptor which is ** passed in */ cd->core = *core_cd; /* ** Return the converter descriptor */ return cd; }
An application invokes the iconv subroutine to do the actual code set conversions. The iconv subroutine invokes the exec subroutine in the core structure.
An application invokes the iconv_close subroutine to free any memory allocated for conversions. The iconv_close subroutine invokes the close subroutine in the core structure.
This section gives details on how to write a converter using the concepts explained so far. This is done starting with a simple converter and proceeds to a more complex one. The following procedures are discussed here:
Every converter should define the following subroutines:
The converter-specific structure should have the core iconv structure as its first element. For example:
typedef struct _LC_example_rec { /* Core should be the first element */ _LC_core_iconv_t core; /* The rest are converter specific data (optional) */ iconv_t curcd; iconv_t sb_cd; iconv_t db_cd; unsigned char *cntl; } _LC_example_iconv_t;
Example 2: A simpler converter structure
typedef struct _LC_sample_iconv_rec { _LC_core_iconv_t core; } _LC_sample_iconv_t;
Every converter should have the subroutines previously specified. Only the subroutine headers are provided without details, except for the instantiate subroutine that is common to all converters and should be coded the same.
The following example of an algorithm-based stateless converter is a sample converter of the IBM-850 code set to the ISO8859-1 code set.
#include <stdlib.h> #include <iconv.h> #include "850_88591.h" /* * Name : _iconv_exec() * * This contains actual conversion method. */ static size_t _iconv_exec(_LC_sample_iconv_t *cd, unsigned char** inbuf, size_t *inbytesleft, unsigned char** outbuf, size_t *outbytesleft) /* * cd : converter descriptor * inbuf : input buffer * outbuf : output buffer * inbytesleft : number of data(in bytes) in input buffer * outbytesleft : number of data(in bytes) in output buffer */ { } /* * Name : _iconv_close() * * Free the allocated converter descriptor */ static void _iconv_close(iconv_t cd) { } /* * Name : init() * * This allocates and initializes the converter descriptor. */ static _LC_sample_iconv_t *init (_LC_core_iconv_t *core_cd, char* toname, char* fromname) { } /* * Name : instantiate() * * Core part of a converter descriptor is initialized here. */ _LC_core_iconv_t *instantiate(void) { static _LC_core_iconv_t cd; /* * * Initialize _LC_MAGIC and _LC_VERSION are ** defined in <lc_core.h>. _LC_ICONV and _LC_core_iconv_t ** are defined in <iconv.h>. */ cd.hdr.magic = _LC_MAGIC; cd.hdr.version = _LC_VERSION; cd.hdr.type_id = _LC_ICONV; cd.hdr.size = sizeof (_LC_core_iconv_t); /* * Set pointers to each method. */ cd.init = init; cd.exec = _iconv_exec; cd.close = _iconv_close; /* * Returns the core part */ return &cd; }
Here, only the subroutine headers are provided without details, except for the instantiate subroutine that is common to all converters and should be coded the same. Because stateful converters need more information, they provide additional converter-dependent information as well.
The following example of a stateful converter is a sample converter of IBM-930 to IBM-932 code set.
The host.h file contains the following structure:
typedef struct _LC_host_iconv_rec { _LC_core_iconv_t core; iconv_t curcd; iconv_t sb_cd; iconv_t db_cd; unsigned char *cntl; } _LC_host_iconv_t;
#include <stdlib.h> #include <sys/types.h> #include <iconv.h> #include "host.h"
/* ** The _iconv_exec subroutine to be invoked via cd->exec() */ static int _iconv_exec(_LC_host_iconv_t *cd, unsigned char **inbuf, size_t *inbytesleft, unsigned char **outbuf, size_t *outbytesleft) { unsigned char *in, *out; int ret_value;
if (!cd){ errno = EBADF; return NULL; }
if (!inbuf) { cd->curcd = cd->sb_cd; return ICONV_DONE; }
do { if ((ret_value = iconv(cd->curcd, inbuf, inbytesleft, outbuf, outbytesleft)) != ICONV_INVAL) return ret_value; in = *inbuf; out = *outbuf; if (in[0] == SO) { if (cd->curcd == cd->db_cd){ errno = EILSEQ; return ICONV_INVAL; } cd->curcd = cd->db_cd; } else if (in[0] == SI) { if (cd->curcd == cd->sb_cd){ errno = EILSEQ; return ICONV_INVAL; } cd->curcd = cd->sb_cd; }else if (in[0] <= 0x3f && cd->curcd == cd->sb_cd) { if (*outbytesleft < 1){ errno = E2BIG; return ICONV_OVER; } out[0] = cd->cntl[in[0]]; *outbuf = ++out; (*outbytesleft)--; } else { errno = EILSEQ; return ICONV_INVAL; } *inbuf = ++in; (*inbytesleft)--; } while (1); } /* ** The iconv_close subroutine is a macro accessing this ** subroutine as set in the core iconv structure. */ static void _iconv_close(_LC_host_iconv_t *cd) { if (cd) { if (cd->sb_cd) iconv_close(cd->sb_cd); if (cd->db_cd) iconv_close(cd->db_cd); free(cd); }else{ errno = EBADF; } } /* ** The init subroutine to be invoked when iconv_open() is called. */ static _LC_host_iconv_t *init(_LC_core_iconv_t *core_cd, char* toname, char* fromname) { _LC_host_iconv_t* cd; int i; for (i = 0; 1; i++) { if (!_iconv_host[i].local) return NULL; if (strcmp(toname, _iconv_host[i].local) == 0 && strcmp(fromname, _iconv_host[i].host) == 0) break; } if (!(cd = (_LC_host_iconv_t *) malloc(sizeof(_LC_host_iconv_t)))) return (NULL); if (!(cd->sb_cd = iconv_open(toname, _iconv_host[i].sbcs))) { free(cd); return NULL; } if (!(cd->db_cd = iconv_open(toname, _iconv_host[i].dbcs))) { iconv_close(cd->sb_cd); free(cd); return NULL; } cd->core = *core_cd; cd->cntl = _iconv_host[i].fcntl; cd->curcd = cd->sb_cd; return cd; } /* ** The instantiate() method is called when iconv_open() loads the ** converter by a call to __lc_load(). */ _LC_core_iconv_t *instantiate(void) { static _LC_core_iconv_t cd; cd.hdr.magic = _LC_MAGIC; cd.hdr.version = _LC_VERSION; cd.hdr.type_id = _LC_ICONV; cd.hdr.size = sizeof (_LC_core_iconv_t); cd.init = init; cd.exec = _iconv_exec; cd.close = _iconv_close; return &cd; }
#include <stdlib.h> #include <iconv.h> #include "850_88591.h" #define DONE 0 /* * Name : _iconv_exec() * * This contains actual conversion method. */ static size_t _iconv_exec(_LC_sample_iconv_t *cd, unsigned char** inbuf, size_t *inbytesleft, unsigned char** outbuf, size_t *outbytesleft) /* * cd : converter descriptor * inbuf : input buffer * outbuf : output buffer * inbytesleft : number of data(in bytes) in input buffer * outbytesleft : number of data(in bytes) in output buffer */ { unsigned char *in; /* point the input buffer */ unsigned char *out; /* point the output buffer */ unsigned char *e_in; /* point the end of input buffer*/ unsigned char *e_out; /* point the end of output buffer*/ /* * If given converter discripter is invalid, * it sets the errno and returns the number * of bytes left to be converted. */ if (!cd) { errno = EBADF; return *inbytesleft; } /* * If the input buffer does not exist or there * is no character to be converted, it returns * 0 (no characters to be converted). */ if (!inbuf || !(*inbytesleft)) return DONE; /* * Set up pointers and initialize other variables */ e_in = (in = *inbuf) + *inbytesleft; e_out = (out = *outbuf) + *outbytesleft; /* * Perform code point conversion until all input * is consumed. * When error occurs (i.e. buffer overflow), error * number is set and exit this loop. */ while (in < e_in) { /* * If there is not enough space left in output buffer * to hold the converted data, it stops converting and * sets the errno to E2BIG. */ if (e_out <= out) { errno = E2BIG; break; } /* * Convert the input data and store it into the output * buffer, then advance the pointers which point to the * buffers. */ *out++ = table[*in++]; } /* while */ /* * Update the pointers to the buffers and * input /output byte counts */ *inbuf = in; *outbuf = out; *inbytesleft = e_in - in; *outbytesleft = e_out - out; /* * Reurn the number of bytes left to be converted * (0 for successful conversion completion) */ return *inbytesleft; } /* * Name : _iconv_close() * * Free the allocated converter descriptor */ static void _iconv_close(iconv_t cd) { if (!cd) free(cd); else /* * If given converter is not valid, * it sets the errno to EBADF */ errno = EBADF; } /* * Name : init() * * This allocates and initializes the converter descriptor. */ static _LC_sample_iconv_t* init (_LC_core_iconv_t *core_cd, char* toname, char* fromname) { _LC_sample_iconv_t *cd; /* converter descriptor */ /* * Allocate a converter descriptor */ if (!(cd = (_LC_sample_iconv_t *) malloc(sizeof(_LC_sample_iconv_t)))) return (NULL); /* *Copy the core part of converter descriptor which is passed *in */ cd->core = *core_cd; /* * Return the converter descriptor */ return cd; } /* * Name : instantiate() * * Core part of a converter descriptor is initialized here. */ _LC_core_iconv_t* instantiate(void) { static _LC_core_iconv_t cd; /* * Initialize * _LC_MAGIC and _LC_VERSION are defined in <lc_core.h>. * _LC_ICONV and _LC_core_iconv_t are defined in <iconv.h>. */ cd.hdr.magic = _LC_MAGIC; cd.hdr.version = _LC_VERSION; cd.hdr.type_id = _LC_ICONV; cd.hdr.size = sizeof (_LC_core_iconv_t); /* * Set pointers to each method. */ cd.init = init; cd.exec = _iconv_exec; cd.close = _iconv_close; /* * Returns the core part */ return &cd; }
#ifndef _ICONV_SAMPLE_H #define _ICONV_SAMPLE_H /* * Define _LC_sample_iconv_t */ typedef struct _LC_sample_iconv_rec { _LC_core_iconv_t core; } _LC_sample_iconv_t; static unsigned char table[] = { /* _______________________________________ | | | IBM-850 ISO8859-1 | |_______________________________________| /* 0x00 */ 0x00, /* 0x01 */ 0x01, /* 0x02 */ 0x02, /* 0x03 */ 0x03, /* 0x04 */ 0x04, /* 0x05 */ 0x05, /* 0x06 */ 0x06, /* 0x07 */ 0x07, /* 0x08 */ 0x08, /* 0x09 */ 0x09, /* 0x0A */ 0x0A, /* 0x0B */ 0x0B, /* 0x0C */ 0x0C, /* 0x0D */ 0x0D, /* 0x0E */ 0x0E, /* 0x0F */ 0x0F, /* 0x10 */ 0x10, /* 0x11 */ 0x11, /* 0x12 */ 0x12, /* 0x13 */ 0x13, /* 0x14 */ 0x14, /* 0x15 */ 0x15, /* 0x16 */ 0x16, /* 0x17 */ 0x17, /* 0x18 */ 0x18, /* 0x19 */ 0x19, /* 0x1A */ 0x1A, /* 0x1B */ 0x1B, /* 0x1C */ 0x1C, /* 0x1D */ 0x1D, /* 0x1E */ 0x1E, /* 0x1F */ 0x1F, /* 0x20 */ 0x20, /* 0x21 */ 0x21, /* 0x22 */ 0x22, /* 0x23 */ 0x23, /* 0x24 */ 0x24, /* 0x25 */ 0x25, /* 0x26 */ 0x26, /* 0x27 */ 0x27, /* 0x28 */ 0x28, /* 0x29 */ 0x29, /* 0x2A */ 0x2A, /* 0x2B */ 0x2B, /* 0x2C */ 0x2C, /* 0x2D */ 0x2D, /* 0x2E */ 0x2E, /* 0x2F */ 0x2F, /* 0x30 */ 0x30, /* 0x31 */ 0x31, /* 0x32 */ 0x32, /* 0x33 */ 0x33, /* 0x34 */ 0x34, /* 0x35 */ 0x35, /* 0x36 */ 0x36, /* 0x37 */ 0x37, /* 0x38 */ 0x38, /* 0x39 */ 0x39, /* 0x3A */ 0x3A, /* 0x3B */ 0x3B, /* 0x3C */ 0x3C, /* 0x3D */ 0x3D, /* 0x3E */ 0x3E, /* 0x3F */ 0x3F, /* 0x40 */ 0x40, /* 0x41 */ 0x41, /* 0x42 */ 0x42, /* 0x43 */ 0x43, /* 0x44 */ 0x44, /* 0x45 */ 0x45, /* 0x46 */ 0x46, /* 0x47 */ 0x47, /* Ox48 */ 0x48, /* 0x49 */ 0x49, /* 0x4A */ 0x4A, /* 0x4B */ 0x4B, /* 0x4C */ 0x4C, /* 0x4D */ 0x4D, /* 0x4E */ 0x4E, /* 0x4F */ 0x4F, /* 0x50 */ 0x50, /* 0x51 */ 0x51, /* 0x52 */ 0x52, /* 0x53 */ 0x53, /* 0x54 */ 0x54, /* 0x55 */ 0x55, /* 0x56 */ 0x56, /* 0x57 */ 0x57, /* 0x58 */ 0x58, /* 0x59 */ 0x59, /* 0x5A */ 0x5A, /* 0x5B */ 0x5B, /* 0x5C */ 0x5C, /* 0x5D */ 0x5D, /* 0x5E */ 0x5E, /* 0x5F */ 0x5F, /* 0x60 */ 0x60, /* 0x61 */ 0x61, /* 0x62 */ 0x62, /* 0x63 */ 0x63, /* 0x64 */ 0x64, /* 0x65 */ 0x65, /* 0x66 */ 0x66, /* 0x67 */ 0x67, /* 0x68 */ 0x68, /* 0x69 */ 0x69, /* 0x6A */ 0x6A, /* 0x6B */ 0x6B, /* 0x6C */ 0x6C, /* 0x6D */ 0x6D, /* 0x6E */ 0x6E, /* 0x6F */ 0x6F, /* 0x70 */ 0x70, /* 0x71 */ 0x71, /* 0x72 */ 0x72, /* 0x73 */ 0x73, /* 0x74 */ 0x74, /* 0x75 */ 0x75, /* 0x76 */ 0x76, /* 0x77 */ 0x77, /* 0x78 */ 0x78, /* 0x79 */ 0x79, /* 0x7A */ 0x7A, /* 0x7B */ 0x7B, /* 0x7C */ 0x7C, /* 0x7D */ 0x7D, /* 0x7E */ 0x7E, /* 0x7F */ 0x7F, /* 0x80 */ 0xC7, /* 0x81 */ 0xFC, /* 0x82 */ 0xE9, /* 0x83 */ 0xE2, /* 0x84 */ 0xE4, /* 0x85 */ 0xE0, /* 0x86 */ 0xE5, /* 0x87 */ 0xE7, /* 0x88 */ 0xEA, /* 0x89 */ 0xEB, /* 0x8A */ 0xE8, /* 0x8B */ 0xEF, /* 0x8C */ 0xEE, /* 0x8D */ 0xEC, /* 0x8E */ 0xC4, /* 0x8F */ 0xC5, /* 0x90 */ 0xC9, /* 0x91 */ 0xE6, /* 0x92 */ 0xC6, /* 0x93 */ 0xF4, /* 0x94 */ 0xF6, /* 0x95 */ 0xF2, /* 0x96 */ 0xFB, /* 0x97 */ 0xF9, /* 0x98 */ 0xFF, /* 0x99 */ 0xD6, /* 0x9A */ 0xDC, /* 0x9B */ 0xF8, /* 0x9C */ 0xA3, /* 0x9D */ 0xD8, /* 0x9E */ 0xD7, /* 0x9F */ 0x1A, /* 0xA0 */ 0xE1, /* 0xA1 */ 0xED, /* 0xA2 */ 0xF3, /* 0xA3 */ 0xFA, /* 0xA4 */ 0xF1, /* 0xA5 */ 0xD1, /* 0xA6 */ 0xAA, /* 0xA7 */ 0xBA, /* 0xA8 */ 0xBF, /* 0xA9 */ 0xAE, /* 0xAA */ 0xAC, /* 0xAB */ 0xBD, /* 0xAC */ 0xBC, /* 0xAD */ 0xA1, /* 0xAE */ 0xAB, /* 0xAF */ 0xBB, /* 0xB0 */ 0x1A, /* 0xB1 */ 0x1A, /* 0xB2 */ 0x1A, /* 0xB3 */ 0x1A, /* 0xB4 */ 0x1A, /* 0xB5 */ 0xC1, /* 0xB6 */ 0xC2, /* 0xB7 */ 0xC0, /* 0xB8 */ 0xA9, /* 0xB9 */ 0x1A, /* 0xBA */ 0x1A, /* 0xBB */ 0x1A, /* 0xBC */ 0x1A, /* 0xBD */ 0xA2, /* 0xBE */ 0xA5, /* 0xBF */ 0x1A, /* 0xC0 */ 0x1A, /* 0xC1 */ 0x1A, /* 0xC2 */ 0x1A, /* 0xC3 */ 0x1A, /* 0xC4 */ 0x1A, /* 0xC5 */ 0x1A, /* 0xC6 */ 0xE3, /* 0xC7 */ 0xC3, /* 0xC8 */ 0x1A, /* 0xC9 */ 0x1A, /* 0xCA */ 0x1A, /* 0xCB */ 0x1A, /* 0xCC */ 0x1A, /* 0xCD */ 0x1A, /* 0xCE */ 0x1A, /* 0xCF */ 0xA4, /* 0xD0 */ 0xF0, /* 0xD1 */ 0xD0, /* 0xD2 */ 0xCA, /* 0xD3 */ 0xCB, /* 0xD4 */ 0xC8, /* 0xD5 */ 0x1A, /* 0xD6 */ 0xCD, /* 0xD7 */ 0xCE, /* 0xD8 */ 0xCF, /* 0xD9 */ 0x1A, /* 0xDA */ 0x1A, /* 0xDB */ 0x1A, /* 0xDC */ 0x1A, /* 0xDD */ 0xA6, /* 0xDE */ 0xCC, /* 0xDF */ 0x1A, /* 0xE0 */ 0xD3, /* 0xE1 */ 0xDF, /* 0xE2 */ 0xD4, /* 0xE3 */ 0xD2, /* 0xE4 */ 0xF5, /* 0xE5 */ 0xD5, /* 0xE6 */ 0xB5, /* 0xE7 */ 0xFE, /* 0xE8 */ 0xDE, /* 0xE9 */ 0xDA, /* 0xEA */ 0xDB, /* 0xEB */ 0xD9, /* 0xEC */ 0xFD, /* 0xED */ 0xDD, /* 0xEE */ 0xAF, /* 0xEF */ 0xB4, /* 0xF0 */ 0xAD, /* 0xF1 */ 0xB1, /* 0xF2 */ 0x1A, /* 0xF3 */ 0xBE, /* 0xF4 */ 0xB6, /* 0xF5 */ 0xA7, /* 0xF6 */ 0xF7, /* 0xF7 */ 0xB8, /* 0xF8 */ 0xB0, /* 0xF9 */ 0xA8, /* 0xFA */ 0xB7, /* 0xFB */ 0xB9, /* 0xFC */ 0xB3, /* 0xFD */ 0xB2, /* 0xFE */ 0x1A, /* 0xFF */ 0xA0, }; #endif
SHELL = /bin/ksh CFLAGS = $(COMPOPT) $(INCLUDE) $(DEFINES) INCLUDE = -I. COMPOPT = DEFINES = -D_POSIX_SOURCE -D_XOPEN_SOURCE CC = /bin/xlc LD = /bin/ld RM = /bin/rm SRC = 850_88591.c TARGET = 850_88591 ENTRY_POINT = instantiate $(TARGET) : cc -e $(ENTRY_POINT) -o $(TARGET) $(SRC) -l iconv clean : $(RM) -f $(TARGET) $(RM) -f *.o
National Language Support Overview for Programming, List of National Language Support Subroutines.
Code Sets Overview in AIX Kernel Extensions and Device Support Programming Concepts.
The iconv command, uuencode and uudecode commands.
The iconv_open subroutine, iconv subroutine, iconv_close subroutine.