mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-05-21 00:52:51 -06:00
Optionally include C run-time support
If the C run-time library is compiled and installed on your system, you can now
do 'cabal configure -fc-runtime' to get the following extras:
+ The haskell binding to the C run-time library will be included in the
PGF library (so you can import it in Haskell applications).
Documentation on the new modules will be included when you run
'cabal haddock'.
+ The new command 'pgf-shell', implemented on top of haskell binding to
the C run-time system.
+ Three new commands in the web API: c-parse, c-linearize and
c-translate. Their interfaces are similar to the corresponding commands
without the "c-" prefix, but they should be considered preliminary.
This commit is contained in:
4
Setup.hs
4
Setup.hs
@@ -351,8 +351,12 @@ run_gfc pkg lbi args =
|
|||||||
|
|
||||||
default_gf pkg lbi = buildDir lbi </> exeName' </> exeNameReal
|
default_gf pkg lbi = buildDir lbi </> exeName' </> exeNameReal
|
||||||
where
|
where
|
||||||
|
exeName' = "gf"
|
||||||
|
exeNameReal = exeName' <.> exeExtension
|
||||||
|
{- --old solution, could pick the wrong executable if there is more than one
|
||||||
exeName' = (exeName . head . executables) pkg
|
exeName' = (exeName . head . executables) pkg
|
||||||
exeNameReal = exeName' <.> (if null $ takeExtension exeName' then exeExtension else "")
|
exeNameReal = exeName' <.> (if null $ takeExtension exeName' then exeExtension else "")
|
||||||
|
-}
|
||||||
|
|
||||||
-- | Create autogen module with detailed version info by querying darcs
|
-- | Create autogen module with detailed version info by querying darcs
|
||||||
extractDarcsVersion distFlag =
|
extractDarcsVersion distFlag =
|
||||||
|
|||||||
25
gf.cabal
25
gf.cabal
@@ -1,7 +1,7 @@
|
|||||||
name: gf
|
name: gf
|
||||||
version: 3.5.11-darcs
|
version: 3.5.11-darcs
|
||||||
|
|
||||||
cabal-version: >= 1.8
|
cabal-version: >= 1.10
|
||||||
build-type: Custom
|
build-type: Custom
|
||||||
license: OtherLicense
|
license: OtherLicense
|
||||||
license-file: LICENSE
|
license-file: LICENSE
|
||||||
@@ -57,7 +57,12 @@ flag custom-binary
|
|||||||
Description: Use a customised version of the binary package
|
Description: Use a customised version of the binary package
|
||||||
Default: True
|
Default: True
|
||||||
|
|
||||||
|
flag c-runtime
|
||||||
|
Description: Include functionality from the C run-time library (which must be installed already)
|
||||||
|
Default: False
|
||||||
|
|
||||||
Library
|
Library
|
||||||
|
default-language: Haskell2010
|
||||||
build-depends: base >= 4.2 && <5,
|
build-depends: base >= 4.2 && <5,
|
||||||
array,
|
array,
|
||||||
fst,
|
fst,
|
||||||
@@ -113,7 +118,16 @@ Library
|
|||||||
PGF.VisualizeTree
|
PGF.VisualizeTree
|
||||||
PGF.OldBinary
|
PGF.OldBinary
|
||||||
|
|
||||||
|
if flag(c-runtime)
|
||||||
|
exposed-modules: CId, CRuntimeFFI
|
||||||
|
other-modules: Gu, PgfLow
|
||||||
|
hs-source-dirs: src/runtime/haskell-bind
|
||||||
|
build-tools: hsc2hs
|
||||||
|
extra-libraries: gu pgf
|
||||||
|
cc-options: -std=c99
|
||||||
|
|
||||||
Executable gf
|
Executable gf
|
||||||
|
default-language: Haskell2010
|
||||||
build-depends: gf,
|
build-depends: gf,
|
||||||
base >= 4.2 && <5,
|
base >= 4.2 && <5,
|
||||||
array,
|
array,
|
||||||
@@ -140,6 +154,8 @@ Executable gf
|
|||||||
other-modules: GFServer
|
other-modules: GFServer
|
||||||
hs-source-dirs: src/server src/server/transfer src/example-based
|
hs-source-dirs: src/server src/server/transfer src/example-based
|
||||||
|
|
||||||
|
if flag(c-runtime)
|
||||||
|
cpp-options: -DC_RUNTIME
|
||||||
--if flag(new-comp)
|
--if flag(new-comp)
|
||||||
-- cpp-options: -DNEW_COMP
|
-- cpp-options: -DNEW_COMP
|
||||||
|
|
||||||
@@ -232,6 +248,13 @@ Executable gf
|
|||||||
else
|
else
|
||||||
other-modules: GF.System.NoSignal
|
other-modules: GF.System.NoSignal
|
||||||
|
|
||||||
|
executable pgf-shell
|
||||||
|
if !flag(c-runtime)
|
||||||
|
buildable: False
|
||||||
|
main-is: pgf-shell.hs
|
||||||
|
hs-source-dirs: src/runtime/haskell-bind/examples
|
||||||
|
build-depends: gf, base
|
||||||
|
default-language: Haskell2010
|
||||||
|
|
||||||
test-suite rgl-tests
|
test-suite rgl-tests
|
||||||
type: exitcode-stdio-1.0
|
type: exitcode-stdio-1.0
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ buildInfo =
|
|||||||
#endif
|
#endif
|
||||||
#ifdef NEW_COMP
|
#ifdef NEW_COMP
|
||||||
++" new-comp"
|
++" new-comp"
|
||||||
|
#endif
|
||||||
|
#ifdef C_RUNTIME
|
||||||
|
++" c-runtime"
|
||||||
#endif
|
#endif
|
||||||
where
|
where
|
||||||
details = either (const no_info) info darcs_info
|
details = either (const no_info) info darcs_info
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ handle documentroot state0 cache execute1
|
|||||||
case (takeDirectory path,takeFileName path,takeExtension path) of
|
case (takeDirectory path,takeFileName path,takeExtension path) of
|
||||||
(_ ,_ ,".pgf") -> wrapCGI $ PS.cgiMain' cache path
|
(_ ,_ ,".pgf") -> wrapCGI $ PS.cgiMain' cache path
|
||||||
(dir,"grammars.cgi",_ ) -> grammarList dir (decoded qs)
|
(dir,"grammars.cgi",_ ) -> grammarList dir (decoded qs)
|
||||||
(dir ,"exb.fcgi" ,_ ) -> wrapCGI $ ES.cgiMain' root dir cache
|
(dir ,"exb.fcgi" ,_ ) -> wrapCGI $ ES.cgiMain' root dir (fst cache)
|
||||||
_ -> liftIO $ serveStaticFile path
|
_ -> liftIO $ serveStaticFile path
|
||||||
where path = translatePath rpath
|
where path = translatePath rpath
|
||||||
_ -> err $ resp400 upath
|
_ -> err $ resp400 upath
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ module CRuntimeFFI(-- * PGF
|
|||||||
) where
|
) where
|
||||||
|
|
||||||
import Prelude hiding (fromEnum)
|
import Prelude hiding (fromEnum)
|
||||||
import Control.Monad
|
--import Control.Monad
|
||||||
import System.IO
|
--import System.IO
|
||||||
import System.IO.Unsafe
|
import System.IO.Unsafe
|
||||||
import CId (CId(..),
|
import CId (CId(..),
|
||||||
mkCId, wildCId,
|
mkCId, wildCId,
|
||||||
@@ -26,11 +26,11 @@ import PgfLow
|
|||||||
|
|
||||||
import Foreign hiding ( Pool, newPool, unsafePerformIO )
|
import Foreign hiding ( Pool, newPool, unsafePerformIO )
|
||||||
import Foreign.C
|
import Foreign.C
|
||||||
import Foreign.C.String
|
--import Foreign.C.String
|
||||||
import Foreign.Ptr
|
--import Foreign.Ptr
|
||||||
|
|
||||||
|
|
||||||
import Data.Char
|
--import Data.Char
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
import Data.IORef
|
import Data.IORef
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{-# LANGUAGE CPP #-}
|
||||||
module PGFService(cgiMain,cgiMain',getPath,
|
module PGFService(cgiMain,cgiMain',getPath,
|
||||||
logFile,stderrToFile,
|
logFile,stderrToFile,
|
||||||
newPGFCache) where
|
newPGFCache) where
|
||||||
@@ -8,6 +9,11 @@ import Cache
|
|||||||
import FastCGIUtils
|
import FastCGIUtils
|
||||||
import URLEncoding
|
import URLEncoding
|
||||||
|
|
||||||
|
#if C_RUNTIME
|
||||||
|
import qualified CRuntimeFFI as C
|
||||||
|
import qualified CId as C
|
||||||
|
#endif
|
||||||
|
|
||||||
import Network.CGI
|
import Network.CGI
|
||||||
import Text.JSON
|
import Text.JSON
|
||||||
import Text.PrettyPrint as PP(render, text, (<+>))
|
import Text.PrettyPrint as PP(render, text, (<+>))
|
||||||
@@ -36,7 +42,16 @@ catchIOE = E.catch
|
|||||||
logFile :: FilePath
|
logFile :: FilePath
|
||||||
logFile = "pgf-error.log"
|
logFile = "pgf-error.log"
|
||||||
|
|
||||||
newPGFCache = newCache PGF.readPGF
|
#ifdef C_RUNTIME
|
||||||
|
type Caches = (Cache PGF,Cache C.PGF)
|
||||||
|
newPGFCache = do pgfCache <- newCache PGF.readPGF
|
||||||
|
cCache <- newCache C.readPGF
|
||||||
|
return (pgfCache,cCache)
|
||||||
|
#else
|
||||||
|
type Caches = (Cache PGF,())
|
||||||
|
newPGFCache = do pgfCache <- newCache PGF.readPGF
|
||||||
|
return (pgfCache,())
|
||||||
|
#endif
|
||||||
|
|
||||||
getPath =
|
getPath =
|
||||||
do path <- getVarWithDefault "PATH_TRANSLATED" "" -- apache mod_fastcgi
|
do path <- getVarWithDefault "PATH_TRANSLATED" "" -- apache mod_fastcgi
|
||||||
@@ -44,30 +59,98 @@ getPath =
|
|||||||
then getVarWithDefault "SCRIPT_FILENAME" "" -- lighttpd
|
then getVarWithDefault "SCRIPT_FILENAME" "" -- lighttpd
|
||||||
else return path
|
else return path
|
||||||
|
|
||||||
cgiMain :: Cache PGF -> CGI CGIResult
|
cgiMain :: Caches -> CGI CGIResult
|
||||||
cgiMain cache = handleErrors . handleCGIErrors $
|
cgiMain cache = handleErrors . handleCGIErrors $
|
||||||
cgiMain' cache =<< getPath
|
cgiMain' cache =<< getPath
|
||||||
|
|
||||||
cgiMain' :: Cache PGF -> FilePath -> CGI CGIResult
|
cgiMain' :: Caches -> FilePath -> CGI CGIResult
|
||||||
cgiMain' cache path =
|
cgiMain' cache path =
|
||||||
do command <- liftM (maybe "grammar" (urlDecodeUnicode . UTF8.decodeString))
|
do command <- liftM (maybe "grammar" (urlDecodeUnicode . UTF8.decodeString))
|
||||||
(getInput "command")
|
(getInput "command")
|
||||||
case command of
|
case command of
|
||||||
"download" -> outputBinary =<< liftIO (BS.readFile path)
|
"download" -> outputBinary =<< liftIO (BS.readFile path)
|
||||||
_ -> pgfMain command =<< liftIO (readCache cache path)
|
#ifdef C_RUNTIME
|
||||||
|
'c':'-':_ -> cpgfMain command =<< liftIO (readCache (snd cache) path)
|
||||||
|
#endif
|
||||||
|
_ -> pgfMain command =<< liftIO (readCache (fst cache) path)
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- * C run-time functionality
|
||||||
|
|
||||||
|
#ifdef C_RUNTIME
|
||||||
|
cpgfMain :: String -> C.PGF -> CGI CGIResult
|
||||||
|
cpgfMain command pgf =
|
||||||
|
case command of
|
||||||
|
"c-parse" -> out =<< parse # input % from % limit % trie
|
||||||
|
"c-linearize" -> out =<< lin # tree % to
|
||||||
|
"c-translate" -> out =<< trans # input % from % to % limit % trie
|
||||||
|
_ -> badRequest "Unknown command" command
|
||||||
|
where
|
||||||
|
parse input (from,concr) mlimit trie =
|
||||||
|
showJSON [makeObj ("from".=from:"trees".=trees :[])]
|
||||||
|
-- :addTrie trie trees
|
||||||
|
where
|
||||||
|
trees = parse' input concr mlimit
|
||||||
|
|
||||||
|
parse' input concr mlimit =
|
||||||
|
map fst $ -- hmm
|
||||||
|
maybe id take mlimit (C.parse concr (C.startCat pgf) input)
|
||||||
|
|
||||||
|
lin tree tos = showJSON (lin' tree tos)
|
||||||
|
lin' tree tos = [makeObj ["to".=to,"text".=C.linearize c tree]|(to,c)<-tos]
|
||||||
|
|
||||||
|
trans input (from,concr) tos mlimit trie =
|
||||||
|
showJSON [ makeObj ["from".=from,
|
||||||
|
"translations".=
|
||||||
|
[makeObj ["tree".=tree,
|
||||||
|
"linearizations".=lin' tree tos]
|
||||||
|
| tree <- parse' input concr mlimit]]]
|
||||||
|
|
||||||
|
from = maybe (missing "from") return =<< getLang "from"
|
||||||
|
|
||||||
|
to = getLangs "to"
|
||||||
|
|
||||||
|
getLangs = getLangs' readLang
|
||||||
|
getLang = getLang' readLang
|
||||||
|
|
||||||
|
readLang :: String -> CGI (C.Language,C.Concr)
|
||||||
|
readLang l =
|
||||||
|
case C.readCId l of
|
||||||
|
Nothing -> badRequest "Bad language" l
|
||||||
|
Just lang ->
|
||||||
|
case C.getConcr pgf lang of
|
||||||
|
Just c -> return (lang,c)
|
||||||
|
_ -> badRequest "Unknown language" l
|
||||||
|
|
||||||
|
tree = do s <- maybe (missing "tree") return =<< getInput1 "tree"
|
||||||
|
let t = C.readExpr s
|
||||||
|
maybe (badRequest "bad tree" s) return t
|
||||||
|
|
||||||
|
instance JSON C.CId where
|
||||||
|
readJSON x = readJSON x >>= maybe (fail "Bad language.") return . C.readCId
|
||||||
|
showJSON = showJSON . C.showCId
|
||||||
|
|
||||||
|
instance JSON C.Expr where
|
||||||
|
readJSON x = readJSON x >>= maybe (fail "Bad expression.") return . C.readExpr
|
||||||
|
showJSON = showJSON . C.showExpr
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- * Haskell run-time functionality
|
||||||
|
|
||||||
pgfMain :: String -> PGF -> CGI CGIResult
|
pgfMain :: String -> PGF -> CGI CGIResult
|
||||||
pgfMain command pgf =
|
pgfMain command pgf =
|
||||||
case command of
|
case command of
|
||||||
"parse" -> out =<< doParse pgf # text % cat % from % limit % trie
|
"parse" -> out =<< doParse pgf # input % cat % from % limit % trie
|
||||||
"complete" -> out =<< doComplete pgf # text % cat % from % limit
|
"complete" -> out =<< doComplete pgf # input % cat % from % limit
|
||||||
"linearize" -> out =<< doLinearize pgf # tree % to
|
"linearize" -> out =<< doLinearize pgf # tree % to
|
||||||
"linearizeAll" -> out =<< doLinearizes pgf # tree % to
|
"linearizeAll" -> out =<< doLinearizes pgf # tree % to
|
||||||
"linearizeTable" -> out =<< doLinearizeTabular pgf # tree % to
|
"linearizeTable" -> out =<< doLinearizeTabular pgf # tree % to
|
||||||
"random" -> cat >>= \c -> depth >>= \dp -> limit >>= \l -> to >>= \to -> liftIO (doRandom pgf c dp l to) >>= out
|
"random" -> cat >>= \c -> depth >>= \dp -> limit >>= \l -> to >>= \to -> liftIO (doRandom pgf c dp l to) >>= out
|
||||||
"generate" -> out =<< doGenerate pgf # cat % depth % limit % to
|
"generate" -> out =<< doGenerate pgf # cat % depth % limit % to
|
||||||
"translate" -> out =<< doTranslate pgf # text % cat % from % to % limit % trie
|
"translate" -> out =<< doTranslate pgf # input % cat % from % to % limit % trie
|
||||||
"translategroup" -> out =<< doTranslateGroup pgf # text % cat % from % to % limit
|
"translategroup" -> out =<< doTranslateGroup pgf # input % cat % from % to % limit
|
||||||
"grammar" -> out =<< doGrammar pgf # requestAcceptLanguage
|
"grammar" -> out =<< doGrammar pgf # requestAcceptLanguage
|
||||||
"abstrtree" -> outputGraphviz =<< abstrTree pgf # graphvizOptions % tree
|
"abstrtree" -> outputGraphviz =<< abstrTree pgf # graphvizOptions % tree
|
||||||
"alignment" -> outputGraphviz =<< alignment pgf # tree % to
|
"alignment" -> outputGraphviz =<< alignment pgf # tree % to
|
||||||
@@ -78,15 +161,9 @@ pgfMain command pgf =
|
|||||||
"abstrjson" -> out . jsonExpr =<< tree
|
"abstrjson" -> out . jsonExpr =<< tree
|
||||||
"browse" -> join $ doBrowse pgf # optId % cssClass % href % format "html" % getIncludePrintNames
|
"browse" -> join $ doBrowse pgf # optId % cssClass % href % format "html" % getIncludePrintNames
|
||||||
"external" -> do cmd <- getInput "external"
|
"external" -> do cmd <- getInput "external"
|
||||||
input <- text
|
doExternal cmd =<< input
|
||||||
doExternal cmd input
|
|
||||||
_ -> throwCGIError 400 "Unknown command" ["Unknown command: " ++ show command]
|
_ -> throwCGIError 400 "Unknown command" ["Unknown command: " ++ show command]
|
||||||
where
|
where
|
||||||
out = outputJSONP
|
|
||||||
|
|
||||||
text :: CGI String
|
|
||||||
text = liftM (maybe "" (urlDecodeUnicode . UTF8.decodeString)) $ getInput "input"
|
|
||||||
|
|
||||||
tree :: CGI PGF.Tree
|
tree :: CGI PGF.Tree
|
||||||
tree = do ms <- getInput "tree"
|
tree = do ms <- getInput "tree"
|
||||||
s <- maybe (throwCGIError 400 "No tree given" ["No tree given"]) return ms
|
s <- maybe (throwCGIError 400 "No tree given" ["No tree given"]) return ms
|
||||||
@@ -101,10 +178,9 @@ pgfMain command pgf =
|
|||||||
|
|
||||||
cat :: CGI (Maybe PGF.Type)
|
cat :: CGI (Maybe PGF.Type)
|
||||||
cat =
|
cat =
|
||||||
do mcat <- getInput "cat"
|
do mcat <- getInput1 "cat"
|
||||||
case mcat of
|
case mcat of
|
||||||
Nothing -> return Nothing
|
Nothing -> return Nothing
|
||||||
Just "" -> return Nothing
|
|
||||||
Just cat -> case PGF.readType cat of
|
Just cat -> case PGF.readType cat of
|
||||||
Nothing -> throwCGIError 400 "Bad category" ["Bad category: " ++ cat]
|
Nothing -> throwCGIError 400 "Bad category" ["Bad category: " ++ cat]
|
||||||
Just typ -> return $ Just typ -- typecheck the category
|
Just typ -> return $ Just typ -- typecheck the category
|
||||||
@@ -119,36 +195,6 @@ pgfMain command pgf =
|
|||||||
cssClass = getInput "css-class"
|
cssClass = getInput "css-class"
|
||||||
href = getInput "href"
|
href = getInput "href"
|
||||||
|
|
||||||
limit, depth :: CGI (Maybe Int)
|
|
||||||
limit = readInput "limit"
|
|
||||||
depth = readInput "depth"
|
|
||||||
|
|
||||||
from :: CGI (Maybe PGF.Language)
|
|
||||||
from = getLang "from"
|
|
||||||
|
|
||||||
to :: CGI [PGF.Language]
|
|
||||||
to = getLangs "to"
|
|
||||||
|
|
||||||
trie :: CGI Bool
|
|
||||||
trie = maybe False toBool # getInput "trie"
|
|
||||||
|
|
||||||
getLangs :: String -> CGI [PGF.Language]
|
|
||||||
getLangs i = mapM readLang . maybe [] words =<< getInput i
|
|
||||||
|
|
||||||
getLang :: String -> CGI (Maybe PGF.Language)
|
|
||||||
getLang i =
|
|
||||||
do mlang <- getInput i
|
|
||||||
case mlang of
|
|
||||||
Just l@(_:_) -> Just # readLang l
|
|
||||||
_ -> return Nothing
|
|
||||||
|
|
||||||
readLang :: String -> CGI PGF.Language
|
|
||||||
readLang l =
|
|
||||||
case PGF.readLanguage l of
|
|
||||||
Nothing -> throwCGIError 400 "Bad language" ["Bad language: " ++ l]
|
|
||||||
Just lang | lang `elem` PGF.languages pgf -> return lang
|
|
||||||
| otherwise -> throwCGIError 400 "Unknown language" ["Unknown language: " ++ l]
|
|
||||||
|
|
||||||
getIncludePrintNames :: CGI Bool
|
getIncludePrintNames :: CGI Bool
|
||||||
getIncludePrintNames = maybe False (const True) # getInput "printnames"
|
getIncludePrintNames = maybe False (const True) # getInput "printnames"
|
||||||
|
|
||||||
@@ -166,12 +212,59 @@ pgfMain command pgf =
|
|||||||
string name = maybe "" id # getInput name
|
string name = maybe "" id # getInput name
|
||||||
bool name = maybe False toBool # getInput name
|
bool name = maybe False toBool # getInput name
|
||||||
|
|
||||||
|
from = getLang "from"
|
||||||
|
to = getLangs "to"
|
||||||
|
|
||||||
|
getLangs = getLangs' readLang
|
||||||
|
getLang = getLang' readLang
|
||||||
|
|
||||||
|
readLang :: String -> CGI PGF.Language
|
||||||
|
readLang l =
|
||||||
|
case PGF.readLanguage l of
|
||||||
|
Nothing -> throwCGIError 400 "Bad language" ["Bad language: " ++ l]
|
||||||
|
Just lang | lang `elem` PGF.languages pgf -> return lang
|
||||||
|
| otherwise -> throwCGIError 400 "Unknown language" ["Unknown language: " ++ l]
|
||||||
|
|
||||||
|
-- * Request parameter access and related auxiliary functions
|
||||||
|
|
||||||
|
out = outputJSONP
|
||||||
|
|
||||||
|
getInput1 x = nonEmpty # getInput x
|
||||||
|
nonEmpty (Just "") = Nothing
|
||||||
|
nonEmpty r = r
|
||||||
|
|
||||||
|
|
||||||
|
input :: CGI String
|
||||||
|
input = liftM (maybe "" (urlDecodeUnicode . UTF8.decodeString)) $ getInput "input"
|
||||||
|
|
||||||
|
getLangs' readLang i = mapM readLang . maybe [] words =<< getInput i
|
||||||
|
|
||||||
|
getLang' readLang i =
|
||||||
|
do mlang <- getInput i
|
||||||
|
case mlang of
|
||||||
|
Just l@(_:_) -> Just # readLang l
|
||||||
|
_ -> return Nothing
|
||||||
|
|
||||||
|
|
||||||
|
limit, depth :: CGI (Maybe Int)
|
||||||
|
limit = readInput "limit"
|
||||||
|
depth = readInput "depth"
|
||||||
|
|
||||||
|
trie :: CGI Bool
|
||||||
|
trie = maybe False toBool # getInput "trie"
|
||||||
|
|
||||||
toBool s = s `elem` ["","yes","true","True"]
|
toBool s = s `elem` ["","yes","true","True"]
|
||||||
|
|
||||||
errorMissingId = throwCGIError 400 "Missing identifier" []
|
missing = badRequest "Missing parameter"
|
||||||
|
errorMissingId = badRequest "Missing identifier" ""
|
||||||
|
|
||||||
|
badRequest msg extra =
|
||||||
|
throwCGIError 400 msg [msg ++(if null extra then "" else ": "++extra)]
|
||||||
|
|
||||||
format def = maybe def id # getInput "format"
|
format def = maybe def id # getInput "format"
|
||||||
|
|
||||||
|
-- * Request implementations
|
||||||
|
|
||||||
-- Hook for simple extensions of the PGF service
|
-- Hook for simple extensions of the PGF service
|
||||||
doExternal Nothing input = throwCGIError 400 "Unknown external command" ["Unknown external command"]
|
doExternal Nothing input = throwCGIError 400 "Unknown external command" ["Unknown external command"]
|
||||||
doExternal (Just cmd) input =
|
doExternal (Just cmd) input =
|
||||||
|
|||||||
Reference in New Issue
Block a user