Skip to content

Commit f6e2ce9

Browse files
committed
icu: Added case functions + tests
1 parent 421659d commit f6e2ce9

File tree

4 files changed

+114
-11
lines changed

4 files changed

+114
-11
lines changed

experimental/icu/cbits/icu.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,26 @@ bool __hs_u_hasBinaryProperty(UChar32 c, UProperty which) {
1515
return u_hasBinaryProperty(c, which);
1616
}
1717

18+
bool __hs_u_islower(UChar32 c) {
19+
return u_islower(c);
20+
}
21+
22+
bool __hs_u_isupper(UChar32 c) {
23+
return u_isupper(c);
24+
}
25+
26+
UChar32 __hs_u_tolower(UChar32 c) {
27+
return u_tolower(c);
28+
}
29+
30+
UChar32 __hs_u_toupper(UChar32 c) {
31+
return u_toupper(c);
32+
}
33+
34+
UChar32 __hs_u_istitle(UChar32 c) {
35+
return u_istitle(c);
36+
}
37+
1838
/*******************************************************************************
1939
* Names
2040
******************************************************************************/

experimental/icu/cbits/icu.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ void __hs_u_getUnicodeVersion(UVersionInfo versionArray);
1313

1414
bool __hs_u_hasBinaryProperty(UChar32 c, UProperty which);
1515

16+
bool __hs_u_islower(UChar32 c);
17+
18+
bool __hs_u_isupper(UChar32 c);
19+
20+
UChar32 __hs_u_tolower(UChar32 c);
21+
22+
UChar32 __hs_u_toupper(UChar32 c);
23+
24+
UChar32 __hs_u_istitle(UChar32 c);
25+
1626
/*******************************************************************************
1727
* Names
1828
******************************************************************************/

experimental/icu/lib/ICU/Char.chs

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,27 @@ module ICU.Char
1515
, UGeneralCategory(..)
1616
, toGeneralCategory
1717
, charType
18+
, UProperty(..)
19+
, hasBinaryProperty
1820
, isNoncharacter
21+
, isLowerCase
22+
, isUpperCase
23+
, isLower
24+
, isUpper
25+
, isTitle
26+
, toLowerCase
27+
, toUpperCase
1928
) where
2029

2130
#include <unicode/uchar.h>
2231

23-
import Data.Char (ord)
32+
import Data.Char (chr, ord)
2433
import qualified Data.Char as Char
2534
import Data.Int (Int8)
2635
import Data.Version (Version, makeVersion)
2736
import Data.Word (Word32)
2837
import Foreign (Ptr)
29-
import Foreign.C (CInt)
38+
import Foreign.C (CInt(..))
3039
import Foreign.Marshal.Array (allocaArray, peekArray)
3140
import System.IO.Unsafe (unsafePerformIO)
3241

@@ -137,19 +146,56 @@ toGeneralCategory = \case
137146
FinalPunctuation -> Char.FinalQuote
138147

139148
{#enum define UProperty {
140-
UCHAR_NONCHARACTER_CODE_POINT as NoncharacterCodePoint
149+
UCHAR_NONCHARACTER_CODE_POINT as NoncharacterCodePoint,
150+
UCHAR_LOWERCASE as LowerCase,
151+
UCHAR_UPPERCASE as UpperCase
141152
}
142153
deriving (Bounded, Eq, Ord, Show) #}
143154

144155
foreign import ccall safe "icu.h __hs_u_hasBinaryProperty" u_hasBinaryProperty
145-
:: UChar32 -> Int -> Bool
156+
:: UChar32 -> CInt -> Bool
146157

147-
-- hasBinaryProperty :: UChar32 -> Int -> Bool
148-
-- hasBinaryProperty = {#call pure u_hasBinaryProperty as __hs_u_hasBinaryProperty#}
149-
-- {#fun pure u_hasBinaryProperty as hasBinaryProperty
150-
-- {`UChar32', `Int'} -> `Bool' #}
158+
hasBinaryProperty :: Char -> UProperty -> Bool
159+
hasBinaryProperty c
160+
= u_hasBinaryProperty (fromIntegral (ord c))
161+
. fromIntegral
162+
. fromEnum
151163

152164
isNoncharacter :: Char -> Bool
153-
isNoncharacter c = u_hasBinaryProperty
154-
(fromIntegral (ord c))
155-
(fromEnum NoncharacterCodePoint)
165+
isNoncharacter = (`hasBinaryProperty` NoncharacterCodePoint)
166+
167+
isLowerCase :: Char -> Bool
168+
isLowerCase = (`hasBinaryProperty` LowerCase)
169+
170+
isUpperCase :: Char -> Bool
171+
isUpperCase = (`hasBinaryProperty` UpperCase)
172+
173+
foreign import ccall safe "icu.h __hs_u_islower" u_islower
174+
:: UChar32 -> Bool
175+
176+
isLower :: Char -> Bool
177+
isLower = u_islower . fromIntegral . ord
178+
179+
foreign import ccall safe "icu.h __hs_u_isupper" u_isupper
180+
:: UChar32 -> Bool
181+
182+
isUpper :: Char -> Bool
183+
isUpper = u_isupper . fromIntegral . ord
184+
185+
foreign import ccall safe "icu.h __hs_u_istitle" u_istitle
186+
:: UChar32 -> Bool
187+
188+
isTitle :: Char -> Bool
189+
isTitle = u_istitle . fromIntegral . ord
190+
191+
foreign import ccall safe "icu.h __hs_u_tolower" u_tolower
192+
:: UChar32 -> UChar32
193+
194+
toLowerCase :: Char -> Char
195+
toLowerCase = chr . fromIntegral . u_tolower . fromIntegral . ord
196+
197+
foreign import ccall safe "icu.h __hs_u_toupper" u_toupper
198+
:: UChar32 -> UChar32
199+
200+
toUpperCase :: Char -> Char
201+
toUpperCase = chr . fromIntegral . u_toupper . fromIntegral . ord

unicode-data/test/ICU/CharSpec.hs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import Test.Hspec
2020

2121
import qualified ICU.Char as ICU
2222
import qualified Unicode.Char as U
23+
import qualified Unicode.Char.Case as C
24+
import qualified Unicode.Char.Case.Compat as CC
2325

2426
spec :: Spec
2527
spec = do
@@ -32,6 +34,31 @@ spec = do
3234
"isNoncharacter"
3335
(GeneralCategory . U.isNoncharacter)
3436
(GeneralCategory . ICU.isNoncharacter)
37+
describe "Case" do
38+
checkAndGatherErrors
39+
"isLowerCase"
40+
C.isLowerCase
41+
ICU.isLowerCase
42+
checkAndGatherErrors
43+
"isUpperCase"
44+
C.isUpperCase
45+
ICU.isUpperCase
46+
checkAndGatherErrors
47+
"isLower"
48+
CC.isLower
49+
ICU.isLower
50+
checkAndGatherErrors
51+
"isUpper"
52+
CC.isUpper
53+
(\c -> ICU.isUpper c || ICU.isTitle c)
54+
checkAndGatherErrors
55+
"toLower"
56+
CC.toLower
57+
ICU.toLowerCase
58+
checkAndGatherErrors
59+
"toUpper"
60+
CC.toUpper
61+
ICU.toUpperCase
3562
-- TODO: other functions
3663
where
3764
ourUnicodeVersion = versionBranch U.unicodeVersion

0 commit comments

Comments
 (0)