Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
dbc3d6dc
Commit
dbc3d6dc
authored
Apr 05, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Flesh out capnpc command-line interface.
parent
99bdcc1b
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
93 additions
and
40 deletions
+93
-40
Makefile.am
c++/Makefile.am
+1
-1
capnpc.ekam-rule
c++/src/capnproto/capnpc.ekam-rule
+1
-1
capnproto-compiler.cabal
compiler/capnproto-compiler.cabal
+2
-2
CxxGenerator.hs
compiler/src/CxxGenerator.hs
+6
-1
Main.hs
compiler/src/Main.hs
+80
-34
Semantics.hs
compiler/src/Semantics.hs
+3
-1
No files found.
c++/Makefile.am
View file @
dbc3d6dc
...
@@ -89,7 +89,7 @@ capnpc_outputs = \
...
@@ -89,7 +89,7 @@ capnpc_outputs = \
# around in the generated Makefile a bit but couldn't figure it out. I give
# around in the generated Makefile a bit but couldn't figure it out. I give
# up. Automake is terrible.
# up. Automake is terrible.
test_capnpc_middleman
:
test_capnpc_middleman
:
$(CAPNPC)
$(capnpc_inputs)
$(CAPNPC)
-oc
++
$(capnpc_inputs)
touch
test_capnpc_middleman
touch
test_capnpc_middleman
$(capnpc_outputs)
:
test_capnpc_middleman
$(capnpc_outputs)
:
test_capnpc_middleman
...
...
c++/src/capnproto/capnpc.ekam-rule
View file @
dbc3d6dc
...
@@ -49,4 +49,4 @@ fi
...
@@ -49,4 +49,4 @@ fi
# When exception stack traces are needed, add: +RTS -xc -RTS
# When exception stack traces are needed, add: +RTS -xc -RTS
LD_PRELOAD
=
$INTERCEPTOR
DYLD_FORCE_FLAT_NAMESPACE
=
DYLD_INSERT_LIBRARIES
=
$INTERCEPTOR
\
LD_PRELOAD
=
$INTERCEPTOR
DYLD_FORCE_FLAT_NAMESPACE
=
DYLD_INSERT_LIBRARIES
=
$INTERCEPTOR
\
$CAPNPC
"
$INPUT
"
3>&1 4<&0
>
&2
$CAPNPC
-oc
++
"
$INPUT
"
3>&1 4<&0
>
&2
compiler/capnproto-compiler.cabal
View file @
dbc3d6dc
...
@@ -19,8 +19,8 @@ executable capnpc
...
@@ -19,8 +19,8 @@ executable capnpc
hastache,
hastache,
array,
array,
data-binary-ieee754,
data-binary-ieee754,
filepath
filepath
,
-- When profiling is needed, add: -prof -fprof-auto -osuf p_o -hisuf p_hi
directory
ghc-options: -Wall -fno-warn-missing-signatures
ghc-options: -Wall -fno-warn-missing-signatures
other-modules:
other-modules:
Lexer,
Lexer,
...
...
compiler/src/CxxGenerator.hs
View file @
dbc3d6dc
...
@@ -23,7 +23,7 @@
...
@@ -23,7 +23,7 @@
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TemplateHaskell #-}
module
CxxGenerator
(
generateCxx
Header
,
generateCxxSource
)
where
module
CxxGenerator
(
generateCxx
)
where
import
qualified
Data.ByteString.UTF8
as
ByteStringUTF8
import
qualified
Data.ByteString.UTF8
as
ByteStringUTF8
import
Data.FileEmbed
(
embedFile
)
import
Data.FileEmbed
(
embedFile
)
...
@@ -244,3 +244,8 @@ hastacheConfig = MuConfig
...
@@ -244,3 +244,8 @@ hastacheConfig = MuConfig
generateCxxHeader
file
=
hastacheStr
hastacheConfig
(
encodeStr
headerTemplate
)
(
fileContext
file
)
generateCxxHeader
file
=
hastacheStr
hastacheConfig
(
encodeStr
headerTemplate
)
(
fileContext
file
)
generateCxxSource
file
=
hastacheStr
hastacheConfig
(
encodeStr
srcTemplate
)
(
fileContext
file
)
generateCxxSource
file
=
hastacheStr
hastacheConfig
(
encodeStr
srcTemplate
)
(
fileContext
file
)
generateCxx
file
=
do
header
<-
generateCxxHeader
file
source
<-
generateCxxSource
file
return
[(
fileName
file
++
".h"
,
header
),
(
fileName
file
++
".c++"
,
source
)]
compiler/src/Main.hs
View file @
dbc3d6dc
...
@@ -25,66 +25,112 @@ module Main ( main ) where
...
@@ -25,66 +25,112 @@ module Main ( main ) where
import
System.Environment
import
System.Environment
import
System.Console.GetOpt
import
System.Console.GetOpt
import
System.Exit
(
exitFailure
,
exitSuccess
)
import
System.IO
(
hPutStr
,
stderr
)
import
System.FilePath
(
takeDirectory
)
import
System.Directory
(
createDirectoryIfMissing
,
doesDirectoryExist
)
import
Control.Monad
import
Compiler
import
Compiler
import
Util
(
delimit
)
import
Util
(
delimit
)
import
Text.Parsec.Pos
import
Text.Parsec.Pos
import
Text.Parsec.Error
import
Text.Parsec.Error
import
Text.Printf
(
printf
)
import
Text.Printf
(
printf
)
import
qualified
Data.List
as
List
import
qualified
Data.List
as
List
import
qualified
Data.Map
as
Map
import
qualified
Data.ByteString.Lazy.Char8
as
LZ
import
qualified
Data.ByteString.Lazy.Char8
as
LZ
import
Data.List
import
Data.Maybe
import
Semantics
import
Semantics
import
CxxGenerator
import
CxxGenerator
(
generateCxx
)
main
::
IO
()
type
GeneratorFn
=
FileDesc
->
IO
[(
FilePath
,
LZ
.
ByteString
)]
generatorFns
=
Map
.
fromList
[
(
"c++"
,
generateCxx
)
]
data
Opt
=
OutputOpt
String
(
Maybe
GeneratorFn
)
FilePath
|
VerboseOpt
|
HelpOpt
main
::
IO
()
main
=
do
main
=
do
let
options
=
[
Option
[
'o'
]
[
"output"
]
(
ReqArg
id
"FILE"
)
"Where to send the files"
]
let
optionDescs
=
[
Option
"o"
[
"output"
]
(
ReqArg
parseOutputArg
"LANG[:DIR]"
)
(
"Generate output for language LANG
\n\
\
to directory DIR (default: current
\n\
\
directory). LANG may be any of:
\n\
\
"
++
unwords
(
Map
.
keys
generatorFns
))
,
Option
"v"
[
"verbose"
]
(
NoArg
VerboseOpt
)
"Write information about parsed files."
,
Option
"h"
[
"help"
]
(
NoArg
HelpOpt
)
"Print usage info and exit."
]
let
usage
=
usageInfo
"capnpc [OPTION]... [FILE]...
\n\
\
Generate source code based on Cap'n Proto definition FILEs.
\n
"
optionDescs
args
<-
getArgs
args
<-
getArgs
let
tup
=
getOpt
RequireOrder
options
args
let
(
options
,
files
,
optErrs
)
=
getOpt
Permute
optionDescs
args
let
(
optionResults
,
files
,
_
)
=
tup
let
langErrs
=
map
(
printf
"Unknown output language: %s
\n
"
)
let
langDirs
=
catMaybes
(
map
splitAtEquals
optionResults
)
[
lang
|
OutputOpt
lang
Nothing
_
<-
options
]
handleFilesLangs
(
generatorFnsFor
langDirs
)
files
let
errs
=
optErrs
++
langErrs
unless
(
null
errs
)
(
do
mapM_
(
hPutStr
stderr
)
errs
hPutStr
stderr
usage
exitFailure
)
when
(
null
options
)
(
do
hPutStr
stderr
"Nothing to do.
\n
"
hPutStr
stderr
usage
exitFailure
)
splitAtEquals
::
String
->
Maybe
(
String
,
String
)
let
isHelp
=
not
$
null
[
opt
|
opt
@
HelpOpt
<-
options
]
splitAtEquals
str
=
do
holder
<-
(
elemIndex
'='
str
)
Just
((
splitAt
holder
str
))
handleFilesLangs
eithers
files
=
mapM_
(
\
x
->
handleFiles
x
files
)
eithers
when
isHelp
(
do
putStr
usage
exitSuccess
)
handleFiles
(
Right
fn
)
files
=
mapM_
(
handleFile
fn
)
files
let
isVerbose
=
not
$
null
[
opt
|
opt
@
VerboseOpt
<-
options
]
handleFiles
(
Left
str
)
_
=
putStrLn
str
let
outputs
=
[(
fn
,
dir
)
|
OutputOpt
_
(
Just
fn
)
dir
<-
options
]
handleFile
generateCode
filename
=
do
let
verifyDirectoryExists
dir
=
do
exists
<-
doesDirectoryExist
dir
unless
exists
(
do
hPutStr
stderr
$
printf
"no such directory: %s
\n
"
dir
exitFailure
)
mapM_
verifyDirectoryExists
[
dir
|
(
_
,
dir
)
<-
outputs
]
mapM_
(
handleFile
outputs
isVerbose
)
files
parseOutputArg
::
String
->
Opt
parseOutputArg
str
=
case
List
.
elemIndex
':'
str
of
Just
i
->
let
(
lang
,
_
:
dir
)
=
splitAt
i
str
in
OutputOpt
lang
(
Map
.
lookup
lang
generatorFns
)
dir
Nothing
->
OutputOpt
str
(
Map
.
lookup
str
generatorFns
)
"."
handleFile
::
[(
GeneratorFn
,
FilePath
)]
->
Bool
->
FilePath
->
IO
()
handleFile
outputs
isVerbose
filename
=
do
text
<-
readFile
filename
text
<-
readFile
filename
case
parseAndCompileFile
filename
text
of
case
parseAndCompileFile
filename
text
of
Active
desc
[]
->
do
Active
desc
[]
->
do
print
desc
when
isVerbose
(
print
desc
)
generateCode
desc
filename
Active
_
e
->
mapM_
printError
(
List
.
sortBy
compareErrors
e
)
Failed
e
->
mapM_
printError
(
List
.
sortBy
compareErrors
e
)
generatorFnsFor
::
[(
String
,
String
)]
->
[
Either
String
(
FileDesc
->
FilePath
->
(
IO
()
))]
let
write
dir
(
name
,
content
)
=
do
generatorFnsFor
langDirs
=
do
let
outFilename
=
dir
++
"/"
++
name
map
(
\
langDir
->
generatorFnFor
(
fst
langDir
)
(
tail
(
snd
langDir
)))
langDirs
createDirectoryIfMissing
True
$
takeDirectory
outFilename
LZ
.
writeFile
outFilename
content
let
generate
(
generatorFn
,
dir
)
=
do
files
<-
generatorFn
desc
mapM_
(
write
dir
)
files
mapM_
generate
outputs
generatorFnFor
::
String
->
String
->
Either
String
(
FileDesc
->
FilePath
->
(
IO
()
))
Active
_
e
->
do
generatorFnFor
lang
dir
=
case
lang
of
mapM_
printError
(
List
.
sortBy
compareErrors
e
)
"c++"
->
Right
(
\
desc
filename
->
do
exitFailure
header
<-
generateCxxHeader
desc
Failed
e
->
do
LZ
.
writeFile
(
dir
++
"/"
++
filename
++
".h"
)
header
mapM_
printError
(
List
.
sortBy
compareErrors
e
)
source
<-
generateCxxSource
desc
exitFailure
LZ
.
writeFile
(
dir
++
"/"
++
filename
++
".c++"
)
source
)
_
->
Left
"Only c++ is supported for now"
compareErrors
a
b
=
compare
(
errorPos
a
)
(
errorPos
b
)
compareErrors
a
b
=
compare
(
errorPos
a
)
(
errorPos
b
)
-- TODO: This is a fairly hacky way to make showErrorMessages' output not suck. We could do better
-- TODO: This is a fairly hacky way to make showErrorMessages' output not suck. We could do better
-- by interpreting the error structure ourselves.
-- by interpreting the error structure ourselves.
printError
e
=
printf
"%s:%d:%d: %s
\n
"
f
l
c
m'
where
printError
e
=
hPutStr
stderr
$
printf
"%s:%d:%d: %s
\n
"
f
l
c
m'
where
pos
=
errorPos
e
pos
=
errorPos
e
f
=
sourceName
pos
f
=
sourceName
pos
l
=
sourceLine
pos
l
=
sourceLine
pos
...
...
compiler/src/Semantics.hs
View file @
dbc3d6dc
...
@@ -389,7 +389,9 @@ data CompiledStatement = CompiledMember Desc
...
@@ -389,7 +389,9 @@ data CompiledStatement = CompiledMember Desc
-- TODO: Print options as well as members. Will be ugly-ish.
-- TODO: Print options as well as members. Will be ugly-ish.
descToCode
::
String
->
Desc
->
String
descToCode
::
String
->
Desc
->
String
descToCode
indent
(
DescFile
desc
)
=
concatMap
(
statementToCode
indent
)
(
fileStatements
desc
)
descToCode
indent
(
DescFile
desc
)
=
printf
"# %s
\n
%s"
(
fileName
desc
)
(
concatMap
(
statementToCode
indent
)
(
fileStatements
desc
))
descToCode
indent
(
DescAlias
desc
)
=
printf
"%susing %s = %s;
\n
"
indent
descToCode
indent
(
DescAlias
desc
)
=
printf
"%susing %s = %s;
\n
"
indent
(
aliasName
desc
)
(
aliasName
desc
)
(
descQualifiedName
(
aliasParent
desc
)
(
aliasTarget
desc
))
(
descQualifiedName
(
aliasParent
desc
)
(
aliasTarget
desc
))
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment