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 37 #ifdef XPG4 38 #if defined(LIBC_SCCS) && !defined(lint) 39 static char sccsid[] = "@(#)euc.c 8.1 (Berkeley) 6/4/93"; 40 #endif /* LIBC_SCCS and not lint */ 41 42 #include <sys/types.h> 43 44 #include <errno.h> 45 #include <rune.h> 46 #include <stddef.h> 47 #include <stdio.h> 48 #include <stdlib.h> 49 50 rune_t _EUC_sgetrune __P((const char *, size_t, char const **)); 51 int _EUC_sputrune __P((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; 65 char *v, *e; 66 67 rl->sgetrune = _EUC_sgetrune; 68 rl->sputrune = _EUC_sputrune; 69 70 if (!rl->variable) { 71 free(rl); 72 return (EFTYPE); 73 } 74 v = (char *) rl->variable; 75 76 while (*v == ' ' || *v == '\t') 77 ++v; 78 79 if ((ei = malloc(sizeof(_EucInfo))) == NULL) { 80 free(rl); 81 return (ENOMEM); 82 } 83 for (x = 0; x < 4; ++x) { 84 ei->count[x] = (int) strtol(v, &e, 0); 85 if (v == e || !(v = e)) { 86 free(rl); 87 free(ei); 88 return (EFTYPE); 89 } 90 while (*v == ' ' || *v == '\t') 91 ++v; 92 ei->bits[x] = (int) strtol(v, &e, 0); 93 if (v == e || !(v = e)) { 94 free(rl); 95 free(ei); 96 return (EFTYPE); 97 } 98 while (*v == ' ' || *v == '\t') 99 ++v; 100 } 101 ei->mask = (int)strtol(v, &e, 0); 102 if (v == e || !(v = e)) { 103 free(rl); 104 free(ei); 105 return (EFTYPE); 106 } 107 if (sizeof(_EucInfo) <= rl->variable_len) { 108 memcpy(rl->variable, ei, sizeof(_EucInfo)); 109 free(ei); 110 } else { 111 rl->variable = &ei; 112 } 113 rl->variable_len = sizeof(_EucInfo); 114 _CurrentRuneLocale = rl; 115 __mb_cur_max = 3; 116 return (0); 117 } 118 119 #define CEI ((_EucInfo *)(_CurrentRuneLocale->variable)) 120 121 #define _SS2 0x008e 122 #define _SS3 0x008f 123 124 static inline int 125 _euc_set(c) 126 u_int c; 127 { 128 c &= 0xff; 129 130 return ((c & 0x80) ? c == _SS3 ? 3 : c == _SS2 ? 2 : 1 : 0); 131 } 132 rune_t 133 _EUC_sgetrune(string, n, result) 134 const char *string; 135 size_t n; 136 char const **result; 137 { 138 rune_t rune = 0; 139 int len, set; 140 141 if (n < 1 || (len = CEI->count[set = _euc_set(*string)]) > n) { 142 if (result) 143 *result = string; 144 return (_INVALID_RUNE); 145 } 146 switch (set) { 147 case 3: 148 case 2: 149 --len; 150 ++string; 151 /* FALLTHROUGH */ 152 case 1: 153 case 0: 154 while (len-- > 0) 155 rune = (rune << 8) | ((u_int)(*string++) & 0xff); 156 break; 157 } 158 if (result) 159 *result = string; 160 return ((rune & ~CEI->mask) | CEI->bits[set]); 161 } 162 163 int 164 _EUC_sputrune(c, string, n, result) 165 rune_t c; 166 char *string, **result; 167 size_t n; 168 { 169 rune_t m = c & CEI->mask; 170 rune_t nm = c & ~m; 171 int i, len; 172 173 if (m == CEI->bits[1]) { 174 CodeSet1: 175 /* Codeset 1: The first byte must have 0x80 in it. */ 176 i = len = CEI->count[1]; 177 if (n >= len) { 178 if (result) 179 *result = string + len; 180 while (i-- > 0) 181 *string++ = (nm >> (i << 3)) | 0x80; 182 } else 183 if (result) 184 *result = (char *) 0; 185 } else { 186 if (m == CEI->bits[0]) { 187 i = len = CEI->count[0]; 188 if (n < len) { 189 if (result) 190 *result = NULL; 191 return (len); 192 } 193 } else 194 if (m == CEI->bits[2]) { 195 i = len = CEI->count[2]; 196 if (n < len) { 197 if (result) 198 *result = NULL; 199 return (len); 200 } 201 *string++ = _SS2; 202 --i; 203 } else 204 if (m == CEI->bits[3]) { 205 i = len = CEI->count[3]; 206 if (n < len) { 207 if (result) 208 *result = NULL; 209 return (len); 210 } 211 *string++ = _SS3; 212 --i; 213 } else 214 goto CodeSet1; /* Bletch */ 215 while (i-- > 0) 216 *string++ = (nm >> (i << 3)) & 0xff; 217 if (result) 218 *result = string; 219 } 220 return (len); 221 } 222 #endif /* XPG4 */ 223