Skip to content

Commit 476a5d4

Browse files
committed
Added documentation for enumerant groups.
1 parent 667a393 commit 476a5d4

File tree

5 files changed

+2816
-922
lines changed

5 files changed

+2816
-922
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
2.5.4.0
2+
-------
3+
* Added documentation for enumerant groups.
4+
15
2.5.3.0
26
-------
37
* Updated OpenGL registry to r31903.

OpenGLRaw.cabal

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: OpenGLRaw
2-
version: 2.5.3.0
2+
version: 2.5.4.0
33
synopsis: A raw binding for the OpenGL graphics system
44
description:
55
OpenGLRaw is a raw Haskell binding for the OpenGL 4.5 graphics system and
@@ -373,6 +373,7 @@ library
373373
Graphics.Rendering.OpenGL.Raw.GREMEDY.FrameTerminator
374374
Graphics.Rendering.OpenGL.Raw.GREMEDY.StringMarker
375375
Graphics.Rendering.OpenGL.Raw.GetProcAddress
376+
Graphics.Rendering.OpenGL.Raw.Groups
376377
Graphics.Rendering.OpenGL.Raw.HP
377378
Graphics.Rendering.OpenGL.Raw.HP.ConvolutionBorderModes
378379
Graphics.Rendering.OpenGL.Raw.HP.ImageTransform

RegistryProcessor/src/Main.hs

Lines changed: 91 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ main = do
2222
Left msg -> SI.hPutStrLn SI.stderr msg
2323
Right registry -> do
2424
printTokens api registry
25+
printGroups api registry
2526
let sigMap = signatureMap registry
2627
printForeign sigMap
2728
printFunctions api registry sigMap
@@ -86,11 +87,65 @@ printTokens api registry = do
8687
, e <- es
8788
, api `matches` enumAPI e ]
8889

90+
printGroups :: API -> Registry -> IO ()
91+
printGroups api registry = do
92+
let comment =
93+
["All enumeration groups from the",
94+
"<http://www.opengl.org/registry/ OpenGL registry>."]
95+
startModule ["Groups"] Nothing comment $ \moduleName h -> do
96+
SI.hPutStrLn h $ "module " ++ moduleName ++ " ("
97+
SI.hPutStrLn h $ " -- $EnumerantGroups"
98+
SI.hPutStrLn h $ ") where"
99+
SI.hPutStrLn h ""
100+
SI.hPutStrLn h $ "-- $EnumerantGroups"
101+
SI.hPutStrLn h $ "-- Note that the actual set of valid values depend on the OpenGL version, the"
102+
SI.hPutStrLn h $ "-- chosen profile and the supported extensions. Therefore, the groups mentioned"
103+
SI.hPutStrLn h $ "-- here should only be considered a rough guideline, for details see the OpenGL"
104+
SI.hPutStrLn h $ "-- specification."
105+
CM.forM_ (M.assocs (groups registry)) $ \(gn, g) -> do
106+
let ugn = unGroupName gn
107+
es = getGroupEnums api registry g
108+
SI.hPutStrLn h $ "--"
109+
SI.hPutStrLn h $ "-- === #" ++ ugn ++ "# " ++ ugn
110+
SI.hPutStrLn h $ "-- " ++ groupHeader es
111+
SI.hPutStrLn h $ "--"
112+
-- TODO: Improve the alias computation below. It takes quadratic time and
113+
-- is very naive about what is the canonical name and what is an alias.
114+
CM.forM_ es $ \e -> do
115+
let same = L.sort [ f | f <- es, enumValue e == enumValue f ]
116+
CM.when (e == head same) $ do
117+
SI.hPutStrLn h $ "-- * " ++ linkToToken e ++
118+
(case tail same of
119+
[] -> ""
120+
aliases -> " (" ++ al ++ ": " ++ L.intercalate ", " (map linkToToken aliases) ++ ")"
121+
where al | length aliases == 1 = "alias"
122+
| otherwise = "aliases")
123+
124+
linkToToken :: Enum' -> String
125+
linkToToken e = "'" ++ moduleNameFor ["Tokens"] ++ "." ++ (unEnumName . enumName) e ++ "'"
126+
127+
-- There are several enums which are mentioned in groups, but commented out in
128+
-- enums (12 GL_*_ICC_SGIX enumerants). These are implicitly filtered out below.
129+
getGroupEnums :: API -> Registry -> Group -> [Enum']
130+
getGroupEnums api registry g =
131+
[ e | name <- groupEnums g
132+
, Just es <- [ M.lookup name (enums registry) ]
133+
, e <- es
134+
, api `matches` enumAPI e ]
135+
136+
groupHeader :: [Enum'] -> String
137+
groupHeader es = case sortUnique (map enumType es) of
138+
-- There are 2 empty groups: DataType and FfdMaskSGIX.
139+
[] -> "There are no values defined for this enumeration group."
140+
[t] | isMask t -> "A bitwise combination of several of the following values:"
141+
| otherwise -> "One of the following values:"
142+
types -> error $ "Contradicting enumerant types " ++ show types
143+
89144
-- Calulate a map from compact signature to short names.
90145
signatureMap :: Registry -> M.Map String String
91146
signatureMap registry = fst $ M.foldl' step (M.empty, 0) (commands registry)
92147
where step (m,n) command = memberAndInsert (n+1) n (sig command) (dyn n) m
93-
sig = flip showSignatureFromCommand False
148+
sig = flip (showSignatureFromCommand registry) False
94149
dyn n = "dyn" ++ show n
95150
memberAndInsert notFound found key value map =
96151
(newMap, maybe notFound (const found) maybeValue)
@@ -124,7 +179,7 @@ printFunctions api registry sigMap = do
124179
SI.hPutStrLn h "import System.IO.Unsafe ( unsafePerformIO )"
125180
SI.hPutStrLn h ""
126181
SI.hPutStrLn h $ "import " ++ moduleNameFor ["Foreign"]
127-
SI.hPutStrLn h $ "import " ++ moduleNameFor ["GetProcAddress"] ++" ( getProcAddress )"
182+
SI.hPutStrLn h $ "import " ++ moduleNameFor ["GetProcAddress"] ++ " ( getProcAddress )"
128183
SI.hPutStrLn h $ "import " ++ moduleNameFor ["Types"]
129184
SI.hPutStrLn h ""
130185
SI.hPutStrLn h "getCommand :: String -> IO (FunPtr a)"
@@ -134,7 +189,7 @@ printFunctions api registry sigMap = do
134189
SI.hPutStrLn h "throwIfNullFunPtr :: String -> IO (FunPtr a) -> IO (FunPtr a)"
135190
SI.hPutStrLn h "throwIfNullFunPtr = throwIf (== nullFunPtr) . const"
136191
SI.hPutStrLn h ""
137-
mapM_ (SI.hPutStrLn h . showCommand api sigMap) (M.elems (commands registry))
192+
mapM_ (SI.hPutStrLn h . showCommand api registry sigMap) (M.elems (commands registry))
138193

139194
printExtensionModule :: (ExtensionName, ExtensionName, ([TypeName], [Enum'], [Command])) -> IO ()
140195
printExtensionModule (extName, mangledExtName, extensionParts) =
@@ -441,8 +496,8 @@ convertEnum e =
441496
, n ++ " = " ++ unEnumValue (enumValue e) ]
442497
where n = unEnumName . enumName $ e
443498

444-
showCommand :: API -> M.Map String String -> Command -> String
445-
showCommand api sigMap c =
499+
showCommand :: API -> Registry -> M.Map String String -> Command -> String
500+
showCommand api registry sigMap c =
446501
showString (take 80 ("-- " ++ name ++ " " ++ repeat '-') ++ "\n\n") .
447502

448503
showString man .
@@ -463,7 +518,7 @@ showCommand api sigMap c =
463518
ptr_name = "ptr_" ++ name
464519
str_name = show name
465520
compactSignature = signature False
466-
signature withComment = showSignatureFromCommand c withComment
521+
signature withComment = showSignatureFromCommand registry c withComment
467522
urls = M.findWithDefault [] (api, CommandName name) manPageURLs
468523
links = L.intercalate " or " (map renderURL urls) ++ "\n"
469524
man = case urls of
@@ -479,34 +534,42 @@ makeImportDynamic compactSignature dyn_name =
479534
" :: FunPtr (" ++ compactSignature ++ ")\n" ++
480535
" -> " ++ compactSignature ++ "\n"
481536

482-
showSignatureFromCommand :: Command -> Bool -> String
483-
showSignatureFromCommand c withComment =
537+
showSignatureFromCommand :: Registry -> Command -> Bool -> String
538+
showSignatureFromCommand registry c withComment =
484539
L.intercalate ((if withComment then " " else "") ++ " -> ")
485-
([showSignatureElement withComment False t | t <- paramTypes c] ++
486-
[showSignatureElement withComment True (resultType c)])
540+
([showSignatureElement registry withComment False t | t <- paramTypes c] ++
541+
[showSignatureElement registry withComment True (resultType c)])
487542

488-
showSignatureElement :: Bool -> Bool -> SignatureElement -> String
489-
showSignatureElement withComment isResult sigElem = el ++ comment
543+
showSignatureElement :: Registry -> Bool -> Bool -> SignatureElement -> String
544+
showSignatureElement registry withComment isResult sigElem = el ++ comment
490545
where el | isResult = monad ++ " " ++ showsPrec 11 sigElem ""
491546
| otherwise = show sigElem
492547
monad | withComment = "m"
493548
| otherwise = "IO"
494-
comment | withComment = showComment name sigElem
549+
comment | withComment = showComment registry name sigElem
495550
| otherwise = ""
496551
name | isResult = ""
497552
| otherwise = signatureElementName sigElem
498553

499-
showComment :: String -> SignatureElement -> String
500-
showComment name sigElem
554+
showComment :: Registry -> String -> SignatureElement -> String
555+
showComment registry name sigElem
501556
| null name' && null info = "\n"
502557
| otherwise = " -- ^" ++ name' ++ info ++ ".\n"
503558

504559
where name' | null name = ""
505560
| otherwise = " " ++ inlineCode name
506561

507-
info | isInteresting = elms ++ " of type " ++ inlineCode (show (base sigElem))
562+
info | isInteresting = elms ++ " of type " ++ hurz
508563
| otherwise = ""
509564

565+
-- Alas, there are tons of group names which are referenced, but never
566+
-- defined, so we have to leave them without a link.
567+
-- TODO: Do not use Show instance for SignatureElement.
568+
hurz = case belongsToGroup sigElem of
569+
Just gn | numPointer sigElem <= 1 &&
570+
gn `M.member` groups registry -> linkToGroup gn
571+
_ -> inlineCode (show (base sigElem))
572+
510573
isInteresting = DM.isJust (arrayLength sigElem) || DM.isJust (belongsToGroup sigElem)
511574

512575
elms | numPointer sigElem > 0 = " pointing to" ++ len ++ " " ++ elements
@@ -522,6 +585,15 @@ showComment name sigElem
522585
| otherwise = e
523586
maybeSetBaseType e = maybe e (\g -> e{baseType = TypeName (unGroupName g)}) (belongsToGroup e)
524587

588+
-- TODO: This is very fragile, but currently there is no clean way to specify
589+
-- link texts when referencing anchors in Haddock.
590+
linkToGroup :: GroupName -> String
591+
linkToGroup g = "[" ++ n ++ "](" ++ htmlFilenameFor ["Groups"] ++ "#" ++ n ++ ")"
592+
where n = unGroupName g
593+
594+
htmlFilenameFor :: [String] -> String
595+
htmlFilenameFor = (++ ".html") . L.intercalate "-" . moduleNameParts
596+
525597
inlineCode :: String -> String
526598
inlineCode s = "@" ++ s ++ "@"
527599

@@ -556,3 +628,6 @@ toEnumType eNamespace eGroup eType suffix = TypeName $
556628
(Just "GL", _, Nothing, Nothing) -> "GLenum"
557629

558630
(_, _, _, _) -> error "can't determine enum type"
631+
632+
isMask :: TypeName -> Bool
633+
isMask = (== TypeName "GLbitfield")

0 commit comments

Comments
 (0)