nexmon – Rev 1

Subversion Repositories:
Rev:
/* make_charset_table.c
 * sample program to generate tables for charsets.c using iconv
 *
 * public domain
 */

#include <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <iconv.h>

#define UNREPL 0xFFFD

int main(int argc, char **argv) {
        /* for now only UCS-2 */
        uint16_t table[0x100];

        iconv_t conv;
        const char *charset;
        int i, j;

        /* 0x00 ... 0x7F same as ASCII? */
        int ascii_based = 1;
        /* 0x00 ... 0x9F same as ISO? */
        int iso_based = 1;

        if (argc != 2) {
                printf("usage: %s <charset>\n", argv[0]);
                return 1;
        }

        charset = argv[1];

        conv = iconv_open("UCS-2", charset);
        if (conv == (iconv_t) -1) {
                perror("iconv_open");
                return 2;
        }
        iconv_close(conv);

        for (i = 0x00; i < 0x100; i++) {
                unsigned char in[1], out[2];
                size_t inlen = 1, outlen = 2;

                char *inbuf = (char *) in;
                char *outbuf = (char *) out;

                size_t ret;

                in[0] = i;

                conv = iconv_open("UCS-2BE", charset);

                if (conv == (iconv_t) -1) {
                        /* shouldn't fail now */
                        perror("iconv_open");
                        return 2;
                }

                ret = iconv(conv, &inbuf, &inlen, &outbuf, &outlen);

                if (ret == (size_t) -1 && errno == EILSEQ) {
                        table[i] = UNREPL;
                        iconv_close(conv);
                        continue;
                }

                if (ret == (size_t) -1) {
                        perror("iconv");
                        iconv_close(conv);
                        return 4;
                }

                iconv_close(conv);

                if (ret != 0 || inlen != 0 || outlen != 0) {
                        fprintf(stderr, "%d: smth went wrong: %zu %zu %zu\n", i, ret, inlen, outlen);
                        return 3;
                }

                if (i < 0x80 && (out[0] != 0 || out[1] != i))
                        ascii_based = 0;

                if (i < 0xA0 && (out[0] != 0 || out[1] != i))
                        iso_based = 0;
                        
                table[i] = (out[0] << 8) | out[1];
        }

        /* iso_based not supported */
        iso_based = 0;

        printf("/* generated by %s %s */\n", argv[0], charset);

        if (iso_based)
                i = 0xA0;
        else if (ascii_based)
                i = 0x80;
        else
                i = 0;

        printf("const gunichar2 charset_table_%s[0x%x] = {\n", charset, 0x100 - i);
        while (i < 0x100) {
                int start = i;

                printf("    ");

                for (j = 0; j < 8; j++, i++) {
                        if (table[i] == UNREPL)
                                printf("UNREPL, ");
                        else
                                printf("0x%.4x, ", table[i]);
                }

                if ((start & 0xf) == 0)
                        printf("       /* 0x%.2X -      */", start);
                else
                        printf("       /*      - 0x%.2X */", i - 1);

                printf("\n");
        }
        printf("};\n");

        return 0;
}