Commit 404385b0 by Zachary Snow Committed by Zachary Snow

allow arbitrary .v output file using -w/--write

parent 5eef44c8
...@@ -74,7 +74,8 @@ running `stack install`, or copy over the executable manually. ...@@ -74,7 +74,8 @@ running `stack install`, or copy over the executable manually.
sv2v takes in a list of files and prints the converted Verilog to `stdout`. sv2v takes in a list of files and prints the converted Verilog to `stdout`.
Using `--write=adjacent` will create a converted `.v` for every `.sv` input file Using `--write=adjacent` will create a converted `.v` for every `.sv` input file
rather than printing to `stdout`. rather than printing to `stdout`. `--write`/`-w` can also be used to specify a
path to a `.v` output file.
Users may specify `include` search paths, define macros during preprocessing, Users may specify `include` search paths, define macros during preprocessing,
and exclude some of the conversions. Specifying `-` as an input file will read and exclude some of the conversions. Specifying `-` as an input file will read
...@@ -95,8 +96,9 @@ Conversion: ...@@ -95,8 +96,9 @@ Conversion:
-E --exclude=CONV Exclude a particular conversion (always, assert, -E --exclude=CONV Exclude a particular conversion (always, assert,
interface, or logic) interface, or logic)
-v --verbose Retain certain conversion artifacts -v --verbose Retain certain conversion artifacts
-w --write=MODE How to write output; default is 'stdout'; use -w --write=MODE/FILE How to write output; default is 'stdout'; use
'adjacent' to create a .v file next to each input 'adjacent' to create a .v file next to each input;
use a path ending in .v to write to a file
Other: Other:
--help Display help message --help Display help message
--version Print version information --version Print version information
......
...@@ -8,12 +8,15 @@ ...@@ -8,12 +8,15 @@
module Job where module Job where
import Data.Char (toLower)
import Data.List (isPrefixOf, isSuffixOf)
import Data.Version (showVersion) import Data.Version (showVersion)
import GitHash (giDescribe, tGitInfoCwdTry) import GitHash (giDescribe, tGitInfoCwdTry)
import qualified Paths_sv2v (version) import qualified Paths_sv2v (version)
import System.IO (stderr, hPutStr) import System.IO (stderr, hPutStr)
import System.Console.CmdArgs import System.Console.CmdArgs
import System.Environment (getArgs, withArgs) import System.Environment (getArgs, withArgs)
import System.Exit (exitFailure)
data Exclude data Exclude
= Always = Always
...@@ -26,12 +29,9 @@ data Exclude ...@@ -26,12 +29,9 @@ data Exclude
data Write data Write
= Stdout = Stdout
| Adjacent | Adjacent
| File | File FilePath
deriving (Show, Typeable, Data, Eq) deriving (Show, Typeable, Data, Eq)
instance Default Write where
def = Stdout
data Job = Job data Job = Job
{ files :: [FilePath] { files :: [FilePath]
, incdir :: [FilePath] , incdir :: [FilePath]
...@@ -41,6 +41,7 @@ data Job = Job ...@@ -41,6 +41,7 @@ data Job = Job
, exclude :: [Exclude] , exclude :: [Exclude]
, verbose :: Bool , verbose :: Bool
, write :: Write , write :: Write
, writeRaw :: String
} deriving (Show, Typeable, Data) } deriving (Show, Typeable, Data)
version :: String version :: String
...@@ -65,10 +66,11 @@ defaultJob = Job ...@@ -65,10 +66,11 @@ defaultJob = Job
++ " or logic)") ++ " or logic)")
&= groupname "Conversion" &= groupname "Conversion"
, verbose = nam "verbose" &= help "Retain certain conversion artifacts" , verbose = nam "verbose" &= help "Retain certain conversion artifacts"
, write = nam_ "write" &= name "w" &= typ "MODE" , write = Stdout &= ignore -- parsed from the flexible flag below
, writeRaw = "s" &= name "write" &= name "w" &= explicit &= typ "MODE/FILE"
&= help ("How to write output; default is 'stdout'; use 'adjacent' to" &= help ("How to write output; default is 'stdout'; use 'adjacent' to"
++ " create a .v file next to each input; use 'file' to create a" ++ " create a .v file next to each input; use a path ending in .v"
++ " sv2v_output.v file") ++ " to write to a file")
} }
&= program "sv2v" &= program "sv2v"
&= summary ("sv2v " ++ version) &= summary ("sv2v " ++ version)
...@@ -83,6 +85,18 @@ defaultJob = Job ...@@ -83,6 +85,18 @@ defaultJob = Job
nam xs = nam_ xs &= name [head xs] nam xs = nam_ xs &= name [head xs]
nam_ xs = def &= name xs &= explicit nam_ xs = def &= name xs &= explicit
parseWrite :: String -> IO Write
parseWrite w | w `matches` "stdout" = return Stdout
parseWrite w | w `matches` "adjacent" = return Adjacent
parseWrite w | ".v" `isSuffixOf` w = return $ File w
parseWrite w | otherwise = do
hPutStr stderr $ "invalid --write " ++ show w
++ ", expected stdout, adjacent, or a path ending in .v"
exitFailure
matches :: String -> String -> Bool
matches = isPrefixOf . map toLower
type DeprecationPhase = [String] -> IO [String] type DeprecationPhase = [String] -> IO [String]
flagRename :: String -> String -> DeprecationPhase flagRename :: String -> String -> DeprecationPhase
...@@ -108,7 +122,13 @@ readJob = do ...@@ -108,7 +122,13 @@ readJob = do
>>= flagRename "-i" "-I" >>= flagRename "-i" "-I"
>>= flagRename "-d" "-D" >>= flagRename "-d" "-D"
>>= flagRename "-e" "-E" >>= flagRename "-e" "-E"
job <- withArgs (strs') $ cmdArgs defaultJob withArgs strs' $ cmdArgs defaultJob
return $ if verbose job >>= setWrite . setSuccinct
then job { exclude = Succinct : exclude job } where
else job setWrite :: Job -> IO Job
setWrite job = do
w <- parseWrite $ writeRaw job
return $ job { write = w }
setSuccinct :: Job -> Job
setSuccinct job | verbose job = job { exclude = Succinct : exclude job }
setSuccinct job | otherwise = job
...@@ -64,9 +64,8 @@ writeOutput _ [] [] = ...@@ -64,9 +64,8 @@ writeOutput _ [] [] =
hPutStrLn stderr "Warning: No input files specified (try `sv2v --help`)" hPutStrLn stderr "Warning: No input files specified (try `sv2v --help`)"
writeOutput Stdout _ asts = writeOutput Stdout _ asts =
hPrint stdout $ concat asts hPrint stdout $ concat asts
writeOutput File _ asts = writeOutput (File f) _ asts =
writeFile f $ show $ concat asts writeFile f $ show $ concat asts
where f = "sv2v_output.v"
writeOutput Adjacent inPaths asts = do writeOutput Adjacent inPaths asts = do
outPaths <- mapM rewritePath inPaths outPaths <- mapM rewritePath inPaths
badPaths <- filterM doesFileExist outPaths badPaths <- filterM doesFileExist outPaths
......
...@@ -66,6 +66,30 @@ test_adjacent_extension() { ...@@ -66,6 +66,30 @@ test_adjacent_extension() {
"$stderr" "$stderr"
} }
test_file() {
runAndCapture --write=stdout *.sv
expected="$stdout"
rm -f out.v
runAndCapture --write=out.v *.sv
assertTrue "file conversion should succeed" $result
assertNull "stdout should be empty" "$stdout"
assertNull "stderr should be empty" "$stderr"
actual=`cat out.v`
assertEquals "file output should match combined" "$expected" "$actual"
clearArtifacts
}
test_unknown() {
runAndCapture --write=unknown *.sv
assertFalse "unknown write mode should fail" $result
assertNull "stdout should be empty" "$stdout"
assertEquals "stderr should list valid write modes" \
"invalid --write \"unknown\", expected stdout, adjacent, or a path ending in .v" \
"$stderr"
}
source ../lib/functions.sh source ../lib/functions.sh
. shunit2 . shunit2
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment