1 /* Copyright (c) 2002 Red Hat Incorporated. 2 All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are met: 6 7 Redistributions of source code must retain the above copyright 8 notice, this list of conditions and the following disclaimer. 9 10 Redistributions in binary form must reproduce the above copyright 11 notice, this list of conditions and the following disclaimer in the 12 documentation and/or other materials provided with the distribution. 13 14 The name of Red Hat Incorporated may not be used to endorse 15 or promote products derived from this software without specific 16 prior written permission. 17 18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 ARE DISCLAIMED. IN NO EVENT SHALL RED HAT INCORPORATED BE LIABLE FOR ANY 22 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 /* 31 FUNCTION 32 <<iswpunct>>---punctuation wide-character test 33 34 INDEX 35 iswpunct 36 37 ANSI_SYNOPSIS 38 #include <wctype.h> 39 int iswpunct(wint_t <[c]>); 40 41 TRAD_SYNOPSIS 42 #include <wctype.h> 43 int iswpunct(<[c]>) 44 wint_t <[c]>; 45 46 DESCRIPTION 47 <<iswpunct>> is a function which classifies wide-character values that 48 are punctuation. 49 50 RETURNS 51 <<iswpunct>> returns non-zero if <[c]> is a punctuation wide-character. 52 53 PORTABILITY 54 <<iswpunct>> is C99. 55 56 No supporting OS subroutines are required. 57 */ 58 #include <_ansi.h> 59 #include <wctype.h> 60 #include <string.h> 61 #include <ctype.h> 62 #include "local.h" 63 64 #ifdef MB_CAPABLE 65 #include "utf8punct.h" 66 #endif /* MB_CAPABLE */ 67 68 int 69 _DEFUN(iswpunct,(c), wint_t c) 70 { 71 int unicode = 0; 72 if (__lc_ctype[0] == 'C' && __lc_ctype[1] == '\0') 73 { 74 unicode = 0; 75 /* fall-through */ 76 } 77 #ifdef MB_CAPABLE 78 else if (!strcmp (__lc_ctype, "C-JIS")) 79 { 80 c = __jp2uc (c, JP_JIS); 81 unicode = 1; 82 } 83 else if (!strcmp (__lc_ctype, "C-SJIS")) 84 { 85 c = __jp2uc (c, JP_SJIS); 86 unicode = 1; 87 } 88 else if (!strcmp (__lc_ctype, "C-EUCJP")) 89 { 90 c = __jp2uc (c, JP_EUCJP); 91 unicode = 1; 92 } 93 else if (!strcmp (__lc_ctype, "C-UTF-8")) 94 { 95 unicode = 1; 96 } 97 98 if (unicode) 99 { 100 unsigned const char *table; 101 unsigned char *ptr; 102 unsigned char ctmp; 103 int size; 104 wint_t x = (c >> 8); 105 106 /* for some large sections, all characters are punctuation so handle them here */ 107 if ((x >= 0xe0 && x <= 0xf8) || 108 (x >= 0xf00 && x <= 0xffe) || 109 (x >= 0x1000 && x <= 0x10fe)) 110 return 1; 111 112 switch (x) 113 { 114 case 0x22: 115 case 0x25: 116 case 0x28: 117 case 0x29: 118 case 0x2a: 119 return 1; 120 case 0x00: 121 table = u0; 122 size = sizeof(u0); 123 break; 124 case 0x02: 125 table = u2; 126 size = sizeof(u2); 127 break; 128 case 0x03: 129 table = u3; 130 size = sizeof(u3); 131 break; 132 case 0x04: 133 table = u4; 134 size = sizeof(u4); 135 break; 136 case 0x05: 137 table = u5; 138 size = sizeof(u5); 139 break; 140 case 0x06: 141 table = u6; 142 size = sizeof(u6); 143 break; 144 case 0x07: 145 table = u7; 146 size = sizeof(u7); 147 break; 148 case 0x09: 149 table = u9; 150 size = sizeof(u9); 151 break; 152 case 0x0a: 153 table = ua; 154 size = sizeof(ua); 155 break; 156 case 0x0b: 157 table = ub; 158 size = sizeof(ub); 159 break; 160 case 0x0c: 161 table = uc; 162 size = sizeof(uc); 163 break; 164 case 0x0d: 165 table = ud; 166 size = sizeof(ud); 167 break; 168 case 0x0e: 169 table = ue; 170 size = sizeof(ue); 171 break; 172 case 0x0f: 173 table = uf; 174 size = sizeof(uf); 175 break; 176 case 0x10: 177 table = u10; 178 size = sizeof(u10); 179 break; 180 case 0x13: 181 table = u13; 182 size = sizeof(u13); 183 break; 184 case 0x16: 185 table = u16; 186 size = sizeof(u16); 187 break; 188 case 0x17: 189 table = u17; 190 size = sizeof(u17); 191 break; 192 case 0x18: 193 table = u18; 194 size = sizeof(u18); 195 break; 196 case 0x1f: 197 table = u1f; 198 size = sizeof(u1f); 199 break; 200 case 0x20: 201 table = u20; 202 size = sizeof(u20); 203 break; 204 case 0x21: 205 table = u21; 206 size = sizeof(u21); 207 break; 208 case 0x23: 209 table = u23; 210 size = sizeof(u23); 211 break; 212 case 0x24: 213 table = u24; 214 size = sizeof(u24); 215 break; 216 case 0x26: 217 table = u26; 218 size = sizeof(u26); 219 break; 220 case 0x27: 221 table = u27; 222 size = sizeof(u27); 223 break; 224 case 0x2e: 225 table = u2e; 226 size = sizeof(u2e); 227 break; 228 case 0x2f: 229 table = u2f; 230 size = sizeof(u2f); 231 break; 232 case 0x30: 233 table = u30; 234 size = sizeof(u30); 235 break; 236 case 0x31: 237 table = u31; 238 size = sizeof(u31); 239 break; 240 case 0x32: 241 table = u32; 242 size = sizeof(u32); 243 break; 244 case 0x33: 245 table = u33; 246 size = sizeof(u33); 247 break; 248 case 0xa4: 249 table = ua4; 250 size = sizeof(ua4); 251 break; 252 case 0xfb: 253 table = ufb; 254 size = sizeof(ufb); 255 break; 256 case 0xfd: 257 table = ufd; 258 size = sizeof(ufd); 259 break; 260 case 0xfe: 261 table = ufe; 262 size = sizeof(ufe); 263 break; 264 case 0xff: 265 table = uff; 266 size = sizeof(uff); 267 break; 268 case 0x103: 269 table = u103; 270 size = sizeof(u103); 271 break; 272 case 0x1d0: 273 table = u1d0; 274 size = sizeof(u1d0); 275 break; 276 case 0x1d1: 277 table = u1d1; 278 size = sizeof(u1d1); 279 break; 280 case 0x1d6: 281 table = u1d6; 282 size = sizeof(u1d6); 283 break; 284 case 0x1d7: 285 table = u1d7; 286 size = sizeof(u1d7); 287 break; 288 case 0xe00: 289 table = ue00; 290 size = sizeof(ue00); 291 break; 292 case 0xfff: 293 table = ufff; 294 size = sizeof(ufff); 295 break; 296 case 0x10ff: 297 table = u10ff; 298 size = sizeof(u10ff); 299 break; 300 default: 301 return 0; 302 } 303 /* we have narrowed down to a section of 256 characters to check */ 304 /* now check if c matches the punctuation wide-chars within that section */ 305 ptr = (unsigned char *)table; 306 ctmp = (unsigned char)c; 307 while (ptr < table + size) 308 { 309 if (ctmp == *ptr) 310 return 1; 311 if (ctmp < *ptr) 312 return 0; 313 /* otherwise c > *ptr */ 314 /* look for 0x0 as next element which indicates a range */ 315 ++ptr; 316 if (*ptr == 0x0) 317 { 318 /* we have a range..see if c falls within range */ 319 ++ptr; 320 if (ctmp <= *ptr) 321 return 1; 322 ++ptr; 323 } 324 } 325 /* not in table */ 326 return 0; 327 } 328 #endif /* MB_CAPABLE */ 329 330 return (c < (wint_t)0x100 ? ispunct (c) : 0); 331 } 332 333