diff --git a/haskell.hs b/haskell.hs index cfdd578..75c84b1 100644 --- a/haskell.hs +++ b/haskell.hs @@ -1,12 +1,12 @@ {-# LANGUAGE ForeignFunctionInterface #-} -{- - $ ghc -o my_program Haskell.hs -L. -ltrie_loader --} - import Foreign import Foreign.C import Control.Monad (when) +import System.Directory (doesFileExist) +import qualified Data.Text as T +import qualified Data.Text.Encoding as E +import qualified Data.ByteString as B -- Declare the C functions foreign import ccall "load_trie" loadTrie :: CString -> IO (Ptr ()) @@ -14,34 +14,60 @@ foreign import ccall "perform_search" performSearch :: Ptr () -> CString -> Ptr foreign import ccall "free_trie" freeTrie :: Ptr () -> IO () foreign import ccall "free_search_results" freeSearchResults :: Ptr (Ptr CChar) -> IO () +-- Convert CString to UTF-8 Text +cStringToText :: CString -> IO T.Text +cStringToText cstr = do + bytes <- B.packCString cstr -- Load as ByteString + return $ E.decodeUtf8 bytes -- Decode to Text + +-- Get Results from the pointer +getResults :: Ptr (Ptr CChar) -> IO [T.Text] +getResults ptr = + if ptr == nullPtr + then return [] + else do + currentPtr <- peek ptr + if currentPtr == nullPtr + then return [] + else do + current <- cStringToText currentPtr + rest <- getResults (ptr `plusPtr` sizeOf (undefined :: Ptr CChar)) + return (current : rest) + +-- Main program main :: IO () main = do - -- Just call the functions, do nothing with the result + -- Check if dictionary file exists + let dictPath = "/home/hashirama/.local/share/hakurei/dict.bin" + fileExists <- doesFileExist dictPath + if not fileExists + then putStrLn "Dictionary file not found!" + else do + putStrLn "Calling load_trie..." + dictFile <- newCString dictPath + trieHandle <- loadTrie dictFile + if trieHandle == nullPtr + then putStrLn "Failed to load trie" + else do + putStrLn "Trie loaded successfully!" - putStrLn "Calling load_trie..." - -- Load the trie (don't care about the result) - dictFile <- newCString "/home/hashirama/.local/share/hakurei/dict.bin" - trieHandle <- loadTrie dictFile - if trieHandle == nullPtr - then putStrLn "Failed to load trie" - else putStrLn "Trie loaded successfully" + -- Perform search + putStrLn "Calling perform_search..." + searchStr <- newCString "電気通信業務取扱規程" + resultCount <- malloc :: IO (Ptr CSize) + resultsPtr <- performSearch trieHandle searchStr resultCount - putStrLn "Calling perform_search..." - -- Perform search (we care about the result here) - searchStr <- newCString "電気通信業務取扱規程" - resultCount <- malloc :: IO (Ptr CSize) - resultsPtr <- performSearch trieHandle searchStr resultCount - when (resultsPtr /= nullPtr) $ do - -- If results are returned, process them - -- Dereference the first result in the results pointer - firstResult <- peek resultsPtr >>= peekCString - putStrLn $ "First search result: " ++ firstResult + if resultsPtr == nullPtr + then putStrLn "perform_search returned a null pointer." + else do + count <- peek resultCount + putStrLn $ "Result count: " ++ show count - -- Free the search results (assuming we have a way to handle multiple results) - freeSearchResults resultsPtr + results <- getResults resultsPtr + putStrLn "Search results as list (UTF-8):" + mapM_ (putStrLn . T.unpack) results + freeSearchResults resultsPtr - putStrLn "Calling free_trie..." - -- Free the trie (again, no checks, just call) - freeTrie trieHandle - - putStrLn "Functions were called" + free resultCount + freeTrie trieHandle + putStrLn "Program completed successfully."