-- Generated by re2hs
{-# LANGUAGE RecordWildCards #-}
#1 "haskell/eof/02_bounds_checking.re"
-- re2hs $INPUT -o $OUTPUT
{-# OPTIONS_GHC -Wno-unused-record-wildcards #-}
{-# LANGUAGE OverloadedStrings #-}

import Control.Exception
import Control.Monad (when)
import qualified Data.ByteString as BS

data State = State {
    _yyinput :: BS.ByteString,
    _yycursor :: Int,
    _yylimit :: Int,
    _count :: Int
}

data FillException = UnexpectedFill deriving (Show)
instance Exception FillException

yymaxfill :: Int
#24 "haskell/eof/02_bounds_checking.hs"
yymaxfill = 1
#20 "haskell/eof/02_bounds_checking.re"



#30 "haskell/eof/02_bounds_checking.hs"
yy0 :: State -> IO Int
yy0 State{..} = do
    when (_yycursor >= _yylimit) $ throw UnexpectedFill
    yych <- return $ BS.index _yyinput _yycursor
    _yycursor <- return $ _yycursor + 1
    case yych of
        _c | 0x00 == _c -> do
            yy1 State{..}
        _c | 0x20 == _c -> do
            yy3 State{..}
        _c | 0x27 == _c -> do
            yy5 State{..}
        _c | True -> do
            yy2 State{..}

yy1 :: State -> IO Int
yy1 State{..} = do
#30 "haskell/eof/02_bounds_checking.re"
    -- check that it is the sentinel, not some unexpected null
    return $ if _yycursor == BS.length _yyinput - yymaxfill + 1 then _count else (-1)
#51 "haskell/eof/02_bounds_checking.hs"

yy2 :: State -> IO Int
yy2 State{..} = do
#36 "haskell/eof/02_bounds_checking.re"
    return (-1)
#57 "haskell/eof/02_bounds_checking.hs"

yy3 :: State -> IO Int
yy3 State{..} = do
    when (_yycursor >= _yylimit) $ throw UnexpectedFill
    yych <- return $ BS.index _yyinput _yycursor
    case yych of
        _c | 0x20 == _c -> do
            _yycursor <- return $ _yycursor + 1
            yy3 State{..}
        _c | True -> do
            yy4 State{..}

yy4 :: State -> IO Int
yy4 State{..} = do
#35 "haskell/eof/02_bounds_checking.re"
    lexer State{..}
#74 "haskell/eof/02_bounds_checking.hs"

yy5 :: State -> IO Int
yy5 State{..} = do
    when (_yycursor >= _yylimit) $ throw UnexpectedFill
    yych <- return $ BS.index _yyinput _yycursor
    _yycursor <- return $ _yycursor + 1
    case yych of
        _c | 0x27 == _c -> do
            yy6 State{..}
        _c | 0x5C == _c -> do
            yy7 State{..}
        _c | True -> do
            yy5 State{..}

yy6 :: State -> IO Int
yy6 State{..} = do
#34 "haskell/eof/02_bounds_checking.re"
    lexer State{_count = _count + 1, ..}
#93 "haskell/eof/02_bounds_checking.hs"

yy7 :: State -> IO Int
yy7 State{..} = do
    when (_yycursor >= _yylimit) $ throw UnexpectedFill
    _yycursor <- return $ _yycursor + 1
    yy5 State{..}

lexer :: State -> IO Int
lexer State{..} = do
    yy0 State{..}

#37 "haskell/eof/02_bounds_checking.re"


main :: IO ()
main = do
    let test s n = do
            let buf = BS.concat [s, BS.replicate yymaxfill 0]
            let st = State {
                    _yyinput = buf,
                    _yycursor = 0,
                    _yylimit = BS.length buf,
                    _count = 0}
            m <- catch (lexer st) (\(_ :: FillException) -> return (-2))
            when (m /= n) $ error "failed"

    test "" 0
    test "'unterminated\\'" (-2)
    test "'qu\0tes' 'are' 'fine: \\'' " 3
    test "'unexpected' \0 'null'" (-1)
