- (a, read) <- slurpFileExpandTabs fname
-
- -- urk! slurpFile gives us a buffer that doesn't have room for
- -- the sentinel. Assume it has a final newline for now, and overwrite
- -- that with the sentinel. slurpFileExpandTabs (below) leaves room
- -- for the sentinel.
- let (A# a#) = a;
- (I# read#) = read;
- end# = read# -# 1#
-
- -- add sentinel '\NUL'
- _casm_ `` ((char *)%0)[(int)%1]=(char)0; '' (A# a#) (I# end#)
- return (StringBuffer a# end# 0# 0#)
-
-unsafeWriteBuffer :: StringBuffer -> Int# -> Char# -> StringBuffer
-unsafeWriteBuffer s@(StringBuffer a _ _ _) i# ch# =
- unsafePerformIO (
- _casm_ `` ((char *)%0)[(int)%1]=(char)%2; '' (A# a) (I# i#) (C# ch#) >>= \ () ->
- return s
- )
-\end{code}
-
------------------------------------------------------------------------------
--- Turn a String into a StringBuffer
-
-\begin{code}
-stringToStringBuffer :: String -> IO StringBuffer
-freeStringBuffer :: StringBuffer -> IO ()
-
-#if __GLASGOW_HASKELL__ >= 411
-stringToStringBuffer str =
- do let sz@(I# sz#) = length str
- (Ptr a#) <- mallocBytes (sz+1)
- fill_in str (A# a#)
- writeCharOffAddr (A# a#) sz '\0' -- sentinel
- return (StringBuffer a# sz# 0# 0#)
- where
- fill_in [] _ = return ()
- fill_in (c:cs) a = do
- writeCharOffAddr a 0 c
- fill_in cs (a `plusAddr` 1)
-
-freeStringBuffer (StringBuffer a# _ _ _) = Foreign.free (Ptr a#)
-#else
-stringToStringBuffer = panic "stringToStringBuffer: not implemented"
-freeStringBuffer sb = return ()
-#endif
-
-\end{code}
-
------------------------------------------------------------------------------
-This very disturbing bit of code is used for expanding the tabs in a
-file before we start parsing it. Expanding the tabs early makes the
-lexer a lot simpler: we only have to record the beginning of the line
-in order to be able to calculate the column offset of the current
-token.
-
-We guess the size of the buffer required as 20% extra for
-expanded tabs, and enlarge it if necessary.
-
-\begin{code}
-getErrType :: IO Int
-getErrType = _ccall_ getErrType__
-
-slurpFileExpandTabs :: FilePath -> IO (Addr,Int)
-slurpFileExpandTabs fname = do
- bracket (openFile fname ReadMode) (hClose)
- (\ handle ->
- do sz <- hFileSize handle
- if sz > toInteger (maxBound::Int)
- then ioError (userError "slurpFile: file too big")
- else do
- let sz_i = fromInteger sz
- if sz_i == 0
- -- empty file: just allocate a buffer containing '\0'
- then do chunk <- allocMem 1
- writeCharOffAddr chunk 0 '\0'
- return (chunk, 0)
- else do let sz_i' = (sz_i * 12) `div` 10 -- add 20% for tabs
- chunk <- allocMem sz_i'
- trySlurp handle sz_i' chunk
- )
-
-trySlurp :: Handle -> Int -> Addr -> IO (Addr, Int)
-trySlurp handle sz_i chunk =
-#if __GLASGOW_HASKELL__ < 501
- wantReadableHandle "hGetChar" handle $ \ handle_ ->
- let fo = haFO__ handle_ in