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 <<iswprint>>---printable wide-character test 33 34 INDEX 35 iswprint 36 37 ANSI_SYNOPSIS 38 #include <wctype.h> 39 int iswprint(wint_t <[c]>); 40 41 TRAD_SYNOPSIS 42 #include <wctype.h> 43 int iswprint(<[c]>) 44 wint_t <[c]>; 45 46 DESCRIPTION 47 <<iswprint>> is a function which classifies wide-character values that 48 are printable. 49 50 RETURNS 51 <<iswprint>> returns non-zero if <[c]> is a printable wide-character. 52 53 PORTABILITY 54 <<iswprint>> 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 "utf8print.h" 66 #endif /* MB_CAPABLE */ 67 68 int 69 _DEFUN(iswprint,(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 printuation so handle them here */ 107 if ((x >= 0x34 && x <= 0x4c) || 108 (x >= 0x4e && x <= 0x9e) || 109 (x >= 0xac && x <= 0xd6) || 110 (x >= 0xe0 && x <= 0xf9) || 111 (x >= 0x200 && x <= 0x2a5) || 112 (x >= 0xf00 && x <= 0xffe) || 113 (x >= 0x1000 && x <= 0x10fe)) 114 return 1; 115 116 switch (x) 117 { 118 case 0x01: 119 case 0x15: 120 case 0x22: 121 case 0x25: 122 case 0x28: 123 case 0x29: 124 case 0x2a: 125 case 0xa0: 126 case 0xa1: 127 case 0xa2: 128 case 0xa3: 129 case 0xfc: 130 case 0x2f8: 131 case 0x2f9: 132 return 1; 133 case 0x00: 134 table = u0; 135 size = sizeof(u0); 136 break; 137 case 0x02: 138 table = u2; 139 size = sizeof(u2); 140 break; 141 case 0x03: 142 table = u3; 143 size = sizeof(u3); 144 break; 145 case 0x04: 146 table = u4; 147 size = sizeof(u4); 148 break; 149 case 0x05: 150 table = u5; 151 size = sizeof(u5); 152 break; 153 case 0x06: 154 table = u6; 155 size = sizeof(u6); 156 break; 157 case 0x07: 158 table = u7; 159 size = sizeof(u7); 160 break; 161 case 0x09: 162 table = u9; 163 size = sizeof(u9); 164 break; 165 case 0x0a: 166 table = ua; 167 size = sizeof(ua); 168 break; 169 case 0x0b: 170 table = ub; 171 size = sizeof(ub); 172 break; 173 case 0x0c: 174 table = uc; 175 size = sizeof(uc); 176 break; 177 case 0x0d: 178 table = ud; 179 size = sizeof(ud); 180 break; 181 case 0x0e: 182 table = ue; 183 size = sizeof(ue); 184 break; 185 case 0x0f: 186 table = uf; 187 size = sizeof(uf); 188 break; 189 case 0x10: 190 table = u10; 191 size = sizeof(u10); 192 break; 193 case 0x11: 194 table = u11; 195 size = sizeof(u11); 196 break; 197 case 0x12: 198 table = u12; 199 size = sizeof(u12); 200 break; 201 case 0x13: 202 table = u13; 203 size = sizeof(u13); 204 break; 205 case 0x14: 206 table = u14; 207 size = sizeof(u14); 208 break; 209 case 0x16: 210 table = u16; 211 size = sizeof(u16); 212 break; 213 case 0x17: 214 table = u17; 215 size = sizeof(u17); 216 break; 217 case 0x18: 218 table = u18; 219 size = sizeof(u18); 220 break; 221 case 0x1e: 222 table = u1e; 223 size = sizeof(u1e); 224 break; 225 case 0x1f: 226 table = u1f; 227 size = sizeof(u1f); 228 break; 229 case 0x20: 230 table = u20; 231 size = sizeof(u20); 232 break; 233 case 0x21: 234 table = u21; 235 size = sizeof(u21); 236 break; 237 case 0x23: 238 table = u23; 239 size = sizeof(u23); 240 break; 241 case 0x24: 242 table = u24; 243 size = sizeof(u24); 244 break; 245 case 0x26: 246 table = u26; 247 size = sizeof(u26); 248 break; 249 case 0x27: 250 table = u27; 251 size = sizeof(u27); 252 break; 253 case 0x2e: 254 table = u2e; 255 size = sizeof(u2e); 256 break; 257 case 0x2f: 258 table = u2f; 259 size = sizeof(u2f); 260 break; 261 case 0x30: 262 table = u30; 263 size = sizeof(u30); 264 break; 265 case 0x31: 266 table = u31; 267 size = sizeof(u31); 268 break; 269 case 0x32: 270 table = u32; 271 size = sizeof(u32); 272 break; 273 case 0x33: 274 table = u33; 275 size = sizeof(u33); 276 break; 277 case 0x4d: 278 table = u4d; 279 size = sizeof(u4d); 280 break; 281 case 0x9f: 282 table = u9f; 283 size = sizeof(u9f); 284 break; 285 case 0xa4: 286 table = ua4; 287 size = sizeof(ua4); 288 break; 289 case 0xd7: 290 table = ud7; 291 size = sizeof(ud7); 292 break; 293 case 0xfa: 294 table = ufa; 295 size = sizeof(ufa); 296 break; 297 case 0xfb: 298 table = ufb; 299 size = sizeof(ufb); 300 break; 301 case 0xfd: 302 table = ufd; 303 size = sizeof(ufd); 304 break; 305 case 0xfe: 306 table = ufe; 307 size = sizeof(ufe); 308 break; 309 case 0xff: 310 table = uff; 311 size = sizeof(uff); 312 break; 313 case 0x103: 314 table = u103; 315 size = sizeof(u103); 316 break; 317 case 0x104: 318 table = u104; 319 size = sizeof(u104); 320 break; 321 case 0x1d0: 322 table = u1d0; 323 size = sizeof(u1d0); 324 break; 325 case 0x1d1: 326 table = u1d1; 327 size = sizeof(u1d1); 328 break; 329 case 0x1d4: 330 table = u1d4; 331 size = sizeof(u1d4); 332 break; 333 case 0x1d5: 334 table = u1d5; 335 size = sizeof(u1d5); 336 break; 337 case 0x1d6: 338 table = u1d6; 339 size = sizeof(u1d6); 340 break; 341 case 0x1d7: 342 table = u1d7; 343 size = sizeof(u1d7); 344 break; 345 case 0x2a6: 346 table = u2a6; 347 size = sizeof(u2a6); 348 break; 349 case 0x2fa: 350 table = u2fa; 351 size = sizeof(u2fa); 352 break; 353 case 0xe00: 354 table = ue00; 355 size = sizeof(ue00); 356 break; 357 case 0xfff: 358 table = ufff; 359 size = sizeof(ufff); 360 break; 361 case 0x10ff: 362 table = u10ff; 363 size = sizeof(u10ff); 364 break; 365 default: 366 return 0; 367 } 368 /* we have narrowed down to a section of 256 characters to check */ 369 /* now check if c matches the printuation wide-chars within that section */ 370 ptr = (unsigned char *)table; 371 ctmp = (unsigned char)c; 372 while (ptr < table + size) 373 { 374 if (ctmp == *ptr) 375 return 1; 376 if (ctmp < *ptr) 377 return 0; 378 /* otherwise c > *ptr */ 379 /* look for 0x0 as next element which indicates a range */ 380 ++ptr; 381 if (*ptr == 0x0) 382 { 383 /* we have a range..see if c falls within range */ 384 ++ptr; 385 if (ctmp <= *ptr) 386 return 1; 387 ++ptr; 388 } 389 } 390 /* not in table */ 391 return 0; 392 } 393 #endif /* MB_CAPABLE */ 394 395 return (c < (wint_t)0x100 ? isprint (c) : 0); 396 } 397 398