1 /*- 2 * Copyright (c) 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Paul Borman at Krystal Technologies. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)euc.c 8.1 (Berkeley) 6/4/93 37 * $FreeBSD: src/lib/libc/locale/euc.c,v 1.3.6.2 2002/08/12 11:17:37 ache Exp $ 38 * $DragonFly: src/lib/libc/locale/Attic/euc.c,v 1.2 2003/06/17 04:26:44 dillon Exp $ 39 */ 40 41 #include <sys/types.h> 42 43 #include <errno.h> 44 #include <rune.h> 45 #include <stddef.h> 46 #include <stdio.h> 47 #include <stdlib.h> 48 #include <string.h> 49 50 rune_t _EUC_sgetrune(const char *, size_t, char const **); 51 int _EUC_sputrune(rune_t, char *, size_t, char **); 52 53 typedef struct { 54 int count[4]; 55 rune_t bits[4]; 56 rune_t mask; 57 } _EucInfo; 58 59 int 60 _EUC_init(rl) 61 _RuneLocale *rl; 62 { 63 _EucInfo *ei; 64 int x, new__mb_cur_max; 65 char *v, *e; 66 67 rl->sgetrune = _EUC_sgetrune; 68 rl->sputrune = _EUC_sputrune; 69 70 if (rl->variable == NULL) 71 return (EFTYPE); 72 73 v = (char *)rl->variable; 74 75 while (*v == ' ' || *v == '\t') 76 ++v; 77 78 if ((ei = malloc(sizeof(_EucInfo))) == NULL) 79 return (errno == 0 ? ENOMEM : errno); 80 81 new__mb_cur_max = 0; 82 for (x = 0; x < 4; ++x) { 83 ei->count[x] = (int)strtol(v, &e, 0); 84 if (v == e || !(v = e)) { 85 free(ei); 86 return (EFTYPE); 87 } 88 if (new__mb_cur_max < ei->count[x]) 89 new__mb_cur_max = ei->count[x]; 90 while (*v == ' ' || *v == '\t') 91 ++v; 92 ei->bits[x] = (int)strtol(v, &e, 0); 93 if (v == e || !(v = e)) { 94 free(ei); 95 return (EFTYPE); 96 } 97 while (*v == ' ' || *v == '\t') 98 ++v; 99 } 100 ei->mask = (int)strtol(v, &e, 0); 101 if (v == e || !(v = e)) { 102 free(ei); 103 return (EFTYPE); 104 } 105 rl->variable = ei; 106 rl->variable_len = sizeof(_EucInfo); 107 _CurrentRuneLocale = rl; 108 __mb_cur_max = new__mb_cur_max; 109 return (0); 110 } 111 112 #define CEI ((_EucInfo *)(_CurrentRuneLocale->variable)) 113 114 #define _SS2 0x008e 115 #define _SS3 0x008f 116 117 #define GR_BITS 0x80808080 /* XXX: to be fixed */ 118 119 static inline int 120 _euc_set(c) 121 u_int c; 122 { 123 c &= 0xff; 124 125 return ((c & 0x80) ? c == _SS3 ? 3 : c == _SS2 ? 2 : 1 : 0); 126 } 127 rune_t 128 _EUC_sgetrune(string, n, result) 129 const char *string; 130 size_t n; 131 char const **result; 132 { 133 rune_t rune = 0; 134 int len, set; 135 136 if (n < 1 || (len = CEI->count[set = _euc_set(*string)]) > n) { 137 if (result) 138 *result = string; 139 return (_INVALID_RUNE); 140 } 141 switch (set) { 142 case 3: 143 case 2: 144 --len; 145 ++string; 146 /* FALLTHROUGH */ 147 case 1: 148 case 0: 149 while (len-- > 0) 150 rune = (rune << 8) | ((u_int)(*string++) & 0xff); 151 break; 152 } 153 if (result) 154 *result = string; 155 return ((rune & ~CEI->mask) | CEI->bits[set]); 156 } 157 158 int 159 _EUC_sputrune(c, string, n, result) 160 rune_t c; 161 char *string, **result; 162 size_t n; 163 { 164 rune_t m = c & CEI->mask; 165 rune_t nm = c & ~m; 166 int i, len; 167 168 if (m == CEI->bits[1]) { 169 CodeSet1: 170 /* Codeset 1: The first byte must have 0x80 in it. */ 171 i = len = CEI->count[1]; 172 if (n >= len) { 173 if (result) 174 *result = string + len; 175 while (i-- > 0) 176 *string++ = (nm >> (i << 3)) | 0x80; 177 } else 178 if (result) 179 *result = (char *) 0; 180 } else { 181 if (m == CEI->bits[0]) { 182 i = len = CEI->count[0]; 183 if (n < len) { 184 if (result) 185 *result = NULL; 186 return (len); 187 } 188 } else 189 if (m == CEI->bits[2]) { 190 i = len = CEI->count[2]; 191 if (n < len) { 192 if (result) 193 *result = NULL; 194 return (len); 195 } 196 *string++ = _SS2; 197 --i; 198 /* SS2 designates G2 into GR */ 199 nm |= GR_BITS; 200 } else 201 if (m == CEI->bits[3]) { 202 i = len = CEI->count[3]; 203 if (n < len) { 204 if (result) 205 *result = NULL; 206 return (len); 207 } 208 *string++ = _SS3; 209 --i; 210 /* SS3 designates G3 into GR */ 211 nm |= GR_BITS; 212 } else 213 goto CodeSet1; /* Bletch */ 214 while (i-- > 0) 215 *string++ = (nm >> (i << 3)) & 0xff; 216 if (result) 217 *result = string; 218 } 219 return (len); 220 } 221