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.
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.
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.
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.
19
33
#include "globals.h"
24
37
#include <stdlib.h>
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,
39
static unsigned char oldibm_map[] = { 0xad, 0x5b, 0xba, 0xdd, 0xbd, 0x5d,
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,
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 };
70
{ "us-intl", us_intl_map },
73
{ "bracket", bracket_map },
74
{ "oldibm", oldibm_map },
75
{ "german", german_map },
76
{ "finnish", finnish_map },
78
{ "norwegian", norwegian_map },
79
{ "french", french_map },
80
{ "icelandic", icelandic_map },
81
{ "belgian", belgian_map },
38
#if !defined(_WIN32) /*[*/
43
#if defined(__CYGWIN__) /*[*/
44
#include <w32api/windows.h>
51
#include "unicode_dbcsc.h"
85
54
unsigned long cgcsgid = 0x02b90025;
86
55
unsigned long cgcsgid_dbcs = 0x02b90025;
90
59
char *converters = CN;
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.
98
remap_pair(const char *s)
100
unsigned long ebc, iso;
103
if (!strncmp(s, "cgcsgid=", 8)) {
106
c = strtoul(s + 8, &ptr, 0);
107
if (c == 0 || *ptr != '\0')
112
#if defined(X3270_DBCS) /*[*/
113
if (!strncmp(s, "cgcsgid_dbcs=", 13)) {
116
c = strtoul(s + 13, &ptr, 0);
117
if (c == 0 || *ptr != '\0')
122
if (!strncmp(s, "encoding=", 9)) {
123
Replace(encoding, NewString((char *)s + 9));
126
if (!strncmp(s, "converters=", 11)) {
127
Replace(converters, NewString((char *)s + 11));
131
ebc = strtoul(s, &ptr, 0);
132
if (ptr == s || (ebc & ~0xff) || *ptr != '=')
135
iso = strtoul(s, &ptr, 0);
136
if (ptr == s || (iso & ~0xff) || *ptr)
143
62
* Change character sets.
144
63
* Returns 0 if the new character set was found, -1 otherwise.
147
charset_init(const char *csname)
66
charset_init(char *csname)
152
/* Set up ebc2asc. */
153
(void) memcpy(ebc2asc, ebc2asc0, 256);
157
/* If the name begins with an '@', the balance is a file name. */
158
if (csname[0] == '@') {
163
if (!*(csname + 1)) {
164
errmsg("Empty charset file name");
167
f = fopen(csname + 1, "r");
169
errmsg("Charset file '%s': %s", csname + 1,
173
while (fgets(buf, sizeof(buf), f) != NULL) {
182
while ((token = strtok(s, " \t\r\n")) != NULL) {
184
if (remap_pair(token) < 0) {
185
errmsg("%s, line %d: invalid value "
186
"'%s'", csname + 1, lno, token);
68
#if !defined(_WIN32) /*[*/
71
const char *host_codepage;
72
const char *cgcsgid_str;
73
const char *display_charsets;
75
#if !defined(_WIN32) /*[*/
76
setlocale(LC_ALL, "");
77
codeset_name = nl_langinfo(CODESET);
78
#if defined(__CYGWIN__) /*[*/
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.
85
* Hopefully at some point Cygwin will start returning something
86
* meaningful here and this logic will stop triggering.
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.
92
if (!strcmp(codeset_name, "US-ASCII")) {
93
codeset_name = Malloc(64);
94
sprintf(codeset_name, "CP%d", GetACP());
97
set_codeset(codeset_name);
100
if (set_uni(csname, &host_codepage, &cgcsgid_str,
101
&display_charsets) < 0)
103
cgcsgid = strtoul(cgcsgid_str, NULL, 0);
104
if (!(cgcsgid & ~0xffff))
105
cgcsgid |= 0x02b90000;
193
107
#if defined(X3270_DBCS) /*[*/
194
if (converters != CN) {
195
if (wide_init(converters, encoding) < 0)
108
if (set_uni_dbcs(csname, &cgcsgid_str, &display_charsets) == 0) {
110
cgcsgid_dbcs = strtoul(cgcsgid_str, NULL, 0);
203
/* If the name begins with an '=', the balance is a literal string. */
204
if (csname[0] == '=') {
210
s0 = malloc(strlen(csname + 1) + 1);
212
errmsg("Insufficient memory to parse charset");
215
s = strcpy(s0, csname + 1);
216
while ((token = strtok(s, " \t\r\n")) != NULL) {
218
if (remap_pair(token) < 0) {
219
errmsg("charset invalid value '%s'", token);
228
/* Otherwise, it's a built-in name. */
229
for (c = cs; c->name != NULL; c++) {
230
if (!strcmp(csname, c->name))
233
if (c->name == NULL) {
234
errmsg("No such charset: %s", csname);
239
for (i = 0; c->map[i]; i += 2) {
240
ebc2asc[c->map[i]] = c->map[i+1];