1 /* Copyright (C) 2023 Free Software Foundation, Inc.
2 This file is part of the GNU LIBICONV Library.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 /* Written by Mike Fulton. */
25 /* See: https://www.ibm.com/docs/en/zos/latest?topic=lf-toccsid-convert-codeset-name-coded-character-set-id */
27 static void chgpfx (char* encoding
, size_t enclen
, size_t pfxlen
, const char* normpfx
, size_t normpfxlen
)
29 /* assertion: enclen >= pfxlen >= normpfxlen */
31 memcpy(encoding
, normpfx
, normpfxlen
);
33 memcpy(&encoding
[normpfxlen
], &encoding
[pfxlen
], enclen
-pfxlen
+1);
36 static __ccsid_t
map_encoding_to_ccsid (const char* encoding
)
38 size_t enclen
= strlen(encoding
);
39 char* updtenc
= (char*) xmalloc(enclen
+1);
40 memcpy(updtenc
, encoding
, enclen
+1);
43 * Some strings are known to gnu iconv but not z/OS __toCcsid.
44 * Examples are ISO-8859-1, ISO_8859-2, CP819 (which map to ISO8859-1, ISO8859-2, 819)
46 * The following are supported encodings and corresponding output CCSIDs
60 #define ISO8859 "ISO8859"
61 #define ISO8859_LEN (sizeof(ISO8859)-1)
62 #define ISO8859_DASH "ISO-8859"
63 #define ISO8859_DASH_LEN (sizeof(ISO8859_DASH)-1)
64 #define ISO8859_UL "ISO_8859"
65 #define ISO8859_UL_LEN (sizeof(ISO8859_UL)-1)
67 #define CP_LEN (sizeof(CP)-1)
69 #define NO_PFX_LEN (0)
71 if (enclen
> ISO8859_DASH_LEN
&& !memcmp(ISO8859_DASH
, encoding
, ISO8859_DASH_LEN
)) {
72 chgpfx(updtenc
, enclen
, ISO8859_DASH_LEN
, ISO8859
, ISO8859_LEN
);
73 } else if (enclen
> ISO8859_UL_LEN
&& !memcmp(ISO8859_UL
, encoding
, ISO8859_UL_LEN
)) {
74 chgpfx(updtenc
, enclen
, ISO8859_UL_LEN
, ISO8859
, ISO8859_LEN
);
75 } else if (enclen
> CP_LEN
&& !memcmp(CP
, encoding
, CP_LEN
)) {
76 chgpfx(updtenc
, enclen
, CP_LEN
, NO_PFX
, NO_PFX_LEN
);
78 return __toCcsid(updtenc
);
81 static int tagfile(int filedes
, const char* tocode
)
85 __ccsid_t newccsid
= map_encoding_to_ccsid(tocode
);
88 attr
.att_filetagchg
= 1;
89 attr
.att_filetag
.ft_ccsid
= newccsid
;
90 attr
.att_filetag
.ft_txtflag
= 1;
91 status
= __fchattr(filedes
, &attr
, sizeof(attr
));