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 * %sccs.include.redist.c% 9 */ 10 11 #if defined(LIBC_SCCS) && !defined(lint) 12 static char sccsid[] = "@(#)euc.c 8.1 (Berkeley) 06/04/93"; 13 #endif /* LIBC_SCCS and not lint */ 14 15 #include <sys/types.h> 16 17 #include <errno.h> 18 #include <rune.h> 19 #include <stddef.h> 20 #include <stdio.h> 21 #include <stdlib.h> 22 23 rune_t _EUC_sgetrune __P((const char *, size_t, char const **)); 24 int _EUC_sputrune __P((rune_t, char *, size_t, char **)); 25 26 typedef struct { 27 int count[4]; 28 rune_t bits[4]; 29 rune_t mask; 30 } _EucInfo; 31 32 int 33 _EUC_init(rl) 34 _RuneLocale *rl; 35 { 36 _EucInfo *ei; 37 int x; 38 char *v, *e; 39 40 rl->sgetrune = _EUC_sgetrune; 41 rl->sputrune = _EUC_sputrune; 42 43 if (!rl->variable) { 44 free(rl); 45 return (EFTYPE); 46 } 47 v = (char *) rl->variable; 48 49 while (*v == ' ' || *v == '\t') 50 ++v; 51 52 if ((ei = malloc(sizeof(_EucInfo))) == NULL) { 53 free(rl); 54 return (ENOMEM); 55 } 56 for (x = 0; x < 4; ++x) { 57 ei->count[x] = (int) strtol(v, &e, 0); 58 if (v == e || !(v = e)) { 59 free(rl); 60 free(ei); 61 return (EFTYPE); 62 } 63 while (*v == ' ' || *v == '\t') 64 ++v; 65 ei->bits[x] = (int) strtol(v, &e, 0); 66 if (v == e || !(v = e)) { 67 free(rl); 68 free(ei); 69 return (EFTYPE); 70 } 71 while (*v == ' ' || *v == '\t') 72 ++v; 73 } 74 ei->mask = (int)strtol(v, &e, 0); 75 if (v == e || !(v = e)) { 76 free(rl); 77 free(ei); 78 return (EFTYPE); 79 } 80 if (sizeof(_EucInfo) <= rl->variable_len) { 81 memcpy(rl->variable, ei, sizeof(_EucInfo)); 82 free(ei); 83 } else { 84 rl->variable = &ei; 85 } 86 rl->variable_len = sizeof(_EucInfo); 87 _CurrentRuneLocale = rl; 88 __mb_cur_max = 3; 89 return (0); 90 } 91 92 #define CEI ((_EucInfo *)(_CurrentRuneLocale->variable)) 93 94 #define _SS2 0x008e 95 #define _SS3 0x008f 96 97 static inline int 98 _euc_set(c) 99 u_int c; 100 { 101 c &= 0xff; 102 103 return ((c & 0x80) ? c == _SS3 ? 3 : c == _SS2 ? 2 : 1 : 0); 104 } 105 rune_t 106 _EUC_sgetrune(string, n, result) 107 const char *string; 108 size_t n; 109 char const **result; 110 { 111 rune_t rune = 0; 112 int len, set; 113 114 if (n < 1 || (len = CEI->count[set = _euc_set(*string)]) > n) { 115 if (result) 116 *result = string; 117 return (_INVALID_RUNE); 118 } 119 switch (set) { 120 case 3: 121 case 2: 122 --len; 123 ++string; 124 /* FALLTHROUGH */ 125 case 1: 126 case 0: 127 while (len-- > 0) 128 rune = (rune << 8) | ((u_int)(*string++) & 0xff); 129 break; 130 } 131 if (result) 132 *result = string; 133 return ((rune & ~CEI->mask) | CEI->bits[set]); 134 } 135 136 int 137 _EUC_sputrune(c, string, n, result) 138 rune_t c; 139 char *string, **result; 140 size_t n; 141 { 142 rune_t m = c & CEI->mask; 143 rune_t nm = c & ~m; 144 int i, len; 145 146 if (m == CEI->bits[1]) { 147 CodeSet1: 148 /* Codeset 1: The first byte must have 0x80 in it. */ 149 i = len = CEI->count[1]; 150 if (n >= len) { 151 if (result) 152 *result = string + len; 153 while (i-- > 0) 154 *string++ = (nm >> (i << 3)) | 0x80; 155 } else 156 if (result) 157 *result = (char *) 0; 158 } else { 159 if (m == CEI->bits[0]) { 160 i = len = CEI->count[0]; 161 if (n < len) { 162 if (result) 163 *result = NULL; 164 return (len); 165 } 166 } else 167 if (m == CEI->bits[2]) { 168 i = len = CEI->count[2]; 169 if (n < len) { 170 if (result) 171 *result = NULL; 172 return (len); 173 } 174 *string++ = _SS2; 175 --i; 176 } else 177 if (m == CEI->bits[3]) { 178 i = len = CEI->count[3]; 179 if (n < len) { 180 if (result) 181 *result = NULL; 182 return (len); 183 } 184 *string++ = _SS3; 185 --i; 186 } else 187 goto CodeSet1; /* Bletch */ 188 while (i-- > 0) 189 *string++ = (nm >> (i << 3)) & 0xff; 190 if (result) 191 *result = string; 192 } 193 return (len); 194 } 195