diff --git a/apps/simplex-broadcast-bot/src/Broadcast/Options.hs b/apps/simplex-broadcast-bot/src/Broadcast/Options.hs index d9f091a13a..b25ee1cbcd 100644 --- a/apps/simplex-broadcast-bot/src/Broadcast/Options.hs +++ b/apps/simplex-broadcast-bot/src/Broadcast/Options.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP #-} {-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE NamedFieldPuns #-} @@ -87,6 +88,9 @@ mkChatOpts BroadcastBotOpts {coreOptions, botDisplayName} = chatCmdDelay = 3, chatCmdLog = CCLNone, chatServerPort = Nothing, +#if defined(picolisp) + evaluatePicolisp = Nothing, +#endif optFilesFolder = Nothing, optTempDirectory = Nothing, showReactions = False, diff --git a/apps/simplex-directory-service/src/Directory/Options.hs b/apps/simplex-directory-service/src/Directory/Options.hs index 7ad3512fe9..976141a958 100644 --- a/apps/simplex-directory-service/src/Directory/Options.hs +++ b/apps/simplex-directory-service/src/Directory/Options.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP #-} {-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE LambdaCase #-} @@ -162,6 +163,9 @@ mkChatOpts DirectoryOpts {coreOptions, serviceName} = chatCmdDelay = 3, chatCmdLog = CCLNone, chatServerPort = Nothing, +#if defined(picolisp) + evaluatePicolisp = Nothing, +#endif optFilesFolder = Nothing, optTempDirectory = Nothing, showReactions = False, diff --git a/simplex-chat.cabal b/simplex-chat.cabal index cb8cd4620a..14d9c79e6e 100644 --- a/simplex-chat.cabal +++ b/simplex-chat.cabal @@ -264,6 +264,11 @@ library Simplex.Chat.Store.SQLite.Migrations.M20250801_via_group_link_uri Simplex.Chat.Store.SQLite.Migrations.M20250802_chat_peer_type Simplex.Chat.Store.SQLite.Migrations.M20250813_delivery_tasks + if flag(picolisp) + -- extra-libraries: picolisp + cpp-options: -Dpicolisp + exposed-modules: + Simplex.Chat.Picolisp other-modules: Paths_simplex_chat hs-source-dirs: @@ -409,6 +414,11 @@ executable simplex-broadcast-bot default-language: Haskell2010 if flag(client_postgres) cpp-options: -DdbPostgres + if flag(picolisp) + -- extra-libraries: picolisp + cpp-options: -Dpicolisp + exposed-modules: + Simplex.Chat.Picolisp if impl(ghc >= 9.6.2) build-depends: text >=2.0.1 && <2.2 @@ -443,7 +453,10 @@ executable simplex-chat if flag(client_postgres) cpp-options: -DdbPostgres if flag(picolisp) - extra-libraries: picolisp + -- extra-libraries: picolisp + cpp-options: -Dpicolisp + exposed-modules: + Simplex.Chat.Picolisp if impl(ghc >= 9.6.2) build-depends: text >=2.0.1 && <2.2 @@ -491,6 +504,11 @@ executable simplex-directory-service default-language: Haskell2010 if flag(client_postgres) cpp-options: -DdbPostgres + if flag(picolisp) + -- extra-libraries: picolisp + cpp-options: -Dpicolisp + exposed-modules: + Simplex.Chat.Picolisp if impl(ghc >= 9.6.2) build-depends: bytestring ==0.11.* diff --git a/src/Simplex/Chat/Mobile.hs b/src/Simplex/Chat/Mobile.hs index fc61fa6fb5..63b522172d 100644 --- a/src/Simplex/Chat/Mobile.hs +++ b/src/Simplex/Chat/Mobile.hs @@ -261,6 +261,9 @@ mobileChatOpts dbOptions = chatCmdDelay = 3, chatCmdLog = CCLNone, chatServerPort = Nothing, +#if defined(picolisp) + evaluatePicolisp = Nothing, +#endif optFilesFolder = Nothing, optTempDirectory = Nothing, showReactions = False, diff --git a/src/Simplex/Chat/Options.hs b/src/Simplex/Chat/Options.hs index 2a224aca8b..661a64969e 100644 --- a/src/Simplex/Chat/Options.hs +++ b/src/Simplex/Chat/Options.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP #-} {-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE LambdaCase #-} @@ -29,13 +30,13 @@ import Data.Text.Encoding (encodeUtf8) import Numeric.Natural (Natural) import Options.Applicative import Simplex.Chat.Controller (ChatLogLevel (..), SimpleNetCfg (..), updateStr, versionNumber, versionString) +import Simplex.Chat.Options.DB import Simplex.FileTransfer.Description (mb) import Simplex.Messaging.Client (HostMode (..), SMPWebPortServers (..), SocksMode (..), textToHostMode) import Simplex.Messaging.Encoding.String import Simplex.Messaging.Parsers (parseAll) import Simplex.Messaging.Protocol (ProtoServerWithAuth, ProtocolTypeI, SMPServerWithAuth, XFTPServerWithAuth) -import Simplex.Messaging.Transport.Client (SocksProxyWithAuth (..), SocksAuth (..), defaultSocksProxyWithAuth) -import Simplex.Chat.Options.DB +import Simplex.Messaging.Transport.Client (SocksAuth (..), SocksProxyWithAuth (..), defaultSocksProxyWithAuth) data ChatOpts = ChatOpts { coreOptions :: CoreChatOpts, @@ -43,6 +44,9 @@ data ChatOpts = ChatOpts chatCmdDelay :: Int, chatCmdLog :: ChatCmdLog, chatServerPort :: Maybe String, +#if defined(picolisp) + evaluatePicolisp :: Maybe String, +#endif optFilesFolder :: Maybe FilePath, optTempDirectory :: Maybe FilePath, showReactions :: Bool, @@ -162,16 +166,17 @@ coreChatOptsP appDir defaultDbName = do <> help "Allow downgrade and connect directly: no, [when IP address is] protected (default), yes" ) smpWebPortServers <- - flag' SWPAll + flag' + SWPAll ( long "smp-web-port" <> help "Use port 443 with SMP servers when not specified" ) <|> option strParse - ( long "smp-web-port-servers" - <> help "Use port 443 with SMP servers when not specified: all, preset (default), off" - <> value SWPPreset - ) + ( long "smp-web-port-servers" + <> help "Use port 443 with SMP servers when not specified: all, preset (default), off" + <> value SWPPreset + ) t <- option auto @@ -278,7 +283,7 @@ coreChatOptsP appDir defaultDbName = do defaultHostMode :: Maybe SocksProxyWithAuth -> HostMode defaultHostMode = \case - Just (SocksProxyWithAuth SocksIsolateByAuth _) -> HMOnionViaSocks; + Just (SocksProxyWithAuth SocksIsolateByAuth _) -> HMOnionViaSocks _ -> HMPublic chatOptsP :: FilePath -> FilePath -> Parser ChatOpts @@ -319,6 +324,14 @@ chatOptsP appDir defaultDbName = do <> help "Run chat server on specified port" <> value Nothing ) +#if defined(picolisp) + evaluatePicolisp <- + optional $ + strOption + ( long "picolisp" + <> help "Evaluate picolisp expression" + ) +#endif optFilesFolder <- optional $ strOption @@ -389,6 +402,9 @@ chatOptsP appDir defaultDbName = do chatCmdDelay, chatCmdLog, chatServerPort, +#if defined(picolisp) + evaluatePicolisp, +#endif optFilesFolder, optTempDirectory, showReactions, diff --git a/src/Simplex/Chat/Terminal/Main.hs b/src/Simplex/Chat/Terminal/Main.hs index 38b0e91a8a..76091306ae 100644 --- a/src/Simplex/Chat/Terminal/Main.hs +++ b/src/Simplex/Chat/Terminal/Main.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP #-} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE NamedFieldPuns #-} @@ -20,6 +21,10 @@ import System.Directory (getAppUserDataDirectory) import System.Exit (exitFailure) import System.Terminal (withTerminal) +#if defined(picolisp) +import Simplex.Chat.Picolisp +#endif + simplexChatCLI :: ChatConfig -> Maybe (ServiceName -> ChatConfig -> ChatOpts -> IO ()) -> IO () simplexChatCLI cfg server_ = do appDir <- getAppUserDataDirectory "simplex" @@ -27,14 +32,19 @@ simplexChatCLI cfg server_ = do simplexChatCLI' cfg opts server_ simplexChatCLI' :: ChatConfig -> ChatOpts -> Maybe (ServiceName -> ChatConfig -> ChatOpts -> IO ()) -> IO () -simplexChatCLI' cfg opts@ChatOpts {chatCmd, chatCmdLog, chatCmdDelay, chatServerPort} server_ = do - if null chatCmd - then case chatServerPort of +simplexChatCLI' cfg opts@ChatOpts {chatCmd, chatCmdLog, chatCmdDelay, chatServerPort} server_ + | null chatCmd = case chatServerPort of Just chatPort -> case server_ of Just server -> server chatPort cfg opts Nothing -> putStrLn "Not allowed to run as a WebSockets server" >> exitFailure - _ -> runCLI - else simplexChatCore cfg opts runCommand +#if defined(picolisp) + Nothing -> case evaluatePicolisp opts of + Just code -> pure () + Nothing -> runCLI +#else + Nothing -> runCLI +#endif + | otherwise = simplexChatCore cfg opts runCommand where runCLI = do welcome cfg opts