| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
| * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
| * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * SUCH DAMAGE. |
| */ |
| |
| #include<wctype.h> |
| |
| #include<ctype.h> |
| #include<errno.h> |
| #include<stdlib.h> |
| #include<string.h> |
| #include<wchar.h> |
| |
| #include"bionic/macros.h" |
| #include"private/icu4x.h" |
| |
| enum{ |
| WC_TYPE_INVALID=0, |
| WC_TYPE_ALNUM, |
| WC_TYPE_ALPHA, |
| WC_TYPE_BLANK, |
| WC_TYPE_CNTRL, |
| WC_TYPE_DIGIT, |
| WC_TYPE_GRAPH, |
| WC_TYPE_LOWER, |
| WC_TYPE_PRINT, |
| WC_TYPE_PUNCT, |
| WC_TYPE_SPACE, |
| WC_TYPE_UPPER, |
| WC_TYPE_XDIGIT, |
| WC_TYPE_MAX |
| }; |
| |
| #define DO_ISW(prop_name, narrow_fn) \ |
| if(__predict_true(wc<0x80)){ \ |
| return narrow_fn(wc); \ |
| } \ |
| return __icu4x_bionic_is_##prop_name(wc); |
| |
| int iswalnum(wint_t wc){ |
| DO_ISW(alnum, isalnum); |
| } |
| __strong_alias(iswalnum_l, iswalnum); |
| int iswalpha(wint_t wc){ |
| DO_ISW(alphabetic, isalpha); |
| } |
| __strong_alias(iswalpha_l, iswalpha); |
| int iswblank(wint_t wc){ |
| DO_ISW(blank, isblank); |
| } |
| __strong_alias(iswblank_l, iswblank); |
| int iswgraph(wint_t wc){ |
| DO_ISW(graph, isgraph); |
| } |
| __strong_alias(iswgraph_l, iswgraph); |
| int iswlower(wint_t wc){ |
| DO_ISW(lowercase, islower); |
| } |
| __strong_alias(iswlower_l, iswlower); |
| int iswprint(wint_t wc){ |
| DO_ISW(print, isprint); |
| } |
| __strong_alias(iswprint_l, iswprint); |
| int iswspace(wint_t wc){ |
| DO_ISW(white_space, isspace); |
| } |
| __strong_alias(iswspace_l, iswspace); |
| int iswupper(wint_t wc){ |
| DO_ISW(uppercase, isupper); |
| } |
| __strong_alias(iswupper_l, iswupper); |
| int iswxdigit(wint_t wc){ |
| DO_ISW(xdigit, isxdigit); |
| } |
| __strong_alias(iswxdigit_l, iswxdigit); |
| |
| int iswcntrl(wint_t wc){ |
| if(wc<0x80)return iscntrl(wc); |
| return __icu4x_bionic_general_category(wc)== U_CONTROL_CHAR; |
| } |
| __strong_alias(iswcntrl_l, iswcntrl); |
| |
| int iswdigit(wint_t wc){ |
| if(wc<0x80)return isdigit(wc); |
| return __icu4x_bionic_general_category(wc)== U_DECIMAL_NUMBER; |
| } |
| __strong_alias(iswdigit_l, iswdigit); |
| |
| int iswpunct(wint_t wc){ |
| if(wc<0x80)return ispunct(wc); |
| int8_t chartype= __icu4x_bionic_general_category(wc); |
| return chartype>= U_DASH_PUNCTUATION&& chartype<= U_OTHER_PUNCTUATION; |
| } |
| __strong_alias(iswpunct_l, iswpunct); |
| |
| int iswctype(wint_t wc,wctype_t char_class){ |
| if(char_class< WC_TYPE_ALNUM|| char_class> WC_TYPE_XDIGIT)return0; |
| staticint(*fns[])(wint_t)={ |
| iswalnum, iswalpha, iswblank, iswcntrl, iswdigit, iswgraph, |
| iswlower, iswprint, iswpunct, iswspace, iswupper, iswxdigit |
| }; |
| return fns[char_class- WC_TYPE_ALNUM](wc); |
| } |
| __strong_alias(iswctype_l, iswctype); |
| |
| wint_t towlower(wint_t wc){ |
| if(wc<0x80)return tolower(wc); |
| |
| return __icu4x_bionic_to_lower(wc); |
| } |
| __strong_alias(towlower_l, towlower); |
| |
| wint_t towupper(wint_t wc){ |
| if(wc<0x80)return toupper(wc); |
| |
| return __icu4x_bionic_to_upper(wc); |
| } |
| __strong_alias(towupper_l, towupper); |
| |
| wctype_t wctype(constchar*property){ |
| staticconstchar*const properties[WC_TYPE_MAX-1]={ |
| "alnum","alpha","blank","cntrl","digit","graph", |
| "lower","print","punct","space","upper","xdigit" |
| }; |
| for(size_t i=0; i< arraysize(properties);++i){ |
| if(!strcmp(properties[i],property)){ |
| returnstatic_cast<wctype_t>(WC_TYPE_ALNUM+ i); |
| } |
| } |
| returnstatic_cast<wctype_t>(0); |
| } |
| __strong_alias(wctype_l, wctype); |
| |
| staticwctrans_t wctrans_tolower=wctrans_t(1); |
| staticwctrans_t wctrans_toupper=wctrans_t(2); |
| |
| wctrans_t wctrans(constchar* name){ |
| if(strcmp(name,"tolower")==0)return wctrans_tolower; |
| if(strcmp(name,"toupper")==0)return wctrans_toupper; |
| errno= EINVAL; |
| returnnullptr; |
| } |
| __strong_alias(wctrans_l, wctrans); |
| |
| wint_t towctrans(wint_t c,wctrans_t t){ |
| if(t== wctrans_tolower)return towlower(c); |
| if(t== wctrans_toupper)return towupper(c); |
| errno= EINVAL; |
| return c; |
| } |
| __strong_alias(towctrans_l, towctrans); |