Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

pass debug information between compiler and debugger

  • Loading branch information...
commit a9146a90256fc246bc44a0d060cf497383d67d77 1 parent 991bd4f
Alexander Bernauer authored
View
6 applications/contiki/common.mak
@@ -24,10 +24,10 @@ endif
all: app-ec.c pal.c contiki debug.json $(SKYS)
app-ec.c pal.c debug.json: app-tc.c app-tc.o $(OCRAM) $(PALGEN) $(OCRAM_PAL_TEMPLATE)
- $(OCRAM) --compile \
- -p pal.c -i $< -o $@ \
- -g $(PALGEN) \
+ $(OCRAM) -i $< -o $@ \
-c "$(CHROOT) $(XGCC) -DOCRAM_MODE -E -o -" \
+ -p pal.c -g $(PALGEN) \
+ -d debug.json \
|| (rm -f app-ec.c pal.c; exit 1)
app-tc.o: app-tc.c
View
203 applications/contiki/dca/generated/debugger.csc
@@ -1,203 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<simconf>
- <project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/mrm</project>
- <project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/mspsim</project>
- <project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/avrora</project>
- <project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/serial_socket</project>
- <project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/collect-view</project>
- <simulation>
- <title>cnf_native</title>
- <delaytime>0</delaytime>
- <randomseed>123456</randomseed>
- <motedelay_us>1000000</motedelay_us>
- <radiomedium>
- se.sics.cooja.radiomediums.UDGM
- <transmitting_range>50.0</transmitting_range>
- <interference_range>100.0</interference_range>
- <success_ratio_tx>1.0</success_ratio_tx>
- <success_ratio_rx>1.0</success_ratio_rx>
- </radiomedium>
- <events>
- <logoutput>40000</logoutput>
- </events>
- <motetype>
- se.sics.cooja.mspmote.SkyMoteType
- <identifier>sky1</identifier>
- <description>source</description>
- <firmware EXPORT="copy">[CONFIG_DIR]/../setup/source.cached.sky</firmware>
- <moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
- <moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
- <moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
- <moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
- <moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyButton</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyFlash</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyByteRadio</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.MspSerial</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyLED</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
- </motetype>
- <motetype>
- se.sics.cooja.mspmote.SkyMoteType
- <identifier>sky2</identifier>
- <description>sink</description>
- <firmware EXPORT="copy">[CONFIG_DIR]/../setup/sink.cached.sky</firmware>
- <moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
- <moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
- <moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
- <moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
- <moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyButton</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyFlash</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyByteRadio</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.MspSerial</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyLED</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
- </motetype>
- <motetype>
- se.sics.cooja.mspmote.SkyMoteType
- <identifier>sky3</identifier>
- <description>app</description>
- <firmware EXPORT="copy">[CONFIG_DIR]/pal.cached.sky</firmware>
- <moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
- <moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
- <moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
- <moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
- <moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyButton</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyFlash</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyByteRadio</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.MspSerial</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyLED</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
- <moteinterface>se.sics.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
- </motetype>
- <mote>
- <breakpoints />
- <interface_config>
- se.sics.cooja.interfaces.Position
- <x>33.87709078321985</x>
- <y>42.126796420218746</y>
- <z>0.0</z>
- </interface_config>
- <interface_config>
- se.sics.cooja.mspmote.interfaces.MspMoteID
- <id>1</id>
- </interface_config>
- <motetype_identifier>sky1</motetype_identifier>
- </mote>
- <mote>
- <breakpoints />
- <interface_config>
- se.sics.cooja.interfaces.Position
- <x>33.845630990679325</x>
- <y>35.36142143815238</y>
- <z>0.0</z>
- </interface_config>
- <interface_config>
- se.sics.cooja.mspmote.interfaces.MspMoteID
- <id>2</id>
- </interface_config>
- <motetype_identifier>sky3</motetype_identifier>
- </mote>
- <mote>
- <breakpoints />
- <interface_config>
- se.sics.cooja.interfaces.Position
- <x>34.257469238273636</x>
- <y>26.643154822248587</y>
- <z>0.0</z>
- </interface_config>
- <interface_config>
- se.sics.cooja.mspmote.interfaces.MspMoteID
- <id>3</id>
- </interface_config>
- <motetype_identifier>sky2</motetype_identifier>
- </mote>
- </simulation>
- <plugin>
- se.sics.cooja.plugins.SimControl
- <width>318</width>
- <z>-1</z>
- <height>186</height>
- <location_x>3</location_x>
- <location_y>2</location_y>
- </plugin>
- <plugin>
- se.sics.cooja.plugins.Visualizer
- <plugin_config>
- <skin>se.sics.cooja.plugins.skins.AddressVisualizerSkin</skin>
- <skin>se.sics.cooja.plugins.skins.TrafficVisualizerSkin</skin>
- <skin>se.sics.cooja.plugins.skins.UDGMVisualizerSkin</skin>
- <skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
- <viewport>10.816250021861679 0.0 0.0 10.816250021861679 -252.53735239740297 -213.17902392861043</viewport>
- </plugin_config>
- <width>319</width>
- <z>1</z>
- <height>379</height>
- <location_x>-1</location_x>
- <location_y>186</location_y>
- </plugin>
- <plugin>
- se.sics.cooja.plugins.LogListener
- <plugin_config>
- <filter />
- <coloring />
- </plugin_config>
- <width>1094</width>
- <z>-1</z>
- <height>672</height>
- <location_x>319</location_x>
- <location_y>1</location_y>
- </plugin>
- <plugin>
- se.sics.cooja.mspmote.plugins.OcramCoojaPlugin
- <plugin_config>
- <process>thread0</process>
- <process>thread1</process>
- <process>thread2</process>
- </plugin_config>
- <mote_arg>1</mote_arg>
- <width>207</width>
- <z>-1</z>
- <height>80</height>
- <location_x>42</location_x>
- <location_y>599</location_y>
- </plugin>
- <plugin>
- se.sics.cooja.plugins.ScriptRunner
- <plugin_config>
- <scriptfile>[CONFIG_DIR]/../../quit.js</scriptfile>
- <active>true</active>
- </plugin_config>
- <width>600</width>
- <z>-1</z>
- <height>700</height>
- <location_x>255</location_x>
- <location_y>78</location_y>
- <minimized>true</minimized>
- </plugin>
- <plugin>
- ch.ethz.inf.vs.ruab.RuabCoojaPlugin
- <mote_arg>1</mote_arg>
- <z>0</z>
- <width>1413</width>
- <height>888</height>
- <location_x>0</location_x>
- <location_y>0</location_y>
- <plugin_config>
- <debugfile>/home/alex/scm/ocram/applications/contiki/dca/generated/debug.json</debugfile>
- </plugin_config>
- </plugin>
-</simconf>
View
1  ocram/ocram.cabal
@@ -36,6 +36,7 @@ Executable ocram
filepath == 1.3.*,
directory == 1.1.*,
nano-md5 == 0.1.*,
+ json == 0.5.*,
HUnit == 1.2.*,
test-framework == 0.6.*,
test-framework-hunit == 0.2.*,
View
BIN  ocram/src/Ocram/.Ruab.hs.swo
Binary file not shown
View
14 ocram/src/Ocram/Debug.hs
@@ -3,12 +3,16 @@ module Ocram.Debug where
-- import {{{1
import Data.Data (Data)
+import Data.Digest.OpenSSL.MD5 (md5sum)
import Data.Maybe (fromMaybe)
import Data.Typeable (Typeable)
import Language.C.Data.Node (lengthOfNode, isUndefNode, posOfNode, CNode(nodeInfo), NodeInfo, undefNode)
import Language.C.Data.Position (posRow, posColumn)
-import Ocram.Util (abort)
+import Ocram.Options (Options(optInput, optOutput))
import Ocram.Ruab
+import Ocram.Util (abort)
+
+import qualified Data.ByteString.Char8 as BS
data ENodeInfo = ENodeInfo { -- {{{1
tnodeInfo :: NodeInfo,
@@ -47,4 +51,10 @@ tlocation eni =
in
TLocation (posRow pos) (posColumn pos) (fromMaybe (-1) (lengthOfNode ni))
-
+create_debug_info :: Options -> BS.ByteString -> BS.ByteString -> BS.ByteString -> VarMap -> LocMap -> DebugInfo
+create_debug_info opt tcode pcode ecode vm lm =
+ let
+ tfile = File (optInput opt) (md5sum tcode)
+ efile = File (optOutput opt) (md5sum ecode)
+ in
+ DebugInfo tfile pcode efile lm vm
View
12 ocram/src/Ocram/IO.hs
@@ -4,6 +4,7 @@ module Ocram.IO
(
parse
, dump_ecode
+ , dump_debug_info
, generate_pal
) where
@@ -30,9 +31,9 @@ parse :: Options -> IO (Either [OcramError] (BS.ByteString, BS.ByteString, CTran
parse opt = do
tcode <- BS.readFile infile
runOcramError $ do
- tcode' <- IoOcramError $ exec ((words (optPreprocessor opt)) ++ [infile]) Nothing
- ast <- parseC' tcode'
- return (tcode, tcode', ast)
+ pcode <- IoOcramError $ exec ((words (optPreprocessor opt)) ++ [infile]) Nothing
+ ast <- parseC' pcode
+ return (tcode, pcode, ast)
where
infile = optInput opt
parseC' code = case parseC code (initPos infile) of
@@ -44,6 +45,11 @@ dump_ecode :: Options -> BS.ByteString -> IO (Either [OcramError] ()) -- {{{1
dump_ecode options ecode =
write (optOutput options) $ ecode
+dump_debug_info :: Options -> BS.ByteString -> IO (Either [OcramError] ()) -- {{{1
+dump_debug_info opt di = case optDebugFile opt of
+ Nothing -> (return . Right) ()
+ Just file -> write file di
+
generate_pal :: Options -> Footprint -> CTranslationUnit ENodeInfo -> IO (Either [OcramError] ()) -- {{{1
generate_pal options fpr header = case optPalGenerator options of
Nothing -> (return . Right) ()
View
12 ocram/src/Ocram/Main.hs
@@ -2,9 +2,11 @@ module Ocram.Main (main) where
-- imports {{{1
import Ocram.Analysis (analysis)
+import Ocram.Debug (create_debug_info)
import Ocram.Options (options)
-import Ocram.IO (parse, generate_pal, dump_ecode)
+import Ocram.IO (parse, generate_pal, dump_ecode, dump_debug_info)
import Ocram.Print (print_with_log)
+import Ocram.Ruab (encode_debug_info)
import Ocram.Text (OcramError, show_errors)
import Ocram.Test (runTests)
import Ocram.Transformation (transformation)
@@ -24,12 +26,14 @@ runCompiler :: [String] -> IO () -- {{{2
runCompiler argv = do
prg <- getProgName
opt <- exitOnError "options" $ options prg argv
- (_, _, ast) <- exitOnError "parser" =<< parse opt
+ (tcode, pcode, ast) <- exitOnError "parser" =<< parse opt
(cg, fpr) <- exitOnError "analysis" $ analysis ast
- let (ast', pal, _) = transformation cg ast
- let (ecode, _) = print_with_log ast'
+ let (ast', pal, vm) = transformation cg ast
+ let (ecode, lm) = print_with_log ast'
+ let di = encode_debug_info $ create_debug_info opt tcode pcode ecode vm lm
exitOnError "output" =<< generate_pal opt fpr pal
exitOnError "output" =<< dump_ecode opt ecode
+ exitOnError "output" =<< dump_debug_info opt di
return ()
exitOnError :: String -> Either [OcramError] a -> IO a -- {{{2
View
27 ocram/src/Ocram/Options.hs
@@ -10,24 +10,22 @@ import Data.Maybe (isJust)
import Ocram.Text (new_error, OcramError)
import System.Console.GetOpt
--- types {{{1
-data Options = Options {
+data Options = Options { -- {{{1
optInput :: FilePath
, optOutput :: FilePath
- , optPalFile :: Maybe FilePath
- , optPTFile :: Maybe FilePath
- , optDebugFile :: Maybe FilePath
, optPreprocessor :: FilePath
, optPalGenerator :: Maybe FilePath
+ , optPalFile :: Maybe FilePath
+ , optDebugFile :: Maybe FilePath
, optHelp :: Bool
-} deriving (Show, Read)
+}
-- options :: String -> [String] -> Either String Options {{{1
options :: String -> [String] -> Either [OcramError] Options
options prg argv =
let use = usage prg in
- case getOpt Permute available_options argv of
+ case getOpt Permute availableOptions argv of
(o,[],[]) ->
let opts = foldl (flip id) defaultOptions o in
if optHelp opts then
@@ -47,15 +45,16 @@ err :: String -> String -> String
err use msg = "Error in command line options\n" ++ msg ++ "\n" ++ use
usage :: String -> String
-usage prg = usageInfo ("Usage: " ++ prg ++ " OPTIONS") available_options
+usage prg = usageInfo ("Usage: " ++ prg ++ " OPTIONS") availableOptions
-available_options :: [OptDescr (Options -> Options)]
-available_options = [
+availableOptions :: [OptDescr (Options -> Options)]
+availableOptions = [
Option "i" ["input"] (ReqArg (\x opts -> opts {optInput = x}) "input") "input tc file (required)"
, Option "o" ["output"] (ReqArg (\x opts -> opts {optOutput = x}) "output") "output ec file (required)"
- , Option "p" ["pal"] (ReqArg (\x opts -> opts {optPalFile = Just x}) "pal") "target file path for the PAL generator program (mandatory if generator is specified)"
, Option "c" ["preprocessor"] (ReqArg (\x opts -> opts {optPreprocessor = x}) "preprocessor") "external program which performs the pre-processing of the input C file (required)"
, Option "g" ["generator"] (ReqArg (\x opts -> opts {optPalGenerator = Just x}) "generator") "external program which generates the PAL implementation (optional)"
+ , Option "p" ["pal"] (ReqArg (\x opts -> opts {optPalFile = Just x}) "pal") "file path for the PAL generator program (mandatory if generator is specified)"
+ , Option "d" ["debug"] (ReqArg (\x opts -> opts {optDebugFile = Just x}) "debug") "file path for the debugging information (optional)"
, Option "h" ["help"] (NoArg (\opts -> opts {optHelp = True})) "print help and quit"
]
@@ -63,11 +62,10 @@ defaultOptions :: Options
defaultOptions = Options {
optInput = ""
, optOutput = ""
+ , optPreprocessor = ""
+ , optPalGenerator = Nothing
, optPalFile = Nothing
, optDebugFile = Nothing
- , optPTFile = Nothing
- , optPalGenerator = Nothing
- , optPreprocessor = ""
, optHelp = False
}
@@ -77,5 +75,4 @@ checkOptions opts
| optOutput opts == optOutput defaultOptions = False
| isJust (optPalGenerator opts) && not (isJust (optPalFile opts)) = False
| optPreprocessor opts == optPreprocessor defaultOptions = False
- | isJust (optDebugFile opts) && not (isJust (optPTFile opts)) = False
| otherwise = True
View
2  ocram/src/Ocram/Print.hs
@@ -51,7 +51,7 @@ import Ocram.Util (abort)
import qualified Data.ByteString.Char8 as BS
-print_with_log :: CTranslationUnit ENodeInfo -> (BS.ByteString, LocMap)
+print_with_log :: CTranslationUnit ENodeInfo -> (BS.ByteString, LocMap) -- {{{1
print_with_log tu = first BS.pack $ renderWithLog (pretty tu)
marker :: ENodeInfo -> DocL LocMap -> DocL LocMap
View
52 ocram/src/Ocram/Ruab.hs
@@ -1,5 +1,9 @@
module Ocram.Ruab where
+import Text.JSON
+
+import qualified Data.ByteString.Char8 as BS
+
data TLocation = TLocation {
tlocRow :: Int
, tlocCol :: Int
@@ -10,9 +14,20 @@ data ELocation = ELocation {
elocRow :: Int
, elocCol :: Int
, elocTidd :: Maybe Int
- } deriving (Show, Read)
+ }
-data Location = Location TLocation ELocation deriving (Show, Read)
+data Location = Location TLocation ELocation
+
+instance JSON Location where
+ readJSON val = do
+ (tr:tc:tl:er:ec:tid) <- readJSON val
+ case tid of
+ [] -> return $ Location (TLocation tr tc tl) (ELocation er ec Nothing)
+ [tid'] -> return $ Location (TLocation tr tc tl) (ELocation er ec (Just tid'))
+ _ -> Error "wrong number of values in JSON array of Location type"
+
+ showJSON (Location (TLocation tr tc tl) (ELocation er ec Nothing)) = showJSON [tr, tc, tl, er, ec]
+ showJSON (Location (TLocation tr tc tl) (ELocation er ec (Just tid))) = showJSON [tr, tc, tl, er, ec, tid]
type LocMap = [Location]
@@ -22,12 +37,41 @@ type VarMap = [(Variable, Variable)]
data File = File {
fileName :: FilePath
, fileChecksum :: String
- } deriving (Show, Read)
+ }
+
+instance JSON File where
+ readJSON val = readJSON val >>= \[n,c] -> return $ File n c
+ showJSON (File n c) = showJSON [n, c]
data DebugInfo = DebugInfo {
diTcode :: File
+ , diPcode :: BS.ByteString
, diEcode :: File
, diLocMap :: LocMap
, diVarMap :: VarMap
- } deriving (Show, Read)
+ }
+
+instance JSON DebugInfo where
+ showJSON (DebugInfo tcode pcode ecode lm vm) = (JSObject . toJSObject) [
+ ("tcode", showJSON tcode)
+ , ("pcode", showJSON pcode)
+ , ("ecode", showJSON ecode)
+ , ("locmap", showJSON lm)
+ , ("varmap", showJSON vm)
+ ]
+
+ readJSON (JSObject obj) = do
+ let [tcode, pcode, ecode, lm, vm] = map snd $ fromJSObject obj
+ [tcode', ecode'] <- mapM readJSON [tcode, ecode]
+ pcode' <- readJSON pcode
+ lm' <- readJSON lm
+ vm' <- readJSON vm
+ return $ DebugInfo tcode' pcode' ecode' lm' vm'
+
+ readJSON _ = Error "unexpected JSON value for DebugInfo type"
+
+encode_debug_info :: DebugInfo -> BS.ByteString
+encode_debug_info = BS.pack . encodeStrict
+decode_debug_info :: BS.ByteString -> Either String DebugInfo
+decode_debug_info string = (resultToEither . decodeStrict . BS.unpack) string
View
2  ruab/ruab.cabal
@@ -35,6 +35,8 @@ Executable ruab
test-framework == 0.6.*,
test-framework-hunit == 0.2.*,
process == 1.1.*,
+ nano-md5 == 0.1.*,
+ json == 0.5.*,
ocramruab == 0.1.*
Other-Modules:
Main,
View
36 ruab/src/Ruab/Debug.hs
@@ -0,0 +1,36 @@
+module Ruab.Debug
+(
+ load_debug_info
+) where
+
+import Data.List (intercalate)
+import Data.Maybe (catMaybes)
+import Data.Digest.OpenSSL.MD5 (md5sum)
+import Ocram.Ruab
+import Prelude hiding (catch)
+import Control.Exception (catch, IOException)
+import Ruab.Options (Options(optDebugFile))
+import System.IO (openFile, IOMode(ReadMode), hClose)
+import System.Exit (ExitCode(ExitFailure))
+
+import qualified Data.ByteString.Char8 as BS
+
+load_debug_info :: Options -> IO (Either (ExitCode, String) DebugInfo)
+load_debug_info opt = do
+ hDi <- openFile (optDebugFile opt) ReadMode
+ contents <- BS.hGetContents hDi
+ hClose hDi
+ case decode_debug_info contents of
+ Left why -> (return . Left) (ExitFailure 6, why)
+ Right di -> do
+ let files = [diTcode di, diEcode di]
+ code <- mapM (BS.readFile . fileName) files
+ case catMaybes (zipWith verify code files) of
+ [] -> (return . Right) di
+ err -> (return . Left) (ExitFailure 5, intercalate "\n" err)
+ `catch` (\e -> (return . Left) (ExitFailure 4, show (e :: IOException)))
+ where
+ verify contents file
+ | md5sum contents == fileChecksum file = Nothing
+ | otherwise = Just $ failed $ fileName file
+ failed file = "checksum for '" ++ file ++ "' differs"
View
1  ruab/src/Ruab/Frontend.hs
@@ -9,6 +9,7 @@ import Paths_Ruab (getDataFileName)
import Graphics.UI.Gtk
import Graphics.UI.Gtk.Glade (xmlNew, xmlGetWidget)
import OcramRuab (LocMap, VarMap)
+import Prelude hiding (log)
import qualified Data.ByteString.Char8 as BS
import Debug.Trace (trace)
View
21 ruab/src/Ruab/Main.hs
@@ -4,13 +4,16 @@ module Ruab.Main
) where
-- imports {{{1
+import Ocram.Ruab
+import Ruab.Backend
+import Ruab.Debug (load_debug_info)
import Ruab.Frontend (ruab_ui)
import Ruab.Mapping
-import Ruab.Backend
-import Ruab.Options
+import Ruab.Options (options)
import Ruab.Test (runTests)
-import System.Environment (getArgs)
-import Ocram.Ruab
+import System.Environment (getArgs, getProgName)
+import System.Exit (exitWith, ExitCode)
+import System.IO (stderr, hPutStrLn)
main :: IO () -- {{{1
main = do
@@ -20,4 +23,12 @@ main = do
_ -> runDebugger argv
runDebugger :: [String] -> IO ()
-runDebugger _ = ruab_ui
+runDebugger argv = do
+ prg <- getProgName
+ opt <- exitOnError $ options prg argv
+ di <- exitOnError =<< load_debug_info opt
+ return ()
+
+exitOnError :: Either (ExitCode, String) a -> IO a -- {{{2
+exitOnError (Left (ec, why)) = hPutStrLn stderr why >> exitWith ec
+exitOnError (Right x) = return x
View
47 ruab/src/Ruab/Options.hs
@@ -1,4 +1,49 @@
module Ruab.Options
+-- export {{{1
(
-
+ Options(..), options
) where
+
+-- imports {{{1
+import Data.List (intercalate)
+import System.Exit (ExitCode(ExitSuccess, ExitFailure))
+import System.Console.GetOpt (getOpt, usageInfo, ArgOrder(Permute), OptDescr, ArgDescr(NoArg, ReqArg), OptDescr(Option))
+
+data Options = Options { -- {{{1
+ optDebugFile :: FilePath
+ , optHelp :: Bool
+}
+
+options :: String -> [String] -> Either (ExitCode, String) Options
+options prg argv =
+ case getOpt Permute availableOptions argv of
+ (o, [], []) ->
+ let opts = foldl (flip id) defaultOptions o in
+ if optHelp opts
+ then Left (ExitSuccess, help)
+ else if checkOptions opts
+ then Right opts
+ else Left (ExitFailure 1, help)
+ (_,n,[]) -> Left (ExitFailure 2, err ("unknown options '" ++ unwords n ++ "'"))
+ (_,_,es) -> Left (ExitFailure 3, err (intercalate "\n" es))
+ where
+ help = "Printing usage:\n" ++ usage
+ err msg = "Error in command line options\n" ++ msg ++ "\n" ++ usage
+ usage = usageInfo ("Usage: " ++ prg ++ " OPTIONS") availableOptions
+
+availableOptions :: [OptDescr (Options -> Options)]
+availableOptions = [
+ Option "d" ["debug"] (ReqArg (\x opts -> opts {optDebugFile = x}) "debug") "file path for the debugging information (required)"
+ , Option "h" ["help"] (NoArg (\opts -> opts {optHelp = True})) "print help and quit"
+ ]
+
+defaultOptions :: Options
+defaultOptions = Options {
+ optDebugFile = ""
+ , optHelp = False
+ }
+
+checkOptions :: Options -> Bool
+checkOptions opts
+ | optDebugFile opts == optDebugFile defaultOptions = False
+ | otherwise = True
View
1  setup
@@ -1,3 +1,4 @@
export ROOT=`pwd`
export OCRAM=$ROOT/ocram/cabal-dev/bin/ocram
+export RUAB=$ROOT/ruab/cabal-dev/bin/ruab
export PATH=/home/alex/code/ghc-7.4.1/install/bin:/home/alex/code/haskell-platform-2012.2.0.0/install/bin:/home/alex/.cabal/bin:$PATH
Please sign in to comment.
Something went wrong with that request. Please try again.