~ubuntu-branches/ubuntu/natty/ibm-3270/natty

« back to all changes in this revision

Viewing changes to pr3287/charset.c

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2009-12-14 11:48:53 UTC
  • mfrom: (1.1.4 upstream) (2.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20091214114853-mywixml32hct9jr1
Tags: 3.3.10ga4-2
* Fix section to match override.
* Use debhelper compat level 7.
* Use 3.0 (quilt) source format.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright 2001, 2004 by Paul Mattes.
3
 
 *  Permission to use, copy, modify, and distribute this software and its
4
 
 *  documentation for any purpose and without fee is hereby granted,
5
 
 *  provided that the above copyright notice appear in all copies and that
6
 
 *  both that copyright notice and this permission notice appear in
7
 
 *  supporting documentation.
8
 
 *
9
 
 * pr3287 is distributed in the hope that it will be useful, but WITHOUT ANY
10
 
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
 
 * FOR A PARTICULAR PURPOSE.  See the file LICENSE for more details.
 
2
 * Copyright (c) 2001-2009, Paul Mattes.
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions are met:
 
7
 *     * Redistributions of source code must retain the above copyright
 
8
 *       notice, this list of conditions and the following disclaimer.
 
9
 *     * Redistributions in binary form must reproduce the above copyright
 
10
 *       notice, this list of conditions and the following disclaimer in the
 
11
 *       documentation and/or other materials provided with the distribution.
 
12
 *     * Neither the names of Paul Mattes nor the names of his contributors
 
13
 *       may be used to endorse or promote products derived from this software
 
14
 *       without specific prior written permission.
 
15
 *
 
16
 * THIS SOFTWARE IS PROVIDED BY PAUL MATTES "AS IS" AND ANY EXPRESS OR IMPLIED
 
17
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 
18
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 
19
 * EVENT SHALL PAUL MATTES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
20
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
21
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 
22
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 
23
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 
24
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 
25
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12
26
 */
13
27
 
14
28
/*
17
31
 */
18
32
 
19
33
#include "globals.h"
20
 
#include "tablesc.h"
21
34
 
22
35
#include <errno.h>
23
36
#include <ctype.h>
24
37
#include <stdlib.h>
25
 
 
26
 
#include "widec.h"
27
 
 
28
 
typedef struct {
29
 
        const char *name;
30
 
        unsigned char *map;
31
 
} cs_t;
32
 
 
33
 
/* Built-in character sets. */
34
 
static unsigned char us_intl_map[] = { 0 };
35
 
static unsigned char us_map[] = { 0 };
36
 
static unsigned char apl_map[] = { 0 };
37
 
static unsigned char bracket_map[] = { 0xad, 0x5b, 0xba, 0xdd, 0xbd, 0x5d,
38
 
    0xbb, 0xa8, 0 };
39
 
static unsigned char oldibm_map[] = { 0xad, 0x5b, 0xba, 0xdd, 0xbd, 0x5d,
40
 
    0xbb, 0xa8, 0 };
41
 
static unsigned char german_map[] = { 0x43, 0x7b, 0x4a, 0xc4, 0x4f, 0x21,
42
 
    0x59, 0x7e, 0x5a, 0xdc, 0x5f, 0x5e, 0x63, 0x5b, 0x6a, 0xf6, 0x7c, 0xa7,
43
 
    0xa1, 0xdf, 0xb0, 0xa2, 0xb5, 0x40, 0xba, 0xac, 0xbb, 0x7c, 0xc0, 0xe4,
44
 
    0xcc, 0xa6, 0xd0, 0xfc, 0xdc, 0x7d, 0xe0, 0xd6, 0xec, 0x5c, 0xfc, 0x5d, 0 };
45
 
static unsigned char finnish_map[] = { 0x43, 0x7b, 0x47, 0x7d, 0x4a, 0xa7,
46
 
    0x4f, 0x21, 0x51, 0x60, 0x5a, 0xa4, 0x5b, 0xc5, 0x5f, 0x5e, 0x63, 0x23,
47
 
    0x67, 0x24, 0x6a, 0xf6, 0x71, 0x5c, 0x79, 0xe9, 0x7b, 0xc4, 0x7c, 0xd6,
48
 
    0x9f, 0x5d, 0xa1, 0xfc, 0xb1, 0xa2, 0xb5, 0x5b, 0xba, 0xac, 0xbb, 0x7c,
49
 
    0xc0, 0xe4, 0xcc, 0xa6, 0xd0, 0xe5, 0xdc, 0x7e, 0xe0, 0xc9, 0xec, 0x40, 0 };
50
 
static unsigned char uk_map[] = { 0x4a, 0x24, 0x5b, 0xa3, 0xa1, 0xaf, 0xb0,
51
 
    0xa2, 0xb1, 0x5b, 0xba, 0x5e, 0xbc, 0x7e, 0 };
52
 
static unsigned char norwegian_map[] = { 0x47, 0x7d, 0x4a, 0x23, 0x4f, 0x21,
53
 
    0x5a, 0xa4, 0x5b, 0xc5, 0x5f, 0x5e, 0x67, 0x24, 0x6a, 0xf8, 0x70, 0xa6,
54
 
    0x7b, 0xc6, 0x7c, 0xd8, 0x80, 0x40, 0x9c, 0x7b, 0x9e, 0x5b, 0x9f, 0x5d,
55
 
    0xa1, 0xfc, 0xb0, 0xa2, 0xba, 0xac, 0xbb, 0x7c, 0xc0, 0xe6, 0xd0, 0xe5,
56
 
    0xdc, 0x7e, 0 };
57
 
static unsigned char french_map[] = { 0x44, 0x40, 0x48, 0x5c, 0x4a, 0xb0,
58
 
    0x4f, 0x21, 0x51, 0x7b, 0x54, 0x7d, 0x5a, 0xa7, 0x5f, 0x5e, 0x6a, 0xf9,
59
 
    0x79, 0xb5, 0x7b, 0xa3, 0x7c, 0xe0, 0x90, 0x5b, 0xa0, 0x60, 0xa1, 0xa8,
60
 
    0xb0, 0xa2, 0xb1, 0x23, 0xb5, 0x5d, 0xba, 0xac, 0xbb, 0x7c, 0xbd, 0x7e,
61
 
    0xc0, 0xe9, 0xd0, 0xe8, 0xe0, 0xe7, 0 };
62
 
static unsigned char icelandic_map[] = { 0xa1, 0xf6, 0x5f, 0xd6, 0x79, 0xf0,
63
 
     0x7c, 0xd0, 0xc0, 0xfe, 0x4a, 0xde, 0xd0, 0xe6, 0x5a, 0xc6, 0xcc, 0x7e,
64
 
    0x4f, 0x21, 0x8e, 0x7b, 0x9c, 0x7d, 0xae, 0x5b, 0x9e, 0x5d, 0xac, 0x40,
65
 
    0xbe, 0x5c, 0x7d, 0x27, 0x8c, 0x60, 0x6a, 0x7c, 0 };
66
 
static unsigned char belgian_map[] = { 0x4a, 0x5b, 0x4f, 0x21, 0x5a, 0x5d,
67
 
    0x5f, 0x5e, 0xb0, 0xa2, 0xba, 0xac, 0xbb, 0x7c, 0 };
68
 
 
69
 
static cs_t cs[] = {
70
 
        { "us-intl", us_intl_map },
71
 
        { "us", us_map },
72
 
        { "apl", apl_map },
73
 
        { "bracket", bracket_map },
74
 
        { "oldibm", oldibm_map },
75
 
        { "german", german_map },
76
 
        { "finnish", finnish_map },
77
 
        { "uk", uk_map },
78
 
        { "norwegian", norwegian_map },
79
 
        { "french", french_map },
80
 
        { "icelandic", icelandic_map },
81
 
        { "belgian", belgian_map },
82
 
        { NULL, NULL }
83
 
};
 
38
#if !defined(_WIN32) /*[*/
 
39
#include <locale.h>
 
40
#include <langinfo.h>
 
41
#endif /*]*/
 
42
 
 
43
#if defined(__CYGWIN__) /*[*/
 
44
#include <w32api/windows.h>
 
45
#undef _WIN32
 
46
#endif /*]*/
 
47
 
 
48
#include "3270ds.h"
 
49
#include "charsetc.h"
 
50
#include "unicodec.h"
 
51
#include "unicode_dbcsc.h"
 
52
#include "utf8c.h"
84
53
 
85
54
unsigned long cgcsgid = 0x02b90025;
86
55
unsigned long cgcsgid_dbcs = 0x02b90025;
90
59
char *converters = CN;
91
60
 
92
61
/*
93
 
 * Parse a remapping string (<ebc>=<iso>), and remap the specific EBCDIC code.
94
 
 * Also understand the syntax "cgcsgid=<n>" for assigning a new CGCSGID.
95
 
 * Returns 0 for success, -1 for a parsing problem.
96
 
 */
97
 
static int
98
 
remap_pair(const char *s)
99
 
{
100
 
        unsigned long ebc, iso;
101
 
        char *ptr;
102
 
 
103
 
        if (!strncmp(s, "cgcsgid=", 8)) {
104
 
                unsigned long c;
105
 
 
106
 
                c = strtoul(s + 8, &ptr, 0);
107
 
                if (c == 0 || *ptr != '\0')
108
 
                        return -1;
109
 
                cgcsgid = c;
110
 
                return 0;
111
 
        }
112
 
#if defined(X3270_DBCS) /*[*/
113
 
        if (!strncmp(s, "cgcsgid_dbcs=", 13)) {
114
 
                unsigned long c;
115
 
 
116
 
                c = strtoul(s + 13, &ptr, 0);
117
 
                if (c == 0 || *ptr != '\0')
118
 
                        return -1;
119
 
                cgcsgid_dbcs = c;
120
 
                return 0;
121
 
        }
122
 
        if (!strncmp(s, "encoding=", 9)) {
123
 
                Replace(encoding, NewString((char *)s + 9));
124
 
                return 0;
125
 
        }
126
 
        if (!strncmp(s, "converters=", 11)) {
127
 
                Replace(converters, NewString((char *)s + 11));
128
 
                return 0;
129
 
        }
130
 
#endif /*]*/
131
 
        ebc = strtoul(s, &ptr, 0);
132
 
        if (ptr == s || (ebc & ~0xff) || *ptr != '=')
133
 
                return -1;
134
 
        s = ptr + 1;
135
 
        iso = strtoul(s, &ptr, 0);
136
 
        if (ptr == s || (iso & ~0xff) || *ptr)
137
 
                return -1;
138
 
        ebc2asc[ebc] = iso;
139
 
        return 0;
140
 
}
141
 
 
142
 
/*
143
62
 * Change character sets.
144
63
 * Returns 0 if the new character set was found, -1 otherwise.
145
64
 */
146
 
int
147
 
charset_init(const char *csname)
 
65
enum cs_result
 
66
charset_init(char *csname)
148
67
{
149
 
        cs_t *c;
150
 
        int i;
151
 
 
152
 
        /* Set up ebc2asc. */
153
 
        (void) memcpy(ebc2asc, ebc2asc0, 256);
154
 
        if (csname == NULL)
155
 
                return 0;
156
 
 
157
 
        /* If the name begins with an '@', the balance is a file name. */
158
 
        if (csname[0] == '@') {
159
 
                FILE *f;
160
 
                char buf[1024];
161
 
                int lno = 0;
162
 
 
163
 
                if (!*(csname + 1)) {
164
 
                        errmsg("Empty charset file name");
165
 
                        return -1;
166
 
                }
167
 
                f = fopen(csname + 1, "r");
168
 
                if (f == NULL) {
169
 
                        errmsg("Charset file '%s': %s", csname + 1,
170
 
                            strerror(errno));
171
 
                        return -1;
172
 
                }
173
 
                while (fgets(buf, sizeof(buf), f) != NULL) {
174
 
                        char *s = buf;
175
 
                        char *token;
176
 
 
177
 
                        lno++;
178
 
                        while (isspace(*s))
179
 
                                s++;
180
 
                        if (*s == '#')
181
 
                                continue;
182
 
                        while ((token = strtok(s, " \t\r\n")) != NULL) {
183
 
                                s = NULL;
184
 
                                if (remap_pair(token) < 0) {
185
 
                                        errmsg("%s, line %d: invalid value "
186
 
                                            "'%s'", csname + 1, lno, token);
187
 
                                        fclose(f);
188
 
                                        return -1;
189
 
                                }
190
 
                        }
191
 
                }
192
 
                fclose(f);
 
68
#if !defined(_WIN32) /*[*/
 
69
        char *codeset_name;
 
70
#endif /*]*/
 
71
        const char *host_codepage;
 
72
        const char *cgcsgid_str;
 
73
        const char *display_charsets;
 
74
 
 
75
#if !defined(_WIN32) /*[*/
 
76
        setlocale(LC_ALL, "");
 
77
        codeset_name = nl_langinfo(CODESET);
 
78
#if defined(__CYGWIN__) /*[*/
 
79
        /*
 
80
         * Cygwin's locale support is quite limited.  If the locale
 
81
         * indicates "US-ASCII", which appears to be the only supported
 
82
         * encoding, ignore it and use the Windows ANSI code page, which
 
83
         * observation indicates is what is actually supported.
 
84
         *
 
85
         * Hopefully at some point Cygwin will start returning something
 
86
         * meaningful here and this logic will stop triggering.
 
87
         *
 
88
         * If this (lack of) functionality persists, then it will probably
 
89
         * become necessary for pr3287 to support the wpr3287 '-printercp'
 
90
         * option, so that the printer code page can be configured.
 
91
         */
 
92
        if (!strcmp(codeset_name, "US-ASCII")) {
 
93
                codeset_name = Malloc(64);
 
94
                sprintf(codeset_name, "CP%d", GetACP());
 
95
        }
 
96
#endif /*]*/
 
97
        set_codeset(codeset_name);
 
98
#endif /*]*/
 
99
 
 
100
        if (set_uni(csname, &host_codepage, &cgcsgid_str,
 
101
                    &display_charsets) < 0)
 
102
                return CS_NOTFOUND;
 
103
        cgcsgid = strtoul(cgcsgid_str, NULL, 0);
 
104
        if (!(cgcsgid & ~0xffff))
 
105
                cgcsgid |= 0x02b90000;
 
106
 
193
107
#if defined(X3270_DBCS) /*[*/
194
 
                if (converters != CN) {
195
 
                        if (wide_init(converters, encoding) < 0)
196
 
                                return -1;
197
 
                        dbcs = 1;
198
 
                }
 
108
        if (set_uni_dbcs(csname, &cgcsgid_str, &display_charsets) == 0) {
 
109
                dbcs = 1;
 
110
                cgcsgid_dbcs = strtoul(cgcsgid_str, NULL, 0);
 
111
        }
199
112
#endif /*]*/
200
 
                return 0;
201
 
        }
202
 
 
203
 
        /* If the name begins with an '=', the balance is a literal string. */
204
 
        if (csname[0] == '=') {
205
 
                char *s0, *s;
206
 
                char *token;
207
 
 
208
 
                if (!*(csname + 1))
209
 
                        return 0;
210
 
                s0 = malloc(strlen(csname + 1) + 1);
211
 
                if (s0 == NULL) {
212
 
                        errmsg("Insufficient memory to parse charset");
213
 
                        return -1;
214
 
                }
215
 
                s = strcpy(s0, csname + 1);
216
 
                while ((token = strtok(s, " \t\r\n")) != NULL) {
217
 
                        s = NULL;
218
 
                        if (remap_pair(token) < 0) {
219
 
                                errmsg("charset invalid value '%s'", token);
220
 
                                free(s0);
221
 
                                return -1;
222
 
                        }
223
 
                }
224
 
                free(s0);
225
 
                return 0;
226
 
        }
227
 
 
228
 
        /* Otherwise, it's a built-in name. */
229
 
        for (c = cs; c->name != NULL; c++) {
230
 
                if (!strcmp(csname, c->name))
231
 
                        break;
232
 
        }
233
 
        if (c->name == NULL) {
234
 
                errmsg("No such charset: %s", csname);
235
 
                return -1;
236
 
        }
237
 
 
238
 
        /* Remap 'em. */
239
 
        for (i = 0; c->map[i]; i += 2) {
240
 
                ebc2asc[c->map[i]] = c->map[i+1];
241
 
        }
242
 
        return 0;
 
113
 
 
114
        return CS_OKAY;
243
115
}